Base version of ncurses-5.7 library
diff --git a/test/Makefile.in b/test/Makefile.in
new file mode 100644
index 0000000..a495eed
--- /dev/null
+++ b/test/Makefile.in
@@ -0,0 +1,117 @@
+# $Id: Makefile.in,v 1.102 2008/09/07 13:58:29 tom Exp $
+##############################################################################
+# Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.                #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+#
+# Author: Thomas E. Dickey 1996-on
+#
+# Makefile for ncurses tests.
+
+# turn off _all_ suffix rules; we'll generate our own
+.SUFFIXES:
+
+SHELL		= /bin/sh
+
+@SET_MAKE@
+
+destdir		=
+x		= @EXEEXT@
+o		= .@OBJEXT@
+
+MODEL		= ../@DFT_OBJ_SUBDIR@
+srcdir		= @srcdir@
+prefix		= @prefix@
+exec_prefix	= @exec_prefix@
+libdir		= @libdir@
+includedir	= @includedir@
+
+LIBTOOL		= @LIBTOOL@
+LIBTOOL_CLEAN	= @LIB_CLEAN@
+LIBTOOL_COMPILE	= @LIB_COMPILE@
+LIBTOOL_LINK	= @LIB_LINK@
+
+CC		= @CC@
+CPP		= @CPP@
+
+CFLAGS		= @CFLAGS@ @EXTRA_CFLAGS@
+CPPFLAGS	=  -I../test -I$(srcdir) -DHAVE_CONFIG_H @CPPFLAGS@
+
+CCFLAGS		= $(CPPFLAGS) $(CFLAGS)
+
+CFLAGS_LIBTOOL	= $(CCFLAGS)
+CFLAGS_NORMAL	= $(CCFLAGS)
+CFLAGS_DEBUG	= $(CCFLAGS) @CC_G_OPT@ -DTRACE
+CFLAGS_PROFILE	= $(CCFLAGS) -pg
+CFLAGS_SHARED	= $(CCFLAGS) @CC_SHARED_OPTS@
+
+CFLAGS_DEFAULT	= $(CFLAGS_@DFT_UPR_MODEL@)
+
+REL_VERSION	= @cf_cv_rel_version@
+ABI_VERSION	= @cf_cv_abi_version@
+LOCAL_LIBDIR	= @top_builddir@/lib
+LOCAL_LIBS	= @TEST_DEPS@
+MATH_LIB	= @MATH_LIB@
+TEST_LIBS	= @TEST_LIBS@
+
+LD		= @LD@
+LINK		= @LINK_TESTS@ $(LIBTOOL_LINK) $(CFLAGS)
+
+LDFLAGS		= @LD_MODEL@ @LOCAL_LDFLAGS@ @LDFLAGS@
+
+LDFLAGS_LIBTOOL	= $(LDFLAGS) $(CFLAGS_LIBTOOL)
+LDFLAGS_NORMAL	= $(LDFLAGS) $(CFLAGS_NORMAL)
+LDFLAGS_DEBUG	= $(LDFLAGS) $(CFLAGS_DEBUG)
+LDFLAGS_PROFILE	= $(LDFLAGS) $(CFLAGS_PROFILE)
+LDFLAGS_SHARED	= $(LDFLAGS) $(CFLAGS_SHARED) @LD_SHARED_OPTS@
+
+TEST_ARGS	= @LDFLAGS_STATIC@ @TEST_ARGS@ @LDFLAGS_SHARED@ 
+
+# use these for linking with all of the libraries
+LIBS_DEFAULT	= $(TEST_ARGS) @LIBS@ $(TEST_LIBS) $(MATH_LIB)
+LDFLAGS_DEFAULT	= $(LDFLAGS_@DFT_UPR_MODEL@) $(LIBS_DEFAULT)
+
+# use these for linking with the (n)curses library and possibly pthreads
+LIBS_THREADS	= `echo "$(TEST_ARGS) @LIBS@" | sed -e 's/-lform.*-lpanel[^ ]*//'` $(TEST_LIBS) $(MATH_LIB) @PTHREAD@
+LDFLAGS_THREADS	= $(LDFLAGS_@DFT_UPR_MODEL@) $(LIBS_THREADS)
+
+# use these for linking with the (n)curses library
+LIBS_CURSES	= `echo "$(TEST_ARGS) @LIBS@" | sed -e 's/-lform.*-lpanel[^ ]*//'` $(TEST_LIBS) $(MATH_LIB)
+LDFLAGS_CURSES	= $(LDFLAGS_@DFT_UPR_MODEL@) $(LIBS_CURSES)
+
+# use these for linking with the tinfo library if we have it, or curses library if not
+LIBS_TINFO	= @LDFLAGS_STATIC@ @TINFO_ARGS@ @LDFLAGS_SHARED@ @LIBS@ $(TEST_LIBS) $(MATH_LIB)
+LDFLAGS_TINFO	= $(LDFLAGS_@DFT_UPR_MODEL@) $(LIBS_TINFO)
+
+LINT		= @LINT@
+LINT_OPTS	= @LINT_OPTS@
+LINT_LIBS	= -lform -lmenu -lpanel -lncurses @LIBS@
+
+HEADER_DEPS	= \
+	../include/curses.h \
+	../include/term.h
+
+# The rest is generated from the "programs" and "modules" files...
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..8e1c8b6
--- /dev/null
+++ b/test/README
@@ -0,0 +1,679 @@
+-------------------------------------------------------------------------------
+-- Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.               --
+--                                                                           --
+-- Permission is hereby granted, free of charge, to any person obtaining a   --
+-- copy of this software and associated documentation files (the             --
+-- "Software"), to deal in the Software without restriction, including       --
+-- without limitation the rights to use, copy, modify, merge, publish,       --
+-- distribute, distribute with modifications, sublicense, and/or sell copies --
+-- of the Software, and to permit persons to whom the Software is furnished  --
+-- to do so, subject to the following conditions:                            --
+--                                                                           --
+-- The above copyright notice and this permission notice shall be included   --
+-- in all copies or substantial portions of the Software.                    --
+--                                                                           --
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS   --
+-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                --
+-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN --
+-- NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,       --
+-- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR     --
+-- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE --
+-- USE OR OTHER DEALINGS IN THE SOFTWARE.                                    --
+--                                                                           --
+-- Except as contained in this notice, the name(s) of the above copyright    --
+-- holders shall not be used in advertising or otherwise to promote the      --
+-- sale, use or other dealings in this Software without prior written        --
+-- authorization.                                                            --
+-------------------------------------------------------------------------------
+-- $Id: README,v 1.38 2008/10/18 21:02:45 tom Exp $
+-------------------------------------------------------------------------------
+
+The programs in this directory are designed to test your newest toy :-)
+Check the sources for any further details.
+
+blue       - Blue Moon, a nifty solitaire (uses color)
+bs.c       - the game of Battleships (uses color)
+firework.c - multi-colored fireworks (uses color)
+gdc.c      - Great Digital Clock (uses color)
+hanoi.c    - the game of hanoi (uses color essentially)
+knight.c   - the game of Knight's Tour (uses color)
+lrtest.c   - test of access to the lower-right corner
+ncurses.c  - multi-test program (uses color)
+newdemo.c  - another test from PDCurses (uses color)
+rain.c     - rain drops keep falling on my head...
+tclock.c   - analog/digital clock
+testcurs.c - a test from the PDCurses people (uses color)
+worm.c     - worms run all over your screen (uses color)
+xmas.c     - Xmas greeting card
+
+The bs and knight games demonstrate processing of mouse events under xterm.
+This directory also contains:
+
+tracemunch - Perl script to crunch trace scripts to make them easier to read
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+These programs provide examples of use, but do not comprise a complete set of
+tests.  Here is a list of library externals, noting those that are used:
+
+libform:
+-------
+TYPE_ALNUM			test: demo_forms
+TYPE_ALPHA			test: demo_forms ncurses
+TYPE_ENUM			test: demo_forms
+TYPE_INTEGER			test: demo_forms
+TYPE_IPV4			test: demo_forms
+TYPE_NUMERIC			test: demo_forms
+TYPE_REGEXP			test: demo_forms
+current_field			test: demo_forms edit_field ncurses
+data_ahead			test: demo_forms
+data_behind			test: demo_forms
+dup_field			-
+dynamic_field_info		test: demo_forms
+field_arg			test: demo_forms
+field_back			test: demo_forms
+field_buffer			test: cardfile demo_forms edit_field ncurses
+field_count			test: demo_forms
+field_fore			test: demo_forms
+field_index			test: demo_forms
+field_info			test: ncurses
+field_init			-
+field_just			-
+field_opts			test: demo_forms ncurses
+field_opts_off			test: cardfile demo_forms
+field_opts_on			test: demo_forms
+field_pad			test: demo_forms
+field_status			test: demo_forms
+field_term			-
+field_type			test: demo_forms
+field_userptr			test: edit_field ncurses
+form_driver			test: cardfile demo_forms edit_field ncurses
+form_fields			test: cardfile demo_forms
+form_init			-
+form_opts			-
+form_opts_off			-
+form_opts_on			-
+form_page			test: demo_forms
+form_request_by_name		-
+form_request_name		test: edit_field
+form_sub			test: cardfile demo_forms ncurses
+form_term			-
+form_userptr			-
+form_win			test: cardfile demo_forms edit_field ncurses
+free_field			test: cardfile demo_forms ncurses
+free_fieldtype			test: ncurses
+free_form			test: cardfile demo_forms ncurses
+link_field			-
+link_fieldtype			-
+move_field			-
+new_field			test: cardfile demo_forms ncurses
+new_fieldtype			test: ncurses
+new_form			test: cardfile demo_forms ncurses
+new_page			test: demo_forms
+pos_form_cursor			-
+post_form			test: cardfile demo_forms ncurses
+scale_form			test: demo_forms ncurses
+set_current_field		test: demo_forms
+set_field_back			test: cardfile demo_forms edit_field ncurses
+set_field_buffer		test: cardfile demo_forms edit_field ncurses
+set_field_fore			test: demo_forms
+set_field_init			-
+set_field_just			test: cardfile demo_forms
+set_field_opts			test: demo_forms ncurses
+set_field_pad			test: demo_forms
+set_field_status		test: demo_forms
+set_field_term			-
+set_field_type			test: demo_forms ncurses
+set_field_userptr		test: demo_forms ncurses
+set_fieldtype_arg		-
+set_fieldtype_choice		-
+set_form_fields			-
+set_form_init			-
+set_form_opts			-
+set_form_page			-
+set_form_sub			test: cardfile demo_forms ncurses
+set_form_term			-
+set_form_userptr		-
+set_form_win			test: cardfile demo_forms ncurses
+set_max_field			test: demo_forms
+set_new_page			test: demo_forms
+unpost_form			test: cardfile demo_forms ncurses
+
+libmenu:
+-------
+current_item			test: demo_menus ncurses
+free_item			test: ncurses
+free_menu			test: demo_menus ncurses
+item_count			test: demo_menus
+item_description		-
+item_index			test: demo_menus ncurses
+item_init			-
+item_name			test: demo_menus ncurses
+item_opts			-
+item_opts_off			-
+item_opts_on			-
+item_term			-
+item_userptr			-
+item_value			test: demo_menus ncurses
+item_visible			-
+menu_back			-
+menu_driver			test: demo_menus ncurses
+menu_fore			-
+menu_format			-
+menu_grey			-
+menu_init			-
+menu_items			test: demo_menus ncurses
+menu_mark			test: demo_menus
+menu_opts			-
+menu_opts_off			test: demo_menus ncurses
+menu_opts_on			test: demo_menus
+menu_pad			-
+menu_pattern			test: demo_menus
+menu_request_by_name		-
+menu_request_name		-
+menu_spacing			test: demo_menus
+menu_sub			test: demo_menus
+menu_term			-
+menu_userptr			-
+menu_win			test: demo_menus ncurses
+new_item			test: demo_menus ncurses
+new_menu			test: demo_menus ncurses
+pos_menu_cursor			lib: menu
+post_menu			test: demo_menus ncurses
+scale_menu			test: demo_menus ncurses
+set_current_item		-
+set_item_init			-
+set_item_opts			-
+set_item_term			-
+set_item_userptr		-
+set_item_value			test: demo_menus ncurses
+set_menu_back			test: demo_menus
+set_menu_fore			test: demo_menus
+set_menu_format			test: demo_menus ncurses
+set_menu_grey			-
+set_menu_init			-
+set_menu_items			-
+set_menu_mark			test: demo_menus
+set_menu_opts			-
+set_menu_pad			-
+set_menu_pattern		-
+set_menu_spacing		-
+set_menu_sub			test: demo_menus ncurses
+set_menu_term			-
+set_menu_userptr		-
+set_menu_win			test: demo_menus ncurses
+set_top_row			-
+top_row				-
+unpost_menu			test: demo_menus ncurses
+
+libncurses:
+----------
+BC				-
+COLORS				test: echochar ncurses savescreen xmas
+COLOR_PAIR			test: background blue bs cardfile demo_forms demo_menus demo_panels echochar filter firework gdc hanoi ins_wide inserts knight ncurses newdemo rain savescreen tclock testaddch testcurs view worm xmas
+COLOR_PAIRS			test: echochar ncurses newdemo savescreen
+COLS				test: cardfile demo_altkeys demo_defkey demo_forms demo_keyok demo_menus demo_panels ditto echochar edit_field firework foldkeys hashtest inch_wide inchs ins_wide inserts lrtest movewindow ncurses newdemo rain savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs view worm
+ESCDELAY			test: test_opaque
+LINES				test: cardfile demo_defkey demo_keyok demo_menus demo_panels ditto echochar edit_field firework hanoi hashtest inch_wide inchs ins_wide inserts lrtest movewindow ncurses newdemo rain savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs view worm xmas
+PAIR_NUMBER			test: ncurses
+PC				lib: ncurses
+SP				lib: ncurses
+TABSIZE				test: test_opaque
+UP				-
+acs_map				test: gdc ins_wide inserts knight movewindow ncurses newdemo testcurs
+add_wch				test: demo_panels ncurses
+add_wchnstr			-
+add_wchstr			test: view
+addch				test: blue bs echochar hashtest ncurses savescreen test_opaque testaddch view worm
+addchnstr			-
+addchstr			-
+addnstr				-
+addnwstr			test: ncurses
+addstr				test: blue bs cardfile gdc hanoi lrtest ncurses savescreen
+addwstr				test: ncurses
+assume_default_colors		test: ncurses
+attr_get			test: ncurses
+attr_off			test: ncurses
+attr_on				test: ncurses
+attr_set			test: ncurses
+attroff				test: echochar filter gdc ncurses tclock
+attron				test: bs echochar filter gdc ncurses
+attrset				test: bs firework gdc hanoi ncurses rain tclock testaddch testcurs
+baudrate			lib: ncurses
+beep				test: blue bs cardfile chgat demo_forms demo_menus demo_panels edit_field hanoi inch_wide inchs ins_wide inserts knight movewindow ncurses savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs view xmas
+bkgd				test: background cardfile demo_forms ncurses savescreen tclock view
+bkgdset				test: background ncurses testaddch
+bkgrnd				test: ncurses
+bkgrndset			test: ncurses
+boolcodes			test: test_arrays progs: dump_entry
+boolfnames			test: test_arrays progs: dump_entry
+boolnames			test: test_arrays progs: dump_entry infocmp
+border				-
+border_set			-
+box				test: cardfile chgat demo_forms demo_menus demo_panels ditto edit_field inch_wide inchs ins_wide inserts lrtest ncurses newdemo redraw test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs
+box_set				test: ncurses
+can_change_color		test: ncurses
+cbreak				test: background blue bs cardfile chgat color_set demo_altkeys demo_defkey demo_forms demo_keyok demo_menus demo_panels ditto filter firework foldkeys gdc hanoi hashtest inch_wide inchs ins_wide inserts knight lrtest movewindow ncurses newdemo savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs view worm xmas
+chgat				test: chgat
+clear				test: blue bs gdc ncurses testcurs xmas
+clearok				test: bs knight
+clrtobot			test: demo_menus ncurses
+clrtoeol			test: blue bs demo_altkeys demo_menus foldkeys hanoi hashtest movewindow ncurses view
+color_content			test: ncurses
+color_set			test: color_set ncurses
+copywin				test: ncurses testcurs
+cur_term			test: dots dots_mvcur lrtest progs: clear tput tset
+curs_set			test: echochar firework gdc hanoi lrtest ncurses newdemo rain savescreen tclock testcurs worm xmas
+curscr				test: demo_panels edit_field knight lrtest ncurses savescreen tclock view
+curses_version			test: ncurses progs: infocmp tic toe tput tset
+def_prog_mode			test: bs ncurses
+def_shell_mode			lib: ncurses
+define_key			test: demo_altkeys demo_defkey foldkeys
+del_curterm			lib: ncurses
+delay_output			test: newdemo
+delch				-
+deleteln			-
+delscreen			test: ditto dots_mvcur
+delwin				test: cardfile chgat demo_forms demo_panels edit_field inch_wide inchs ins_wide inserts movewindow ncurses newdemo redraw test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs
+derwin				test: cardfile chgat demo_forms demo_menus ditto inch_wide inchs ins_wide inserts movewindow ncurses test_get_wstr test_getstr test_instr test_inwstr test_opaque
+doupdate			test: cardfile demo_menus demo_panels ditto edit_field ins_wide inserts knight movewindow ncurses redraw savescreen test_get_wstr test_getstr
+dupwin				test: edit_field
+echo				test: bs hanoi ncurses test_get_wstr test_getstr testcurs testscanw
+echo_wchar			test: ncurses
+echochar			test: echochar ncurses
+endwin				test: background blue bs cardfile chgat color_set demo_altkeys demo_defkey demo_forms demo_keyok demo_menus demo_panels ditto dots_mvcur echochar filter firework firstlast foldkeys gdc hanoi hashtest inch_wide inchs ins_wide inserts key_names keynames knight lrtest movewindow ncurses newdemo rain redraw savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testaddch testcurs testscanw view worm xmas
+erase				test: cardfile demo_menus filter firework firstlast hanoi lrtest ncurses tclock test_opaque testcurs
+erasechar			lib: ncurses
+erasewchar			-
+filter				test: filter
+flash				test: cardfile lrtest ncurses tclock testcurs
+flushinp			test: ncurses newdemo testcurs
+get_wch				-
+get_wstr			test: test_get_wstr
+getattrs			-
+getbegx				test: chgat demo_menus demo_panels movewindow ncurses newdemo redraw testcurs
+getbegy				test: chgat demo_menus demo_panels movewindow ncurses newdemo redraw testcurs
+getbkgd				test: ncurses
+getbkgrnd			test: ncurses
+getcchar			test: ncurses view
+getch				test: background blue bs chgat color_set demo_altkeys filter firework firstlast foldkeys hanoi hashtest lrtest savescreen tclock test_opaque testaddch testcurs view xmas
+getcurx				test: bs chgat demo_altkeys demo_defkey demo_panels foldkeys movewindow ncurses redraw savescreen test_get_wstr test_getstr test_opaque testcurs
+getcury				test: bs chgat demo_altkeys demo_defkey demo_panels edit_field foldkeys movewindow ncurses redraw savescreen test_opaque testcurs
+getmaxx				test: chgat demo_panels inch_wide inchs movewindow ncurses newdemo redraw test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs
+getmaxy				test: chgat demo_forms demo_panels inch_wide inchs movewindow ncurses newdemo redraw test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs
+getmouse			test: bs knight movewindow ncurses
+getn_wstr			test: test_get_wstr
+getnstr				test: filter ncurses test_getstr
+getparx				test: movewindow
+getpary				test: movewindow
+getstr				test: test_getstr
+getwin				test: ncurses
+halfdelay			test: view
+has_colors			test: background bs cardfile chgat color_set demo_forms demo_menus demo_panels echochar filter firework gdc hanoi ins_wide inserts knight ncurses newdemo rain savescreen tclock testcurs view worm xmas
+has_ic				test: lrtest
+has_il				lib: ncurses
+has_key				lib: ncurses
+hline				test: gdc ncurses
+hline_set			-
+idcok				test: test_opaque
+idlok				test: ncurses test_opaque testscanw view
+immedok				test: test_opaque
+in_wch				test: inch_wide
+in_wchnstr			test: inch_wide
+in_wchstr			test: inch_wide
+inch				test: inchs
+inchnstr			test: inchs
+inchstr				test: inchs
+init_color			test: ncurses
+init_pair			test: background blue bs cardfile chgat color_set demo_forms demo_menus demo_panels echochar filter firework gdc hanoi ins_wide inserts knight ncurses newdemo rain savescreen tclock testaddch testcurs view worm xmas
+initscr				test: background blue bs cardfile chgat color_set demo_defkey demo_forms demo_keyok demo_menus demo_panels echochar firework firstlast gdc hanoi hashtest inch_wide inchs ins_wide inserts knight lrtest movewindow ncurses newdemo rain redraw savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testaddch testcurs testscanw view worm xmas
+innstr				test: test_instr
+innwstr				test: test_inwstr
+ins_nwstr			test: ins_wide
+ins_wch				test: ins_wide
+ins_wstr			test: ins_wide
+insch				test: ins_wide inserts
+insdelln			-
+insertln			-
+insnstr				test: inserts
+insstr				test: inserts
+instr				test: test_instr
+intrflush			test: demo_forms movewindow
+inwstr				test: test_inwstr
+is_cleared			test: test_opaque
+is_idcok			test: test_opaque
+is_idlok			test: test_opaque
+is_immedok			test: test_opaque
+is_keypad			test: test_opaque
+is_leaveok			test: test_opaque
+is_linetouched			lib: form
+is_nodelay			test: test_opaque
+is_notimeout			test: test_opaque
+is_scrollok			test: test_opaque
+is_syncok			test: test_opaque
+is_term_resized			-
+is_wintouched			lib: ncurses
+isendwin			-
+key_defined			test: demo_defkey foldkeys
+key_name			test: key_names ncurses
+keybound			test: demo_altkeys demo_defkey
+keyname				test: demo_altkeys demo_defkey demo_keyok demo_menus edit_field foldkeys keynames movewindow ncurses redraw testcurs view progs: tic
+keyok				test: demo_keyok foldkeys
+keypad				test: bs cardfile chgat demo_altkeys demo_defkey demo_forms demo_keyok demo_menus demo_panels ditto edit_field filter firework foldkeys hashtest inch_wide inchs ins_wide inserts key_names keynames knight lrtest movewindow ncurses redraw savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs testscanw view
+killchar			lib: ncurses
+killwchar			-
+leaveok				test: hanoi test_opaque
+longname			test: testcurs progs: tput
+mcprint				-
+meta				test: key_names keynames ncurses
+mouse_trafo			-
+mouseinterval			-
+mousemask			test: bs demo_forms demo_menus knight movewindow ncurses
+move				test: blue bs cardfile chgat demo_altkeys demo_menus echochar foldkeys gdc hanoi hashtest inch_wide inchs ins_wide inserts knight lrtest movewindow ncurses savescreen test_get_wstr test_getstr test_instr test_inwstr test_opaque testscanw view xmas
+mvadd_wch			test: ncurses
+mvadd_wchnstr			-
+mvadd_wchstr			-
+mvaddch				test: bs gdc hanoi lrtest ncurses rain tclock xmas
+mvaddchnstr			test: gdc
+mvaddchstr			-
+mvaddnstr			-
+mvaddnwstr			-
+mvaddstr			test: bs demo_forms gdc hanoi knight ncurses rain tclock testcurs xmas
+mvaddwstr			-
+mvchgat				test: chgat
+mvcur				test: dots_mvcur redraw
+mvdelch				-
+mvderwin			test: movewindow
+mvget_wch			-
+mvget_wstr			test: test_get_wstr
+mvgetch				-
+mvgetn_wstr			test: test_get_wstr
+mvgetnstr			test: test_getstr
+mvgetstr			test: test_getstr
+mvhline				test: ncurses
+mvhline_set			test: ncurses
+mvin_wch			test: inch_wide
+mvin_wchnstr			test: inch_wide
+mvin_wchstr			test: inch_wide
+mvinch				test: inchs
+mvinchnstr			test: gdc inchs
+mvinchstr			test: inchs
+mvinnstr			test: test_instr
+mvinnwstr			test: test_inwstr
+mvins_nwstr			test: ins_wide
+mvins_wch			test: ins_wide
+mvins_wstr			test: ins_wide
+mvinsch				test: ins_wide inserts
+mvinsnstr			test: inserts
+mvinsstr			test: inserts
+mvinstr				test: test_instr
+mvinwstr			test: test_inwstr
+mvprintw			test: bs demo_menus firework hanoi ncurses tclock view
+mvscanw				-
+mvvline				test: ncurses
+mvvline_set			test: ncurses
+mvwadd_wch			-
+mvwadd_wchnstr			lib: form
+mvwadd_wchstr			test: inch_wide
+mvwaddch			test: movewindow newdemo testcurs xmas
+mvwaddchnstr			-
+mvwaddchstr			test: inchs
+mvwaddnstr			test: newdemo testcurs
+mvwaddnwstr			-
+mvwaddstr			test: ditto firstlast ins_wide inserts knight ncurses newdemo test_instr testcurs xmas
+mvwaddwstr			test: test_inwstr
+mvwchgat			test: chgat
+mvwdelch			test: ncurses
+mvwget_wch			-
+mvwget_wstr			test: test_get_wstr
+mvwgetch			test: inch_wide inchs test_get_wstr test_getstr test_instr test_inwstr test_opaque
+mvwgetn_wstr			test: test_get_wstr
+mvwgetnstr			test: test_getstr
+mvwgetstr			test: test_getstr
+mvwhline			test: movewindow
+mvwhline_set			-
+mvwin				test: cardfile demo_menus movewindow testcurs xmas
+mvwin_wch			test: inch_wide
+mvwin_wchnstr			test: inch_wide
+mvwin_wchstr			test: inch_wide
+mvwinch				test: inchs newdemo testcurs
+mvwinchnstr			test: inchs
+mvwinchstr			test: inchs
+mvwinnstr			test: test_instr testcurs
+mvwinnwstr			test: test_inwstr
+mvwins_nwstr			test: ins_wide
+mvwins_wch			test: ins_wide
+mvwins_wstr			test: ins_wide
+mvwinsch			test: ins_wide inserts
+mvwinsnstr			test: inserts
+mvwinsstr			test: inserts testcurs
+mvwinstr			test: test_instr
+mvwinwstr			test: test_inwstr
+mvwprintw			test: chgat demo_panels inch_wide inchs ncurses test_instr test_inwstr testcurs
+mvwscanw			test: testcurs
+mvwvline			test: ins_wide inserts movewindow
+mvwvline_set			-
+napms				test: demo_panels ditto dots dots_mvcur echochar firework gdc hanoi lrtest ncurses railroad rain tclock test_opaque testcurs view worm xmas progs: tset
+newpad				test: edit_field ncurses testcurs
+newscr				lib: ncurses
+newterm				test: demo_altkeys ditto dots_mvcur filter foldkeys gdc key_names keynames
+newwin				test: cardfile chgat demo_defkey demo_forms demo_keyok demo_menus demo_panels ditto edit_field firstlast inch_wide inchs ins_wide inserts knight movewindow ncurses newdemo redraw test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs xmas
+nl				test: demo_forms ncurses rain testcurs
+nocbreak			test: testcurs
+nodelay				test: ditto firework gdc lrtest ncurses newdemo rain tclock test_opaque view worm xmas
+noecho				test: background bs cardfile chgat color_set demo_altkeys demo_defkey demo_forms demo_keyok demo_menus demo_panels ditto firework firstlast foldkeys gdc hanoi hashtest inch_wide inchs ins_wide inserts knight lrtest movewindow ncurses rain redraw savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs view worm xmas
+nofilter			-
+nonl				test: bs demo_forms hashtest movewindow ncurses view worm xmas
+noqiflush			-
+noraw				test: demo_forms demo_menus ncurses testcurs
+notimeout			test: test_opaque
+numcodes			test: test_arrays progs: dump_entry
+numfnames			test: test_arrays progs: dump_entry
+numnames			test: test_arrays progs: dump_entry infocmp
+ospeed				progs: tset
+overlay				test: ncurses testcurs xmas
+overwrite			test: ncurses savescreen
+pair_content			test: background color_set
+pecho_wchar			-
+pechochar			-
+pnoutrefresh			test: edit_field ncurses
+prefresh			test: testcurs
+printw				test: background blue bs color_set demo_altkeys demo_defkey demo_keyok demo_menus filter foldkeys ncurses savescreen testcurs testscanw view
+putp				progs: tput
+putwin				test: ncurses
+qiflush				-
+raw				test: demo_forms ncurses redraw testcurs
+redrawwin			test: redraw
+refresh				test: blue bs demo_defkey demo_forms demo_keyok demo_menus demo_panels echochar filter firstlast gdc hanoi hashtest lrtest movewindow ncurses savescreen tclock testcurs view xmas
+reset_prog_mode			test: filter ncurses
+reset_shell_mode		test: bs filter savescreen
+resetty				-
+resize_term			test: view
+resizeterm			lib: ncurses
+restartterm			-
+ripoffline			test: demo_menus ncurses
+savetty				-
+scanw				test: testcurs testscanw
+scr_dump			test: savescreen
+scr_init			test: savescreen
+scr_restore			test: savescreen
+scr_set				test: savescreen
+scrl				test: view
+scroll				test: testcurs
+scrollok			test: demo_altkeys demo_defkey demo_keyok demo_panels ditto foldkeys hashtest knight ncurses redraw test_opaque testcurs testscanw view
+set_curterm			lib: ncurses
+set_escdelay			test: test_opaque
+set_tabsize			test: test_opaque
+set_term			lib: ncurses
+setcchar			test: demo_panels ins_wide ncurses view
+setscrreg			test: view
+setupterm			test: dots progs: clear tput tset
+slk_attr			-
+slk_attr_off			-
+slk_attr_on			-
+slk_attr_set			-
+slk_attroff			lib: ncurses
+slk_attron			lib: ncurses
+slk_attrset			-
+slk_clear			test: ncurses
+slk_color			test: ncurses
+slk_init			test: ncurses
+slk_label			test: ncurses
+slk_noutrefresh			-
+slk_refresh			test: ncurses
+slk_restore			test: ncurses
+slk_set				test: ncurses
+slk_touch			lib: ncurses
+slk_wset			test: ncurses
+standend			test: blue gdc ncurses
+standout			test: blue ncurses
+start_color			test: background blue bs cardfile chgat color_set demo_forms demo_menus demo_panels echochar filter firework gdc hanoi ins_wide inserts knight ncurses newdemo rain savescreen tclock testaddch testcurs view worm xmas
+stdscr				test: bs chgat demo_altkeys demo_forms demo_menus demo_panels ditto filter firework foldkeys gdc hanoi hashtest inch_wide inchs ins_wide inserts key_names keynames knight lrtest movewindow ncurses rain redraw savescreen tclock test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs testscanw view worm xmas
+strcodes			test: test_arrays progs: dump_entry
+strfnames			test: test_arrays progs: dump_entry
+strnames			test: foldkeys test_arrays progs: dump_entry infocmp tic
+subpad				test: testcurs
+subwin				test: movewindow ncurses newdemo testcurs
+syncok				test: test_opaque
+term_attrs			test: ncurses
+termattrs			test: ncurses testcurs
+termname			test: testcurs
+tgetent				test: demo_termcap railroad
+tgetflag			test: demo_termcap
+tgetnum				test: demo_termcap railroad
+tgetstr				test: demo_termcap railroad
+tgoto				test: railroad
+tigetflag			progs: tput
+tigetnum			test: ncurses progs: tput
+tigetstr			test: blue demo_defkey foldkeys testcurs progs: tput
+timeout				test: rain savescreen
+touchline			test: chgat
+touchwin			test: chgat demo_menus edit_field filter firstlast inch_wide inchs ins_wide inserts movewindow ncurses redraw test_get_wstr test_getstr test_instr test_inwstr test_opaque xmas
+tparm				test: dots dots_mvcur progs: tic tput
+tputs				test: dots dots_mvcur railroad progs: clear tset
+trace				test: demo_menus hanoi hashtest lrtest ncurses testcurs view worm
+ttytype				lib: ncurses
+typeahead			test: testcurs
+unctrl				test: ncurses redraw testcurs
+unget_wch			-
+ungetch				test: bs knight
+ungetmouse			-
+untouchwin			lib: form
+use_default_colors		test: filter firework gdc hanoi knight ncurses rain tclock worm xmas
+use_env				progs: tput
+use_extended_names		progs: infocmp tic
+use_legacy_coding		-
+use_screen			test: ditto
+use_window			test: rain worm
+vid_attr			-
+vid_puts			-
+vidattr				lib: ncurses
+vidputs				lib: ncurses
+vline				test: gdc ncurses
+vline_set			-
+vw_printw			-
+vw_scanw			-
+vwprintw			test: movewindow
+vwscanw				lib: ncurses
+wadd_wch			test: inch_wide
+wadd_wchnstr			lib: form
+wadd_wchstr			-
+waddch				test: demo_forms demo_panels ditto firstlast inch_wide inchs knight ncurses test_get_wstr test_getstr test_instr test_inwstr test_opaque worm
+waddchnstr			lib: ncurses
+waddchstr			-
+waddnstr			lib: menu
+waddnwstr			test: ncurses
+waddstr				test: chgat demo_forms demo_panels edit_field firstlast ins_wide knight ncurses redraw testcurs
+waddwstr			test: ins_wide test_get_wstr
+wattr_get			-
+wattr_off			lib: ncurses
+wattr_on			lib: ncurses
+wattr_set			-
+wattroff			test: demo_forms ncurses testcurs xmas
+wattron				test: testcurs xmas
+wattrset			test: demo_forms ncurses newdemo test_get_wstr test_getstr testcurs xmas
+wbkgd				test: cardfile demo_forms demo_menus ncurses newdemo testcurs
+wbkgdset			test: demo_panels ins_wide inserts ncurses
+wbkgrnd				lib: ncurses
+wbkgrndset			lib: ncurses
+wborder				lib: ncurses
+wborder_set			lib: ncurses
+wchgat				test: chgat test_get_wstr test_getstr view
+wclear				test: ncurses test_opaque testcurs
+wclrtobot			test: firstlast inch_wide inchs ncurses test_instr test_inwstr testcurs
+wclrtoeol			test: chgat demo_defkey demo_keyok demo_panels firstlast inch_wide inchs ins_wide inserts knight ncurses test_instr test_inwstr testcurs
+wcolor_set			lib: ncurses
+wcursyncup			lib: form
+wdelch				test: ncurses testcurs
+wdeleteln			test: testcurs
+wecho_wchar			lib: ncurses
+wechochar			lib: ncurses
+wenclose			lib: form
+werase				test: cardfile demo_forms demo_menus demo_panels edit_field firstlast knight ncurses newdemo test_get_wstr test_getstr test_opaque testcurs xmas
+wget_wch			test: ins_wide ncurses
+wget_wstr			test: test_get_wstr
+wgetbkgrnd			lib: ncurses
+wgetch				test: cardfile chgat demo_defkey demo_keyok demo_menus demo_panels ditto edit_field gdc inserts knight movewindow ncurses newdemo rain redraw test_opaque testcurs worm
+wgetn_wstr			test: ncurses test_get_wstr
+wgetnstr			test: ncurses test_getstr
+wgetparent			test: test_opaque
+wgetscrreg			test: test_opaque
+wgetstr				test: test_getstr
+whline				test: testcurs
+whline_set			lib: ncurses
+win_wch				test: inch_wide
+win_wchnstr			test: inch_wide
+win_wchstr			test: inch_wide
+winch				test: inchs knight testcurs
+winchnstr			test: inchs
+winchstr			test: inchs
+winnstr				test: demo_altkeys demo_defkey foldkeys test_instr
+winnwstr			test: test_inwstr
+wins_nwstr			test: ins_wide
+wins_wch			test: ins_wide
+wins_wstr			test: ins_wide
+winsch				test: ins_wide inserts testcurs
+winsdelln			lib: ncurses
+winsertln			test: testcurs
+winsnstr			test: inserts
+winsstr				test: inserts
+winstr				test: test_instr
+winwstr				test: test_inwstr
+wmouse_trafo			lib: form
+wmove				test: chgat demo_altkeys demo_defkey demo_keyok demo_menus demo_panels firstlast foldkeys inch_wide inchs ins_wide inserts knight movewindow ncurses newdemo redraw test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs worm
+wnoutrefresh			test: demo_menus ditto edit_field inch_wide inchs ins_wide inserts knight movewindow ncurses redraw test_get_wstr test_getstr test_instr test_inwstr test_opaque
+wprintw				test: chgat demo_defkey demo_forms demo_keyok demo_menus demo_panels edit_field inch_wide inchs ins_wide inserts knight movewindow ncurses test_get_wstr test_getstr test_instr test_inwstr test_opaque testcurs
+wredrawln			test: redraw
+wrefresh			test: chgat demo_forms demo_keyok demo_menus demo_panels edit_field firstlast knight lrtest movewindow ncurses newdemo redraw savescreen tclock testcurs view worm xmas
+wresize				test: cardfile ncurses
+wscanw				test: testcurs
+wscrl				test: ncurses testcurs
+wsetscrreg			test: ncurses testcurs
+wstandend			test: test_opaque xmas
+wstandout			test: test_opaque xmas
+wsyncdown			test: movewindow
+wsyncup				lib: form
+wtimeout			test: ncurses
+wtouchln			lib: ncurses
+wunctrl				lib: ncurses
+wvline				test: testcurs
+wvline_set			lib: ncurses
+
+libpanel:
+--------
+bottom_panel			test: demo_panels ncurses
+del_panel			test: demo_panels ncurses
+hide_panel			test: demo_panels ncurses
+move_panel			test: demo_panels ncurses
+new_panel			test: cardfile demo_panels ncurses
+panel_above			test: demo_panels
+panel_below			test: demo_panels
+panel_hidden			test: demo_panels
+panel_userptr			test: demo_panels ncurses
+panel_window			test: cardfile demo_panels ncurses
+replace_panel			test: demo_panels
+set_panel_userptr		test: demo_panels ncurses
+show_panel			test: demo_panels ncurses
+top_panel			test: cardfile demo_panels ncurses
+update_panels			test: cardfile demo_panels ncurses
diff --git a/test/aclocal.m4 b/test/aclocal.m4
new file mode 100644
index 0000000..afc50fe
--- /dev/null
+++ b/test/aclocal.m4
@@ -0,0 +1,2141 @@
+dnl***************************************************************************
+dnl Copyright (c) 2003-2007,2008 Free Software Foundation, Inc.              *
+dnl                                                                          *
+dnl Permission is hereby granted, free of charge, to any person obtaining a  *
+dnl copy of this software and associated documentation files (the            *
+dnl "Software"), to deal in the Software without restriction, including      *
+dnl without limitation the rights to use, copy, modify, merge, publish,      *
+dnl distribute, distribute with modifications, sublicense, and/or sell       *
+dnl copies of the Software, and to permit persons to whom the Software is    *
+dnl furnished to do so, subject to the following conditions:                 *
+dnl                                                                          *
+dnl The above copyright notice and this permission notice shall be included  *
+dnl in all copies or substantial portions of the Software.                   *
+dnl                                                                          *
+dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+dnl IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+dnl DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+dnl OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+dnl THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+dnl                                                                          *
+dnl Except as contained in this notice, the name(s) of the above copyright   *
+dnl holders shall not be used in advertising or otherwise to promote the     *
+dnl sale, use or other dealings in this Software without prior written       *
+dnl authorization.                                                           *
+dnl***************************************************************************
+dnl
+dnl $Id: aclocal.m4,v 1.22 2008/02/09 18:22:17 tom Exp $
+dnl
+dnl Author: Thomas E. Dickey
+dnl
+dnl Macros used in NCURSES test programs auto-configuration script.
+dnl
+dnl These macros are maintained separately from NCURSES.  The copyright on
+dnl this file applies to the aggregation of macros and does not affect use of
+dnl these macros in other applications.
+dnl
+dnl See http://invisible-island.net/autoconf/ for additional information.
+dnl
+dnl ---------------------------------------------------------------------------
+dnl ---------------------------------------------------------------------------
+dnl CF_ADD_CFLAGS version: 7 updated: 2004/04/25 17:48:30
+dnl -------------
+dnl Copy non-preprocessor flags to $CFLAGS, preprocessor flags to $CPPFLAGS
+dnl The second parameter if given makes this macro verbose.
+dnl
+dnl Put any preprocessor definitions that use quoted strings in $EXTRA_CPPFLAGS,
+dnl to simplify use of $CPPFLAGS in compiler checks, etc., that are easily
+dnl confused by the quotes (which require backslashes to keep them usable).
+AC_DEFUN([CF_ADD_CFLAGS],
+[
+cf_fix_cppflags=no
+cf_new_cflags=
+cf_new_cppflags=
+cf_new_extra_cppflags=
+
+for cf_add_cflags in $1
+do
+case $cf_fix_cppflags in
+no)
+	case $cf_add_cflags in #(vi
+	-undef|-nostdinc*|-I*|-D*|-U*|-E|-P|-C) #(vi
+		case $cf_add_cflags in
+		-D*)
+			cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^-D[[^=]]*='\''\"[[^"]]*//'`
+
+			test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+			&& test -z "${cf_tst_cflags}" \
+			&& cf_fix_cppflags=yes
+
+			if test $cf_fix_cppflags = yes ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			elif test "${cf_tst_cflags}" = "\"'" ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			fi
+			;;
+		esac
+		case "$CPPFLAGS" in
+		*$cf_add_cflags) #(vi
+			;;
+		*) #(vi
+			cf_new_cppflags="$cf_new_cppflags $cf_add_cflags"
+			;;
+		esac
+		;;
+	*)
+		cf_new_cflags="$cf_new_cflags $cf_add_cflags"
+		;;
+	esac
+	;;
+yes)
+	cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+
+	cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^[[^"]]*"'\''//'`
+
+	test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+	&& test -z "${cf_tst_cflags}" \
+	&& cf_fix_cppflags=no
+	;;
+esac
+done
+
+if test -n "$cf_new_cflags" ; then
+	ifelse($2,,,[CF_VERBOSE(add to \$CFLAGS $cf_new_cflags)])
+	CFLAGS="$CFLAGS $cf_new_cflags"
+fi
+
+if test -n "$cf_new_cppflags" ; then
+	ifelse($2,,,[CF_VERBOSE(add to \$CPPFLAGS $cf_new_cppflags)])
+	CPPFLAGS="$cf_new_cppflags $CPPFLAGS"
+fi
+
+if test -n "$cf_new_extra_cppflags" ; then
+	ifelse($2,,,[CF_VERBOSE(add to \$EXTRA_CPPFLAGS $cf_new_extra_cppflags)])
+	EXTRA_CPPFLAGS="$cf_new_extra_cppflags $EXTRA_CPPFLAGS"
+fi
+
+AC_SUBST(EXTRA_CPPFLAGS)
+
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ADD_INCDIR version: 9 updated: 2008/02/09 13:15:34
+dnl -------------
+dnl Add an include-directory to $CPPFLAGS.  Don't add /usr/include, since it's
+dnl redundant.  We don't normally need to add -I/usr/local/include for gcc,
+dnl but old versions (and some misinstalled ones) need that.  To make things
+dnl worse, gcc 3.x may give error messages if -I/usr/local/include is added to
+dnl the include-path).
+AC_DEFUN([CF_ADD_INCDIR],
+[
+if test -n "$1" ; then
+  for cf_add_incdir in $1
+  do
+	while test $cf_add_incdir != /usr/include
+	do
+	  if test -d $cf_add_incdir
+	  then
+		cf_have_incdir=no
+		if test -n "$CFLAGS$CPPFLAGS" ; then
+		  # a loop is needed to ensure we can add subdirs of existing dirs
+		  for cf_test_incdir in $CFLAGS $CPPFLAGS ; do
+			if test ".$cf_test_incdir" = ".-I$cf_add_incdir" ; then
+			  cf_have_incdir=yes; break
+			fi
+		  done
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+          if test "$cf_add_incdir" = /usr/local/include ; then
+			if test "$GCC" = yes
+			then
+			  cf_save_CPPFLAGS=$CPPFLAGS
+			  CPPFLAGS="$CPPFLAGS -I$cf_add_incdir"
+			  AC_TRY_COMPILE([#include <stdio.h>],
+				  [printf("Hello")],
+				  [],
+				  [cf_have_incdir=yes])
+			  CPPFLAGS=$cf_save_CPPFLAGS
+			fi
+		  fi
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+		  CF_VERBOSE(adding $cf_add_incdir to include-path)
+		  ifelse($2,,CPPFLAGS,$2)="-I$cf_add_incdir $ifelse($2,,CPPFLAGS,[$]$2)"
+
+          cf_top_incdir=`echo $cf_add_incdir | sed -e 's%/include/.*$%/include%'`
+          test "$cf_top_incdir" = "$cf_add_incdir" && break
+          cf_add_incdir="$cf_top_incdir"
+		else
+		  break
+		fi
+	  fi
+	done
+  done
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ADD_LIBDIR version: 6 updated: 2008/02/09 13:15:34
+dnl -------------
+dnl	Adds to the library-path
+dnl
+dnl	Some machines have trouble with multiple -L options.
+dnl
+dnl $1 is the (list of) directory(s) to add
+dnl $2 is the optional name of the variable to update (default LDFLAGS)
+dnl
+AC_DEFUN([CF_ADD_LIBDIR],
+[
+if test -n "$1" ; then
+  for cf_add_libdir in $1
+  do
+    if test $cf_add_libdir = /usr/lib ; then
+      :
+    elif test -d $cf_add_libdir
+    then
+      cf_have_libdir=no
+      if test -n "$LDFLAGS$LIBS" ; then
+        # a loop is needed to ensure we can add subdirs of existing dirs
+        for cf_test_libdir in $LDFLAGS $LIBS ; do
+          if test ".$cf_test_libdir" = ".-L$cf_add_libdir" ; then
+            cf_have_libdir=yes; break
+          fi
+        done
+      fi
+      if test "$cf_have_libdir" = no ; then
+        CF_VERBOSE(adding $cf_add_libdir to library-path)
+        ifelse($2,,LDFLAGS,$2)="-L$cf_add_libdir $ifelse($2,,LDFLAGS,[$]$2)"
+      fi
+    fi
+  done
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ADD_SUBDIR_PATH version: 2 updated: 2007/07/29 10:12:59
+dnl ------------------
+dnl Append to a search-list for a nonstandard header/lib-file
+dnl	$1 = the variable to return as result
+dnl	$2 = the package name
+dnl	$3 = the subdirectory, e.g., bin, include or lib
+dnl $4 = the directory under which we will test for subdirectories
+dnl $5 = a directory that we do not want $4 to match
+AC_DEFUN([CF_ADD_SUBDIR_PATH],
+[
+test "$4" != "$5" && \
+test -d "$4" && \
+ifelse([$5],NONE,,[(test $5 = NONE || test -d $5) &&]) {
+	test -n "$verbose" && echo "	... testing for $3-directories under $4"
+	test -d $4/$3 &&          $1="[$]$1 $4/$3"
+	test -d $4/$3/$2 &&       $1="[$]$1 $4/$3/$2"
+	test -d $4/$3/$2/$3 &&    $1="[$]$1 $4/$3/$2/$3"
+	test -d $4/$2/$3 &&       $1="[$]$1 $4/$2/$3"
+	test -d $4/$2/$3/$2 &&    $1="[$]$1 $4/$2/$3/$2"
+}
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ANSI_CC_CHECK version: 9 updated: 2001/12/30 17:53:34
+dnl ----------------
+dnl This is adapted from the macros 'fp_PROG_CC_STDC' and 'fp_C_PROTOTYPES'
+dnl in the sharutils 4.2 distribution.
+AC_DEFUN([CF_ANSI_CC_CHECK],
+[
+AC_CACHE_CHECK(for ${CC-cc} option to accept ANSI C, cf_cv_ansi_cc,[
+cf_cv_ansi_cc=no
+cf_save_CFLAGS="$CFLAGS"
+cf_save_CPPFLAGS="$CPPFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+# UnixWare 1.2		(cannot use -Xc, since ANSI/POSIX clashes)
+for cf_arg in "-DCC_HAS_PROTOS" \
+	"" \
+	-qlanglvl=ansi \
+	-std1 \
+	-Ae \
+	"-Aa -D_HPUX_SOURCE" \
+	-Xc
+do
+	CF_ADD_CFLAGS($cf_arg)
+	AC_TRY_COMPILE(
+[
+#ifndef CC_HAS_PROTOS
+#if !defined(__STDC__) || (__STDC__ != 1)
+choke me
+#endif
+#endif
+],[
+	int test (int i, double x);
+	struct s1 {int (*f) (int a);};
+	struct s2 {int (*f) (double a);};],
+	[cf_cv_ansi_cc="$cf_arg"; break])
+done
+CFLAGS="$cf_save_CFLAGS"
+CPPFLAGS="$cf_save_CPPFLAGS"
+])
+
+if test "$cf_cv_ansi_cc" != "no"; then
+if test ".$cf_cv_ansi_cc" != ".-DCC_HAS_PROTOS"; then
+	CF_ADD_CFLAGS($cf_cv_ansi_cc)
+else
+	AC_DEFINE(CC_HAS_PROTOS)
+fi
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ANSI_CC_REQD version: 3 updated: 1997/09/06 13:40:44
+dnl ---------------
+dnl For programs that must use an ANSI compiler, obtain compiler options that
+dnl will make it recognize prototypes.  We'll do preprocessor checks in other
+dnl macros, since tools such as unproto can fake prototypes, but only part of
+dnl the preprocessor.
+AC_DEFUN([CF_ANSI_CC_REQD],
+[AC_REQUIRE([CF_ANSI_CC_CHECK])
+if test "$cf_cv_ansi_cc" = "no"; then
+	AC_ERROR(
+[Your compiler does not appear to recognize prototypes.
+You have the following choices:
+	a. adjust your compiler options
+	b. get an up-to-date compiler
+	c. use a wrapper such as unproto])
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ARG_DISABLE version: 3 updated: 1999/03/30 17:24:31
+dnl --------------
+dnl Allow user to disable a normally-on option.
+AC_DEFUN([CF_ARG_DISABLE],
+[CF_ARG_OPTION($1,[$2],[$3],[$4],yes)])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ARG_ENABLE version: 3 updated: 1999/03/30 17:24:31
+dnl -------------
+dnl Allow user to enable a normally-off option.
+AC_DEFUN([CF_ARG_ENABLE],
+[CF_ARG_OPTION($1,[$2],[$3],[$4],no)])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ARG_OPTION version: 3 updated: 1997/10/18 14:42:41
+dnl -------------
+dnl Restricted form of AC_ARG_ENABLE that ensures user doesn't give bogus
+dnl values.
+dnl
+dnl Parameters:
+dnl $1 = option name
+dnl $2 = help-string
+dnl $3 = action to perform if option is not default
+dnl $4 = action if perform if option is default
+dnl $5 = default option value (either 'yes' or 'no')
+AC_DEFUN([CF_ARG_OPTION],
+[AC_ARG_ENABLE($1,[$2],[test "$enableval" != ifelse($5,no,yes,no) && enableval=ifelse($5,no,no,yes)
+  if test "$enableval" != "$5" ; then
+ifelse($3,,[    :]dnl
+,[    $3]) ifelse($4,,,[
+  else
+    $4])
+  fi],[enableval=$5 ifelse($4,,,[
+  $4
+])dnl
+  ])])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CHECK_CACHE version: 10 updated: 2004/05/23 13:03:31
+dnl --------------
+dnl Check if we're accidentally using a cache from a different machine.
+dnl Derive the system name, as a check for reusing the autoconf cache.
+dnl
+dnl If we've packaged config.guess and config.sub, run that (since it does a
+dnl better job than uname).  Normally we'll use AC_CANONICAL_HOST, but allow
+dnl an extra parameter that we may override, e.g., for AC_CANONICAL_SYSTEM
+dnl which is useful in cross-compiles.
+dnl
+dnl Note: we would use $ac_config_sub, but that is one of the places where
+dnl autoconf 2.5x broke compatibility with autoconf 2.13
+AC_DEFUN([CF_CHECK_CACHE],
+[
+if test -f $srcdir/config.guess || test -f $ac_aux_dir/config.guess ; then
+	ifelse([$1],,[AC_CANONICAL_HOST],[$1])
+	system_name="$host_os"
+else
+	system_name="`(uname -s -r) 2>/dev/null`"
+	if test -z "$system_name" ; then
+		system_name="`(hostname) 2>/dev/null`"
+	fi
+fi
+test -n "$system_name" && AC_DEFINE_UNQUOTED(SYSTEM_NAME,"$system_name")
+AC_CACHE_VAL(cf_cv_system_name,[cf_cv_system_name="$system_name"])
+
+test -z "$system_name" && system_name="$cf_cv_system_name"
+test -n "$cf_cv_system_name" && AC_MSG_RESULT(Configuring for $cf_cv_system_name)
+
+if test ".$system_name" != ".$cf_cv_system_name" ; then
+	AC_MSG_RESULT(Cached system name ($system_name) does not agree with actual ($cf_cv_system_name))
+	AC_ERROR("Please remove config.cache and try again.")
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CHECK_CFLAGS version: 2 updated: 2001/12/30 19:09:58
+dnl ---------------
+dnl Conditionally add to $CFLAGS and $CPPFLAGS values which are derived from
+dnl a build-configuration such as imake.  These have the pitfall that they
+dnl often contain compiler-specific options which we cannot use, mixed with
+dnl preprocessor options that we usually can.
+AC_DEFUN([CF_CHECK_CFLAGS],
+[
+CF_VERBOSE(checking additions to CFLAGS)
+cf_check_cflags="$CFLAGS"
+cf_check_cppflags="$CPPFLAGS"
+CF_ADD_CFLAGS($1,yes)
+if test "$cf_check_cflags" != "$CFLAGS" ; then
+AC_TRY_LINK([#include <stdio.h>],[printf("Hello world");],,
+	[CF_VERBOSE(test-compile failed.  Undoing change to \$CFLAGS)
+	 if test "$cf_check_cppflags" != "$CPPFLAGS" ; then
+		 CF_VERBOSE(but keeping change to \$CPPFLAGS)
+	 fi
+	 CFLAGS="$cf_check_flags"])
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CURSES_ACS_MAP version: 3 updated: 2003/05/17 22:19:02
+dnl -----------------
+dnl Check for likely values of acs_map[]:
+AC_DEFUN([CF_CURSES_ACS_MAP],
+[
+AC_CACHE_CHECK(for alternate character set array, cf_cv_curses_acs_map,[
+cf_cv_curses_acs_map=unknown
+for name in acs_map _acs_map __acs_map _nc_acs_map
+do
+AC_TRY_LINK([
+#include <${cf_cv_ncurses_header-curses.h}>
+],[
+$name['k'] = ACS_PLUS
+],[cf_cv_curses_acs_map=$name; break])
+done
+])
+
+test "$cf_cv_curses_acs_map" != unknown && AC_DEFINE_UNQUOTED(CURSES_ACS_ARRAY,$cf_cv_curses_acs_map)
+])
+dnl ---------------------------------------------------------------------------
+dnl CF_CURSES_CHECK_TYPE version: 2 updated: 2003/03/01 23:40:33
+dnl --------------------
+dnl Check if curses.h defines the given type
+AC_DEFUN([CF_CURSES_CHECK_TYPE],
+[
+AC_MSG_CHECKING(for type $1 in ${cf_cv_ncurses_header-curses.h})
+AC_TRY_COMPILE([
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+#include <${cf_cv_ncurses_header-curses.h}>],[
+$1 foo
+],cf_result=yes,cf_result=no)
+AC_MSG_RESULT($cf_result)
+if test $cf_result = yes ; then
+	CF_UPPER(cf_result,have_type_$1)
+	AC_DEFINE_UNQUOTED($cf_result)
+else
+	AC_DEFINE_UNQUOTED($1,$2)
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CURSES_CPPFLAGS version: 9 updated: 2006/02/04 19:44:43
+dnl ------------------
+dnl Look for the curses headers.
+AC_DEFUN([CF_CURSES_CPPFLAGS],[
+
+AC_CACHE_CHECK(for extra include directories,cf_cv_curses_incdir,[
+cf_cv_curses_incdir=no
+case $host_os in #(vi
+hpux10.*) #(vi
+	test -d /usr/include/curses_colr && \
+	cf_cv_curses_incdir="-I/usr/include/curses_colr"
+	;;
+sunos3*|sunos4*)
+	test -d /usr/5lib && \
+	test -d /usr/5include && \
+	cf_cv_curses_incdir="-I/usr/5include"
+	;;
+esac
+])
+test "$cf_cv_curses_incdir" != no && CPPFLAGS="$cf_cv_curses_incdir $CPPFLAGS"
+
+CF_CURSES_HEADER
+CF_TERM_HEADER
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CURSES_FUNCS version: 13 updated: 2007/04/28 09:15:55
+dnl ---------------
+dnl Curses-functions are a little complicated, since a lot of them are macros.
+AC_DEFUN([CF_CURSES_FUNCS],
+[
+AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
+AC_REQUIRE([CF_XOPEN_CURSES])
+AC_REQUIRE([CF_CURSES_TERM_H])
+for cf_func in $1
+do
+	CF_UPPER(cf_tr_func,$cf_func)
+	AC_MSG_CHECKING(for ${cf_func})
+	CF_MSG_LOG(${cf_func})
+	AC_CACHE_VAL(cf_cv_func_$cf_func,[
+		eval cf_result='$ac_cv_func_'$cf_func
+		if test ".$cf_result" != ".no"; then
+			AC_TRY_LINK([
+#ifdef HAVE_XCURSES
+#include <xcurses.h>
+char * XCursesProgramName = "test";
+#else
+#include <${cf_cv_ncurses_header-curses.h}>
+#if defined(NCURSES_VERSION) && defined(HAVE_NCURSESW_TERM_H)
+#include <ncursesw/term.h>
+#else
+#if defined(NCURSES_VERSION) && defined(HAVE_NCURSES_TERM_H)
+#include <ncurses/term.h>
+#else
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
+#endif
+#endif
+#endif],
+			[
+#ifndef ${cf_func}
+long foo = (long)(&${cf_func});
+${cf_cv_main_return-return}(foo == 0);
+#endif
+			],
+			[cf_result=yes],
+			[cf_result=no])
+		fi
+		eval 'cf_cv_func_'$cf_func'=$cf_result'
+	])
+	# use the computed/retrieved cache-value:
+	eval 'cf_result=$cf_cv_func_'$cf_func
+	AC_MSG_RESULT($cf_result)
+	if test $cf_result != no; then
+		AC_DEFINE_UNQUOTED(HAVE_${cf_tr_func})
+	fi
+done
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CURSES_HEADER version: 1 updated: 2005/12/31 13:28:25
+dnl ----------------
+dnl Find a "curses" header file, e.g,. "curses.h", or one of the more common
+dnl variations of ncurses' installs.
+dnl
+dnl See also CF_NCURSES_HEADER, which sets the same cache variable.
+AC_DEFUN([CF_CURSES_HEADER],[
+AC_CACHE_CHECK(if we have identified curses headers,cf_cv_ncurses_header,[
+cf_cv_ncurses_header=none
+for cf_header in \
+	curses.h \
+	ncurses.h \
+	ncurses/curses.h \
+	ncurses/ncurses.h
+do
+AC_TRY_COMPILE([#include <${cf_header}>],
+	[initscr(); tgoto("?", 0,0)],
+	[cf_cv_ncurses_header=$cf_header; break],[])
+done
+])
+
+if test "$cf_cv_ncurses_header" = none ; then
+	AC_MSG_ERROR(No curses header-files found)
+fi
+
+# cheat, to get the right #define's for HAVE_NCURSES_H, etc.
+AC_CHECK_HEADERS($cf_cv_ncurses_header)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CURSES_LIBS version: 26 updated: 2007/07/29 10:32:40
+dnl --------------
+dnl Look for the curses libraries.  Older curses implementations may require
+dnl termcap/termlib to be linked as well.  Call CF_CURSES_CPPFLAGS first.
+AC_DEFUN([CF_CURSES_LIBS],[
+
+AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
+AC_MSG_CHECKING(if we have identified curses libraries)
+AC_TRY_LINK([#include <${cf_cv_ncurses_header-curses.h}>],
+    [initscr(); tgoto("?", 0,0)],
+    cf_result=yes,
+    cf_result=no)
+AC_MSG_RESULT($cf_result)
+
+if test "$cf_result" = no ; then
+case $host_os in #(vi
+freebsd*) #(vi
+    AC_CHECK_LIB(mytinfo,tgoto,[LIBS="-lmytinfo $LIBS"])
+    ;;
+hpux10.*) #(vi
+    AC_CHECK_LIB(cur_colr,initscr,[
+        LIBS="-lcur_colr $LIBS"
+        ac_cv_func_initscr=yes
+        ],[
+    AC_CHECK_LIB(Hcurses,initscr,[
+        # HP's header uses __HP_CURSES, but user claims _HP_CURSES.
+        LIBS="-lHcurses $LIBS"
+        CPPFLAGS="-D__HP_CURSES -D_HP_CURSES $CPPFLAGS"
+        ac_cv_func_initscr=yes
+        ])])
+    ;;
+linux*) # Suse Linux does not follow /usr/lib convention
+    CF_ADD_LIBDIR(/lib)
+    ;;
+sunos3*|sunos4*)
+    if test -d /usr/5lib ; then
+      CF_ADD_LIBDIR(/usr/5lib)
+      LIBS="$LIBS -lcurses -ltermcap"
+    fi
+    ac_cv_func_initscr=yes
+    ;;
+esac
+
+if test ".$ac_cv_func_initscr" != .yes ; then
+    cf_save_LIBS="$LIBS"
+    cf_term_lib=""
+    cf_curs_lib=""
+
+    if test ".${cf_cv_ncurses_version-no}" != .no
+    then
+        cf_check_list="ncurses curses cursesX"
+    else
+        cf_check_list="cursesX curses ncurses"
+    fi
+
+    # Check for library containing tgoto.  Do this before curses library
+    # because it may be needed to link the test-case for initscr.
+    AC_CHECK_FUNC(tgoto,[cf_term_lib=predefined],[
+        for cf_term_lib in $cf_check_list termcap termlib unknown
+        do
+            AC_CHECK_LIB($cf_term_lib,tgoto,[break])
+        done
+    ])
+
+    # Check for library containing initscr
+    test "$cf_term_lib" != predefined && test "$cf_term_lib" != unknown && LIBS="-l$cf_term_lib $cf_save_LIBS"
+    for cf_curs_lib in $cf_check_list xcurses jcurses unknown
+    do
+        AC_CHECK_LIB($cf_curs_lib,initscr,[break])
+    done
+    test $cf_curs_lib = unknown && AC_ERROR(no curses library found)
+
+    LIBS="-l$cf_curs_lib $cf_save_LIBS"
+    if test "$cf_term_lib" = unknown ; then
+        AC_MSG_CHECKING(if we can link with $cf_curs_lib library)
+        AC_TRY_LINK([#include <${cf_cv_ncurses_header-curses.h}>],
+            [initscr()],
+            [cf_result=yes],
+            [cf_result=no])
+        AC_MSG_RESULT($cf_result)
+        test $cf_result = no && AC_ERROR(Cannot link curses library)
+    elif test "$cf_curs_lib" = "$cf_term_lib" ; then
+        :
+    elif test "$cf_term_lib" != predefined ; then
+        AC_MSG_CHECKING(if we need both $cf_curs_lib and $cf_term_lib libraries)
+        AC_TRY_LINK([#include <${cf_cv_ncurses_header-curses.h}>],
+            [initscr(); tgoto((char *)0, 0, 0);],
+            [cf_result=no],
+            [
+            LIBS="-l$cf_curs_lib -l$cf_term_lib $cf_save_LIBS"
+            AC_TRY_LINK([#include <${cf_cv_ncurses_header-curses.h}>],
+                [initscr()],
+                [cf_result=yes],
+                [cf_result=error])
+            ])
+        AC_MSG_RESULT($cf_result)
+    fi
+fi
+fi
+
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CURSES_TERM_H version: 6 updated: 2003/11/06 19:59:57
+dnl ----------------
+dnl SVr4 curses should have term.h as well (where it puts the definitions of
+dnl the low-level interface).  This may not be true in old/broken implementations,
+dnl as well as in misconfigured systems (e.g., gcc configured for Solaris 2.4
+dnl running with Solaris 2.5.1).
+AC_DEFUN([CF_CURSES_TERM_H],
+[
+AC_CACHE_CHECK(for term.h, cf_cv_term_header,[
+
+AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
+# If we found <ncurses/curses.h>, look for <ncurses/term.h>, but always look
+# for <term.h> if we do not find the variant.
+for cf_header in \
+	`echo ${cf_cv_ncurses_header-curses.h} | sed -e 's%/.*%/%'`term.h \
+	term.h
+do
+	AC_TRY_COMPILE([
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <${cf_header}>],
+	[WINDOW *x],
+	[cf_cv_term_header=$cf_header
+	 break],
+	[cf_cv_term_header=no])
+done
+])
+
+case $cf_cv_term_header in #(vi
+term.h) #(vi
+	AC_DEFINE(HAVE_TERM_H)
+	;;
+ncurses/term.h)
+	AC_DEFINE(HAVE_NCURSES_TERM_H)
+	;;
+ncursesw/term.h)
+	AC_DEFINE(HAVE_NCURSESW_TERM_H)
+	;;
+esac
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_CURSES_WACS_MAP version: 3 updated: 2003/05/17 22:19:02
+dnl ------------------
+dnl Check for likely values of wacs_map[]:
+AC_DEFUN([CF_CURSES_WACS_MAP],
+[
+AC_CACHE_CHECK(for wide alternate character set array, cf_cv_curses_wacs_map,[
+	cf_cv_curses_wacs_map=unknown
+	for name in wacs_map _wacs_map __wacs_map _nc_wacs
+	do
+	AC_TRY_LINK([
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+#include <${cf_cv_ncurses_header-curses.h}>],
+	[$name['k'] = *WACS_PLUS],
+	[cf_cv_curses_wacs_map=$name
+	 break])
+	done])
+])
+dnl ---------------------------------------------------------------------------
+dnl CF_DIRNAME version: 4 updated: 2002/12/21 19:25:52
+dnl ----------
+dnl "dirname" is not portable, so we fake it with a shell script.
+AC_DEFUN([CF_DIRNAME],[$1=`echo $2 | sed -e 's%/[[^/]]*$%%'`])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_DISABLE_ECHO version: 10 updated: 2003/04/17 22:27:11
+dnl ---------------
+dnl You can always use "make -n" to see the actual options, but it's hard to
+dnl pick out/analyze warning messages when the compile-line is long.
+dnl
+dnl Sets:
+dnl	ECHO_LT - symbol to control if libtool is verbose
+dnl	ECHO_LD - symbol to prefix "cc -o" lines
+dnl	RULE_CC - symbol to put before implicit "cc -c" lines (e.g., .c.o)
+dnl	SHOW_CC - symbol to put before explicit "cc -c" lines
+dnl	ECHO_CC - symbol to put before any "cc" line
+dnl
+AC_DEFUN([CF_DISABLE_ECHO],[
+AC_MSG_CHECKING(if you want to see long compiling messages)
+CF_ARG_DISABLE(echo,
+	[  --disable-echo          display "compiling" commands],
+	[
+    ECHO_LT='--silent'
+    ECHO_LD='@echo linking [$]@;'
+    RULE_CC='	@echo compiling [$]<'
+    SHOW_CC='	@echo compiling [$]@'
+    ECHO_CC='@'
+],[
+    ECHO_LT=''
+    ECHO_LD=''
+    RULE_CC='# compiling'
+    SHOW_CC='# compiling'
+    ECHO_CC=''
+])
+AC_MSG_RESULT($enableval)
+AC_SUBST(ECHO_LT)
+AC_SUBST(ECHO_LD)
+AC_SUBST(RULE_CC)
+AC_SUBST(SHOW_CC)
+AC_SUBST(ECHO_CC)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_ENABLE_WARNINGS version: 3 updated: 2003/05/24 14:24:29
+dnl ------------------
+dnl Configure-option to enable gcc warnings
+AC_DEFUN([CF_ENABLE_WARNINGS],[
+if ( test "$GCC" = yes || test "$GXX" = yes )
+then
+AC_MSG_CHECKING(if you want to turn on gcc warnings)
+CF_ARG_ENABLE(warnings,
+	[  --enable-warnings       test: turn on gcc compiler warnings],
+	[with_warnings=yes],
+	[with_warnings=no])
+AC_MSG_RESULT($with_warnings)
+if test "$with_warnings" = "yes"
+then
+	CF_GCC_WARNINGS
+fi
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_FIND_LIBRARY version: 8 updated: 2004/11/23 20:14:58
+dnl ---------------
+dnl Look for a non-standard library, given parameters for AC_TRY_LINK.  We
+dnl prefer a standard location, and use -L options only if we do not find the
+dnl library in the standard library location(s).
+dnl	$1 = library name
+dnl	$2 = library class, usually the same as library name
+dnl	$3 = includes
+dnl	$4 = code fragment to compile/link
+dnl	$5 = corresponding function-name
+dnl	$6 = flag, nonnull if failure should not cause an error-exit
+dnl
+dnl Sets the variable "$cf_libdir" as a side-effect, so we can see if we had
+dnl to use a -L option.
+AC_DEFUN([CF_FIND_LIBRARY],
+[
+	eval 'cf_cv_have_lib_'$1'=no'
+	cf_libdir=""
+	AC_CHECK_FUNC($5,
+		eval 'cf_cv_have_lib_'$1'=yes',[
+		cf_save_LIBS="$LIBS"
+		AC_MSG_CHECKING(for $5 in -l$1)
+		LIBS="-l$1 $LIBS"
+		AC_TRY_LINK([$3],[$4],
+			[AC_MSG_RESULT(yes)
+			 eval 'cf_cv_have_lib_'$1'=yes'
+			],
+			[AC_MSG_RESULT(no)
+			CF_LIBRARY_PATH(cf_search,$2)
+			for cf_libdir in $cf_search
+			do
+				AC_MSG_CHECKING(for -l$1 in $cf_libdir)
+				LIBS="-L$cf_libdir -l$1 $cf_save_LIBS"
+				AC_TRY_LINK([$3],[$4],
+					[AC_MSG_RESULT(yes)
+			 		 eval 'cf_cv_have_lib_'$1'=yes'
+					 break],
+					[AC_MSG_RESULT(no)
+					 LIBS="$cf_save_LIBS"])
+			done
+			])
+		])
+eval 'cf_found_library=[$]cf_cv_have_lib_'$1
+ifelse($6,,[
+if test $cf_found_library = no ; then
+	AC_ERROR(Cannot link $1 library)
+fi
+])
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_FUNC_CURSES_VERSION version: 4 updated: 2007/04/28 09:15:55
+dnl ----------------------
+dnl Solaris has a data item 'curses_version', which confuses AC_CHECK_FUNCS.
+dnl It's a character string "SVR4", not documented.
+AC_DEFUN([CF_FUNC_CURSES_VERSION],
+[
+AC_CACHE_CHECK(for function curses_version, cf_cv_func_curses_version,[
+AC_TRY_RUN([
+#include <${cf_cv_ncurses_header-curses.h}>
+int main()
+{
+	char temp[1024];
+	sprintf(temp, "%s\n", curses_version());
+	${cf_cv_main_return-return}(0);
+}]
+,[cf_cv_func_curses_version=yes]
+,[cf_cv_func_curses_version=no]
+,[cf_cv_func_curses_version=unknown])
+rm -f core])
+test "$cf_cv_func_curses_version" = yes && AC_DEFINE(HAVE_CURSES_VERSION)
+])
+dnl ---------------------------------------------------------------------------
+dnl CF_GCC_ATTRIBUTES version: 11 updated: 2007/07/29 09:55:12
+dnl -----------------
+dnl Test for availability of useful gcc __attribute__ directives to quiet
+dnl compiler warnings.  Though useful, not all are supported -- and contrary
+dnl to documentation, unrecognized directives cause older compilers to barf.
+AC_DEFUN([CF_GCC_ATTRIBUTES],
+[
+if test "$GCC" = yes
+then
+cat > conftest.i <<EOF
+#ifndef GCC_PRINTF
+#define GCC_PRINTF 0
+#endif
+#ifndef GCC_SCANF
+#define GCC_SCANF 0
+#endif
+#ifndef GCC_NORETURN
+#define GCC_NORETURN /* nothing */
+#endif
+#ifndef GCC_UNUSED
+#define GCC_UNUSED /* nothing */
+#endif
+EOF
+if test "$GCC" = yes
+then
+	AC_CHECKING([for $CC __attribute__ directives])
+cat > conftest.$ac_ext <<EOF
+#line __oline__ "${as_me-configure}"
+#include "confdefs.h"
+#include "conftest.h"
+#include "conftest.i"
+#if	GCC_PRINTF
+#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
+#else
+#define GCC_PRINTFLIKE(fmt,var) /*nothing*/
+#endif
+#if	GCC_SCANF
+#define GCC_SCANFLIKE(fmt,var)  __attribute__((format(scanf,fmt,var)))
+#else
+#define GCC_SCANFLIKE(fmt,var)  /*nothing*/
+#endif
+extern void wow(char *,...) GCC_SCANFLIKE(1,2);
+extern void oops(char *,...) GCC_PRINTFLIKE(1,2) GCC_NORETURN;
+extern void foo(void) GCC_NORETURN;
+int main(int argc GCC_UNUSED, char *argv[[]] GCC_UNUSED) { return 0; }
+EOF
+	for cf_attribute in scanf printf unused noreturn
+	do
+		CF_UPPER(cf_ATTRIBUTE,$cf_attribute)
+		cf_directive="__attribute__(($cf_attribute))"
+		echo "checking for $CC $cf_directive" 1>&AC_FD_CC
+		case $cf_attribute in
+		scanf|printf)
+		cat >conftest.h <<EOF
+#define GCC_$cf_ATTRIBUTE 1
+EOF
+			;;
+		*)
+		cat >conftest.h <<EOF
+#define GCC_$cf_ATTRIBUTE $cf_directive
+EOF
+			;;
+		esac
+		if AC_TRY_EVAL(ac_compile); then
+			test -n "$verbose" && AC_MSG_RESULT(... $cf_attribute)
+			cat conftest.h >>confdefs.h
+		fi
+	done
+else
+	fgrep define conftest.i >>confdefs.h
+fi
+rm -rf conftest*
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_GCC_VERSION version: 4 updated: 2005/08/27 09:53:42
+dnl --------------
+dnl Find version of gcc
+AC_DEFUN([CF_GCC_VERSION],[
+AC_REQUIRE([AC_PROG_CC])
+GCC_VERSION=none
+if test "$GCC" = yes ; then
+	AC_MSG_CHECKING(version of $CC)
+	GCC_VERSION="`${CC} --version| sed -e '2,$d' -e 's/^.*(GCC) //' -e 's/^[[^0-9.]]*//' -e 's/[[^0-9.]].*//'`"
+	test -z "$GCC_VERSION" && GCC_VERSION=unknown
+	AC_MSG_RESULT($GCC_VERSION)
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_GCC_WARNINGS version: 22 updated: 2007/07/29 09:55:12
+dnl ---------------
+dnl Check if the compiler supports useful warning options.  There's a few that
+dnl we don't use, simply because they're too noisy:
+dnl
+dnl	-Wconversion (useful in older versions of gcc, but not in gcc 2.7.x)
+dnl	-Wredundant-decls (system headers make this too noisy)
+dnl	-Wtraditional (combines too many unrelated messages, only a few useful)
+dnl	-Wwrite-strings (too noisy, but should review occasionally).  This
+dnl		is enabled for ncurses using "--enable-const".
+dnl	-pedantic
+dnl
+dnl Parameter:
+dnl	$1 is an optional list of gcc warning flags that a particular
+dnl		application might want to use, e.g., "no-unused" for
+dnl		-Wno-unused
+dnl Special:
+dnl	If $with_ext_const is "yes", add a check for -Wwrite-strings
+dnl
+AC_DEFUN([CF_GCC_WARNINGS],
+[
+AC_REQUIRE([CF_GCC_VERSION])
+CF_INTEL_COMPILER(GCC,INTEL_COMPILER,CFLAGS)
+
+cat > conftest.$ac_ext <<EOF
+#line __oline__ "${as_me-configure}"
+int main(int argc, char *argv[[]]) { return (argv[[argc-1]] == 0) ; }
+EOF
+
+if test "$INTEL_COMPILER" = yes
+then
+# The "-wdXXX" options suppress warnings:
+# remark #1419: external declaration in primary source file
+# remark #1682: implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem)
+# remark #1683: explicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem)
+# remark #1684: conversion from pointer to same-sized integral type (potential portability problem)
+# remark #193: zero used for undefined preprocessing identifier
+# remark #593: variable "curs_sb_left_arrow" was set but never used
+# remark #810: conversion from "int" to "Dimension={unsigned short}" may lose significant bits
+# remark #869: parameter "tw" was never referenced
+# remark #981: operands are evaluated in unspecified order
+# warning #269: invalid format string conversion
+
+	AC_CHECKING([for $CC warning options])
+	cf_save_CFLAGS="$CFLAGS"
+	EXTRA_CFLAGS="-Wall"
+	for cf_opt in \
+		wd1419 \
+		wd1682 \
+		wd1683 \
+		wd1684 \
+		wd193 \
+		wd279 \
+		wd593 \
+		wd810 \
+		wd869 \
+		wd981
+	do
+		CFLAGS="$cf_save_CFLAGS $EXTRA_CFLAGS -$cf_opt"
+		if AC_TRY_EVAL(ac_compile); then
+			test -n "$verbose" && AC_MSG_RESULT(... -$cf_opt)
+			EXTRA_CFLAGS="$EXTRA_CFLAGS -$cf_opt"
+		fi
+	done
+	CFLAGS="$cf_save_CFLAGS"
+
+elif test "$GCC" = yes
+then
+	AC_CHECKING([for $CC warning options])
+	cf_save_CFLAGS="$CFLAGS"
+	EXTRA_CFLAGS="-W -Wall"
+	cf_warn_CONST=""
+	test "$with_ext_const" = yes && cf_warn_CONST="Wwrite-strings"
+	for cf_opt in \
+		Wbad-function-cast \
+		Wcast-align \
+		Wcast-qual \
+		Winline \
+		Wmissing-declarations \
+		Wmissing-prototypes \
+		Wnested-externs \
+		Wpointer-arith \
+		Wshadow \
+		Wstrict-prototypes \
+		Wundef $cf_warn_CONST $1
+	do
+		CFLAGS="$cf_save_CFLAGS $EXTRA_CFLAGS -$cf_opt"
+		if AC_TRY_EVAL(ac_compile); then
+			test -n "$verbose" && AC_MSG_RESULT(... -$cf_opt)
+			case $cf_opt in #(vi
+			Wcast-qual) #(vi
+				CPPFLAGS="$CPPFLAGS -DXTSTRINGDEFINES"
+				;;
+			Winline) #(vi
+				case $GCC_VERSION in
+				3.3*)
+					CF_VERBOSE(feature is broken in gcc $GCC_VERSION)
+					continue;;
+				esac
+				;;
+			esac
+			EXTRA_CFLAGS="$EXTRA_CFLAGS -$cf_opt"
+		fi
+	done
+	CFLAGS="$cf_save_CFLAGS"
+fi
+rm -f conftest*
+
+AC_SUBST(EXTRA_CFLAGS)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_GNU_SOURCE version: 6 updated: 2005/07/09 13:23:07
+dnl -------------
+dnl Check if we must define _GNU_SOURCE to get a reasonable value for
+dnl _XOPEN_SOURCE, upon which many POSIX definitions depend.  This is a defect
+dnl (or misfeature) of glibc2, which breaks portability of many applications,
+dnl since it is interwoven with GNU extensions.
+dnl
+dnl Well, yes we could work around it...
+AC_DEFUN([CF_GNU_SOURCE],
+[
+AC_CACHE_CHECK(if we must define _GNU_SOURCE,cf_cv_gnu_source,[
+AC_TRY_COMPILE([#include <sys/types.h>],[
+#ifndef _XOPEN_SOURCE
+make an error
+#endif],
+	[cf_cv_gnu_source=no],
+	[cf_save="$CPPFLAGS"
+	 CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
+	 AC_TRY_COMPILE([#include <sys/types.h>],[
+#ifdef _XOPEN_SOURCE
+make an error
+#endif],
+	[cf_cv_gnu_source=no],
+	[cf_cv_gnu_source=yes])
+	CPPFLAGS="$cf_save"
+	])
+])
+test "$cf_cv_gnu_source" = yes && CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_HEADER_PATH version: 8 updated: 2002/11/10 14:46:59
+dnl --------------
+dnl Construct a search-list for a nonstandard header-file
+AC_DEFUN([CF_HEADER_PATH],
+[CF_SUBDIR_PATH($1,$2,include)
+test "$includedir" != NONE && \
+test "$includedir" != "/usr/include" && \
+test -d "$includedir" && {
+	test -d $includedir &&    $1="[$]$1 $includedir"
+	test -d $includedir/$2 && $1="[$]$1 $includedir/$2"
+}
+
+test "$oldincludedir" != NONE && \
+test "$oldincludedir" != "/usr/include" && \
+test -d "$oldincludedir" && {
+	test -d $oldincludedir    && $1="[$]$1 $oldincludedir"
+	test -d $oldincludedir/$2 && $1="[$]$1 $oldincludedir/$2"
+}
+
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_INHERIT_SCRIPT version: 2 updated: 2003/03/01 23:50:42
+dnl -----------------
+dnl If we do not have a given script, look for it in the parent directory.
+AC_DEFUN([CF_INHERIT_SCRIPT],
+[
+test -f $1 || ( test -f ../$1 && cp ../$1 ./ )
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_INTEL_COMPILER version: 3 updated: 2005/08/06 18:37:29
+dnl -----------------
+dnl Check if the given compiler is really the Intel compiler for Linux.  It
+dnl tries to imitate gcc, but does not return an error when it finds a mismatch
+dnl between prototypes, e.g., as exercised by CF_MISSING_CHECK.
+dnl
+dnl This macro should be run "soon" after AC_PROG_CC or AC_PROG_CPLUSPLUS, to
+dnl ensure that it is not mistaken for gcc/g++.  It is normally invoked from
+dnl the wrappers for gcc and g++ warnings.
+dnl
+dnl $1 = GCC (default) or GXX
+dnl $2 = INTEL_COMPILER (default) or INTEL_CPLUSPLUS
+dnl $3 = CFLAGS (default) or CXXFLAGS
+AC_DEFUN([CF_INTEL_COMPILER],[
+ifelse($2,,INTEL_COMPILER,[$2])=no
+
+if test "$ifelse($1,,[$1],GCC)" = yes ; then
+	case $host_os in
+	linux*|gnu*)
+		AC_MSG_CHECKING(if this is really Intel ifelse($1,GXX,C++,C) compiler)
+		cf_save_CFLAGS="$ifelse($3,,CFLAGS,[$3])"
+		ifelse($3,,CFLAGS,[$3])="$ifelse($3,,CFLAGS,[$3]) -no-gcc"
+		AC_TRY_COMPILE([],[
+#ifdef __INTEL_COMPILER
+#else
+make an error
+#endif
+],[ifelse($2,,INTEL_COMPILER,[$2])=yes
+cf_save_CFLAGS="$cf_save_CFLAGS -we147 -no-gcc"
+],[])
+		ifelse($3,,CFLAGS,[$3])="$cf_save_CFLAGS"
+		AC_MSG_RESULT($ifelse($2,,INTEL_COMPILER,[$2]))
+		;;
+	esac
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_LIBRARY_PATH version: 7 updated: 2002/11/10 14:46:59
+dnl ---------------
+dnl Construct a search-list for a nonstandard library-file
+AC_DEFUN([CF_LIBRARY_PATH],
+[CF_SUBDIR_PATH($1,$2,lib)])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_MSG_LOG version: 4 updated: 2007/07/29 09:55:12
+dnl ----------
+dnl Write a debug message to config.log, along with the line number in the
+dnl configure script.
+AC_DEFUN([CF_MSG_LOG],[
+echo "${as_me-configure}:__oline__: testing $* ..." 1>&AC_FD_CC
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_NCURSES_CC_CHECK version: 4 updated: 2007/07/29 10:39:05
+dnl -------------------
+dnl Check if we can compile with ncurses' header file
+dnl $1 is the cache variable to set
+dnl $2 is the header-file to include
+dnl $3 is the root name (ncurses or ncursesw)
+AC_DEFUN([CF_NCURSES_CC_CHECK],[
+	AC_TRY_COMPILE([
+]ifelse($3,ncursesw,[
+#define _XOPEN_SOURCE_EXTENDED
+#undef  HAVE_LIBUTF8_H	/* in case we used CF_UTF8_LIB */
+#define HAVE_LIBUTF8_H	/* to force ncurses' header file to use cchar_t */
+])[
+#include <$2>],[
+#ifdef NCURSES_VERSION
+]ifelse($3,ncursesw,[
+#ifndef WACS_BSSB
+	make an error
+#endif
+])[
+printf("%s\n", NCURSES_VERSION);
+#else
+#ifdef __NCURSES_H
+printf("old\n");
+#else
+	make an error
+#endif
+#endif
+	]
+	,[$1=$2]
+	,[$1=no])
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_NCURSES_CPPFLAGS version: 19 updated: 2007/07/29 13:35:20
+dnl -------------------
+dnl Look for the SVr4 curses clone 'ncurses' in the standard places, adjusting
+dnl the CPPFLAGS variable so we can include its header.
+dnl
+dnl The header files may be installed as either curses.h, or ncurses.h (would
+dnl be obsolete, except that some packagers prefer this name to distinguish it
+dnl from a "native" curses implementation).  If not installed for overwrite,
+dnl the curses.h file would be in an ncurses subdirectory (e.g.,
+dnl /usr/include/ncurses), but someone may have installed overwriting the
+dnl vendor's curses.  Only very old versions (pre-1.9.2d, the first autoconf'd
+dnl version) of ncurses don't define either __NCURSES_H or NCURSES_VERSION in
+dnl the header.
+dnl
+dnl If the installer has set $CFLAGS or $CPPFLAGS so that the ncurses header
+dnl is already in the include-path, don't even bother with this, since we cannot
+dnl easily determine which file it is.  In this case, it has to be <curses.h>.
+dnl
+dnl The optional parameter gives the root name of the library, in case it is
+dnl not installed as the default curses library.  That is how the
+dnl wide-character version of ncurses is installed.
+AC_DEFUN([CF_NCURSES_CPPFLAGS],
+[AC_REQUIRE([CF_WITH_CURSES_DIR])
+
+AC_PROVIDE([CF_CURSES_CPPFLAGS])dnl
+cf_ncuhdr_root=ifelse($1,,ncurses,$1)
+
+test -n "$cf_cv_curses_dir" && \
+test "$cf_cv_curses_dir" != "no" && { \
+  CF_ADD_INCDIR($cf_cv_curses_dir/include $cf_cv_curses_dir/include/$cf_ncuhdr_root)
+}
+
+AC_CACHE_CHECK(for $cf_ncuhdr_root header in include-path, cf_cv_ncurses_h,[
+	cf_header_list="$cf_ncuhdr_root/curses.h $cf_ncuhdr_root/ncurses.h"
+	( test "$cf_ncuhdr_root" = ncurses || test "$cf_ncuhdr_root" = ncursesw ) && cf_header_list="$cf_header_list curses.h ncurses.h"
+	for cf_header in $cf_header_list
+	do
+		CF_NCURSES_CC_CHECK(cf_cv_ncurses_h,$cf_header,$1)
+		test "$cf_cv_ncurses_h" != no && break
+	done
+])
+
+CF_NCURSES_HEADER
+CF_TERM_HEADER
+
+# some applications need this, but should check for NCURSES_VERSION
+AC_DEFINE(NCURSES)
+
+CF_NCURSES_VERSION
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_NCURSES_HEADER version: 1 updated: 2005/12/31 13:28:37
+dnl -----------------
+dnl Find a "curses" header file, e.g,. "curses.h", or one of the more common
+dnl variations of ncurses' installs.
+dnl
+dnl See also CF_CURSES_HEADER, which sets the same cache variable.
+AC_DEFUN([CF_NCURSES_HEADER],[
+
+if test "$cf_cv_ncurses_h" != no ; then
+	cf_cv_ncurses_header=$cf_cv_ncurses_h
+else
+
+AC_CACHE_CHECK(for $cf_ncuhdr_root include-path, cf_cv_ncurses_h2,[
+	test -n "$verbose" && echo
+	CF_HEADER_PATH(cf_search,$cf_ncuhdr_root)
+	test -n "$verbose" && echo search path $cf_search
+	cf_save2_CPPFLAGS="$CPPFLAGS"
+	for cf_incdir in $cf_search
+	do
+		CF_ADD_INCDIR($cf_incdir)
+		for cf_header in \
+			ncurses.h \
+			curses.h
+		do
+			CF_NCURSES_CC_CHECK(cf_cv_ncurses_h2,$cf_header,$1)
+			if test "$cf_cv_ncurses_h2" != no ; then
+				cf_cv_ncurses_h2=$cf_incdir/$cf_header
+				test -n "$verbose" && echo $ac_n "	... found $ac_c" 1>&AC_FD_MSG
+				break
+			fi
+			test -n "$verbose" && echo "	... tested $cf_incdir/$cf_header" 1>&AC_FD_MSG
+		done
+		CPPFLAGS="$cf_save2_CPPFLAGS"
+		test "$cf_cv_ncurses_h2" != no && break
+	done
+	test "$cf_cv_ncurses_h2" = no && AC_ERROR(not found)
+	])
+
+	CF_DIRNAME(cf_1st_incdir,$cf_cv_ncurses_h2)
+	cf_cv_ncurses_header=`basename $cf_cv_ncurses_h2`
+	if test `basename $cf_1st_incdir` = $cf_ncuhdr_root ; then
+		cf_cv_ncurses_header=$cf_ncuhdr_root/$cf_cv_ncurses_header
+	fi
+	CF_ADD_INCDIR($cf_1st_incdir)
+
+fi
+
+# Set definitions to allow ifdef'ing for ncurses.h
+
+case $cf_cv_ncurses_header in # (vi
+*ncurses.h)
+	AC_DEFINE(HAVE_NCURSES_H)
+	;;
+esac
+
+case $cf_cv_ncurses_header in # (vi
+ncurses/curses.h|ncurses/ncurses.h)
+	AC_DEFINE(HAVE_NCURSES_NCURSES_H)
+	;;
+ncursesw/curses.h|ncursesw/ncurses.h)
+	AC_DEFINE(HAVE_NCURSESW_NCURSES_H)
+	;;
+esac
+
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_NCURSES_LIBS version: 13 updated: 2007/07/29 10:29:20
+dnl ---------------
+dnl Look for the ncurses library.  This is a little complicated on Linux,
+dnl because it may be linked with the gpm (general purpose mouse) library.
+dnl Some distributions have gpm linked with (bsd) curses, which makes it
+dnl unusable with ncurses.  However, we don't want to link with gpm unless
+dnl ncurses has a dependency, since gpm is normally set up as a shared library,
+dnl and the linker will record a dependency.
+dnl
+dnl The optional parameter gives the root name of the library, in case it is
+dnl not installed as the default curses library.  That is how the
+dnl wide-character version of ncurses is installed.
+AC_DEFUN([CF_NCURSES_LIBS],
+[AC_REQUIRE([CF_NCURSES_CPPFLAGS])
+
+cf_nculib_root=ifelse($1,,ncurses,$1)
+	# This works, except for the special case where we find gpm, but
+	# ncurses is in a nonstandard location via $LIBS, and we really want
+	# to link gpm.
+cf_ncurses_LIBS=""
+cf_ncurses_SAVE="$LIBS"
+AC_CHECK_LIB(gpm,Gpm_Open,
+	[AC_CHECK_LIB(gpm,initscr,
+		[LIBS="$cf_ncurses_SAVE"],
+		[cf_ncurses_LIBS="-lgpm"])])
+
+case $host_os in #(vi
+freebsd*)
+	# This is only necessary if you are linking against an obsolete
+	# version of ncurses (but it should do no harm, since it's static).
+	if test "$cf_nculib_root" = ncurses ; then
+		AC_CHECK_LIB(mytinfo,tgoto,[cf_ncurses_LIBS="-lmytinfo $cf_ncurses_LIBS"])
+	fi
+	;;
+esac
+
+LIBS="$cf_ncurses_LIBS $LIBS"
+
+if ( test -n "$cf_cv_curses_dir" && test "$cf_cv_curses_dir" != "no" )
+then
+	CF_ADD_LIBDIR($cf_cv_curses_dir/lib)
+	LIBS="-l$cf_nculib_root $LIBS"
+else
+	CF_FIND_LIBRARY($cf_nculib_root,$cf_nculib_root,
+		[#include <${cf_cv_ncurses_header-curses.h}>],
+		[initscr()],
+		initscr)
+fi
+
+if test -n "$cf_ncurses_LIBS" ; then
+	AC_MSG_CHECKING(if we can link $cf_nculib_root without $cf_ncurses_LIBS)
+	cf_ncurses_SAVE="$LIBS"
+	for p in $cf_ncurses_LIBS ; do
+		q=`echo $LIBS | sed -e "s%$p %%" -e "s%$p$%%"`
+		if test "$q" != "$LIBS" ; then
+			LIBS="$q"
+		fi
+	done
+	AC_TRY_LINK([#include <${cf_cv_ncurses_header-curses.h}>],
+		[initscr(); mousemask(0,0); tgoto((char *)0, 0, 0);],
+		[AC_MSG_RESULT(yes)],
+		[AC_MSG_RESULT(no)
+		 LIBS="$cf_ncurses_SAVE"])
+fi
+
+CF_UPPER(cf_nculib_ROOT,HAVE_LIB$cf_nculib_root)
+AC_DEFINE_UNQUOTED($cf_nculib_ROOT)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_NCURSES_VERSION version: 12 updated: 2007/04/28 09:15:55
+dnl ------------------
+dnl Check for the version of ncurses, to aid in reporting bugs, etc.
+dnl Call CF_CURSES_CPPFLAGS first, or CF_NCURSES_CPPFLAGS.  We don't use
+dnl AC_REQUIRE since that does not work with the shell's if/then/else/fi.
+AC_DEFUN([CF_NCURSES_VERSION],
+[
+AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
+AC_CACHE_CHECK(for ncurses version, cf_cv_ncurses_version,[
+	cf_cv_ncurses_version=no
+	cf_tempfile=out$$
+	rm -f $cf_tempfile
+	AC_TRY_RUN([
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <stdio.h>
+int main()
+{
+	FILE *fp = fopen("$cf_tempfile", "w");
+#ifdef NCURSES_VERSION
+# ifdef NCURSES_VERSION_PATCH
+	fprintf(fp, "%s.%d\n", NCURSES_VERSION, NCURSES_VERSION_PATCH);
+# else
+	fprintf(fp, "%s\n", NCURSES_VERSION);
+# endif
+#else
+# ifdef __NCURSES_H
+	fprintf(fp, "old\n");
+# else
+	make an error
+# endif
+#endif
+	${cf_cv_main_return-return}(0);
+}],[
+	cf_cv_ncurses_version=`cat $cf_tempfile`],,[
+
+	# This will not work if the preprocessor splits the line after the
+	# Autoconf token.  The 'unproto' program does that.
+	cat > conftest.$ac_ext <<EOF
+#include <${cf_cv_ncurses_header-curses.h}>
+#undef Autoconf
+#ifdef NCURSES_VERSION
+Autoconf NCURSES_VERSION
+#else
+#ifdef __NCURSES_H
+Autoconf "old"
+#endif
+;
+#endif
+EOF
+	cf_try="$ac_cpp conftest.$ac_ext 2>&AC_FD_CC | grep '^Autoconf ' >conftest.out"
+	AC_TRY_EVAL(cf_try)
+	if test -f conftest.out ; then
+		cf_out=`cat conftest.out | sed -e 's%^Autoconf %%' -e 's%^[[^"]]*"%%' -e 's%".*%%'`
+		test -n "$cf_out" && cf_cv_ncurses_version="$cf_out"
+		rm -f conftest.out
+	fi
+])
+	rm -f $cf_tempfile
+])
+test "$cf_cv_ncurses_version" = no || AC_DEFINE(NCURSES)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_PATH_SYNTAX version: 11 updated: 2006/09/02 08:55:46
+dnl --------------
+dnl Check the argument to see that it looks like a pathname.  Rewrite it if it
+dnl begins with one of the prefix/exec_prefix variables, and then again if the
+dnl result begins with 'NONE'.  This is necessary to work around autoconf's
+dnl delayed evaluation of those symbols.
+AC_DEFUN([CF_PATH_SYNTAX],[
+if test "x$prefix" != xNONE; then
+  cf_path_syntax="$prefix"
+else
+  cf_path_syntax="$ac_default_prefix"
+fi
+
+case ".[$]$1" in #(vi
+.\[$]\(*\)*|.\'*\'*) #(vi
+  ;;
+..|./*|.\\*) #(vi
+  ;;
+.[[a-zA-Z]]:[[\\/]]*) #(vi OS/2 EMX
+  ;;
+.\[$]{*prefix}*) #(vi
+  eval $1="[$]$1"
+  case ".[$]$1" in #(vi
+  .NONE/*)
+    $1=`echo [$]$1 | sed -e s%NONE%$cf_path_syntax%`
+    ;;
+  esac
+  ;; #(vi
+.no|.NONE/*)
+  $1=`echo [$]$1 | sed -e s%NONE%$cf_path_syntax%`
+  ;;
+*)
+  ifelse($2,,[AC_ERROR([expected a pathname, not \"[$]$1\"])],$2)
+  ;;
+esac
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_PDCURSES_X11 version: 7 updated: 2006/11/12 17:31:59
+dnl ---------------
+dnl Configure for PDCurses' X11 library
+AC_DEFUN([CF_PDCURSES_X11],[
+AC_REQUIRE([CF_X_ATHENA])
+
+AC_PATH_PROGS(XCURSES_CONFIG,xcurses-config,none)
+
+if test "$XCURSES_CONFIG" != none ; then
+
+CPPFLAGS="`$XCURSES_CONFIG --cflags` $CPPFLAGS"
+LIBS="`$XCURSES_CONFIG --libs` $LIBS"
+
+cf_cv_lib_XCurses=yes
+
+else
+
+LDFLAGS="$LDFLAGS $X_LIBS"
+CF_CHECK_CFLAGS($X_CFLAGS)
+AC_CHECK_LIB(X11,XOpenDisplay,
+	[LIBS="-lX11 $LIBS"],,
+	[$X_PRE_LIBS $LIBS $X_EXTRA_LIBS])
+AC_CACHE_CHECK(for XCurses library,cf_cv_lib_XCurses,[
+LIBS="-lXCurses $LIBS"
+AC_TRY_LINK([
+#include <xcurses.h>
+char *XCursesProgramName = "test";
+],[XCursesExit();],
+[cf_cv_lib_XCurses=yes],
+[cf_cv_lib_XCurses=no])
+])
+
+fi
+
+if test $cf_cv_lib_XCurses = yes ; then
+	AC_DEFINE(UNIX)
+	AC_DEFINE(XCURSES)
+	AC_DEFINE(HAVE_XCURSES)
+else
+	AC_ERROR(Cannot link with XCurses)
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_POSIX_C_SOURCE version: 6 updated: 2005/07/14 20:25:10
+dnl -----------------
+dnl Define _POSIX_C_SOURCE to the given level, and _POSIX_SOURCE if needed.
+dnl
+dnl	POSIX.1-1990				_POSIX_SOURCE
+dnl	POSIX.1-1990 and			_POSIX_SOURCE and
+dnl		POSIX.2-1992 C-Language			_POSIX_C_SOURCE=2
+dnl		Bindings Option
+dnl	POSIX.1b-1993				_POSIX_C_SOURCE=199309L
+dnl	POSIX.1c-1996				_POSIX_C_SOURCE=199506L
+dnl	X/Open 2000				_POSIX_C_SOURCE=200112L
+dnl
+dnl Parameters:
+dnl	$1 is the nominal value for _POSIX_C_SOURCE
+AC_DEFUN([CF_POSIX_C_SOURCE],
+[
+cf_POSIX_C_SOURCE=ifelse($1,,199506L,$1)
+
+cf_save_CFLAGS="$CFLAGS"
+cf_save_CPPFLAGS="$CPPFLAGS"
+
+CF_REMOVE_DEFINE(cf_trim_CFLAGS,$cf_save_CFLAGS,_POSIX_C_SOURCE)
+CF_REMOVE_DEFINE(cf_trim_CPPFLAGS,$cf_save_CPPFLAGS,_POSIX_C_SOURCE)
+
+AC_CACHE_CHECK(if we should define _POSIX_C_SOURCE,cf_cv_posix_c_source,[
+	CF_MSG_LOG(if the symbol is already defined go no further)
+	AC_TRY_COMPILE([#include <sys/types.h>],[
+#ifndef _POSIX_C_SOURCE
+make an error
+#endif],
+	[cf_cv_posix_c_source=no],
+	[cf_want_posix_source=no
+	 case .$cf_POSIX_C_SOURCE in #(vi
+	 .[[12]]??*) #(vi
+		cf_cv_posix_c_source="-D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE"
+		;;
+	 .2) #(vi
+		cf_cv_posix_c_source="-D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE"
+		cf_want_posix_source=yes
+		;;
+	 .*)
+		cf_want_posix_source=yes
+		;;
+	 esac
+	 if test "$cf_want_posix_source" = yes ; then
+		AC_TRY_COMPILE([#include <sys/types.h>],[
+#ifdef _POSIX_SOURCE
+make an error
+#endif],[],
+		cf_cv_posix_c_source="$cf_cv_posix_c_source -D_POSIX_SOURCE")
+	 fi
+	 CF_MSG_LOG(ifdef from value $cf_POSIX_C_SOURCE)
+	 CFLAGS="$cf_trim_CFLAGS"
+	 CPPFLAGS="$cf_trim_CPPFLAGS $cf_cv_posix_c_source"
+	 CF_MSG_LOG(if the second compile does not leave our definition intact error)
+	 AC_TRY_COMPILE([#include <sys/types.h>],[
+#ifndef _POSIX_C_SOURCE
+make an error
+#endif],,
+	 [cf_cv_posix_c_source=no])
+	 CFLAGS="$cf_save_CFLAGS"
+	 CPPFLAGS="$cf_save_CPPFLAGS"
+	])
+])
+
+if test "$cf_cv_posix_c_source" != no ; then
+	CFLAGS="$cf_trim_CFLAGS"
+	CPPFLAGS="$cf_trim_CPPFLAGS"
+	if test "$cf_cv_cc_u_d_options" = yes ; then
+		cf_temp_posix_c_source=`echo "$cf_cv_posix_c_source" | \
+				sed -e 's/-D/-U/g' -e 's/=[[^ 	]]*//g'`
+		CPPFLAGS="$CPPFLAGS $cf_temp_posix_c_source"
+	fi
+	CPPFLAGS="$CPPFLAGS $cf_cv_posix_c_source"
+fi
+
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_PRG_RULES version: 1 updated: 2006/06/03 11:45:08
+dnl ------------
+dnl Append definitions and rules for the given programs to the subdirectory
+dnl Makefiles, and the recursion rule for the top-level Makefile.
+dnl
+dnl parameters
+dnl	$1 = script to run
+dnl	$2 = list of subdirectories
+dnl
+dnl variables
+dnl	$AWK
+AC_DEFUN([CF_PRG_RULES],
+[
+for cf_dir in $2
+do
+	if test ! -d $srcdir/$cf_dir; then
+		continue
+	elif test -f $srcdir/$cf_dir/programs; then
+		$AWK -f $1 $srcdir/$cf_dir/programs >>$cf_dir/Makefile
+	fi
+done
+
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_PROG_CC_U_D version: 1 updated: 2005/07/14 16:59:30
+dnl --------------
+dnl Check if C (preprocessor) -U and -D options are processed in the order
+dnl given rather than by type of option.  Some compilers insist on apply all
+dnl of the -U options after all of the -D options.  Others allow mixing them,
+dnl and may predefine symbols that conflict with those we define.
+AC_DEFUN([CF_PROG_CC_U_D],
+[
+AC_CACHE_CHECK(if $CC -U and -D options work together,cf_cv_cc_u_d_options,[
+	cf_save_CPPFLAGS="$CPPFLAGS"
+	CPPFLAGS="-UU_D_OPTIONS -DU_D_OPTIONS -DD_U_OPTIONS -UD_U_OPTIONS"
+	AC_TRY_COMPILE([],[
+#ifndef U_D_OPTIONS
+make an undefined-error
+#endif
+#ifdef  D_U_OPTIONS
+make a defined-error
+#endif
+	],[
+	cf_cv_cc_u_d_options=yes],[
+	cf_cv_cc_u_d_options=no])
+	CPPFLAGS="$cf_save_CPPFLAGS"
+])
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_REMOVE_DEFINE version: 2 updated: 2005/07/09 16:12:18
+dnl ----------------
+dnl Remove all -U and -D options that refer to the given symbol from a list
+dnl of C compiler options.  This works around the problem that not all
+dnl compilers process -U and -D options from left-to-right, so a -U option
+dnl cannot be used to cancel the effect of a preceding -D option.
+dnl
+dnl $1 = target (which could be the same as the source variable)
+dnl $2 = source (including '$')
+dnl $3 = symbol to remove
+define([CF_REMOVE_DEFINE],
+[
+# remove $3 symbol from $2
+$1=`echo "$2" | \
+	sed	-e 's/-[[UD]]$3\(=[[^ 	]]*\)\?[[ 	]]/ /g' \
+		-e 's/-[[UD]]$3\(=[[^ 	]]*\)\?[$]//g'`
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_SIG_ATOMIC_T version: 2 updated: 2005/09/18 17:27:12
+dnl ---------------
+dnl signal handler, but there are some gcc depedencies in that recommendation.
+dnl Try anyway.
+AC_DEFUN([CF_SIG_ATOMIC_T],
+[
+AC_MSG_CHECKING(for signal global datatype)
+AC_CACHE_VAL(cf_cv_sig_atomic_t,[
+	for cf_type in \
+		"volatile sig_atomic_t" \
+		"sig_atomic_t" \
+		"int"
+	do
+	AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+
+extern $cf_type x;
+$cf_type x;
+static void handler(int sig)
+{
+	x = 5;
+}],
+		[signal(SIGINT, handler);
+		 x = 1],
+		[cf_cv_sig_atomic_t=$cf_type],
+		[cf_cv_sig_atomic_t=no])
+		test "$cf_cv_sig_atomic_t" != no && break
+	done
+	])
+AC_MSG_RESULT($cf_cv_sig_atomic_t)
+test "$cf_cv_sig_atomic_t" != no && AC_DEFINE_UNQUOTED(SIG_ATOMIC_T, $cf_cv_sig_atomic_t)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_SUBDIR_PATH version: 5 updated: 2007/07/29 09:55:12
+dnl --------------
+dnl Construct a search-list for a nonstandard header/lib-file
+dnl	$1 = the variable to return as result
+dnl	$2 = the package name
+dnl	$3 = the subdirectory, e.g., bin, include or lib
+AC_DEFUN([CF_SUBDIR_PATH],
+[$1=""
+
+CF_ADD_SUBDIR_PATH($1,$2,$3,/usr,$prefix)
+CF_ADD_SUBDIR_PATH($1,$2,$3,$prefix,NONE)
+CF_ADD_SUBDIR_PATH($1,$2,$3,/usr/local,$prefix)
+CF_ADD_SUBDIR_PATH($1,$2,$3,/opt,$prefix)
+CF_ADD_SUBDIR_PATH($1,$2,$3,[$]HOME,$prefix)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_SYS_TIME_SELECT version: 4 updated: 2000/10/04 09:18:40
+dnl ------------------
+dnl Check if we can include <sys/time.h> with <sys/select.h>; this breaks on
+dnl older SCO configurations.
+AC_DEFUN([CF_SYS_TIME_SELECT],
+[
+AC_MSG_CHECKING(if sys/time.h works with sys/select.h)
+AC_CACHE_VAL(cf_cv_sys_time_select,[
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+],[],[cf_cv_sys_time_select=yes],
+     [cf_cv_sys_time_select=no])
+     ])
+AC_MSG_RESULT($cf_cv_sys_time_select)
+test "$cf_cv_sys_time_select" = yes && AC_DEFINE(HAVE_SYS_TIME_SELECT)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_TERM_HEADER version: 1 updated: 2005/12/31 13:26:39
+dnl --------------
+dnl Look for term.h, which is part of X/Open curses.  It defines the interface
+dnl to terminfo database.  Usually it is in the same include-path as curses.h,
+dnl but some packagers change this, breaking various applications.
+AC_DEFUN([CF_TERM_HEADER],[
+AC_CACHE_CHECK(for terminfo header, cf_cv_term_header,[
+case ${cf_cv_ncurses_header} in #(vi
+*/ncurses.h|*/ncursesw.h) #(vi
+	cf_term_header=`echo "$cf_cv_ncurses_header" | sed -e 's%ncurses[[^.]]*\.h$%term.h%'`
+	;;
+*)
+	cf_term_header=term.h
+	;;
+esac
+
+for cf_test in $cf_term_header "ncurses/term.h" "ncursesw/term.h"
+do
+AC_TRY_COMPILE([#include <stdio.h>
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <$cf_test>
+],[int x = auto_left_margin],[
+	cf_cv_term_header="$cf_test"],[
+	cf_cv_term_header=unknown
+	])
+	test "$cf_cv_term_header" != unknown && break
+done
+])
+
+# Set definitions to allow ifdef'ing to accommodate subdirectories
+
+case $cf_cv_term_header in # (vi
+*term.h)
+	AC_DEFINE(HAVE_TERM_H)
+	;;
+esac
+
+case $cf_cv_term_header in # (vi
+ncurses/term.h) #(vi
+	AC_DEFINE(HAVE_NCURSES_TERM_H)
+	;;
+ncursesw/term.h)
+	AC_DEFINE(HAVE_NCURSESW_TERM_H)
+	;;
+esac
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_UPPER version: 5 updated: 2001/01/29 23:40:59
+dnl --------
+dnl Make an uppercase version of a variable
+dnl $1=uppercase($2)
+AC_DEFUN([CF_UPPER],
+[
+$1=`echo "$2" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_UTF8_LIB version: 4 updated: 2003/03/01 18:36:42
+dnl -----------
+dnl Check for multibyte support, and if not found, utf8 compatibility library
+AC_DEFUN([CF_UTF8_LIB],
+[
+AC_CACHE_CHECK(for multibyte character support,cf_cv_utf8_lib,[
+	cf_save_LIBS="$LIBS"
+	AC_TRY_LINK([
+#include <stdlib.h>],[putwc(0,0);],
+	[cf_cv_utf8_lib=yes],
+	[LIBS="-lutf8 $LIBS"
+	 AC_TRY_LINK([
+#include <libutf8.h>],[putwc(0,0);],
+		[cf_cv_utf8_lib=add-on],
+		[cf_cv_utf8_lib=no])
+	LIBS="$cf_save_LIBS"
+])])
+
+# HAVE_LIBUTF8_H is used by ncurses if curses.h is shared between
+# ncurses/ncursesw:
+if test "$cf_cv_utf8_lib" = "add-on" ; then
+	AC_DEFINE(HAVE_LIBUTF8_H)
+	LIBS="-lutf8 $LIBS"
+fi
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_VERBOSE version: 3 updated: 2007/07/29 09:55:12
+dnl ----------
+dnl Use AC_VERBOSE w/o the warnings
+AC_DEFUN([CF_VERBOSE],
+[test -n "$verbose" && echo "	$1" 1>&AC_FD_MSG
+CF_MSG_LOG([$1])
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_WITH_CURSES_DIR version: 2 updated: 2002/11/10 14:46:59
+dnl ------------------
+dnl Wrapper for AC_ARG_WITH to specify directory under which to look for curses
+dnl libraries.
+AC_DEFUN([CF_WITH_CURSES_DIR],[
+AC_ARG_WITH(curses-dir,
+	[  --with-curses-dir=DIR   directory in which (n)curses is installed],
+	[CF_PATH_SYNTAX(withval)
+	 cf_cv_curses_dir=$withval],
+	[cf_cv_curses_dir=no])
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_XOPEN_CURSES version: 8 updated: 2003/11/07 19:47:46
+dnl ---------------
+dnl Test if we should define X/Open source for curses, needed on Digital Unix
+dnl 4.x, to see the extended functions, but breaks on IRIX 6.x.
+dnl
+dnl The getbegyx() check is needed for HPUX, which omits legacy macros such
+dnl as getbegy().  The latter is better design, but the former is standard.
+AC_DEFUN([CF_XOPEN_CURSES],
+[
+AC_REQUIRE([CF_CURSES_CPPFLAGS])dnl
+AC_CACHE_CHECK(if we must define _XOPEN_SOURCE_EXTENDED,cf_cv_need_xopen_extension,[
+AC_TRY_LINK([
+#include <stdlib.h>
+#include <${cf_cv_ncurses_header-curses.h}>],[
+	long x = winnstr(stdscr, "", 0);
+	int x1, y1;
+	getbegyx(stdscr, y1, x1)],
+	[cf_cv_need_xopen_extension=no],
+	[AC_TRY_LINK([
+#define _XOPEN_SOURCE_EXTENDED
+#include <stdlib.h>
+#include <${cf_cv_ncurses_header-curses.h}>],[
+	long x = winnstr(stdscr, "", 0);
+	int x1, y1;
+	getbegyx(stdscr, y1, x1)],
+	[cf_cv_need_xopen_extension=yes],
+	[cf_cv_need_xopen_extension=unknown])])])
+test $cf_cv_need_xopen_extension = yes && CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED"
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_XOPEN_SOURCE version: 25 updated: 2007/01/29 18:36:38
+dnl ---------------
+dnl Try to get _XOPEN_SOURCE defined properly that we can use POSIX functions,
+dnl or adapt to the vendor's definitions to get equivalent functionality,
+dnl without losing the common non-POSIX features.
+dnl
+dnl Parameters:
+dnl	$1 is the nominal value for _XOPEN_SOURCE
+dnl	$2 is the nominal value for _POSIX_C_SOURCE
+AC_DEFUN([CF_XOPEN_SOURCE],[
+
+AC_REQUIRE([CF_PROG_CC_U_D])
+
+cf_XOPEN_SOURCE=ifelse($1,,500,$1)
+cf_POSIX_C_SOURCE=ifelse($2,,199506L,$2)
+
+case $host_os in #(vi
+aix[[45]]*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE"
+	;;
+freebsd*) #(vi
+	# 5.x headers associate
+	#	_XOPEN_SOURCE=600 with _POSIX_C_SOURCE=200112L
+	#	_XOPEN_SOURCE=500 with _POSIX_C_SOURCE=199506L
+	cf_POSIX_C_SOURCE=200112L
+	cf_XOPEN_SOURCE=600
+	CPPFLAGS="$CPPFLAGS -D_BSD_TYPES -D__BSD_VISIBLE -D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE -D_XOPEN_SOURCE=$cf_XOPEN_SOURCE"
+	;;
+hpux*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE"
+	;;
+irix[[56]].*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_SGI_SOURCE"
+	;;
+linux*|gnu*|k*bsd*-gnu) #(vi
+	CF_GNU_SOURCE
+	;;
+mirbsd*) #(vi
+	# setting _XOPEN_SOURCE or _POSIX_SOURCE breaks <arpa/inet.h>
+	;;
+netbsd*) #(vi
+	# setting _XOPEN_SOURCE breaks IPv6 for lynx on NetBSD 1.6, breaks xterm, is not needed for ncursesw
+	;;
+openbsd*) #(vi
+	# setting _XOPEN_SOURCE breaks xterm on OpenBSD 2.8, is not needed for ncursesw
+	;;
+osf[[45]]*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_OSF_SOURCE"
+	;;
+nto-qnx*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_QNX_SOURCE"
+	;;
+sco*) #(vi
+	# setting _XOPEN_SOURCE breaks Lynx on SCO Unix / OpenServer
+	;;
+solaris*) #(vi
+	CPPFLAGS="$CPPFLAGS -D__EXTENSIONS__"
+	;;
+*)
+	AC_CACHE_CHECK(if we should define _XOPEN_SOURCE,cf_cv_xopen_source,[
+	AC_TRY_COMPILE([#include <sys/types.h>],[
+#ifndef _XOPEN_SOURCE
+make an error
+#endif],
+	[cf_cv_xopen_source=no],
+	[cf_save="$CPPFLAGS"
+	 CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=$cf_XOPEN_SOURCE"
+	 AC_TRY_COMPILE([#include <sys/types.h>],[
+#ifdef _XOPEN_SOURCE
+make an error
+#endif],
+	[cf_cv_xopen_source=no],
+	[cf_cv_xopen_source=$cf_XOPEN_SOURCE])
+	CPPFLAGS="$cf_save"
+	])
+])
+	if test "$cf_cv_xopen_source" != no ; then
+		CF_REMOVE_DEFINE(CFLAGS,$CFLAGS,_XOPEN_SOURCE)
+		CF_REMOVE_DEFINE(CPPFLAGS,$CPPFLAGS,_XOPEN_SOURCE)
+		test "$cf_cv_cc_u_d_options" = yes && \
+			CPPFLAGS="$CPPFLAGS -U_XOPEN_SOURCE"
+		CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=$cf_cv_xopen_source"
+	fi
+	CF_POSIX_C_SOURCE($cf_POSIX_C_SOURCE)
+	;;
+esac
+])
+dnl ---------------------------------------------------------------------------
+dnl CF_X_ATHENA version: 12 updated: 2004/06/15 21:14:41
+dnl -----------
+dnl Check for Xaw (Athena) libraries
+dnl
+dnl Sets $cf_x_athena according to the flavor of Xaw which is used.
+AC_DEFUN([CF_X_ATHENA],
+[AC_REQUIRE([CF_X_TOOLKIT])
+cf_x_athena=${cf_x_athena-Xaw}
+
+AC_MSG_CHECKING(if you want to link with Xaw 3d library)
+withval=
+AC_ARG_WITH(Xaw3d,
+	[  --with-Xaw3d            link with Xaw 3d library])
+if test "$withval" = yes ; then
+	cf_x_athena=Xaw3d
+	AC_MSG_RESULT(yes)
+else
+	AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(if you want to link with neXT Athena library)
+withval=
+AC_ARG_WITH(neXtaw,
+	[  --with-neXtaw           link with neXT Athena library])
+if test "$withval" = yes ; then
+	cf_x_athena=neXtaw
+	AC_MSG_RESULT(yes)
+else
+	AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(if you want to link with Athena-Plus library)
+withval=
+AC_ARG_WITH(XawPlus,
+	[  --with-XawPlus          link with Athena-Plus library])
+if test "$withval" = yes ; then
+	cf_x_athena=XawPlus
+	AC_MSG_RESULT(yes)
+else
+	AC_MSG_RESULT(no)
+fi
+
+AC_CHECK_LIB(Xext,XextCreateExtension,
+	[LIBS="-lXext $LIBS"])
+
+cf_x_athena_lib=""
+
+CF_X_ATHENA_CPPFLAGS($cf_x_athena)
+CF_X_ATHENA_LIBS($cf_x_athena)
+])dnl
+dnl ---------------------------------------------------------------------------
+dnl CF_X_ATHENA_CPPFLAGS version: 2 updated: 2002/10/09 20:00:37
+dnl --------------------
+dnl Normally invoked by CF_X_ATHENA, with $1 set to the appropriate flavor of
+dnl the Athena widgets, e.g., Xaw, Xaw3d, neXtaw.
+AC_DEFUN([CF_X_ATHENA_CPPFLAGS],
+[
+cf_x_athena_root=ifelse($1,,Xaw,$1)
+cf_x_athena_include=""
+
+for cf_path in default \
+	/usr/contrib/X11R6 \
+	/usr/contrib/X11R5 \
+	/usr/lib/X11R5 \
+	/usr/local
+do
+	if test -z "$cf_x_athena_include" ; then
+		cf_save="$CPPFLAGS"
+		cf_test=X11/$cf_x_athena_root/SimpleMenu.h
+		if test $cf_path != default ; then
+			CPPFLAGS="-I$cf_path/include $cf_save"
+			AC_MSG_CHECKING(for $cf_test in $cf_path)
+		else
+			AC_MSG_CHECKING(for $cf_test)
+		fi
+		AC_TRY_COMPILE([
+#include <X11/Intrinsic.h>
+#include <$cf_test>],[],
+			[cf_result=yes],
+			[cf_result=no])
+		AC_MSG_RESULT($cf_result)
+		if test "$cf_result" = yes ; then
+			cf_x_athena_include=$cf_path
+			break
+		else
+			CPPFLAGS="$cf_save"
+		fi
+	fi
+done
+
+if test -z "$cf_x_athena_include" ; then
+	AC_MSG_WARN(
+[Unable to successfully find Athena header files with test program])
+elif test "$cf_x_athena_include" != default ; then
+	CPPFLAGS="$CPPFLAGS -I$cf_x_athena_include"
+fi
+])
+dnl ---------------------------------------------------------------------------
+dnl CF_X_ATHENA_LIBS version: 6 updated: 2006/11/30 17:57:11
+dnl ----------------
+dnl Normally invoked by CF_X_ATHENA, with $1 set to the appropriate flavor of
+dnl the Athena widgets, e.g., Xaw, Xaw3d, neXtaw.
+AC_DEFUN([CF_X_ATHENA_LIBS],
+[AC_REQUIRE([CF_X_TOOLKIT])
+cf_x_athena_root=ifelse($1,,Xaw,$1)
+cf_x_athena_lib=""
+
+for cf_path in default \
+	/usr/contrib/X11R6 \
+	/usr/contrib/X11R5 \
+	/usr/lib/X11R5 \
+	/usr/local
+do
+	for cf_lib in \
+		"-l$cf_x_athena_root -lXmu" \
+		"-l$cf_x_athena_root -lXpm -lXmu" \
+		"-l${cf_x_athena_root}_s -lXmu_s"
+	do
+		if test -z "$cf_x_athena_lib" ; then
+			cf_save="$LIBS"
+			cf_test=XawSimpleMenuAddGlobalActions
+			if test $cf_path != default ; then
+				LIBS="-L$cf_path/lib $cf_lib $LIBS"
+				AC_MSG_CHECKING(for $cf_lib in $cf_path)
+			else
+				LIBS="$cf_lib $LIBS"
+				AC_MSG_CHECKING(for $cf_test in $cf_lib)
+			fi
+			AC_TRY_LINK([],[$cf_test()],
+				[cf_result=yes],
+				[cf_result=no])
+			AC_MSG_RESULT($cf_result)
+			if test "$cf_result" = yes ; then
+				cf_x_athena_lib="$cf_lib"
+				break
+			fi
+			LIBS="$cf_save"
+		fi
+	done
+done
+
+if test -z "$cf_x_athena_lib" ; then
+	AC_ERROR(
+[Unable to successfully link Athena library (-l$cf_x_athena_root) with test program])
+fi
+
+CF_UPPER(cf_x_athena_LIBS,HAVE_LIB_$cf_x_athena)
+AC_DEFINE_UNQUOTED($cf_x_athena_LIBS)
+])
+dnl ---------------------------------------------------------------------------
+dnl CF_X_TOOLKIT version: 11 updated: 2006/11/29 19:05:14
+dnl ------------
+dnl Check for X Toolkit libraries
+dnl
+AC_DEFUN([CF_X_TOOLKIT],
+[
+AC_REQUIRE([AC_PATH_XTRA])
+AC_REQUIRE([CF_CHECK_CACHE])
+
+# SYSTEM_NAME=`echo "$cf_cv_system_name"|tr ' ' -`
+
+cf_have_X_LIBS=no
+
+LDFLAGS="$X_LIBS $LDFLAGS"
+CF_CHECK_CFLAGS($X_CFLAGS)
+
+AC_CHECK_FUNC(XOpenDisplay,,[
+AC_CHECK_LIB(X11,XOpenDisplay,
+	[LIBS="-lX11 $LIBS"],,
+	[$X_PRE_LIBS $LIBS $X_EXTRA_LIBS])])
+
+AC_CHECK_FUNC(XtAppInitialize,,[
+AC_CHECK_LIB(Xt, XtAppInitialize,
+	[AC_DEFINE(HAVE_LIBXT)
+	 cf_have_X_LIBS=Xt
+	 LIBS="-lXt $X_PRE_LIBS $LIBS $X_EXTRA_LIBS"],,
+	[$X_PRE_LIBS $LIBS $X_EXTRA_LIBS])])
+
+if test $cf_have_X_LIBS = no ; then
+	AC_WARN(
+[Unable to successfully link X Toolkit library (-lXt) with
+test program.  You will have to check and add the proper libraries by hand
+to makefile.])
+fi
+])dnl
diff --git a/test/background.c b/test/background.c
new file mode 100644
index 0000000..afbe5f5
--- /dev/null
+++ b/test/background.c
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * Copyright (c) 2003,2006 Free Software Foundation, Inc.                   *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: background.c,v 1.3 2006/06/03 16:43:08 tom Exp $
+ */
+
+#include <test.priv.h>
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    short f, b;
+
+    initscr();
+    cbreak();
+    noecho();
+
+    if (has_colors()) {
+	start_color();
+
+	pair_content(0, &f, &b);
+	printw("pair 0 contains (%d,%d)\n", f, b);
+	getch();
+
+	printw("Initializing pair 1 to red/black\n");
+	init_pair(1, COLOR_RED, COLOR_BLACK);
+	bkgdset(' ' | COLOR_PAIR(1));
+	printw("RED/BLACK\n");
+	getch();
+
+	printw("Initializing pair 2 to white/blue\n");
+	init_pair(2, COLOR_WHITE, COLOR_BLUE);
+	bkgdset(' ' | COLOR_PAIR(2));
+	printw("WHITE/BLUE\n");
+	getch();
+
+	printw("Resetting colors to pair 0\n");
+	bkgdset(' ' | COLOR_PAIR(0));
+	printw("Default Colors\n");
+	getch();
+
+	printw("Resetting colors to pair 1\n");
+	bkgdset(' ' | COLOR_PAIR(1));
+	printw("RED/BLACK\n");
+	getch();
+
+	printw("Setting screen to pair 0\n");
+	bkgd(' ' | COLOR_PAIR(0));
+	getch();
+
+	printw("Setting screen to pair 1\n");
+	bkgd(' ' | COLOR_PAIR(1));
+	getch();
+
+	printw("Setting screen to pair 2\n");
+	bkgd(' ' | COLOR_PAIR(2));
+	getch();
+
+	printw("Setting screen to pair 0\n");
+	bkgd(' ' | COLOR_PAIR(0));
+	getch();
+
+    } else {
+	printw("This demo requires a color terminal");
+	getch();
+    }
+    endwin();
+
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/blue.c b/test/blue.c
new file mode 100644
index 0000000..dac0c76
--- /dev/null
+++ b/test/blue.c
@@ -0,0 +1,463 @@
+/****************************************************************************
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ *                         B l u e   M o o n                                 *
+ *                         =================                                 *
+ *                               V2.2                                        *
+ *                   A patience game by T.A.Lister                           *
+ *            Integral screen support by Eric S. Raymond                     *
+ *                                                                           *
+ *****************************************************************************/
+
+/*
+ * Compile this with the command `cc -O blue.c -lcurses -o blue'.  For best
+ * results, use the ncurses(3) library.  On non-Intel machines, SVr4 curses is
+ * just as good.
+ *
+ * $Id: blue.c,v 1.30 2008/08/03 18:20:27 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <time.h>
+
+#define NOCARD		(-1)
+
+#define ACE		0
+#define KING		12
+#define SUIT_LENGTH	13
+
+#define HEARTS		0
+#define SPADES		1
+#define DIAMONDS	2
+#define CLUBS		3
+#define NSUITS		4
+
+#define GRID_WIDTH	14	/*    13+1  */
+#define GRID_LENGTH	56	/* 4*(13+1) */
+#define PACK_SIZE	52
+
+#define BASEROW		1
+#define PROMPTROW	11
+
+#define RED_ON_WHITE    1
+#define BLACK_ON_WHITE  2
+#define BLUE_ON_WHITE   3
+
+static RETSIGTYPE die(int onsig) GCC_NORETURN;
+
+static int deck_size = PACK_SIZE;	/* initial deck */
+static int deck[PACK_SIZE];
+
+static int grid[GRID_LENGTH];	/* card layout grid */
+static int freeptr[4];		/* free card space pointers */
+
+static int deal_number = 0;
+
+static chtype ranks[SUIT_LENGTH][2] =
+{
+    {' ', 'A'},
+    {' ', '2'},
+    {' ', '3'},
+    {' ', '4'},
+    {' ', '5'},
+    {' ', '6'},
+    {' ', '7'},
+    {' ', '8'},
+    {' ', '9'},
+    {'1', '0'},
+    {' ', 'J'},
+    {' ', 'Q'},
+    {' ', 'K'}
+};
+
+/* Please note, that this is a bad example.
+   Color values should not be or'ed in. This
+   only works, because the characters used here
+   are plain and have no color attribute themselves. */
+#ifdef COLOR_PAIR
+#define OR_COLORS(value,pair) ((value) | COLOR_PAIR(pair))
+#else
+#define OR_COLORS(value,pair) (value)
+#endif
+
+#define PC_COLORS(value,pair) (OR_COLORS(value,pair) | A_ALTCHARSET)
+
+static chtype letters[4] =
+{
+    OR_COLORS('h', RED_ON_WHITE),	/* hearts */
+    OR_COLORS('s', BLACK_ON_WHITE),	/* spades */
+    OR_COLORS('d', RED_ON_WHITE),	/* diamonds */
+    OR_COLORS('c', BLACK_ON_WHITE),	/* clubs */
+};
+
+#if defined(__i386__) && defined(A_ALTCHARSET) && HAVE_TIGETSTR
+static chtype glyphs[] =
+{
+    PC_COLORS('\003', RED_ON_WHITE),	/* hearts */
+    PC_COLORS('\006', BLACK_ON_WHITE),	/* spades */
+    PC_COLORS('\004', RED_ON_WHITE),	/* diamonds */
+    PC_COLORS('\005', BLACK_ON_WHITE),	/* clubs */
+};
+#define USE_CP437 1
+#else
+#define USE_CP437 0
+#endif /* __i386__ */
+
+static chtype *suits = letters;	/* this may change to glyphs below */
+
+static RETSIGTYPE
+die(int onsig)
+{
+    (void) signal(onsig, SIG_IGN);
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+
+static void
+init_vars(void)
+{
+    int i;
+
+    deck_size = PACK_SIZE;
+    for (i = 0; i < PACK_SIZE; i++)
+	deck[i] = i;
+    for (i = 0; i < 4; i++)
+	freeptr[i] = i * GRID_WIDTH;
+}
+
+static void
+shuffle(int size)
+{
+    int i, j, numswaps, swapnum, temp;
+
+    numswaps = size * 10;	/* an arbitrary figure */
+
+    for (swapnum = 0; swapnum < numswaps; swapnum++) {
+	i = rand() % size;
+	j = rand() % size;
+	temp = deck[i];
+	deck[i] = deck[j];
+	deck[j] = temp;
+    }
+}
+
+static void
+deal_cards(void)
+{
+    int ptr, card = 0, value, csuit, crank, suit, aces[4];
+
+    memset(aces, 0, sizeof(aces));
+    for (suit = HEARTS; suit <= CLUBS; suit++) {
+	ptr = freeptr[suit];
+	grid[ptr++] = NOCARD;	/* 1st card space is blank */
+	while ((ptr % GRID_WIDTH) != 0) {
+	    value = deck[card++];
+	    crank = value % SUIT_LENGTH;
+	    csuit = value / SUIT_LENGTH;
+	    if (crank == ACE)
+		aces[csuit] = ptr;
+	    grid[ptr++] = value;
+	}
+    }
+
+    if (deal_number == 1)	/* shift the aces down to the 1st column */
+	for (suit = HEARTS; suit <= CLUBS; suit++) {
+	    grid[suit * GRID_WIDTH] = suit * SUIT_LENGTH;
+	    grid[aces[suit]] = NOCARD;
+	    freeptr[suit] = aces[suit];
+	}
+}
+
+static void
+printcard(int value)
+{
+    (void) addch(' ');
+    if (value == NOCARD)
+	(void) addstr("   ");
+    else {
+	addch(ranks[value % SUIT_LENGTH][0] | COLOR_PAIR(BLUE_ON_WHITE));
+	addch(ranks[value % SUIT_LENGTH][1] | COLOR_PAIR(BLUE_ON_WHITE));
+	addch(suits[value / SUIT_LENGTH]);
+    }
+    (void) addch(' ');
+}
+
+static void
+display_cards(int deal)
+{
+    int row, card;
+
+    clear();
+    (void) printw(
+		     "Blue Moon 2.1 - by Tim Lister & Eric Raymond - Deal %d.\n",
+		     deal);
+    for (row = HEARTS; row <= CLUBS; row++) {
+	move(BASEROW + row + row + 2, 1);
+	for (card = 0; card < GRID_WIDTH; card++)
+	    printcard(grid[row * GRID_WIDTH + card]);
+    }
+
+    move(PROMPTROW + 2, 0);
+    refresh();
+#define P(x)	(void)printw("%s\n", x)
+    P("   This 52-card solitaire starts with  the entire deck shuffled and dealt");
+    P("out in four rows.  The aces are then moved to the left end of the layout,");
+    P("making 4 initial free spaces.  You may move to a space only the card that");
+    P("matches the left neighbor in suit, and is one greater in rank.  Kings are");
+    P("high, so no cards may be placed to their right (they create dead spaces).");
+    P("  When no moves can be made,  cards still out of sequence are  reshuffled");
+    P("and dealt face up after the ends of the partial sequences, leaving a card");
+    P("space after each sequence, so that each row looks like a partial sequence");
+    P("followed by a space, followed by enough cards to make a row of 14.       ");
+    P("  A moment's reflection will show that this game cannot take more than 13");
+    P("deals. A good score is 1-3 deals, 4-7 is average, 8 or more is poor.     ");
+#undef P
+    refresh();
+}
+
+static int
+find(int card)
+{
+    int i;
+
+    if ((card < 0) || (card >= PACK_SIZE))
+	return (NOCARD);
+    for (i = 0; i < GRID_LENGTH; i++)
+	if (grid[i] == card)
+	    return i;
+    return (NOCARD);
+}
+
+static void
+movecard(int src, int dst)
+{
+    grid[dst] = grid[src];
+    grid[src] = NOCARD;
+
+    move(BASEROW + (dst / GRID_WIDTH) * 2 + 2, (dst % GRID_WIDTH) * 5 + 1);
+    printcard(grid[dst]);
+
+    move(BASEROW + (src / GRID_WIDTH) * 2 + 2, (src % GRID_WIDTH) * 5 + 1);
+    printcard(grid[src]);
+
+    refresh();
+}
+
+static void
+play_game(void)
+{
+    int dead = 0, i, j;
+    char c;
+    int selection[4], card;
+
+    while (dead < 4) {
+	dead = 0;
+	for (i = 0; i < 4; i++) {
+	    card = grid[freeptr[i] - 1];
+
+	    if (((card % SUIT_LENGTH) == KING)
+		||
+		(card == NOCARD))
+		selection[i] = NOCARD;
+	    else
+		selection[i] = find(card + 1);
+
+	    if (selection[i] == NOCARD)
+		dead++;
+	};
+
+	if (dead < 4) {
+	    char live[NSUITS + 1], *lp = live;
+
+	    for (i = 0; i < 4; i++) {
+		if (selection[i] != NOCARD) {
+		    move(BASEROW + (selection[i] / GRID_WIDTH) * 2 + 3,
+			 (selection[i] % GRID_WIDTH) * 5);
+		    (void) printw("   %c ", *lp++ = 'a' + i);
+		}
+	    };
+	    *lp = '\0';
+
+	    if (strlen(live) == 1) {
+		move(PROMPTROW, 0);
+		(void) printw(
+				 "Making forced moves...                                 ");
+		refresh();
+		(void) sleep(1);
+		c = live[0];
+	    } else {
+		char buf[BUFSIZ];
+
+		(void) sprintf(buf,
+			       "Type [%s] to move, r to redraw, q or INTR to quit: ",
+			       live);
+
+		do {
+		    move(PROMPTROW, 0);
+		    (void) addstr(buf);
+		    move(PROMPTROW, (int) strlen(buf));
+		    clrtoeol();
+		    (void) addch(' ');
+		} while
+		    (((c = getch()) < 'a' || c > 'd') && (c != 'r') && (c != 'q'));
+	    }
+
+	    for (j = 0; j < 4; j++)
+		if (selection[j] != NOCARD) {
+		    move(BASEROW + (selection[j] / GRID_WIDTH) * 2 + 3,
+			 (selection[j] % GRID_WIDTH) * 5);
+		    (void) printw("     ");
+		}
+
+	    if (c == 'r')
+		display_cards(deal_number);
+	    else if (c == 'q')
+		die(SIGINT);
+	    else {
+		i = c - 'a';
+		if (selection[i] == NOCARD)
+		    beep();
+		else {
+		    movecard(selection[i], freeptr[i]);
+		    freeptr[i] = selection[i];
+		}
+	    }
+	}
+    }
+
+    move(PROMPTROW, 0);
+    standout();
+    (void) printw("Finished deal %d - type any character to continue...", deal_number);
+    standend();
+    (void) getch();
+}
+
+static int
+collect_discards(void)
+{
+    int row, col, cardno = 0, finish, gridno;
+
+    for (row = HEARTS; row <= CLUBS; row++) {
+	finish = 0;
+	for (col = 1; col < GRID_WIDTH; col++) {
+	    gridno = row * GRID_WIDTH + col;
+
+	    if ((grid[gridno] != (grid[gridno - 1] + 1)) && (finish == 0)) {
+		finish = 1;
+		freeptr[row] = gridno;
+	    };
+
+	    if ((finish != 0) && (grid[gridno] != NOCARD))
+		deck[cardno++] = grid[gridno];
+	}
+    }
+    return cardno;
+}
+
+static void
+game_finished(int deal)
+{
+    clear();
+    (void) printw("You finished the game in %d deals. This is ", deal);
+    standout();
+    if (deal < 2)
+	(void) addstr("excellent");
+    else if (deal < 4)
+	(void) addstr("good");
+    else if (deal < 8)
+	(void) addstr("average");
+    else
+	(void) addstr("poor");
+    standend();
+    (void) addstr(".         ");
+    refresh();
+}
+
+int
+main(int argc, char *argv[])
+{
+    CATCHALL(die);
+
+    setlocale(LC_ALL, "");
+
+    initscr();
+
+    /*
+     * We use COLOR_GREEN because COLOR_BLACK is wired to the wrong thing.
+     */
+    start_color();
+    init_pair(RED_ON_WHITE, COLOR_RED, COLOR_WHITE);
+    init_pair(BLUE_ON_WHITE, COLOR_BLUE, COLOR_WHITE);
+    init_pair(BLACK_ON_WHITE, COLOR_BLACK, COLOR_WHITE);
+
+#ifndef COLOR_PAIR
+    letters[0] = OR_COLORS('h', RED_ON_WHITE);	/* hearts */
+    letters[1] = OR_COLORS('s', BLACK_ON_WHITE);	/* spades */
+    letters[2] = OR_COLORS('d', RED_ON_WHITE);	/* diamonds */
+    letters[3] = OR_COLORS('c', BLACK_ON_WHITE);	/* clubs */
+#if USE_CP437
+    glyphs[0] = PC_COLORS('\003', RED_ON_WHITE);	/* hearts */
+    glyphs[1] = PC_COLORS('\006', BLACK_ON_WHITE);	/* spades */
+    glyphs[2] = PC_COLORS('\004', RED_ON_WHITE);	/* diamonds */
+    glyphs[3] = PC_COLORS('\005', BLACK_ON_WHITE);	/* clubs */
+#endif
+#endif
+
+#if USE_CP437
+    if (tigetstr("smpch"))
+	suits = glyphs;
+#endif /* USE_CP437 */
+
+    cbreak();
+
+    if (argc == 2)
+	srand((unsigned) atoi(argv[1]));
+    else
+	srand((unsigned) time((time_t *) 0));
+
+    init_vars();
+
+    do {
+	deal_number++;
+	shuffle(deck_size);
+	deal_cards();
+	display_cards(deal_number);
+	play_game();
+    }
+    while
+	((deck_size = collect_discards()) != 0);
+
+    game_finished(deal_number);
+
+    die(SIGINT);
+    /*NOTREACHED */
+}
+
+/* blue.c ends here */
diff --git a/test/bs.6 b/test/bs.6
new file mode 100644
index 0000000..657f538
--- /dev/null
+++ b/test/bs.6
@@ -0,0 +1,71 @@
+.\"***************************************************************************
+.\" Copyright (c) 1998,2006 Free Software Foundation, Inc.                   *
+.\"                                                                          *
+.\" Permission is hereby granted, free of charge, to any person obtaining a  *
+.\" copy of this software and associated documentation files (the            *
+.\" "Software"), to deal in the Software without restriction, including      *
+.\" without limitation the rights to use, copy, modify, merge, publish,      *
+.\" distribute, distribute with modifications, sublicense, and/or sell       *
+.\" copies of the Software, and to permit persons to whom the Software is    *
+.\" furnished to do so, subject to the following conditions:                 *
+.\"                                                                          *
+.\" The above copyright notice and this permission notice shall be included  *
+.\" in all copies or substantial portions of the Software.                   *
+.\"                                                                          *
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+.\" IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+.\" DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+.\" OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+.\" THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+.\"                                                                          *
+.\" Except as contained in this notice, the name(s) of the above copyright   *
+.\" holders shall not be used in advertising or otherwise to promote the     *
+.\" sale, use or other dealings in this Software without prior written       *
+.\" authorization.                                                           *
+.\"***************************************************************************
+.\"
+.\" $Id: bs.6,v 1.2 2006/04/22 22:42:44 tom Exp $
+.TH BATTLESHIPS 6 "Aug 23, 1989"
+.SH NAME
+bs \- battleships game
+.SH SYNOPSIS
+battle [ -b | -s ] [ -c ]
+.SH DESCRIPTION
+This program allows you to play the familiar Battleships game against the
+computer on a 10x10 board. The interface is visual and largely
+self-explanatory; you place your ships and pick your shots by moving the
+cursor around the `sea' with the rogue/hack motion keys hjklyubn.
+.PP
+Note that when selecting a ship to place, you must type the capital letter
+(these are, after all, capital ships). During ship placement, the `r' command
+may be used to ignore the current position and randomly place your currently
+selected ship. The `R' command will place all remaining ships randomly. The ^L
+command (form feed, ASCII 12) will force a screen redraw).
+.PP
+The command-line arguments control game modes. 
+
+.nf
+	-b selects a `blitz' variant
+	-s selects a `salvo' variant
+	-c permits ships to be placed adjacently
+.fi
+
+The `blitz' variant allows a side to shoot for as long as it continues to
+score hits.
+.PP
+The `salvo' game allows a player one shot per turn for each of his/her ships
+still afloat.  This puts a premium scoring hits early and knocking out some
+ships and also makes much harder the situation where you face a superior force
+with only your PT-boat.
+.PP
+Normally, ships must be separated by at least one square of open water. The
+-c option disables this check and allows them to close-pack.
+.PP
+The algorithm the computer uses once it has found a ship to sink is provably
+optimal. The dispersion criterion for the random-fire algorithm may not be.
+.SH AUTHORS
+Originally written by one Bruce Holloway in 1986. Salvo mode added by Chuck A.
+DeGaul (cbosgd!cad). Visual user interface, `closepack' option, code rewrite
+and manual page by Eric S. Raymond <esr@snark.thyrsus.com> August 1989.
diff --git a/test/bs.c b/test/bs.c
new file mode 100644
index 0000000..f9572be
--- /dev/null
+++ b/test/bs.c
@@ -0,0 +1,1256 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/* 
+ * bs.c - original author: Bruce Holloway
+ *		salvo option by: Chuck A DeGaul
+ * with improved user interface, autoconfiguration and code cleanup
+ *		by Eric S. Raymond <esr@snark.thyrsus.com>
+ * v1.2 with color support and minor portability fixes, November 1990
+ * v2.0 featuring strict ANSI/POSIX conformance, November 1993.
+ * v2.1 with ncurses mouse support, September 1995
+ *
+ * $Id: bs.c,v 1.47 2008/08/03 18:30:28 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <time.h>
+
+#ifndef SIGIOT
+#define SIGIOT SIGABRT
+#endif
+
+static int getcoord(int);
+
+/*
+ * Constants for tuning the random-fire algorithm. It prefers moves that
+ * diagonal-stripe the board with a stripe separation of srchstep. If
+ * no such preferred moves are found, srchstep is decremented.
+ */
+#define BEGINSTEP	3	/* initial value of srchstep */
+
+/* miscellaneous constants */
+#define SHIPTYPES	5
+#define	OTHER		(1-turn)
+#define PLAYER		0
+#define COMPUTER	1
+#define MARK_HIT	'H'
+#define MARK_MISS	'o'
+#define CTRLC		'\003'	/* used as terminate command */
+#define FF		'\014'	/* used as redraw command */
+
+/* coordinate handling */
+#define BWIDTH		10
+#define BDEPTH		10
+
+/* display symbols */
+#define SHOWHIT		'*'
+#define SHOWSPLASH	' '
+#define IS_SHIP(c)	(isupper(UChar(c)) ? TRUE : FALSE)
+
+/* how to position us on player board */
+#define PYBASE	3
+#define PXBASE	3
+#define PY(y)	(PYBASE + (y))
+#define PX(x)	(PXBASE + (x)*3)
+#define pgoto(y, x)	(void)move(PY(y), PX(x))
+
+/* how to position us on cpu board */
+#define CYBASE	3
+#define CXBASE	48
+#define CY(y)	(CYBASE + (y))
+#define CX(x)	(CXBASE + (x)*3)
+#define CYINV(y)	((y) - CYBASE)
+#define CXINV(x)	(((x) - CXBASE) / 3)
+#define cgoto(y, x)	(void)move(CY(y), CX(x))
+
+#define ONBOARD(x, y)	(x >= 0 && x < BWIDTH && y >= 0 && y < BDEPTH)
+
+/* other board locations */
+#define COLWIDTH	80
+#define PROMPTLINE	21	/* prompt line */
+#define SYBASE		CYBASE + BDEPTH + 3	/* move key diagram */
+#define SXBASE		63
+#define MYBASE		SYBASE - 1	/* diagram caption */
+#define MXBASE		64
+#define HYBASE		SYBASE - 1	/* help area */
+#define HXBASE		0
+
+/* this will need to be changed if BWIDTH changes */
+static char numbers[] = "   0  1  2  3  4  5  6  7  8  9";
+
+static char carrier[] = "Aircraft Carrier";
+static char battle[] = "Battleship";
+static char sub[] = "Submarine";
+static char destroy[] = "Destroyer";
+static char ptboat[] = "PT Boat";
+
+static char name[40];
+static char dftname[] = "stranger";
+
+/* direction constants */
+#define E	0
+#define SE	1
+#define S	2
+#define SW	3
+#define W	4
+#define NW	5
+#define N	6
+#define NE	7
+static int xincr[8] =
+{1, 1, 0, -1, -1, -1, 0, 1};
+static int yincr[8] =
+{0, 1, 1, 1, 0, -1, -1, -1};
+
+/* current ship position and direction */
+static int curx = (BWIDTH / 2);
+static int cury = (BDEPTH / 2);
+
+typedef struct {
+    char *name;			/* name of the ship type */
+    int hits;			/* how many times has this ship been hit? */
+    char symbol;		/* symbol for game purposes */
+    int length;			/* length of ship */
+    int x, y;			/* coordinates of ship start point */
+    int dir;			/* direction of `bow' */
+    bool placed;		/* has it been placed on the board? */
+} ship_t;
+
+static bool checkplace(int b, ship_t * ss, int vis);
+
+#define SHIPIT(name, symbol, length) { name, 0, symbol, length, 0,0, 0, FALSE }
+
+static ship_t plyship[SHIPTYPES] =
+{
+    SHIPIT(carrier, 'A', 5),
+    SHIPIT(battle, 'B', 4),
+    SHIPIT(destroy, 'D', 3),
+    SHIPIT(sub, 'S', 3),
+    SHIPIT(ptboat, 'P', 2),
+};
+
+static ship_t cpuship[SHIPTYPES] =
+{
+    SHIPIT(carrier, 'A', 5),
+    SHIPIT(battle, 'B', 4),
+    SHIPIT(destroy, 'D', 3),
+    SHIPIT(sub, 'S', 3),
+    SHIPIT(ptboat, 'P', 2),
+};
+
+/* "Hits" board, and main board. */
+static char hits[2][BWIDTH][BDEPTH];
+static char board[2][BWIDTH][BDEPTH];
+
+static int turn;		/* 0=player, 1=computer */
+static int plywon = 0, cpuwon = 0;	/* How many games has each won? */
+
+static int salvo, blitz, closepack;
+
+#define	PR	(void)addstr
+
+static RETSIGTYPE uninitgame(int sig) GCC_NORETURN;
+
+static RETSIGTYPE
+uninitgame(int sig GCC_UNUSED)
+/* end the game, either normally or due to signal */
+{
+    clear();
+    (void) refresh();
+    (void) reset_shell_mode();
+    (void) echo();
+    (void) endwin();
+    ExitProgram(sig ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+static void
+announceopts(void)
+/* announce which game options are enabled */
+{
+    if (salvo || blitz || closepack) {
+	(void) printw("Playing optional game (");
+	if (salvo)
+	    (void) printw("salvo, ");
+	else
+	    (void) printw("nosalvo, ");
+	if (blitz)
+	    (void) printw("blitz ");
+	else
+	    (void) printw("noblitz, ");
+	if (closepack)
+	    (void) printw("closepack)");
+	else
+	    (void) printw("noclosepack)");
+    } else
+	(void) printw(
+			 "Playing standard game (noblitz, nosalvo, noclosepack)");
+}
+
+static void
+intro(void)
+{
+    char *tmpname;
+
+    srand((unsigned) (time(0L) + getpid()));	/* Kick the random number generator */
+
+    CATCHALL(uninitgame);
+
+    if ((tmpname = getlogin()) != 0) {
+	(void) strcpy(name, tmpname);
+	name[0] = toupper(UChar(name[0]));
+    } else
+	(void) strcpy(name, dftname);
+
+    (void) initscr();
+    keypad(stdscr, TRUE);
+    (void) def_prog_mode();
+    (void) nonl();
+    (void) cbreak();
+    (void) noecho();
+
+#ifdef PENGUIN
+    (void) clear();
+    (void) mvaddstr(4, 29, "Welcome to Battleship!");
+    (void) move(8, 0);
+    PR("                                                  \\\n");
+    PR("                           \\                     \\ \\\n");
+    PR("                          \\ \\                   \\ \\ \\_____________\n");
+    PR("                         \\ \\ \\_____________      \\ \\/            |\n");
+    PR("                          \\ \\/             \\      \\/             |\n");
+    PR("                           \\/               \\_____/              |__\n");
+    PR("           ________________/                                       |\n");
+    PR("           \\  S.S. Penguin                                         |\n");
+    PR("            \\                                                     /\n");
+    PR("             \\___________________________________________________/\n");
+
+    (void) mvaddstr(22, 27, "Hit any key to continue...");
+    (void) refresh();
+    (void) getch();
+#endif /* PENGUIN */
+
+#ifdef A_COLOR
+    start_color();
+
+    init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
+    init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
+    init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);
+    init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
+    init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
+    init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
+    init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
+    init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
+#endif /* A_COLOR */
+
+#ifdef NCURSES_MOUSE_VERSION
+    (void) mousemask(BUTTON1_CLICKED, (mmask_t *) NULL);
+#endif /* NCURSES_MOUSE_VERSION */
+}
+
+/* VARARGS1 */
+static void
+prompt(int n, NCURSES_CONST char *f, const char *s)
+/* print a message at the prompt line */
+{
+    (void) move(PROMPTLINE + n, 0);
+    (void) clrtoeol();
+    (void) printw(f, s);
+    (void) refresh();
+}
+
+static void
+error(NCURSES_CONST char *s)
+{
+    (void) move(PROMPTLINE + 2, 0);
+    (void) clrtoeol();
+    if (s) {
+	(void) addstr(s);
+	(void) beep();
+    }
+}
+
+static void
+placeship(int b, ship_t * ss, int vis)
+{
+    int l;
+
+    for (l = 0; l < ss->length; ++l) {
+	int newx = ss->x + l * xincr[ss->dir];
+	int newy = ss->y + l * yincr[ss->dir];
+
+	board[b][newx][newy] = ss->symbol;
+	if (vis) {
+	    pgoto(newy, newx);
+	    (void) addch((chtype) ss->symbol);
+	}
+    }
+    ss->hits = 0;
+}
+
+static int
+rnd(int n)
+{
+    return (((rand() & 0x7FFF) % n));
+}
+
+static void
+randomplace(int b, ship_t * ss)
+/* generate a valid random ship placement into px,py */
+{
+
+    do {
+	ss->dir = rnd(2) ? E : S;
+	ss->x = rnd(BWIDTH - (ss->dir == E ? ss->length : 0));
+	ss->y = rnd(BDEPTH - (ss->dir == S ? ss->length : 0));
+    } while
+	(!checkplace(b, ss, FALSE));
+}
+
+static void
+initgame(void)
+{
+    int i, j, unplaced;
+    ship_t *ss;
+
+    (void) clear();
+    (void) mvaddstr(0, 35, "BATTLESHIPS");
+    (void) move(PROMPTLINE + 2, 0);
+    announceopts();
+
+    memset(board, 0, sizeof(char) * BWIDTH * BDEPTH * 2);
+    memset(hits, 0, sizeof(char) * BWIDTH * BDEPTH * 2);
+    for (i = 0; i < SHIPTYPES; i++) {
+	ss = cpuship + i;
+
+	ss->x =
+	    ss->y =
+	    ss->dir =
+	    ss->hits = 0;
+	ss->placed = FALSE;
+
+	ss = plyship + i;
+
+	ss->x =
+	    ss->y =
+	    ss->dir =
+	    ss->hits = 0;
+	ss->placed = FALSE;
+    }
+
+    /* draw empty boards */
+    (void) mvaddstr(PYBASE - 2, PXBASE + 5, "Main Board");
+    (void) mvaddstr(PYBASE - 1, PXBASE - 3, numbers);
+    for (i = 0; i < BDEPTH; ++i) {
+	(void) mvaddch(PYBASE + i, PXBASE - 3, (chtype) (i + 'A'));
+#ifdef A_COLOR
+	if (has_colors())
+	    attron(COLOR_PAIR(COLOR_BLUE));
+#endif /* A_COLOR */
+	(void) addch(' ');
+	for (j = 0; j < BWIDTH; j++)
+	    (void) addstr(" . ");
+#ifdef A_COLOR
+	attrset(0);
+#endif /* A_COLOR */
+	(void) addch(' ');
+	(void) addch((chtype) (i + 'A'));
+    }
+    (void) mvaddstr(PYBASE + BDEPTH, PXBASE - 3, numbers);
+    (void) mvaddstr(CYBASE - 2, CXBASE + 7, "Hit/Miss Board");
+    (void) mvaddstr(CYBASE - 1, CXBASE - 3, numbers);
+    for (i = 0; i < BDEPTH; ++i) {
+	(void) mvaddch(CYBASE + i, CXBASE - 3, (chtype) (i + 'A'));
+#ifdef A_COLOR
+	if (has_colors())
+	    attron(COLOR_PAIR(COLOR_BLUE));
+#endif /* A_COLOR */
+	(void) addch(' ');
+	for (j = 0; j < BWIDTH; j++)
+	    (void) addstr(" . ");
+#ifdef A_COLOR
+	attrset(0);
+#endif /* A_COLOR */
+	(void) addch(' ');
+	(void) addch((chtype) (i + 'A'));
+    }
+
+    (void) mvaddstr(CYBASE + BDEPTH, CXBASE - 3, numbers);
+
+    (void) mvprintw(HYBASE, HXBASE,
+		    "To position your ships: move the cursor to a spot, then");
+    (void) mvprintw(HYBASE + 1, HXBASE,
+		    "type the first letter of a ship type to select it, then");
+    (void) mvprintw(HYBASE + 2, HXBASE,
+		    "type a direction ([hjkl] or [4862]), indicating how the");
+    (void) mvprintw(HYBASE + 3, HXBASE,
+		    "ship should be pointed. You may also type a ship letter");
+    (void) mvprintw(HYBASE + 4, HXBASE,
+		    "followed by `r' to position it randomly, or type `R' to");
+    (void) mvprintw(HYBASE + 5, HXBASE,
+		    "place all remaining ships randomly.");
+
+    (void) mvaddstr(MYBASE, MXBASE, "Aiming keys:");
+    (void) mvaddstr(SYBASE, SXBASE, "y k u    7 8 9");
+    (void) mvaddstr(SYBASE + 1, SXBASE, " \\|/      \\|/ ");
+    (void) mvaddstr(SYBASE + 2, SXBASE, "h-+-l    4-+-6");
+    (void) mvaddstr(SYBASE + 3, SXBASE, " /|\\      /|\\ ");
+    (void) mvaddstr(SYBASE + 4, SXBASE, "b j n    1 2 3");
+
+    /* have the computer place ships */
+    for (ss = cpuship; ss < cpuship + SHIPTYPES; ss++) {
+	randomplace(COMPUTER, ss);
+	placeship(COMPUTER, ss, FALSE);
+    }
+
+    ss = (ship_t *) NULL;
+    do {
+	char c, docked[SHIPTYPES + 2], *cp = docked;
+
+	/* figure which ships still wait to be placed */
+	*cp++ = 'R';
+	for (i = 0; i < SHIPTYPES; i++)
+	    if (!plyship[i].placed)
+		*cp++ = plyship[i].symbol;
+	*cp = '\0';
+
+	/* get a command letter */
+	prompt(1, "Type one of [%s] to pick a ship.", docked + 1);
+	do {
+	    c = getcoord(PLAYER);
+	} while
+	    (!strchr(docked, c));
+
+	if (c == 'R')
+	    (void) ungetch('R');
+	else {
+	    /* map that into the corresponding symbol */
+	    for (ss = plyship; ss < plyship + SHIPTYPES; ss++)
+		if (ss->symbol == c)
+		    break;
+
+	    prompt(1, "Type one of [hjklrR] to place your %s.", ss->name);
+	    pgoto(cury, curx);
+	}
+
+	do {
+	    c = getch();
+	} while
+	    (!(strchr("hjklrR", c) || c == FF));
+
+	if (c == FF) {
+	    (void) clearok(stdscr, TRUE);
+	    (void) refresh();
+	} else if (c == 'r') {
+	    assert(ss != 0);
+	    prompt(1, "Random-placing your %s", ss->name);
+	    randomplace(PLAYER, ss);
+	    placeship(PLAYER, ss, TRUE);
+	    error((char *) NULL);
+	    ss->placed = TRUE;
+	} else if (c == 'R') {
+	    prompt(1, "Placing the rest of your fleet at random...", "");
+	    for (ss = plyship; ss < plyship + SHIPTYPES; ss++)
+		if (!ss->placed) {
+		    randomplace(PLAYER, ss);
+		    placeship(PLAYER, ss, TRUE);
+		    ss->placed = TRUE;
+		}
+	    error((char *) NULL);
+	} else if (strchr("hjkl8462", c)) {
+	    assert(ss != 0);
+	    ss->x = curx;
+	    ss->y = cury;
+
+	    switch (c) {
+	    case 'k':
+	    case '8':
+		ss->dir = N;
+		break;
+	    case 'j':
+	    case '2':
+		ss->dir = S;
+		break;
+	    case 'h':
+	    case '4':
+		ss->dir = W;
+		break;
+	    case 'l':
+	    case '6':
+		ss->dir = E;
+		break;
+	    }
+
+	    if (checkplace(PLAYER, ss, TRUE)) {
+		placeship(PLAYER, ss, TRUE);
+		error((char *) NULL);
+		ss->placed = TRUE;
+	    }
+	}
+
+	for (unplaced = i = 0; i < SHIPTYPES; i++)
+	    unplaced += !plyship[i].placed;
+    } while
+	(unplaced);
+
+    turn = rnd(2);
+
+    (void) mvprintw(HYBASE, HXBASE,
+		    "To fire, move the cursor to your chosen aiming point   ");
+    (void) mvprintw(HYBASE + 1, HXBASE,
+		    "and strike any key other than a motion key.            ");
+    (void) mvprintw(HYBASE + 2, HXBASE,
+		    "                                                       ");
+    (void) mvprintw(HYBASE + 3, HXBASE,
+		    "                                                       ");
+    (void) mvprintw(HYBASE + 4, HXBASE,
+		    "                                                       ");
+    (void) mvprintw(HYBASE + 5, HXBASE,
+		    "                                                       ");
+
+    (void) prompt(0, "Press any key to start...", "");
+    (void) getch();
+}
+
+static int
+getcoord(int atcpu)
+{
+    int ny, nx, c;
+
+    if (atcpu)
+	cgoto(cury, curx);
+    else
+	pgoto(cury, curx);
+    (void) refresh();
+    for (;;) {
+	if (atcpu) {
+	    (void) mvprintw(CYBASE + BDEPTH + 1, CXBASE + 11, "(%d, %c)",
+			    curx, 'A' + cury);
+	    cgoto(cury, curx);
+	} else {
+	    (void) mvprintw(PYBASE + BDEPTH + 1, PXBASE + 11, "(%d, %c)",
+			    curx, 'A' + cury);
+	    pgoto(cury, curx);
+	}
+
+	switch (c = getch()) {
+	case 'k':
+	case '8':
+	case KEY_UP:
+	    ny = cury + BDEPTH - 1;
+	    nx = curx;
+	    break;
+	case 'j':
+	case '2':
+	case KEY_DOWN:
+	    ny = cury + 1;
+	    nx = curx;
+	    break;
+	case 'h':
+	case '4':
+	case KEY_LEFT:
+	    ny = cury;
+	    nx = curx + BWIDTH - 1;
+	    break;
+	case 'l':
+	case '6':
+	case KEY_RIGHT:
+	    ny = cury;
+	    nx = curx + 1;
+	    break;
+	case 'y':
+	case '7':
+	case KEY_A1:
+	    ny = cury + BDEPTH - 1;
+	    nx = curx + BWIDTH - 1;
+	    break;
+	case 'b':
+	case '1':
+	case KEY_C1:
+	    ny = cury + 1;
+	    nx = curx + BWIDTH - 1;
+	    break;
+	case 'u':
+	case '9':
+	case KEY_A3:
+	    ny = cury + BDEPTH - 1;
+	    nx = curx + 1;
+	    break;
+	case 'n':
+	case '3':
+	case KEY_C3:
+	    ny = cury + 1;
+	    nx = curx + 1;
+	    break;
+	case FF:
+	    nx = curx;
+	    ny = cury;
+	    (void) clearok(stdscr, TRUE);
+	    (void) refresh();
+	    break;
+#ifdef NCURSES_MOUSE_VERSION
+	case KEY_MOUSE:
+	    {
+		MEVENT myevent;
+
+		getmouse(&myevent);
+		if (atcpu
+		    && myevent.y >= CY(0) && myevent.y <= CY(BDEPTH)
+		    && myevent.x >= CX(0) && myevent.x <= CX(BDEPTH)) {
+		    curx = CXINV(myevent.x);
+		    cury = CYINV(myevent.y);
+		    return (' ');
+		} else {
+		    beep();
+		    continue;
+		}
+	    }
+	    /* no fall through */
+#endif /* NCURSES_MOUSE_VERSION */
+
+	default:
+	    if (atcpu)
+		(void) mvaddstr(CYBASE + BDEPTH + 1, CXBASE + 11, "      ");
+	    else
+		(void) mvaddstr(PYBASE + BDEPTH + 1, PXBASE + 11, "      ");
+	    return (c);
+	}
+
+	curx = nx % BWIDTH;
+	cury = ny % BDEPTH;
+    }
+}
+
+static bool
+collidecheck(int b, int y, int x)
+/* is this location on the selected zboard adjacent to a ship? */
+{
+    bool collide;
+
+    /* anything on the square */
+    if ((collide = IS_SHIP(board[b][x][y])) != FALSE)
+	return (collide);
+
+    /* anything on the neighbors */
+    if (!closepack) {
+	int i;
+
+	for (i = 0; i < 8; i++) {
+	    int xend, yend;
+
+	    yend = y + yincr[i];
+	    xend = x + xincr[i];
+	    if (ONBOARD(xend, yend)
+		&& IS_SHIP(board[b][xend][yend])) {
+		collide = TRUE;
+		break;
+	    }
+	}
+    }
+    return (collide);
+}
+
+static bool
+checkplace(int b, ship_t * ss, int vis)
+{
+    int l, xend, yend;
+
+    /* first, check for board edges */
+    xend = ss->x + (ss->length - 1) * xincr[ss->dir];
+    yend = ss->y + (ss->length - 1) * yincr[ss->dir];
+    if (!ONBOARD(xend, yend)) {
+	if (vis)
+	    switch (rnd(3)) {
+	    case 0:
+		error("Ship is hanging from the edge of the world");
+		break;
+	    case 1:
+		error("Try fitting it on the board");
+		break;
+	    case 2:
+		error("Figure I won't find it if you put it there?");
+		break;
+	    }
+	return (FALSE);
+    }
+
+    for (l = 0; l < ss->length; ++l) {
+	if (collidecheck(b, ss->y + l * yincr[ss->dir], ss->x + l * xincr[ss->dir])) {
+	    if (vis)
+		switch (rnd(3)) {
+		case 0:
+		    error("There's already a ship there");
+		    break;
+		case 1:
+		    error("Collision alert!  Aaaaaagh!");
+		    break;
+		case 2:
+		    error("Er, Admiral, what about the other ship?");
+		    break;
+		}
+	    return (FALSE);
+	}
+    }
+    return (TRUE);
+}
+
+static int
+awinna(void)
+{
+    int i, j;
+    ship_t *ss;
+
+    for (i = 0; i < 2; ++i) {
+	ss = (i) ? cpuship : plyship;
+	for (j = 0; j < SHIPTYPES; ++j, ++ss)
+	    if (ss->length > ss->hits)
+		break;
+	if (j == SHIPTYPES)
+	    return (OTHER);
+    }
+    return (-1);
+}
+
+static ship_t *
+hitship(int x, int y)
+/* register a hit on the targeted ship */
+{
+    ship_t *sb, *ss;
+    char sym;
+    int oldx, oldy;
+
+    getyx(stdscr, oldy, oldx);
+    sb = (turn) ? plyship : cpuship;
+    if ((sym = board[OTHER][x][y]) == 0)
+	return ((ship_t *) NULL);
+    for (ss = sb; ss < sb + SHIPTYPES; ++ss)
+	if (ss->symbol == sym) {
+	    if (++ss->hits < ss->length)	/* still afloat? */
+		return ((ship_t *) NULL);
+	    else {		/* sunk! */
+		int i, j;
+
+		if (!closepack)
+		    for (j = -1; j <= 1; j++) {
+			int bx = ss->x + j * xincr[(ss->dir + 2) % 8];
+			int by = ss->y + j * yincr[(ss->dir + 2) % 8];
+
+			for (i = -1; i <= ss->length; ++i) {
+			    int x1, y1;
+
+			    x1 = bx + i * xincr[ss->dir];
+			    y1 = by + i * yincr[ss->dir];
+			    if (ONBOARD(x1, y1)) {
+				hits[turn][x1][y1] = MARK_MISS;
+				if (turn % 2 == PLAYER) {
+				    cgoto(y1, x1);
+#ifdef A_COLOR
+				    if (has_colors())
+					attron(COLOR_PAIR(COLOR_GREEN));
+#endif /* A_COLOR */
+				    (void) addch(MARK_MISS);
+#ifdef A_COLOR
+				    attrset(0);
+#endif /* A_COLOR */
+				} else {
+				    pgoto(y1, x1);
+				    (void) addch(SHOWSPLASH);
+				}
+			    }
+			}
+		    }
+
+		for (i = 0; i < ss->length; ++i) {
+		    int x1 = ss->x + i * xincr[ss->dir];
+		    int y1 = ss->y + i * yincr[ss->dir];
+
+		    hits[turn][x1][y1] = ss->symbol;
+		    if (turn % 2 == PLAYER) {
+			cgoto(y1, x1);
+			(void) addch((chtype) (ss->symbol));
+		    } else {
+			pgoto(y1, x1);
+#ifdef A_COLOR
+			if (has_colors())
+			    attron(COLOR_PAIR(COLOR_RED));
+#endif /* A_COLOR */
+			(void) addch(SHOWHIT);
+#ifdef A_COLOR
+			attrset(0);
+#endif /* A_COLOR */
+		    }
+		}
+
+		(void) move(oldy, oldx);
+		return (ss);
+	    }
+	}
+    (void) move(oldy, oldx);
+    return ((ship_t *) NULL);
+}
+
+static bool
+plyturn(void)
+{
+    ship_t *ss;
+    bool hit;
+    NCURSES_CONST char *m = NULL;
+
+    prompt(1, "Where do you want to shoot? ", "");
+    for (;;) {
+	(void) getcoord(COMPUTER);
+	if (hits[PLAYER][curx][cury]) {
+	    prompt(1, "You shelled this spot already! Try again.", "");
+	    beep();
+	} else
+	    break;
+    }
+    hit = IS_SHIP(board[COMPUTER][curx][cury]);
+    hits[PLAYER][curx][cury] = (hit ? MARK_HIT : MARK_MISS);
+    cgoto(cury, curx);
+#ifdef A_COLOR
+    if (has_colors()) {
+	if (hit)
+	    attron(COLOR_PAIR(COLOR_RED));
+	else
+	    attron(COLOR_PAIR(COLOR_GREEN));
+    }
+#endif /* A_COLOR */
+    (void) addch((chtype) hits[PLAYER][curx][cury]);
+#ifdef A_COLOR
+    attrset(0);
+#endif /* A_COLOR */
+
+    prompt(1, "You %s.", hit ? "scored a hit" : "missed");
+    if (hit && (ss = hitship(curx, cury))) {
+	switch (rnd(5)) {
+	case 0:
+	    m = " You sank my %s!";
+	    break;
+	case 1:
+	    m = " I have this sinking feeling about my %s....";
+	    break;
+	case 2:
+	    m = " My %s has gone to Davy Jones's locker!";
+	    break;
+	case 3:
+	    m = " Glub, glub -- my %s is headed for the bottom!";
+	    break;
+	case 4:
+	    m = " You'll pick up survivors from my %s, I hope...!";
+	    break;
+	}
+	(void) printw(m, ss->name);
+	(void) beep();
+    }
+    return (hit);
+}
+
+static int
+sgetc(const char *s)
+{
+    const char *s1;
+    int ch;
+
+    (void) refresh();
+    for (;;) {
+	ch = getch();
+	if (islower(ch))
+	    ch = toupper(ch);
+	if (ch == CTRLC)
+	    uninitgame(0);
+	for (s1 = s; *s1 && ch != *s1; ++s1)
+	    continue;
+	if (*s1) {
+	    (void) addch((chtype) ch);
+	    (void) refresh();
+	    return (ch);
+	}
+    }
+}
+
+static void
+randomfire(int *px, int *py)
+/* random-fire routine -- implements simple diagonal-striping strategy */
+{
+    static int turncount = 0;
+    static int srchstep = BEGINSTEP;
+    static int huntoffs;	/* Offset on search strategy */
+    int ypossible[BWIDTH * BDEPTH], xpossible[BWIDTH * BDEPTH], nposs;
+    int ypreferred[BWIDTH * BDEPTH], xpreferred[BWIDTH * BDEPTH], npref;
+    int x, y, i;
+
+    if (turncount++ == 0)
+	huntoffs = rnd(srchstep);
+
+    /* first, list all possible moves */
+    nposs = npref = 0;
+    for (x = 0; x < BWIDTH; x++)
+	for (y = 0; y < BDEPTH; y++)
+	    if (!hits[COMPUTER][x][y]) {
+		xpossible[nposs] = x;
+		ypossible[nposs] = y;
+		nposs++;
+		if (((x + huntoffs) % srchstep) != (y % srchstep)) {
+		    xpreferred[npref] = x;
+		    ypreferred[npref] = y;
+		    npref++;
+		}
+	    }
+
+    if (npref) {
+	i = rnd(npref);
+
+	*px = xpreferred[i];
+	*py = ypreferred[i];
+    } else if (nposs) {
+	i = rnd(nposs);
+
+	*px = xpossible[i];
+	*py = ypossible[i];
+
+	if (srchstep > 1)
+	    --srchstep;
+    } else {
+	error("No moves possible?? Help!");
+	ExitProgram(EXIT_FAILURE);
+	/*NOTREACHED */
+    }
+}
+
+#define S_MISS	0
+#define S_HIT	1
+#define S_SUNK	-1
+
+static int
+cpufire(int x, int y)
+/* fire away at given location */
+{
+    bool hit, sunk;
+    ship_t *ss = NULL;
+
+    hits[COMPUTER][x][y] = (hit = (board[PLAYER][x][y])) ? MARK_HIT : MARK_MISS;
+    (void) mvprintw(PROMPTLINE, 0,
+		    "I shoot at %c%d. I %s!", y + 'A', x, hit ? "hit" :
+		    "miss");
+    if ((sunk = (hit && (ss = hitship(x, y)))) != 0)
+	(void) printw(" I've sunk your %s", ss->name);
+    (void) clrtoeol();
+
+    pgoto(y, x);
+#ifdef A_COLOR
+    if (has_colors()) {
+	if (hit)
+	    attron(COLOR_PAIR(COLOR_RED));
+	else
+	    attron(COLOR_PAIR(COLOR_GREEN));
+    }
+#endif /* A_COLOR */
+    (void) addch((chtype) (hit ? SHOWHIT : SHOWSPLASH));
+#ifdef A_COLOR
+    attrset(0);
+#endif /* A_COLOR */
+
+    return hit ? (sunk ? S_SUNK : S_HIT) : S_MISS;
+}
+
+/*
+ * This code implements a fairly irregular FSM, so please forgive the rampant
+ * unstructuredness below. The five labels are states which need to be held
+ * between computer turns.
+ *
+ * The FSM is not externally reset to RANDOM_FIRE if the player wins. Instead,
+ * the other states check for "impossible" conditions which signify a new
+ * game, then if found transition to RANDOM_FIRE.
+ */
+static bool
+cputurn(void)
+{
+#define POSSIBLE(x, y)	(ONBOARD(x, y) && !hits[COMPUTER][x][y])
+#define RANDOM_FIRE	0
+#define RANDOM_HIT	1
+#define HUNT_DIRECT	2
+#define FIRST_PASS	3
+#define REVERSE_JUMP	4
+#define SECOND_PASS	5
+    static int next = RANDOM_FIRE;
+    static bool used[4];
+    static ship_t ts;
+    int navail, x, y, d, n;
+    int hit = S_MISS;
+
+    switch (next) {
+    case RANDOM_FIRE:		/* last shot was random and missed */
+      refire:
+	randomfire(&x, &y);
+	if (!(hit = cpufire(x, y)))
+	    next = RANDOM_FIRE;
+	else {
+	    ts.x = x;
+	    ts.y = y;
+	    ts.hits = 1;
+	    next = (hit == S_SUNK) ? RANDOM_FIRE : RANDOM_HIT;
+	}
+	break;
+
+    case RANDOM_HIT:		/* last shot was random and hit */
+	used[E / 2] = used[S / 2] = used[W / 2] = used[N / 2] = FALSE;
+	/* FALLTHROUGH */
+
+    case HUNT_DIRECT:		/* last shot hit, we're looking for ship's long axis */
+	for (d = navail = 0; d < 4; d++) {
+	    x = ts.x + xincr[d * 2];
+	    y = ts.y + yincr[d * 2];
+	    if (!used[d] && POSSIBLE(x, y))
+		navail++;
+	    else
+		used[d] = TRUE;
+	}
+	if (navail == 0)	/* no valid places for shots adjacent... */
+	    goto refire;	/* ...so we must random-fire */
+	else {
+	    n = rnd(navail) + 1;
+	    for (d = 0; used[d]; d++) ;
+	    /* used[d] is first that == 0 */
+	    for (; n > 1; n--)
+		while (used[++d]) ;
+	    /* used[d] is next that == 0 */
+
+	    assert(d < 4);
+	    assert(used[d] == FALSE);
+
+	    used[d] = TRUE;
+	    x = ts.x + xincr[d * 2];
+	    y = ts.y + yincr[d * 2];
+
+	    assert(POSSIBLE(x, y));
+
+	    if (!(hit = cpufire(x, y)))
+		next = HUNT_DIRECT;
+	    else {
+		ts.x = x;
+		ts.y = y;
+		ts.dir = d * 2;
+		ts.hits++;
+		next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS;
+	    }
+	}
+	break;
+
+    case FIRST_PASS:		/* we have a start and a direction now */
+	x = ts.x + xincr[ts.dir];
+	y = ts.y + yincr[ts.dir];
+	if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
+	    ts.x = x;
+	    ts.y = y;
+	    ts.hits++;
+	    next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS;
+	} else
+	    next = REVERSE_JUMP;
+	break;
+
+    case REVERSE_JUMP:		/* nail down the ship's other end */
+	d = (ts.dir + 4) % 8;
+	x = ts.x + ts.hits * xincr[d];
+	y = ts.y + ts.hits * yincr[d];
+	if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
+	    ts.x = x;
+	    ts.y = y;
+	    ts.dir = d;
+	    ts.hits++;
+	    next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS;
+	} else
+	    next = RANDOM_FIRE;
+	break;
+
+    case SECOND_PASS:		/* continue shooting after reversing */
+	x = ts.x + xincr[ts.dir];
+	y = ts.y + yincr[ts.dir];
+	if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
+	    ts.x = x;
+	    ts.y = y;
+	    ts.hits++;
+	    next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS;
+	    break;
+	} else
+	    next = RANDOM_FIRE;
+	break;
+    }
+
+    /* pause between shots in salvo */
+    if (salvo) {
+	(void) refresh();
+	(void) sleep(1);
+    }
+#ifdef DEBUG
+    (void) mvprintw(PROMPTLINE + 2, 0,
+		    "New state %d, x=%d, y=%d, d=%d",
+		    next, x, y, d);
+#endif /* DEBUG */
+    return ((hit) ? TRUE : FALSE);
+}
+
+static int
+playagain(void)
+{
+    int j;
+    ship_t *ss;
+
+    for (ss = cpuship; ss < cpuship + SHIPTYPES; ss++)
+	for (j = 0; j < ss->length; j++) {
+	    cgoto(ss->y + j * yincr[ss->dir], ss->x + j * xincr[ss->dir]);
+	    (void) addch((chtype) ss->symbol);
+	}
+
+    if (awinna())
+	++cpuwon;
+    else
+	++plywon;
+    j = 18 + strlen(name);
+    if (plywon >= 10)
+	++j;
+    if (cpuwon >= 10)
+	++j;
+    (void) mvprintw(1, (COLWIDTH - j) / 2,
+		    "%s: %d     Computer: %d", name, plywon, cpuwon);
+
+    prompt(2, (awinna())? "Want to be humiliated again, %s [yn]? "
+	   : "Going to give me a chance for revenge, %s [yn]? ", name);
+    return (sgetc("YN") == 'Y');
+}
+
+static void
+do_options(int c, char *op[])
+{
+    register int i;
+
+    if (c > 1) {
+	for (i = 1; i < c; i++) {
+	    switch (op[i][0]) {
+	    default:
+	    case '?':
+		(void) fprintf(stderr, "Usage: battle [-s | -b] [-c]\n");
+		(void) fprintf(stderr, "\tWhere the options are:\n");
+		(void) fprintf(stderr, "\t-s : play a salvo game\n");
+		(void) fprintf(stderr, "\t-b : play a blitz game\n");
+		(void) fprintf(stderr, "\t-c : ships may be adjacent\n");
+		ExitProgram(EXIT_FAILURE);
+		break;
+	    case '-':
+		switch (op[i][1]) {
+		case 'b':
+		    blitz = 1;
+		    if (salvo == 1) {
+			(void) fprintf(stderr,
+				       "Bad Arg: -b and -s are mutually exclusive\n");
+			ExitProgram(EXIT_FAILURE);
+		    }
+		    break;
+		case 's':
+		    salvo = 1;
+		    if (blitz == 1) {
+			(void) fprintf(stderr,
+				       "Bad Arg: -s and -b are mutually exclusive\n");
+			ExitProgram(EXIT_FAILURE);
+		    }
+		    break;
+		case 'c':
+		    closepack = 1;
+		    break;
+		default:
+		    (void) fprintf(stderr,
+				   "Bad arg: type \"%s ?\" for usage message\n",
+				   op[0]);
+		    ExitProgram(EXIT_FAILURE);
+		}
+	    }
+	}
+    }
+}
+
+static int
+scount(int who)
+{
+    register int i, shots;
+    register ship_t *sp;
+
+    if (who)
+	sp = cpuship;		/* count cpu shots */
+    else
+	sp = plyship;		/* count player shots */
+
+    for (i = 0, shots = 0; i < SHIPTYPES; i++, sp++) {
+	if (sp->hits >= sp->length)
+	    continue;		/* dead ship */
+	else
+	    shots++;
+    }
+    return (shots);
+}
+
+int
+main(int argc, char *argv[])
+{
+    setlocale(LC_ALL, "");
+
+    do_options(argc, argv);
+
+    intro();
+    do {
+	initgame();
+	while (awinna() == -1) {
+	    if (!blitz) {
+		if (!salvo) {
+		    if (turn)
+			(void) cputurn();
+		    else
+			(void) plyturn();
+		} else {
+		    register int i;
+
+		    i = scount(turn);
+		    while (i--) {
+			if (turn) {
+			    if (cputurn() && awinna() != -1)
+				i = 0;
+			} else {
+			    if (plyturn() && awinna() != -1)
+				i = 0;
+			}
+		    }
+		}
+	    } else
+		while ((turn ? cputurn() : plyturn()) && awinna() == -1)
+		    continue;
+	    turn = OTHER;
+	}
+    } while
+	(playagain());
+    uninitgame(0);
+    /*NOTREACHED */
+}
+
+/* bs.c ends here */
diff --git a/test/bulgarian-utf8.txt b/test/bulgarian-utf8.txt
new file mode 100644
index 0000000..046c059
--- /dev/null
+++ b/test/bulgarian-utf8.txt
@@ -0,0 +1,6 @@
+Показване на помощна информация -- 1
+Създаване на дялове             -- 2
+Избор на дял и форматиране      -- 3
+Записване в избрания дял        -- 4
+Инсталиране на LILO             -- 5
+Изход от програмата             -- 6
diff --git a/test/cardfile.c b/test/cardfile.c
new file mode 100644
index 0000000..68ae4fe
--- /dev/null
+++ b/test/cardfile.c
@@ -0,0 +1,623 @@
+/****************************************************************************
+ * Copyright (c) 1999-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * Author: Thomas E. Dickey
+ *
+ * $Id: cardfile.c,v 1.35 2008/08/05 00:42:24 tom Exp $
+ *
+ * File format: text beginning in column 1 is a title; other text is content.
+ */
+
+#include <test.priv.h>
+
+#if USE_LIBFORM && USE_LIBPANEL
+
+#include <form.h>
+#include <panel.h>
+
+#define VISIBLE_CARDS 10
+#define OFFSET_CARD 2
+#define pair_1 1
+#define pair_2 2
+
+#define isVisible(cardp) ((cardp)->panel != 0)
+
+enum {
+    MY_CTRL_x = MAX_FORM_COMMAND
+    ,MY_CTRL_N
+    ,MY_CTRL_P
+    ,MY_CTRL_Q
+    ,MY_CTRL_W
+};
+
+typedef struct _card {
+    struct _card *link;
+    PANEL *panel;
+    FORM *form;
+    char *title;
+    char *content;
+} CARD;
+
+static CARD *all_cards;
+static bool try_color = FALSE;
+static char default_name[] = "cardfile.dat";
+
+#if !HAVE_STRDUP
+#define strdup my_strdup
+static char *
+strdup(const char *s)
+{
+    char *p = typeMalloc(char, strlen(s) + 1);
+    if (p)
+	strcpy(p, s);
+    return (p);
+}
+#endif /* not HAVE_STRDUP */
+
+static const char *
+skip(const char *buffer)
+{
+    while (isspace(UChar(*buffer)))
+	buffer++;
+    return buffer;
+}
+
+static void
+trim(char *buffer)
+{
+    unsigned n = strlen(buffer);
+    while (n-- && isspace(UChar(buffer[n])))
+	buffer[n] = 0;
+}
+
+/*******************************************************************************/
+
+static CARD *
+add_title(const char *title)
+{
+    CARD *card, *p, *q;
+
+    for (p = all_cards, q = 0; p != 0; q = p, p = p->link) {
+	int cmp = strcmp(p->title, title);
+	if (cmp == 0)
+	    return p;
+	if (cmp > 0)
+	    break;
+    }
+
+    card = typeCalloc(CARD, 1);
+    card->title = strdup(title);
+    card->content = strdup("");
+
+    if (q == 0) {
+	card->link = all_cards;
+	all_cards = card;
+    } else {
+	card->link = q->link;
+	q->link = card;
+    }
+
+    return card;
+}
+
+static void
+add_content(CARD * card, const char *content)
+{
+    unsigned total, offset;
+
+    content = skip(content);
+    if ((total = strlen(content)) != 0) {
+	if (card->content != 0 && (offset = strlen(card->content)) != 0) {
+	    total += 1 + offset;
+	    card->content = typeRealloc(char, total + 1, card->content);
+	    if (card->content)
+		strcpy(card->content + offset++, " ");
+	} else {
+	    offset = 0;
+	    if (card->content != 0)
+		free(card->content);
+	    card->content = typeMalloc(char, total + 1);
+	}
+	if (card->content)
+	    strcpy(card->content + offset, content);
+    }
+}
+
+static CARD *
+new_card(void)
+{
+    CARD *card = add_title("");
+    add_content(card, "");
+    return card;
+}
+
+static CARD *
+find_card(char *title)
+{
+    CARD *card;
+
+    for (card = all_cards; card != 0; card = card->link)
+	if (!strcmp(card->title, title))
+	    break;
+
+    return card;
+}
+
+static void
+read_data(char *fname)
+{
+    FILE *fp;
+    CARD *card = 0;
+    char buffer[BUFSIZ];
+
+    if ((fp = fopen(fname, "r")) != 0) {
+	while (fgets(buffer, sizeof(buffer), fp)) {
+	    trim(buffer);
+	    if (isspace(UChar(*buffer))) {
+		if (card == 0)
+		    card = add_title("");
+		add_content(card, buffer);
+	    } else if ((card = find_card(buffer)) == 0) {
+		card = add_title(buffer);
+	    }
+	}
+	fclose(fp);
+    }
+}
+
+/*******************************************************************************/
+
+static void
+write_data(const char *fname)
+{
+    FILE *fp;
+    CARD *p = 0;
+    int n;
+
+    if (!strcmp(fname, default_name))
+	fname = "cardfile.out";
+
+    if ((fp = fopen(fname, "w")) != 0) {
+	for (p = all_cards; p != 0; p = p->link) {
+	    FIELD **f = form_fields(p->form);
+	    for (n = 0; f[n] != 0; n++) {
+		char *s = field_buffer(f[n], 0);
+		if (s != 0
+		    && (s = strdup(s)) != 0) {
+		    trim(s);
+		    fprintf(fp, "%s%s\n", n ? "\t" : "", s);
+		    free(s);
+		}
+	    }
+	}
+	fclose(fp);
+    }
+}
+
+/*******************************************************************************/
+
+/*
+ * Count the cards
+ */
+static int
+count_cards(void)
+{
+    CARD *p;
+    int count = 0;
+
+    for (p = all_cards; p != 0; p = p->link)
+	count++;
+
+    return count;
+}
+
+/*
+ * Shuffle the panels to keep them in a natural hierarchy.
+ */
+static void
+order_cards(CARD * first, int depth)
+{
+    if (first) {
+	if (depth && first->link)
+	    order_cards(first->link, depth - 1);
+	if (isVisible(first))
+	    top_panel(first->panel);
+    }
+}
+
+/*
+ * Return the next card in the list
+ */
+static CARD *
+next_card(CARD * now)
+{
+    if (now->link != 0) {
+	CARD *tst = now->link;
+	if (isVisible(tst))
+	    now = tst;
+	else
+	    tst = next_card(tst);
+    }
+    return now;
+}
+
+/*
+ * Return the previous card in the list
+ */
+static CARD *
+prev_card(CARD * now)
+{
+    CARD *p;
+    for (p = all_cards; p != 0; p = p->link) {
+	if (p->link == now) {
+	    if (!isVisible(p))
+		p = prev_card(p);
+	    return p;
+	}
+    }
+    return now;
+}
+
+/*
+ * Returns the first card in the list that we will display.
+ */
+static CARD *
+first_card(CARD * now)
+{
+    if (!isVisible(now))
+	now = next_card(now);
+    return now;
+}
+
+/*******************************************************************************/
+
+static int
+form_virtualize(WINDOW *w)
+{
+    int c = wgetch(w);
+
+    switch (c) {
+    case CTRL('W'):
+	return (MY_CTRL_W);
+    case CTRL('N'):
+	return (MY_CTRL_N);
+    case CTRL('P'):
+	return (MY_CTRL_P);
+    case QUIT:
+    case ESCAPE:
+	return (MY_CTRL_Q);
+
+    case KEY_BACKSPACE:
+	return (REQ_DEL_PREV);
+    case KEY_DC:
+	return (REQ_DEL_CHAR);
+    case KEY_LEFT:
+	return (REQ_LEFT_CHAR);
+    case KEY_RIGHT:
+	return (REQ_RIGHT_CHAR);
+
+    case KEY_DOWN:
+    case KEY_NEXT:
+	return (REQ_NEXT_FIELD);
+    case KEY_UP:
+    case KEY_PREVIOUS:
+	return (REQ_PREV_FIELD);
+
+    default:
+	return (c);
+    }
+}
+
+static FIELD **
+make_fields(CARD * p, int form_high, int form_wide)
+{
+    FIELD **f = typeCalloc(FIELD *, 3);
+
+    f[0] = new_field(1, form_wide, 0, 0, 0, 0);
+    set_field_back(f[0], A_REVERSE);
+    set_field_buffer(f[0], 0, p->title);
+    field_opts_off(f[0], O_BLANK);
+
+    f[1] = new_field(form_high - 1, form_wide, 1, 0, 0, 0);
+    set_field_buffer(f[1], 0, p->content);
+    set_field_just(f[1], JUSTIFY_LEFT);
+    field_opts_off(f[1], O_BLANK);
+
+    f[2] = 0;
+    return f;
+}
+
+static void
+show_legend(void)
+{
+    erase();
+    move(LINES - 3, 0);
+    addstr("^Q/ESC -- exit form            ^W   -- writes data to file\n");
+    addstr("^N   -- go to next card        ^P   -- go to previous card\n");
+    addstr("Arrow keys move left/right within a field, up/down between fields");
+}
+
+#if (defined(KEY_RESIZE) && HAVE_WRESIZE) || NO_LEAKS
+static void
+free_form_fields(FIELD ** f)
+{
+    int n;
+
+    for (n = 0; f[n] != 0; ++n) {
+	free_field(f[n]);
+    }
+    free(f);
+}
+#endif
+
+/*******************************************************************************/
+
+static void
+cardfile(char *fname)
+{
+    WINDOW *win;
+    CARD *p;
+    CARD *top_card;
+    int visible_cards;
+    int panel_wide;
+    int panel_high;
+    int form_wide;
+    int form_high;
+    int y;
+    int x;
+    int ch = ERR;
+    int finished = FALSE;
+
+    show_legend();
+
+    /* decide how many cards we can display */
+    visible_cards = count_cards();
+    while (
+	      (panel_wide = COLS - (visible_cards * OFFSET_CARD)) < 10 ||
+	      (panel_high = LINES - (visible_cards * OFFSET_CARD) - 5) < 5) {
+	--visible_cards;
+    }
+    form_wide = panel_wide - 2;
+    form_high = panel_high - 2;
+    y = (visible_cards - 1) * OFFSET_CARD;
+    x = 0;
+
+    /* make a panel for each CARD */
+    for (p = all_cards; p != 0; p = p->link) {
+
+	if ((win = newwin(panel_high, panel_wide, y, x)) == 0)
+	    break;
+
+	wbkgd(win, COLOR_PAIR(pair_2));
+	keypad(win, TRUE);
+	p->panel = new_panel(win);
+	box(win, 0, 0);
+
+	p->form = new_form(make_fields(p, form_high, form_wide));
+	set_form_win(p->form, win);
+	set_form_sub(p->form, derwin(win, form_high, form_wide, 1, 1));
+	post_form(p->form);
+
+	y -= OFFSET_CARD;
+	x += OFFSET_CARD;
+    }
+
+    top_card = first_card(all_cards);
+    order_cards(top_card, visible_cards);
+
+    while (!finished) {
+	update_panels();
+	doupdate();
+
+	ch = form_virtualize(panel_window(top_card->panel));
+	switch (form_driver(top_card->form, ch)) {
+	case E_OK:
+	    break;
+	case E_UNKNOWN_COMMAND:
+	    switch (ch) {
+	    case MY_CTRL_Q:
+		finished = TRUE;
+		break;
+	    case MY_CTRL_P:
+		top_card = prev_card(top_card);
+		order_cards(top_card, visible_cards);
+		break;
+	    case MY_CTRL_N:
+		top_card = next_card(top_card);
+		order_cards(top_card, visible_cards);
+		break;
+	    case MY_CTRL_W:
+		form_driver(top_card->form, REQ_VALIDATION);
+		write_data(fname);
+		break;
+#if defined(KEY_RESIZE) && HAVE_WRESIZE
+	    case KEY_RESIZE:
+		/* resizeterm already did "something" reasonable, but it cannot
+		 * know much about layout.  So let's make it nicer.
+		 */
+		panel_wide = COLS - (visible_cards * OFFSET_CARD);
+		panel_high = LINES - (visible_cards * OFFSET_CARD) - 5;
+
+		form_wide = panel_wide - 2;
+		form_high = panel_high - 2;
+
+		y = (visible_cards - 1) * OFFSET_CARD;
+		x = 0;
+
+		show_legend();
+		for (p = all_cards; p != 0; p = p->link) {
+		    FIELD **oldf = form_fields(p->form);
+		    WINDOW *olds = form_sub(p->form);
+
+		    if (!isVisible(p))
+			continue;
+		    win = form_win(p->form);
+
+		    /* move and resize the card as needed
+		     * FIXME: if the windows are shrunk too much, this won't do
+		     */
+		    mvwin(win, y, x);
+		    wresize(win, panel_high, panel_wide);
+
+		    /* reconstruct each form.  Forms are not resizable, and
+		     * there appears to be no good way to reload the text in
+		     * a resized window.
+		     */
+		    werase(win);
+
+		    unpost_form(p->form);
+		    free_form(p->form);
+
+		    p->form = new_form(make_fields(p, form_high, form_wide));
+		    set_form_win(p->form, win);
+		    set_form_sub(p->form, derwin(win, form_high, form_wide,
+						 1, 1));
+		    post_form(p->form);
+
+		    free_form_fields(oldf);
+		    delwin(olds);
+
+		    box(win, 0, 0);
+
+		    y -= OFFSET_CARD;
+		    x += OFFSET_CARD;
+		}
+		break;
+#endif
+	    default:
+		beep();
+		break;
+	    }
+	    break;
+	default:
+	    flash();
+	    break;
+	}
+    }
+#if NO_LEAKS
+    while (all_cards != 0) {
+	FIELD **f;
+	int count;
+
+	p = all_cards;
+	all_cards = all_cards->link;
+
+	if (isVisible(p)) {
+	    f = form_fields(p->form);
+	    count = field_count(p->form);
+
+	    unpost_form(p->form);	/* ...so we can free it */
+	    free_form(p->form);	/* this also disconnects the fields */
+
+	    free_form_fields(f);
+
+	    del_panel(p->panel);
+	}
+	free(p->title);
+	free(p->content);
+	free(p);
+    }
+#endif
+}
+
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+	"Usage: view [options] file"
+	,""
+	,"Options:"
+	," -c       use color if terminal supports it"
+    };
+    size_t n;
+    for (n = 0; n < SIZEOF(msg); n++)
+	fprintf(stderr, "%s\n", msg[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+/*******************************************************************************/
+
+int
+main(int argc, char *argv[])
+{
+    int n;
+
+    setlocale(LC_ALL, "");
+
+    while ((n = getopt(argc, argv, "c")) != -1) {
+	switch (n) {
+	case 'c':
+	    try_color = TRUE;
+	    break;
+	default:
+	    usage();
+	}
+    }
+
+    initscr();
+    cbreak();
+    noecho();
+
+    if (try_color) {
+	if (has_colors()) {
+	    start_color();
+	    init_pair(pair_1, COLOR_WHITE, COLOR_BLUE);
+	    init_pair(pair_2, COLOR_WHITE, COLOR_CYAN);
+	    bkgd(COLOR_PAIR(pair_1));
+	} else {
+	    try_color = FALSE;
+	}
+    }
+
+    if (optind + 1 == argc) {
+	for (n = 1; n < argc; n++)
+	    read_data(argv[n]);
+	if (count_cards() == 0)
+	    new_card();
+	cardfile(argv[1]);
+    } else {
+	read_data(default_name);
+	if (count_cards() == 0)
+	    new_card();
+	cardfile(default_name);
+    }
+
+    endwin();
+
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the curses form and panel libraries\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/cardfile.dat b/test/cardfile.dat
new file mode 100644
index 0000000..deb4b76
--- /dev/null
+++ b/test/cardfile.dat
@@ -0,0 +1,13 @@
+title 1
+	Some text for title1
+	and some more text
+title 2
+	The quicker brown fox ran all over the lazy dog.
+put a card before the first two
+	This is an example of a simple cardfile.
+show a fourth card
+	The fourth card
+	has a large amount of data,
+	more than the other cards.
+	At least, that is what I thought it should do, since I want to see how well
+	the forms package handles justification.
diff --git a/test/chgat.c b/test/chgat.c
new file mode 100644
index 0000000..ee51297
--- /dev/null
+++ b/test/chgat.c
@@ -0,0 +1,368 @@
+/****************************************************************************
+ * Copyright (c) 2006-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: chgat.c,v 1.8 2008/02/09 23:19:13 tom Exp $
+ *
+ * test-driver for chgat/wchgat/mvchgat/mvwchgat
+ */
+
+#include <test.priv.h>
+
+#if HAVE_CHGAT
+
+#define SHOW(n) ((n) == ERR ? "ERR" : "OK")
+#define COLOR_DEFAULT (-1)
+
+#if defined(NCURSES_VERSION_PATCH) && NCURSES_VERSION_PATCH < 20060715
+#define touch_if_needed(win, row) touchline(win, row, 1)
+#else
+#define touch_if_needed(win, row)	/* nothing */
+#endif
+
+typedef struct {
+    unsigned c;
+    unsigned v;
+    int pair;
+    unsigned attr;
+    int count;
+    int ch;
+    const char *c_msg;
+    const char *v_msg;
+    int y_val;
+    int x_val;
+    int y_beg, x_beg;
+    int y_max, x_max;
+} STATUS;
+
+static const char *
+color_params(unsigned state, int *pair)
+{
+    /* *INDENT-OFF* */
+    static struct {
+	int pair;
+	int fg, bg;
+	const char *msg;
+    } table[] = {
+	{ 0, COLOR_DEFAULT, COLOR_DEFAULT, "default" },
+	{ 1, COLOR_RED,     COLOR_BLACK,   "red/black" },
+	{ 2, COLOR_WHITE,   COLOR_BLUE,    "white/blue" },
+    };
+    /* *INDENT-ON* */
+
+    static bool first = TRUE;
+    const char *result = 0;
+
+    if (has_colors()) {
+	if (first) {
+	    unsigned n;
+
+	    start_color();
+	    for (n = 0; n < SIZEOF(table); ++n) {
+		init_pair(table[n].pair, table[n].fg, table[n].bg);
+	    }
+	}
+	if (state < SIZEOF(table)) {
+	    *pair = table[state].pair;
+	    result = table[state].msg;
+	}
+    }
+    return result;
+}
+
+static const char *
+video_params(unsigned state, unsigned *attr)
+{
+    /* *INDENT-OFF* */
+    static struct {
+	unsigned attr;
+	const char *msg;
+    } table[] = {
+	{ A_NORMAL,	"normal" },
+	{ A_BOLD,	"bold" },
+	{ A_REVERSE,	"reverse" },
+	{ A_UNDERLINE,	"underline" },
+	{ A_BLINK, 	"blink" },
+    };
+    /* *INDENT-ON* */
+
+    const char *result = 0;
+
+    if (state < SIZEOF(table)) {
+	*attr = table[state].attr;
+	result = table[state].msg;
+    }
+    return result;
+}
+
+/* fill the window with a test-pattern */
+static void
+fill_window(WINDOW *win)
+{
+    int y, x;
+
+    getyx(win, y, x);
+    wmove(win, 0, 0);
+    while (waddstr(win, "0123456789 abcdefghijklmnopqrstuvwxyz ") != ERR) {
+    }
+    wmove(win, y, x);
+}
+
+static void
+show_status(WINDOW *win, STATUS * sp)
+{
+    int y, x;
+
+    getyx(win, y, x);
+    wmove(win, 0, 0);
+    wprintw(win, "Count %d", sp->count);
+    if (sp->v_msg != 0)
+	wprintw(win, " Video %s", sp->v_msg);
+    if (sp->c_msg != 0)
+	wprintw(win, " Color %s", sp->c_msg);
+    wclrtoeol(win);
+    wmove(win, y, x);
+}
+
+static void
+do_subwindow(WINDOW *win, STATUS * sp, void func(WINDOW *))
+{
+    WINDOW *win1 = newwin(sp->y_max - 2, sp->x_max - 2,
+			  sp->y_beg + 1, sp->x_beg + 1);
+
+    if (win1 != 0 && sp->y_max > 4 && sp->x_max > 4) {
+	WINDOW *win2 = derwin(win1, sp->y_max - 4, sp->x_max - 4, 1, 1);
+
+	if (win2 != 0) {
+	    box(win1, 0, 0);
+	    wrefresh(win1);
+	    func(win2);
+
+	    delwin(win2);
+	} else {
+	    beep();
+	}
+	delwin(win1);
+	touchwin(win);
+    } else {
+	beep();
+    }
+}
+
+static void
+init_status(WINDOW *win, STATUS * sp)
+{
+    memset(sp, 0, sizeof(*sp));
+    sp->c = 99;
+    sp->v = 99;
+    sp->ch = ' ';
+
+    keypad(win, TRUE);
+    fill_window(win);
+
+    getbegyx(win, sp->y_beg, sp->x_beg);
+    getmaxyx(win, sp->y_max, sp->x_max);
+}
+
+static void
+show_help(WINDOW *win)
+{
+    static const char *table[] =
+    {
+	"Basic commands:"
+	,"Use h/j/k/l or arrow keys to move the cursor."
+	,"Set the count parameter for chgat by entering digits 0-9."
+	,""
+	,"Other commands:"
+	,"space toggles through the set of video attributes and colors."
+	,"t     touches (forces repaint) of the current line."
+	,".     calls *chgat at the current position with the given count."
+	,",     calls *chgat at the window beginning with the given count."
+	,"=     resets count to zero."
+	,"-     negates count."
+	,"?     shows this help-window"
+	,""
+	,""
+    };
+
+    int y_max, x_max;
+    int row;
+
+    getmaxyx(win, y_max, x_max);
+    for (row = 0; row < (int) SIZEOF(table) && row < y_max; ++row) {
+	mvwprintw(win, row, 0, "%.*s", x_max, table[row]);
+    }
+    while (wgetch(win) != 'q')
+	beep();
+}
+
+static void
+update_status(WINDOW *win, STATUS * sp)
+{
+    switch (sp->ch) {
+    case ' ':			/* next test-iteration */
+	if (has_colors()) {
+	    if ((sp->c_msg = color_params(++(sp->c), &(sp->pair))) == 0) {
+		sp->c_msg = color_params(sp->c = 0, &(sp->pair));
+		if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
+		    sp->v_msg = video_params(sp->v = 0, &(sp->attr));
+		}
+	    }
+	} else {
+	    if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
+		sp->v_msg = video_params(sp->v = 0, &(sp->attr));
+	    }
+	}
+	sp->count = 0;
+	show_status(win, sp);
+	break;
+    case KEY_LEFT:
+    case 'h':
+	if (sp->x_val > 0)
+	    wmove(win, sp->y_val, --(sp->x_val));
+	break;
+    case KEY_DOWN:
+    case 'j':
+	if (sp->y_val < sp->y_max)
+	    wmove(win, ++(sp->y_val), sp->x_val);
+	break;
+    case KEY_UP:
+    case 'k':
+	if (sp->y_val > 0)
+	    wmove(win, --(sp->y_val), sp->x_val);
+	break;
+    case KEY_RIGHT:
+    case 'l':
+	if (sp->x_val < sp->x_max)
+	    wmove(win, sp->y_val, ++(sp->x_val));
+	break;
+    case 't':
+	touchline(win, sp->y_val, 1);
+	break;
+    case '=':
+	sp->count = 0;
+	show_status(win, sp);
+	break;
+    case '-':
+	sp->count = -(sp->count);
+	show_status(win, sp);
+	break;
+    case '?':
+	do_subwindow(win, sp, show_help);
+	break;
+    default:
+	if (isdigit(sp->ch)) {
+	    sp->count = (sp->count * 10) + (sp->ch - '0');
+	    show_status(win, sp);
+	} else {
+	    beep();
+	}
+	break;
+    }
+}
+
+static void
+test_wchgat(WINDOW *win)
+{
+    STATUS st;
+
+    init_status(win, &st);
+
+    do {
+	switch (st.ch) {
+	case '.':		/* change from current position */
+	    wchgat(win, st.count, st.attr, st.pair, (void *) 0);
+	    touch_if_needed(win, st.y_val);
+	    break;
+	case ',':		/* change from beginning of window */
+	    mvwchgat(win, 0, 0, st.count, st.attr, st.pair, (void *) 0);
+	    touch_if_needed(win, 0);
+	    wmove(win, st.y_val, st.x_val);
+	    break;
+	case 'w':
+	    do_subwindow(win, &st, test_wchgat);
+	    break;
+	case 'q':
+	    return;
+	default:
+	    update_status(win, &st);
+	    break;
+	}
+    } while ((st.ch = wgetch(win)) != ERR);
+}
+
+static void
+test_chgat(void)
+{
+    STATUS st;
+
+    init_status(stdscr, &st);
+
+    do {
+	switch (st.ch) {
+	case '.':		/* change from current position */
+	    chgat(st.count, st.attr, st.pair, (void *) 0);
+	    touch_if_needed(stdscr, st.y_val);
+	    break;
+	case ',':		/* change from beginning of window */
+	    mvchgat(0, 0, st.count, st.attr, st.pair, (void *) 0);
+	    touch_if_needed(stdscr, 0);
+	    move(st.y_val, st.x_val);
+	    break;
+	case 'w':
+	    do_subwindow(stdscr, &st, test_wchgat);
+	    break;
+	case 'q':
+	    return;
+	default:
+	    update_status(stdscr, &st);
+	    break;
+	}
+    } while ((st.ch = getch()) != ERR);
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    initscr();
+    cbreak();
+    noecho();
+
+    test_chgat();
+    endwin();
+
+    ExitProgram(EXIT_SUCCESS);
+}
+
+#else
+int
+main(void)
+{
+    printf("This program requires the curses chgat function\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/color_set.c b/test/color_set.c
new file mode 100644
index 0000000..2e981cb
--- /dev/null
+++ b/test/color_set.c
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * Copyright (c) 2003-2006,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: color_set.c,v 1.6 2008/02/10 00:18:01 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#if HAVE_COLOR_SET
+
+#define SHOW(n) ((n) == ERR ? "ERR" : "OK")
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    short f, b;
+    int i;
+
+    initscr();
+    cbreak();
+    noecho();
+
+    if (has_colors()) {
+	start_color();
+
+	pair_content(0, &f, &b);
+	printw("pair 0 contains (%d,%d)\n", f, b);
+	getch();
+
+	printw("Initializing pair 1 to red/black\n");
+	init_pair(1, COLOR_RED, COLOR_BLACK);
+	i = color_set(1, NULL);
+	printw("RED/BLACK (%s)\n", SHOW(i));
+	getch();
+
+	printw("Initializing pair 2 to white/blue\n");
+	init_pair(2, COLOR_WHITE, COLOR_BLUE);
+	i = color_set(2, NULL);
+	printw("WHITE/BLUE (%s)\n", SHOW(i));
+	getch();
+
+	printw("Resetting colors to pair 0\n");
+	i = color_set(0, NULL);
+	printw("Default Colors (%s)\n", SHOW(i));
+	getch();
+
+	printw("Resetting colors to pair 1\n");
+	i = color_set(1, NULL);
+	printw("RED/BLACK (%s)\n", SHOW(i));
+	getch();
+
+    } else {
+	printw("This demo requires a color terminal");
+	getch();
+    }
+    endwin();
+
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the curses color_set function\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/configure b/test/configure
new file mode 100755
index 0000000..564fc5c
--- /dev/null
+++ b/test/configure
@@ -0,0 +1,8140 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13.20030927 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+cat <<\EOF
+--enable and --with options recognized:
+  --disable-echo          display "compiling" commands
+  --enable-warnings       test: turn on gcc compiler warnings
+  --with-curses-dir=DIR   directory in which (n)curses is installed
+  --with-5lib             use SunOS sysv-libraries
+  --with-ncursesw         use wide ncurses-libraries (installed)
+  --with-ncurses          use ncurses-libraries (installed)
+  --with-pdcurses         compile/link with pdcurses X11 library
+  --with-x                use the X Window System
+  --with-Xaw3d            link with Xaw 3d library
+  --with-neXtaw           link with neXT Athena library
+  --with-XawPlus          link with Athena-Plus library
+EOF
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13.20030927"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=ncurses.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:540: checking for X" >&5
+
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+  withval="$with_x"
+  :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+    # Both variables are already set.
+    have_x=yes
+  else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+  cd conftestdir
+  # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+  cat > Imakefile <<'EOF'
+acfindx:
+	@echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+  if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl; do
+      if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+        test -f $ac_im_libdir/libX11.$ac_extension; then
+        ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case "$ac_im_incroot" in
+	/usr/include) ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+    esac
+    case "$ac_im_usrlibdir" in
+	/usr/lib | /lib) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+    esac
+  fi
+  cd ..
+  rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+  # Guess where to find include files, by looking for this one X11 .h file.
+  test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+  # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 603 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:608: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+  for ac_dir in               \
+    /usr/X11/include          \
+    /usr/X11R6/include        \
+    /usr/X11R5/include        \
+    /usr/X11R4/include        \
+                              \
+    /usr/include/X11          \
+    /usr/include/X11R6        \
+    /usr/include/X11R5        \
+    /usr/include/X11R4        \
+                              \
+    /usr/local/X11/include    \
+    /usr/local/X11R6/include  \
+    /usr/local/X11R5/include  \
+    /usr/local/X11R4/include  \
+                              \
+    /usr/local/include/X11    \
+    /usr/local/include/X11R6  \
+    /usr/local/include/X11R5  \
+    /usr/local/include/X11R4  \
+                              \
+    /usr/X386/include         \
+    /usr/x386/include         \
+    /usr/XFree86/include/X11  \
+                              \
+    /usr/include              \
+    /usr/local/include        \
+    /usr/unsupported/include  \
+    /usr/athena/include       \
+    /usr/local/x11r5/include  \
+    /usr/lpp/Xamples/include  \
+                              \
+    /usr/openwin/include      \
+    /usr/openwin/share/include \
+    ; \
+  do
+    if test -r "$ac_dir/$x_direct_test_include"; then
+      ac_x_includes=$ac_dir
+      break
+    fi
+  done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+  # Check for the libraries.
+
+  test -z "$x_direct_test_library" && x_direct_test_library=Xt
+  test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS="$LIBS"
+  LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 677 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+    /usr/X11/lib          \
+    /usr/X11R6/lib        \
+    /usr/X11R5/lib        \
+    /usr/X11R4/lib        \
+                          \
+    /usr/lib/X11          \
+    /usr/lib/X11R6        \
+    /usr/lib/X11R5        \
+    /usr/lib/X11R4        \
+                          \
+    /usr/local/X11/lib    \
+    /usr/local/X11R6/lib  \
+    /usr/local/X11R5/lib  \
+    /usr/local/X11R4/lib  \
+                          \
+    /usr/local/lib/X11    \
+    /usr/local/lib/X11R6  \
+    /usr/local/lib/X11R5  \
+    /usr/local/lib/X11R4  \
+                          \
+    /usr/X386/lib         \
+    /usr/x386/lib         \
+    /usr/XFree86/lib/X11  \
+                          \
+    /usr/lib              \
+    /usr/local/lib        \
+    /usr/unsupported/lib  \
+    /usr/athena/lib       \
+    /usr/local/x11r5/lib  \
+    /usr/lpp/Xamples/lib  \
+    /lib/usr/lib/X11	  \
+                          \
+    /usr/openwin/lib      \
+    /usr/openwin/share/lib \
+    ; \
+do
+  for ac_extension in a so sl; do
+    if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+  # Didn't find X anywhere.  Cache the known absence of X.
+  ac_cv_have_x="have_x=no"
+else
+  # Record where we found X for the cache.
+  ac_cv_have_x="have_x=yes \
+	        ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+  fi
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  echo "$ac_t""$have_x" 1>&6
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes \
+		ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+  echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+
+
+
+
+test -f config.guess || ( test -f ../config.guess && cp ../config.guess ./ )
+
+
+test -f config.sub || ( test -f ../config.sub && cp ../config.sub ./ )
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+if test -f $srcdir/config.guess || test -f $ac_aux_dir/config.guess ; then
+	
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:807: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+	system_name="$host_os"
+else
+	system_name="`(uname -s -r) 2>/dev/null`"
+	if test -z "$system_name" ; then
+		system_name="`(hostname) 2>/dev/null`"
+	fi
+fi
+test -n "$system_name" && cat >> confdefs.h <<EOF
+#define SYSTEM_NAME "$system_name"
+EOF
+
+if eval "test \"`echo '$''{'cf_cv_system_name'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cf_cv_system_name="$system_name"
+fi
+
+
+test -z "$system_name" && system_name="$cf_cv_system_name"
+test -n "$cf_cv_system_name" && echo "$ac_t""Configuring for $cf_cv_system_name" 1>&6
+
+if test ".$system_name" != ".$cf_cv_system_name" ; then
+	echo "$ac_t""Cached system name ($system_name) does not agree with actual ($cf_cv_system_name)" 1>&6
+	{ echo "configure: error: "Please remove config.cache and try again."" 1>&2; exit 1; }
+fi
+
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:855: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+	@echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:884: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:914: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:965: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:997: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1008 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1039: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1044: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1072: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1104: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 1119 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1125: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 1136 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1142: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 1153 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1159: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_prog in mawk gawk nawk awk
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1188: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AWK="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+  echo "$ac_t""$AWK" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AWK" && break
+done
+
+
+CC_G_OPT="-g"					
+CC_SHARED_OPTS=unknown			
+CPPFLAGS="$CPPFLAGS"			
+DFT_DEP_SUFFIX=""				
+DFT_OBJ_SUBDIR=`pwd|sed -e's:.*/::'`	
+DFT_UPR_MODEL="NORMAL"			
+LD="ld"							
+LDFLAGS_SHARED=""				
+LDFLAGS_STATIC=""				
+LD_MODEL=""						
+LD_SHARED_OPTS=""				
+LIBTOOL=""						
+LIB_CLEAN=""					
+LIB_COMPILE=""					
+LIB_LINK='${CC}'				
+LINK_TESTS=""					
+LINT=lint						
+LINT_OPTS=""					
+LOCAL_LDFLAGS=""				
+MATH_LIB="-lm"					
+PTHREAD="-lm"					
+TEST_ARGS=""					
+TEST_DEPS=""					
+TEST_LIBS=""					
+TINFO_ARGS='$(LIBS_CURSES)'		
+cf_cv_abi_version=""			
+cf_cv_rel_version=""			
+
+cf_cv_screen=curses
+cf_cv_libtype=
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:1250: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1255 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:1266: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_cygwin=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:1283: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1288 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1295: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_mingw32=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1314: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+  ac_cv_exeext=.exe
+else
+  rm -f conftest*
+  echo 'int main () { return 0; }' > conftest.$ac_ext
+  ac_cv_exeext=
+  if { (eval echo configure:1324: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+    for file in conftest.*; do
+      case $file in
+      *.c | *.o | *.obj) ;;
+      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+      esac
+    done
+  else
+    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+  fi
+  rm -f conftest*
+  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+echo "configure:1345: checking for object suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftest*
+echo 'int i = 1;' > conftest.$ac_ext
+if { (eval echo configure:1351: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_objext" 1>&6
+OBJEXT=$ac_cv_objext
+ac_objext=$ac_cv_objext
+
+
+
+echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
+echo "configure:1371: checking for ${CC-cc} option to accept ANSI C" >&5
+if eval "test \"`echo '$''{'cf_cv_ansi_cc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cf_cv_ansi_cc=no
+cf_save_CFLAGS="$CFLAGS"
+cf_save_CPPFLAGS="$CPPFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+# UnixWare 1.2		(cannot use -Xc, since ANSI/POSIX clashes)
+for cf_arg in "-DCC_HAS_PROTOS" \
+	"" \
+	-qlanglvl=ansi \
+	-std1 \
+	-Ae \
+	"-Aa -D_HPUX_SOURCE" \
+	-Xc
+do
+	
+cf_fix_cppflags=no
+cf_new_cflags=
+cf_new_cppflags=
+cf_new_extra_cppflags=
+
+for cf_add_cflags in $cf_arg
+do
+case $cf_fix_cppflags in
+no)
+	case $cf_add_cflags in #(vi
+	-undef|-nostdinc*|-I*|-D*|-U*|-E|-P|-C) #(vi
+		case $cf_add_cflags in
+		-D*)
+			cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^-D[^=]*='\''\"[^"]*//'`
+
+			test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+			&& test -z "${cf_tst_cflags}" \
+			&& cf_fix_cppflags=yes
+
+			if test $cf_fix_cppflags = yes ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			elif test "${cf_tst_cflags}" = "\"'" ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			fi
+			;;
+		esac
+		case "$CPPFLAGS" in
+		*$cf_add_cflags) #(vi
+			;;
+		*) #(vi
+			cf_new_cppflags="$cf_new_cppflags $cf_add_cflags"
+			;;
+		esac
+		;;
+	*)
+		cf_new_cflags="$cf_new_cflags $cf_add_cflags"
+		;;
+	esac
+	;;
+yes)
+	cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+
+	cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^[^"]*"'\''//'`
+
+	test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+	&& test -z "${cf_tst_cflags}" \
+	&& cf_fix_cppflags=no
+	;;
+esac
+done
+
+if test -n "$cf_new_cflags" ; then
+	
+	CFLAGS="$CFLAGS $cf_new_cflags"
+fi
+
+if test -n "$cf_new_cppflags" ; then
+	
+	CPPFLAGS="$cf_new_cppflags $CPPFLAGS"
+fi
+
+if test -n "$cf_new_extra_cppflags" ; then
+	
+	EXTRA_CPPFLAGS="$cf_new_extra_cppflags $EXTRA_CPPFLAGS"
+fi
+
+
+
+
+	cat > conftest.$ac_ext <<EOF
+#line 1467 "configure"
+#include "confdefs.h"
+
+#ifndef CC_HAS_PROTOS
+#if !defined(__STDC__) || (__STDC__ != 1)
+choke me
+#endif
+#endif
+
+int main() {
+
+	int test (int i, double x);
+	struct s1 {int (*f) (int a);};
+	struct s2 {int (*f) (double a);};
+; return 0; }
+EOF
+if { (eval echo configure:1483: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_ansi_cc="$cf_arg"; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CFLAGS="$cf_save_CFLAGS"
+CPPFLAGS="$cf_save_CPPFLAGS"
+
+fi
+
+echo "$ac_t""$cf_cv_ansi_cc" 1>&6
+
+if test "$cf_cv_ansi_cc" != "no"; then
+if test ".$cf_cv_ansi_cc" != ".-DCC_HAS_PROTOS"; then
+	
+cf_fix_cppflags=no
+cf_new_cflags=
+cf_new_cppflags=
+cf_new_extra_cppflags=
+
+for cf_add_cflags in $cf_cv_ansi_cc
+do
+case $cf_fix_cppflags in
+no)
+	case $cf_add_cflags in #(vi
+	-undef|-nostdinc*|-I*|-D*|-U*|-E|-P|-C) #(vi
+		case $cf_add_cflags in
+		-D*)
+			cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^-D[^=]*='\''\"[^"]*//'`
+
+			test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+			&& test -z "${cf_tst_cflags}" \
+			&& cf_fix_cppflags=yes
+
+			if test $cf_fix_cppflags = yes ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			elif test "${cf_tst_cflags}" = "\"'" ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			fi
+			;;
+		esac
+		case "$CPPFLAGS" in
+		*$cf_add_cflags) #(vi
+			;;
+		*) #(vi
+			cf_new_cppflags="$cf_new_cppflags $cf_add_cflags"
+			;;
+		esac
+		;;
+	*)
+		cf_new_cflags="$cf_new_cflags $cf_add_cflags"
+		;;
+	esac
+	;;
+yes)
+	cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+
+	cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^[^"]*"'\''//'`
+
+	test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+	&& test -z "${cf_tst_cflags}" \
+	&& cf_fix_cppflags=no
+	;;
+esac
+done
+
+if test -n "$cf_new_cflags" ; then
+	
+	CFLAGS="$CFLAGS $cf_new_cflags"
+fi
+
+if test -n "$cf_new_cppflags" ; then
+	
+	CPPFLAGS="$cf_new_cppflags $CPPFLAGS"
+fi
+
+if test -n "$cf_new_extra_cppflags" ; then
+	
+	EXTRA_CPPFLAGS="$cf_new_extra_cppflags $EXTRA_CPPFLAGS"
+fi
+
+
+
+
+else
+	cat >> confdefs.h <<\EOF
+#define CC_HAS_PROTOS 1
+EOF
+
+fi
+fi
+
+
+if test "$cf_cv_ansi_cc" = "no"; then
+	{ echo "configure: error: Your compiler does not appear to recognize prototypes.
+You have the following choices:
+	a. adjust your compiler options
+	b. get an up-to-date compiler
+	c. use a wrapper such as unproto" 1>&2; exit 1; }
+fi
+
+
+if test "$GCC" = yes
+then
+cat > conftest.i <<EOF
+#ifndef GCC_PRINTF
+#define GCC_PRINTF 0
+#endif
+#ifndef GCC_SCANF
+#define GCC_SCANF 0
+#endif
+#ifndef GCC_NORETURN
+#define GCC_NORETURN /* nothing */
+#endif
+#ifndef GCC_UNUSED
+#define GCC_UNUSED /* nothing */
+#endif
+EOF
+if test "$GCC" = yes
+then
+	echo "checking for $CC __attribute__ directives" 1>&6
+echo "configure:1610: checking for $CC __attribute__ directives" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1612 "${as_me-configure}"
+#include "confdefs.h"
+#include "conftest.h"
+#include "conftest.i"
+#if	GCC_PRINTF
+#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
+#else
+#define GCC_PRINTFLIKE(fmt,var) /*nothing*/
+#endif
+#if	GCC_SCANF
+#define GCC_SCANFLIKE(fmt,var)  __attribute__((format(scanf,fmt,var)))
+#else
+#define GCC_SCANFLIKE(fmt,var)  /*nothing*/
+#endif
+extern void wow(char *,...) GCC_SCANFLIKE(1,2);
+extern void oops(char *,...) GCC_PRINTFLIKE(1,2) GCC_NORETURN;
+extern void foo(void) GCC_NORETURN;
+int main(int argc GCC_UNUSED, char *argv[] GCC_UNUSED) { return 0; }
+EOF
+	for cf_attribute in scanf printf unused noreturn
+	do
+		
+cf_ATTRIBUTE=`echo "$cf_attribute" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
+
+		cf_directive="__attribute__(($cf_attribute))"
+		echo "checking for $CC $cf_directive" 1>&5
+		case $cf_attribute in
+		scanf|printf)
+		cat >conftest.h <<EOF
+#define GCC_$cf_ATTRIBUTE 1
+EOF
+			;;
+		*)
+		cat >conftest.h <<EOF
+#define GCC_$cf_ATTRIBUTE $cf_directive
+EOF
+			;;
+		esac
+		if { (eval echo configure:1650: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+			test -n "$verbose" && echo "$ac_t""... $cf_attribute" 1>&6
+			cat conftest.h >>confdefs.h
+		fi
+	done
+else
+	fgrep define conftest.i >>confdefs.h
+fi
+rm -rf conftest*
+fi
+
+
+echo $ac_n "checking if $CC -U and -D options work together""... $ac_c" 1>&6
+echo "configure:1663: checking if $CC -U and -D options work together" >&5
+if eval "test \"`echo '$''{'cf_cv_cc_u_d_options'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cf_save_CPPFLAGS="$CPPFLAGS"
+	CPPFLAGS="-UU_D_OPTIONS -DU_D_OPTIONS -DD_U_OPTIONS -UD_U_OPTIONS"
+	cat > conftest.$ac_ext <<EOF
+#line 1671 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef U_D_OPTIONS
+make an undefined-error
+#endif
+#ifdef  D_U_OPTIONS
+make a defined-error
+#endif
+	
+; return 0; }
+EOF
+if { (eval echo configure:1685: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  
+	cf_cv_cc_u_d_options=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+	cf_cv_cc_u_d_options=no
+fi
+rm -f conftest*
+	CPPFLAGS="$cf_save_CPPFLAGS"
+
+fi
+
+echo "$ac_t""$cf_cv_cc_u_d_options" 1>&6
+
+
+
+
+
+cf_XOPEN_SOURCE=500
+cf_POSIX_C_SOURCE=199506L
+
+case $host_os in #(vi
+aix[45]*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE"
+	;;
+freebsd*) #(vi
+	# 5.x headers associate
+	#	_XOPEN_SOURCE=600 with _POSIX_C_SOURCE=200112L
+	#	_XOPEN_SOURCE=500 with _POSIX_C_SOURCE=199506L
+	cf_POSIX_C_SOURCE=200112L
+	cf_XOPEN_SOURCE=600
+	CPPFLAGS="$CPPFLAGS -D_BSD_TYPES -D__BSD_VISIBLE -D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE -D_XOPEN_SOURCE=$cf_XOPEN_SOURCE"
+	;;
+hpux*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE"
+	;;
+irix[56].*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_SGI_SOURCE"
+	;;
+linux*|gnu*|k*bsd*-gnu) #(vi
+	
+echo $ac_n "checking if we must define _GNU_SOURCE""... $ac_c" 1>&6
+echo "configure:1731: checking if we must define _GNU_SOURCE" >&5
+if eval "test \"`echo '$''{'cf_cv_gnu_source'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cat > conftest.$ac_ext <<EOF
+#line 1737 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+
+#ifndef _XOPEN_SOURCE
+make an error
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1747: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_gnu_source=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_save="$CPPFLAGS"
+	 CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
+	 cat > conftest.$ac_ext <<EOF
+#line 1757 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+
+#ifdef _XOPEN_SOURCE
+make an error
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1767: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_gnu_source=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_gnu_source=yes
+fi
+rm -f conftest*
+	CPPFLAGS="$cf_save"
+	
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$cf_cv_gnu_source" 1>&6
+test "$cf_cv_gnu_source" = yes && CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
+
+	;;
+mirbsd*) #(vi
+	# setting _XOPEN_SOURCE or _POSIX_SOURCE breaks <arpa/inet.h>
+	;;
+netbsd*) #(vi
+	# setting _XOPEN_SOURCE breaks IPv6 for lynx on NetBSD 1.6, breaks xterm, is not needed for ncursesw
+	;;
+openbsd*) #(vi
+	# setting _XOPEN_SOURCE breaks xterm on OpenBSD 2.8, is not needed for ncursesw
+	;;
+osf[45]*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_OSF_SOURCE"
+	;;
+nto-qnx*) #(vi
+	CPPFLAGS="$CPPFLAGS -D_QNX_SOURCE"
+	;;
+sco*) #(vi
+	# setting _XOPEN_SOURCE breaks Lynx on SCO Unix / OpenServer
+	;;
+solaris*) #(vi
+	CPPFLAGS="$CPPFLAGS -D__EXTENSIONS__"
+	;;
+*)
+	echo $ac_n "checking if we should define _XOPEN_SOURCE""... $ac_c" 1>&6
+echo "configure:1811: checking if we should define _XOPEN_SOURCE" >&5
+if eval "test \"`echo '$''{'cf_cv_xopen_source'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cat > conftest.$ac_ext <<EOF
+#line 1817 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+
+#ifndef _XOPEN_SOURCE
+make an error
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1827: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_xopen_source=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_save="$CPPFLAGS"
+	 CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=$cf_XOPEN_SOURCE"
+	 cat > conftest.$ac_ext <<EOF
+#line 1837 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+
+#ifdef _XOPEN_SOURCE
+make an error
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1847: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_xopen_source=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_xopen_source=$cf_XOPEN_SOURCE
+fi
+rm -f conftest*
+	CPPFLAGS="$cf_save"
+	
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$cf_cv_xopen_source" 1>&6
+	if test "$cf_cv_xopen_source" != no ; then
+		
+# remove _XOPEN_SOURCE symbol from $CFLAGS
+CFLAGS=`echo "$CFLAGS" | \
+	sed	-e 's/-[UD]_XOPEN_SOURCE\(=[^ 	]*\)\?[ 	]/ /g' \
+		-e 's/-[UD]_XOPEN_SOURCE\(=[^ 	]*\)\?$//g'`
+
+		
+# remove _XOPEN_SOURCE symbol from $CPPFLAGS
+CPPFLAGS=`echo "$CPPFLAGS" | \
+	sed	-e 's/-[UD]_XOPEN_SOURCE\(=[^ 	]*\)\?[ 	]/ /g' \
+		-e 's/-[UD]_XOPEN_SOURCE\(=[^ 	]*\)\?$//g'`
+
+		test "$cf_cv_cc_u_d_options" = yes && \
+			CPPFLAGS="$CPPFLAGS -U_XOPEN_SOURCE"
+		CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=$cf_cv_xopen_source"
+	fi
+	
+cf_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE
+
+cf_save_CFLAGS="$CFLAGS"
+cf_save_CPPFLAGS="$CPPFLAGS"
+
+
+# remove _POSIX_C_SOURCE symbol from $cf_save_CFLAGS
+cf_trim_CFLAGS=`echo "$cf_save_CFLAGS" | \
+	sed	-e 's/-[UD]_POSIX_C_SOURCE\(=[^ 	]*\)\?[ 	]/ /g' \
+		-e 's/-[UD]_POSIX_C_SOURCE\(=[^ 	]*\)\?$//g'`
+
+
+# remove _POSIX_C_SOURCE symbol from $cf_save_CPPFLAGS
+cf_trim_CPPFLAGS=`echo "$cf_save_CPPFLAGS" | \
+	sed	-e 's/-[UD]_POSIX_C_SOURCE\(=[^ 	]*\)\?[ 	]/ /g' \
+		-e 's/-[UD]_POSIX_C_SOURCE\(=[^ 	]*\)\?$//g'`
+
+
+echo $ac_n "checking if we should define _POSIX_C_SOURCE""... $ac_c" 1>&6
+echo "configure:1902: checking if we should define _POSIX_C_SOURCE" >&5
+if eval "test \"`echo '$''{'cf_cv_posix_c_source'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	
+echo "${as_me-configure}:1908: testing if the symbol is already defined go no further ..." 1>&5
+
+	cat > conftest.$ac_ext <<EOF
+#line 1911 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+
+#ifndef _POSIX_C_SOURCE
+make an error
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1921: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_posix_c_source=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_want_posix_source=no
+	 case .$cf_POSIX_C_SOURCE in #(vi
+	 .[12]??*) #(vi
+		cf_cv_posix_c_source="-D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE"
+		;;
+	 .2) #(vi
+		cf_cv_posix_c_source="-D_POSIX_C_SOURCE=$cf_POSIX_C_SOURCE"
+		cf_want_posix_source=yes
+		;;
+	 .*)
+		cf_want_posix_source=yes
+		;;
+	 esac
+	 if test "$cf_want_posix_source" = yes ; then
+		cat > conftest.$ac_ext <<EOF
+#line 1943 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+
+#ifdef _POSIX_SOURCE
+make an error
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1953: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_posix_c_source="$cf_cv_posix_c_source -D_POSIX_SOURCE"
+fi
+rm -f conftest*
+	 fi
+	 
+echo "${as_me-configure}:1964: testing ifdef from value $cf_POSIX_C_SOURCE ..." 1>&5
+
+	 CFLAGS="$cf_trim_CFLAGS"
+	 CPPFLAGS="$cf_trim_CPPFLAGS $cf_cv_posix_c_source"
+	 
+echo "${as_me-configure}:1969: testing if the second compile does not leave our definition intact error ..." 1>&5
+
+	 cat > conftest.$ac_ext <<EOF
+#line 1972 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+
+#ifndef _POSIX_C_SOURCE
+make an error
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1982: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_posix_c_source=no
+fi
+rm -f conftest*
+	 CFLAGS="$cf_save_CFLAGS"
+	 CPPFLAGS="$cf_save_CPPFLAGS"
+	
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$cf_cv_posix_c_source" 1>&6
+
+if test "$cf_cv_posix_c_source" != no ; then
+	CFLAGS="$cf_trim_CFLAGS"
+	CPPFLAGS="$cf_trim_CPPFLAGS"
+	if test "$cf_cv_cc_u_d_options" = yes ; then
+		cf_temp_posix_c_source=`echo "$cf_cv_posix_c_source" | \
+				sed -e 's/-D/-U/g' -e 's/=[^ 	]*//g'`
+		CPPFLAGS="$CPPFLAGS $cf_temp_posix_c_source"
+	fi
+	CPPFLAGS="$CPPFLAGS $cf_cv_posix_c_source"
+fi
+
+
+	;;
+esac
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2017: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2022 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2071: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+
+echo $ac_n "checking for signal global datatype""... $ac_c" 1>&6
+echo "configure:2093: checking for signal global datatype" >&5
+if eval "test \"`echo '$''{'cf_cv_sig_atomic_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	for cf_type in \
+		"volatile sig_atomic_t" \
+		"sig_atomic_t" \
+		"int"
+	do
+	cat > conftest.$ac_ext <<EOF
+#line 2104 "configure"
+#include "confdefs.h"
+
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+
+extern $cf_type x;
+$cf_type x;
+static void handler(int sig)
+{
+	x = 5;
+}
+int main() {
+signal(SIGINT, handler);
+		 x = 1
+; return 0; }
+EOF
+if { (eval echo configure:2122: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_sig_atomic_t=$cf_type
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_sig_atomic_t=no
+fi
+rm -f conftest*
+		test "$cf_cv_sig_atomic_t" != no && break
+	done
+	
+fi
+
+echo "$ac_t""$cf_cv_sig_atomic_t" 1>&6
+test "$cf_cv_sig_atomic_t" != no && cat >> confdefs.h <<EOF
+#define SIG_ATOMIC_T $cf_cv_sig_atomic_t
+EOF
+
+
+
+
+echo $ac_n "checking if you want to see long compiling messages""... $ac_c" 1>&6
+echo "configure:2146: checking if you want to see long compiling messages" >&5
+
+# Check whether --enable-echo or --disable-echo was given.
+if test "${enable_echo+set}" = set; then
+  enableval="$enable_echo"
+  test "$enableval" != no && enableval=yes
+  if test "$enableval" != "yes" ; then
+    
+    ECHO_LT='--silent'
+    ECHO_LD='@echo linking $@;'
+    RULE_CC='	@echo compiling $<'
+    SHOW_CC='	@echo compiling $@'
+    ECHO_CC='@'
+ 
+  else
+    
+    ECHO_LT=''
+    ECHO_LD=''
+    RULE_CC='# compiling'
+    SHOW_CC='# compiling'
+    ECHO_CC=''
+
+  fi
+else
+  enableval=yes 
+  
+    ECHO_LT=''
+    ECHO_LD=''
+    RULE_CC='# compiling'
+    SHOW_CC='# compiling'
+    ECHO_CC=''
+
+  
+fi
+
+echo "$ac_t""$enableval" 1>&6
+
+
+
+
+
+
+
+
+GCC_VERSION=none
+if test "$GCC" = yes ; then
+	echo $ac_n "checking version of $CC""... $ac_c" 1>&6
+echo "configure:2193: checking version of $CC" >&5
+	GCC_VERSION="`${CC} --version| sed -e '2,$d' -e 's/^.*(GCC) //' -e 's/^[^0-9.]*//' -e 's/[^0-9.].*//'`"
+	test -z "$GCC_VERSION" && GCC_VERSION=unknown
+	echo "$ac_t""$GCC_VERSION" 1>&6
+fi
+
+
+if ( test "$GCC" = yes || test "$GXX" = yes )
+then
+echo $ac_n "checking if you want to turn on gcc warnings""... $ac_c" 1>&6
+echo "configure:2203: checking if you want to turn on gcc warnings" >&5
+
+# Check whether --enable-warnings or --disable-warnings was given.
+if test "${enable_warnings+set}" = set; then
+  enableval="$enable_warnings"
+  test "$enableval" != yes && enableval=no
+  if test "$enableval" != "no" ; then
+    with_warnings=yes 
+  else
+    with_warnings=no
+  fi
+else
+  enableval=no 
+  with_warnings=no
+  
+fi
+
+echo "$ac_t""$with_warnings" 1>&6
+if test "$with_warnings" = "yes"
+then
+	
+
+
+INTEL_COMPILER=no
+
+if test "$GCC" = yes ; then
+	case $host_os in
+	linux*|gnu*)
+		echo $ac_n "checking if this is really Intel C compiler""... $ac_c" 1>&6
+echo "configure:2232: checking if this is really Intel C compiler" >&5
+		cf_save_CFLAGS="$CFLAGS"
+		CFLAGS="$CFLAGS -no-gcc"
+		cat > conftest.$ac_ext <<EOF
+#line 2236 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifdef __INTEL_COMPILER
+#else
+make an error
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2248: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  INTEL_COMPILER=yes
+cf_save_CFLAGS="$cf_save_CFLAGS -we147 -no-gcc"
+
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+		CFLAGS="$cf_save_CFLAGS"
+		echo "$ac_t""$INTEL_COMPILER" 1>&6
+		;;
+	esac
+fi
+
+
+cat > conftest.$ac_ext <<EOF
+#line 2266 "${as_me-configure}"
+int main(int argc, char *argv[]) { return (argv[argc-1] == 0) ; }
+EOF
+
+if test "$INTEL_COMPILER" = yes
+then
+# The "-wdXXX" options suppress warnings:
+# remark #1419: external declaration in primary source file
+# remark #1682: implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem)
+# remark #1683: explicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem)
+# remark #1684: conversion from pointer to same-sized integral type (potential portability problem)
+# remark #193: zero used for undefined preprocessing identifier
+# remark #593: variable "curs_sb_left_arrow" was set but never used
+# remark #810: conversion from "int" to "Dimension={unsigned short}" may lose significant bits
+# remark #869: parameter "tw" was never referenced
+# remark #981: operands are evaluated in unspecified order
+# warning #269: invalid format string conversion
+
+	echo "checking for $CC warning options" 1>&6
+echo "configure:2285: checking for $CC warning options" >&5
+	cf_save_CFLAGS="$CFLAGS"
+	EXTRA_CFLAGS="-Wall"
+	for cf_opt in \
+		wd1419 \
+		wd1682 \
+		wd1683 \
+		wd1684 \
+		wd193 \
+		wd279 \
+		wd593 \
+		wd810 \
+		wd869 \
+		wd981
+	do
+		CFLAGS="$cf_save_CFLAGS $EXTRA_CFLAGS -$cf_opt"
+		if { (eval echo configure:2301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+			test -n "$verbose" && echo "$ac_t""... -$cf_opt" 1>&6
+			EXTRA_CFLAGS="$EXTRA_CFLAGS -$cf_opt"
+		fi
+	done
+	CFLAGS="$cf_save_CFLAGS"
+
+elif test "$GCC" = yes
+then
+	echo "checking for $CC warning options" 1>&6
+echo "configure:2311: checking for $CC warning options" >&5
+	cf_save_CFLAGS="$CFLAGS"
+	EXTRA_CFLAGS="-W -Wall"
+	cf_warn_CONST=""
+	test "$with_ext_const" = yes && cf_warn_CONST="Wwrite-strings"
+	for cf_opt in \
+		Wbad-function-cast \
+		Wcast-align \
+		Wcast-qual \
+		Winline \
+		Wmissing-declarations \
+		Wmissing-prototypes \
+		Wnested-externs \
+		Wpointer-arith \
+		Wshadow \
+		Wstrict-prototypes \
+		Wundef $cf_warn_CONST 
+	do
+		CFLAGS="$cf_save_CFLAGS $EXTRA_CFLAGS -$cf_opt"
+		if { (eval echo configure:2330: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+			test -n "$verbose" && echo "$ac_t""... -$cf_opt" 1>&6
+			case $cf_opt in #(vi
+			Wcast-qual) #(vi
+				CPPFLAGS="$CPPFLAGS -DXTSTRINGDEFINES"
+				;;
+			Winline) #(vi
+				case $GCC_VERSION in
+				3.3*)
+					test -n "$verbose" && echo "	feature is broken in gcc $GCC_VERSION" 1>&6
+
+echo "${as_me-configure}:2341: testing feature is broken in gcc $GCC_VERSION ..." 1>&5
+
+
+					continue;;
+				esac
+				;;
+			esac
+			EXTRA_CFLAGS="$EXTRA_CFLAGS -$cf_opt"
+		fi
+	done
+	CFLAGS="$cf_save_CFLAGS"
+fi
+rm -f conftest*
+
+
+
+fi
+fi
+
+
+
+
+# Check whether --with-curses-dir or --without-curses-dir was given.
+if test "${with_curses_dir+set}" = set; then
+  withval="$with_curses_dir"
+  
+if test "x$prefix" != xNONE; then
+  cf_path_syntax="$prefix"
+else
+  cf_path_syntax="$ac_default_prefix"
+fi
+
+case ".$withval" in #(vi
+.\$\(*\)*|.\'*\'*) #(vi
+  ;;
+..|./*|.\\*) #(vi
+  ;;
+.[a-zA-Z]:[\\/]*) #(vi OS/2 EMX
+  ;;
+.\${*prefix}*) #(vi
+  eval withval="$withval"
+  case ".$withval" in #(vi
+  .NONE/*)
+    withval=`echo $withval | sed -e s%NONE%$cf_path_syntax%`
+    ;;
+  esac
+  ;; #(vi
+.no|.NONE/*)
+  withval=`echo $withval | sed -e s%NONE%$cf_path_syntax%`
+  ;;
+*)
+  { echo "configure: error: expected a pathname, not \"$withval\"" 1>&2; exit 1; }
+  ;;
+esac
+
+	 cf_cv_curses_dir=$withval
+else
+  cf_cv_curses_dir=no
+fi
+
+
+
+
+# Check whether --with-5lib or --without-5lib was given.
+if test "${with_5lib+set}" = set; then
+  withval="$with_5lib"
+  LIBS="-L/usr/5lib $LIBS"
+	 CPPFLAGS="$CPPFLAGS -I/usr/5include"
+fi
+
+
+
+# Check whether --with-ncursesw or --without-ncursesw was given.
+if test "${with_ncursesw+set}" = set; then
+  withval="$with_ncursesw"
+  cf_cv_screen=ncursesw
+else
+  
+
+
+# Check whether --with-ncurses or --without-ncurses was given.
+if test "${with_ncurses+set}" = set; then
+  withval="$with_ncurses"
+  cf_cv_screen=ncurses
+else
+  
+
+
+# Check whether --with-pdcurses or --without-pdcurses was given.
+if test "${with_pdcurses+set}" = set; then
+  withval="$with_pdcurses"
+  cf_cv_screen=pdcurses
+fi
+
+fi
+
+fi
+
+
+case $cf_cv_screen in
+curses)
+	
+
+echo $ac_n "checking for extra include directories""... $ac_c" 1>&6
+echo "configure:2445: checking for extra include directories" >&5
+if eval "test \"`echo '$''{'cf_cv_curses_incdir'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cf_cv_curses_incdir=no
+case $host_os in #(vi
+hpux10.*) #(vi
+	test -d /usr/include/curses_colr && \
+	cf_cv_curses_incdir="-I/usr/include/curses_colr"
+	;;
+sunos3*|sunos4*)
+	test -d /usr/5lib && \
+	test -d /usr/5include && \
+	cf_cv_curses_incdir="-I/usr/5include"
+	;;
+esac
+
+fi
+
+echo "$ac_t""$cf_cv_curses_incdir" 1>&6
+test "$cf_cv_curses_incdir" != no && CPPFLAGS="$cf_cv_curses_incdir $CPPFLAGS"
+
+
+echo $ac_n "checking if we have identified curses headers""... $ac_c" 1>&6
+echo "configure:2470: checking if we have identified curses headers" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_header'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cf_cv_ncurses_header=none
+for cf_header in \
+	curses.h \
+	ncurses.h \
+	ncurses/curses.h \
+	ncurses/ncurses.h
+do
+cat > conftest.$ac_ext <<EOF
+#line 2483 "configure"
+#include "confdefs.h"
+#include <${cf_header}>
+int main() {
+initscr(); tgoto("?", 0,0)
+; return 0; }
+EOF
+if { (eval echo configure:2490: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_ncurses_header=$cf_header; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$cf_cv_ncurses_header" 1>&6
+
+if test "$cf_cv_ncurses_header" = none ; then
+	{ echo "configure: error: No curses header-files found" 1>&2; exit 1; }
+fi
+
+# cheat, to get the right #define's for HAVE_NCURSES_H, etc.
+for ac_hdr in $cf_cv_ncurses_header
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2513: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2518 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2523: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+echo $ac_n "checking for terminfo header""... $ac_c" 1>&6
+echo "configure:2552: checking for terminfo header" >&5
+if eval "test \"`echo '$''{'cf_cv_term_header'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+case ${cf_cv_ncurses_header} in #(vi
+*/ncurses.h|*/ncursesw.h) #(vi
+	cf_term_header=`echo "$cf_cv_ncurses_header" | sed -e 's%ncurses[^.]*\.h$%term.h%'`
+	;;
+*)
+	cf_term_header=term.h
+	;;
+esac
+
+for cf_test in $cf_term_header "ncurses/term.h" "ncursesw/term.h"
+do
+cat > conftest.$ac_ext <<EOF
+#line 2569 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <$cf_test>
+
+int main() {
+int x = auto_left_margin
+; return 0; }
+EOF
+if { (eval echo configure:2579: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  
+	cf_cv_term_header="$cf_test"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+	cf_cv_term_header=unknown
+	
+fi
+rm -f conftest*
+	test "$cf_cv_term_header" != unknown && break
+done
+
+fi
+
+echo "$ac_t""$cf_cv_term_header" 1>&6
+
+# Set definitions to allow ifdef'ing to accommodate subdirectories
+
+case $cf_cv_term_header in # (vi
+*term.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_TERM_H 1
+EOF
+
+	;;
+esac
+
+case $cf_cv_term_header in # (vi
+ncurses/term.h) #(vi
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSES_TERM_H 1
+EOF
+
+	;;
+ncursesw/term.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSESW_TERM_H 1
+EOF
+
+	;;
+esac
+
+
+	
+echo $ac_n "checking for ncurses version""... $ac_c" 1>&6
+echo "configure:2628: checking for ncurses version" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_version'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cf_cv_ncurses_version=no
+	cf_tempfile=out$$
+	rm -f $cf_tempfile
+	if test "$cross_compiling" = yes; then
+  
+
+	# This will not work if the preprocessor splits the line after the
+	# Autoconf token.  The 'unproto' program does that.
+	cat > conftest.$ac_ext <<EOF
+#include <${cf_cv_ncurses_header-curses.h}>
+#undef Autoconf
+#ifdef NCURSES_VERSION
+Autoconf NCURSES_VERSION
+#else
+#ifdef __NCURSES_H
+Autoconf "old"
+#endif
+;
+#endif
+EOF
+	cf_try="$ac_cpp conftest.$ac_ext 2>&5 | grep '^Autoconf ' >conftest.out"
+	{ (eval echo configure:2654: \"$cf_try\") 1>&5; (eval $cf_try) 2>&5; }
+	if test -f conftest.out ; then
+		cf_out=`cat conftest.out | sed -e 's%^Autoconf %%' -e 's%^[^"]*"%%' -e 's%".*%%'`
+		test -n "$cf_out" && cf_cv_ncurses_version="$cf_out"
+		rm -f conftest.out
+	fi
+
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2663 "configure"
+#include "confdefs.h"
+
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <stdio.h>
+int main()
+{
+	FILE *fp = fopen("$cf_tempfile", "w");
+#ifdef NCURSES_VERSION
+# ifdef NCURSES_VERSION_PATCH
+	fprintf(fp, "%s.%d\n", NCURSES_VERSION, NCURSES_VERSION_PATCH);
+# else
+	fprintf(fp, "%s\n", NCURSES_VERSION);
+# endif
+#else
+# ifdef __NCURSES_H
+	fprintf(fp, "old\n");
+# else
+	make an error
+# endif
+#endif
+	${cf_cv_main_return-return}(0);
+}
+EOF
+if { (eval echo configure:2687: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  
+	cf_cv_ncurses_version=`cat $cf_tempfile`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -fr conftest*
+fi
+
+	rm -f $cf_tempfile
+
+fi
+
+echo "$ac_t""$cf_cv_ncurses_version" 1>&6
+test "$cf_cv_ncurses_version" = no || cat >> confdefs.h <<\EOF
+#define NCURSES 1
+EOF
+
+
+	
+
+echo $ac_n "checking if we have identified curses libraries""... $ac_c" 1>&6
+echo "configure:2711: checking if we have identified curses libraries" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2713 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr(); tgoto("?", 0,0)
+; return 0; }
+EOF
+if { (eval echo configure:2720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_result=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_result=no
+fi
+rm -f conftest*
+echo "$ac_t""$cf_result" 1>&6
+
+if test "$cf_result" = no ; then
+case $host_os in #(vi
+freebsd*) #(vi
+    echo $ac_n "checking for tgoto in -lmytinfo""... $ac_c" 1>&6
+echo "configure:2736: checking for tgoto in -lmytinfo" >&5
+ac_lib_var=`echo mytinfo'_'tgoto | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lmytinfo  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2744 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char tgoto();
+
+int main() {
+tgoto()
+; return 0; }
+EOF
+if { (eval echo configure:2755: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="-lmytinfo $LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    ;;
+hpux10.*) #(vi
+    echo $ac_n "checking for initscr in -lcur_colr""... $ac_c" 1>&6
+echo "configure:2778: checking for initscr in -lcur_colr" >&5
+ac_lib_var=`echo cur_colr'_'initscr | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lcur_colr  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2786 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char initscr();
+
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:2797: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  
+        LIBS="-lcur_colr $LIBS"
+        ac_cv_func_initscr=yes
+        
+else
+  echo "$ac_t""no" 1>&6
+
+    echo $ac_n "checking for initscr in -lHcurses""... $ac_c" 1>&6
+echo "configure:2820: checking for initscr in -lHcurses" >&5
+ac_lib_var=`echo Hcurses'_'initscr | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lHcurses  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2828 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char initscr();
+
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:2839: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  
+        # HP's header uses __HP_CURSES, but user claims _HP_CURSES.
+        LIBS="-lHcurses $LIBS"
+        CPPFLAGS="-D__HP_CURSES -D_HP_CURSES $CPPFLAGS"
+        ac_cv_func_initscr=yes
+        
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+    ;;
+linux*) # Suse Linux does not follow /usr/lib convention
+    
+if test -n "/lib" ; then
+  for cf_add_libdir in /lib
+  do
+    if test $cf_add_libdir = /usr/lib ; then
+      :
+    elif test -d $cf_add_libdir
+    then
+      cf_have_libdir=no
+      if test -n "$LDFLAGS$LIBS" ; then
+        # a loop is needed to ensure we can add subdirs of existing dirs
+        for cf_test_libdir in $LDFLAGS $LIBS ; do
+          if test ".$cf_test_libdir" = ".-L$cf_add_libdir" ; then
+            cf_have_libdir=yes; break
+          fi
+        done
+      fi
+      if test "$cf_have_libdir" = no ; then
+        test -n "$verbose" && echo "	adding $cf_add_libdir to library-path" 1>&6
+
+echo "${as_me-configure}:2888: testing adding $cf_add_libdir to library-path ..." 1>&5
+
+
+        LDFLAGS="-L$cf_add_libdir $LDFLAGS"
+      fi
+    fi
+  done
+fi
+
+    ;;
+sunos3*|sunos4*)
+    if test -d /usr/5lib ; then
+      
+if test -n "/usr/5lib" ; then
+  for cf_add_libdir in /usr/5lib
+  do
+    if test $cf_add_libdir = /usr/lib ; then
+      :
+    elif test -d $cf_add_libdir
+    then
+      cf_have_libdir=no
+      if test -n "$LDFLAGS$LIBS" ; then
+        # a loop is needed to ensure we can add subdirs of existing dirs
+        for cf_test_libdir in $LDFLAGS $LIBS ; do
+          if test ".$cf_test_libdir" = ".-L$cf_add_libdir" ; then
+            cf_have_libdir=yes; break
+          fi
+        done
+      fi
+      if test "$cf_have_libdir" = no ; then
+        test -n "$verbose" && echo "	adding $cf_add_libdir to library-path" 1>&6
+
+echo "${as_me-configure}:2920: testing adding $cf_add_libdir to library-path ..." 1>&5
+
+
+        LDFLAGS="-L$cf_add_libdir $LDFLAGS"
+      fi
+    fi
+  done
+fi
+
+      LIBS="$LIBS -lcurses -ltermcap"
+    fi
+    ac_cv_func_initscr=yes
+    ;;
+esac
+
+if test ".$ac_cv_func_initscr" != .yes ; then
+    cf_save_LIBS="$LIBS"
+    cf_term_lib=""
+    cf_curs_lib=""
+
+    if test ".${cf_cv_ncurses_version-no}" != .no
+    then
+        cf_check_list="ncurses curses cursesX"
+    else
+        cf_check_list="cursesX curses ncurses"
+    fi
+
+    # Check for library containing tgoto.  Do this before curses library
+    # because it may be needed to link the test-case for initscr.
+    echo $ac_n "checking for tgoto""... $ac_c" 1>&6
+echo "configure:2950: checking for tgoto" >&5
+if eval "test \"`echo '$''{'ac_cv_func_tgoto'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2955 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char tgoto(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char tgoto();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_tgoto) || defined (__stub___tgoto)
+choke me
+#else
+tgoto();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_tgoto=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_tgoto=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'tgoto`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cf_term_lib=predefined
+else
+  echo "$ac_t""no" 1>&6
+
+        for cf_term_lib in $cf_check_list termcap termlib unknown
+        do
+            echo $ac_n "checking for tgoto in -l$cf_term_lib""... $ac_c" 1>&6
+echo "configure:2999: checking for tgoto in -l$cf_term_lib" >&5
+ac_lib_var=`echo $cf_term_lib'_'tgoto | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-l$cf_term_lib  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3007 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char tgoto();
+
+int main() {
+tgoto()
+; return 0; }
+EOF
+if { (eval echo configure:3018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  break
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+        done
+    
+fi
+
+
+    # Check for library containing initscr
+    test "$cf_term_lib" != predefined && test "$cf_term_lib" != unknown && LIBS="-l$cf_term_lib $cf_save_LIBS"
+    for cf_curs_lib in $cf_check_list xcurses jcurses unknown
+    do
+        echo $ac_n "checking for initscr in -l$cf_curs_lib""... $ac_c" 1>&6
+echo "configure:3048: checking for initscr in -l$cf_curs_lib" >&5
+ac_lib_var=`echo $cf_curs_lib'_'initscr | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-l$cf_curs_lib  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3056 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char initscr();
+
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:3067: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  break
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    done
+    test $cf_curs_lib = unknown && { echo "configure: error: no curses library found" 1>&2; exit 1; }
+
+    LIBS="-l$cf_curs_lib $cf_save_LIBS"
+    if test "$cf_term_lib" = unknown ; then
+        echo $ac_n "checking if we can link with $cf_curs_lib library""... $ac_c" 1>&6
+echo "configure:3093: checking if we can link with $cf_curs_lib library" >&5
+        cat > conftest.$ac_ext <<EOF
+#line 3095 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:3102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_result=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_result=no
+fi
+rm -f conftest*
+        echo "$ac_t""$cf_result" 1>&6
+        test $cf_result = no && { echo "configure: error: Cannot link curses library" 1>&2; exit 1; }
+    elif test "$cf_curs_lib" = "$cf_term_lib" ; then
+        :
+    elif test "$cf_term_lib" != predefined ; then
+        echo $ac_n "checking if we need both $cf_curs_lib and $cf_term_lib libraries""... $ac_c" 1>&6
+echo "configure:3118: checking if we need both $cf_curs_lib and $cf_term_lib libraries" >&5
+        cat > conftest.$ac_ext <<EOF
+#line 3120 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr(); tgoto((char *)0, 0, 0);
+; return 0; }
+EOF
+if { (eval echo configure:3127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_result=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+            LIBS="-l$cf_curs_lib -l$cf_term_lib $cf_save_LIBS"
+            cat > conftest.$ac_ext <<EOF
+#line 3137 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:3144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_result=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_result=error
+fi
+rm -f conftest*
+            
+fi
+rm -f conftest*
+        echo "$ac_t""$cf_result" 1>&6
+    fi
+fi
+fi
+
+
+	;;
+ncurses)
+	
+
+cf_ncuhdr_root=ncurses
+
+test -n "$cf_cv_curses_dir" && \
+test "$cf_cv_curses_dir" != "no" && { \
+  
+if test -n "$cf_cv_curses_dir/include $cf_cv_curses_dir/include/$cf_ncuhdr_root" ; then
+  for cf_add_incdir in $cf_cv_curses_dir/include $cf_cv_curses_dir/include/$cf_ncuhdr_root
+  do
+	while test $cf_add_incdir != /usr/include
+	do
+	  if test -d $cf_add_incdir
+	  then
+		cf_have_incdir=no
+		if test -n "$CFLAGS$CPPFLAGS" ; then
+		  # a loop is needed to ensure we can add subdirs of existing dirs
+		  for cf_test_incdir in $CFLAGS $CPPFLAGS ; do
+			if test ".$cf_test_incdir" = ".-I$cf_add_incdir" ; then
+			  cf_have_incdir=yes; break
+			fi
+		  done
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+          if test "$cf_add_incdir" = /usr/local/include ; then
+			if test "$GCC" = yes
+			then
+			  cf_save_CPPFLAGS=$CPPFLAGS
+			  CPPFLAGS="$CPPFLAGS -I$cf_add_incdir"
+			  cat > conftest.$ac_ext <<EOF
+#line 3196 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+printf("Hello")
+; return 0; }
+EOF
+if { (eval echo configure:3203: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_have_incdir=yes
+fi
+rm -f conftest*
+			  CPPFLAGS=$cf_save_CPPFLAGS
+			fi
+		  fi
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+		  test -n "$verbose" && echo "	adding $cf_add_incdir to include-path" 1>&6
+
+echo "${as_me-configure}:3220: testing adding $cf_add_incdir to include-path ..." 1>&5
+
+
+		  CPPFLAGS="-I$cf_add_incdir $CPPFLAGS"
+
+          cf_top_incdir=`echo $cf_add_incdir | sed -e 's%/include/.*$%/include%'`
+          test "$cf_top_incdir" = "$cf_add_incdir" && break
+          cf_add_incdir="$cf_top_incdir"
+		else
+		  break
+		fi
+	  fi
+	done
+  done
+fi
+
+}
+
+echo $ac_n "checking for $cf_ncuhdr_root header in include-path""... $ac_c" 1>&6
+echo "configure:3239: checking for $cf_ncuhdr_root header in include-path" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cf_header_list="$cf_ncuhdr_root/curses.h $cf_ncuhdr_root/ncurses.h"
+	( test "$cf_ncuhdr_root" = ncurses || test "$cf_ncuhdr_root" = ncursesw ) && cf_header_list="$cf_header_list curses.h ncurses.h"
+	for cf_header in $cf_header_list
+	do
+		
+	cat > conftest.$ac_ext <<EOF
+#line 3250 "configure"
+#include "confdefs.h"
+
+
+#include <$cf_header>
+int main() {
+
+#ifdef NCURSES_VERSION
+
+printf("%s\n", NCURSES_VERSION);
+#else
+#ifdef __NCURSES_H
+printf("old\n");
+#else
+	make an error
+#endif
+#endif
+	
+	
+; return 0; }
+EOF
+if { (eval echo configure:3271: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_ncurses_h=$cf_header
+	
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_ncurses_h=no
+fi
+rm -f conftest*
+
+		test "$cf_cv_ncurses_h" != no && break
+	done
+
+fi
+
+echo "$ac_t""$cf_cv_ncurses_h" 1>&6
+
+
+
+if test "$cf_cv_ncurses_h" != no ; then
+	cf_cv_ncurses_header=$cf_cv_ncurses_h
+else
+
+echo $ac_n "checking for $cf_ncuhdr_root include-path""... $ac_c" 1>&6
+echo "configure:3297: checking for $cf_ncuhdr_root include-path" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_h2'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	test -n "$verbose" && echo
+	cf_search=""
+
+
+test "/usr" != "$prefix" && \
+test -d "/usr" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for include-directories under /usr"
+	test -d /usr/include &&          cf_search="$cf_search /usr/include"
+	test -d /usr/include/$cf_ncuhdr_root &&       cf_search="$cf_search /usr/include/$cf_ncuhdr_root"
+	test -d /usr/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search /usr/include/$cf_ncuhdr_root/include"
+	test -d /usr/$cf_ncuhdr_root/include &&       cf_search="$cf_search /usr/$cf_ncuhdr_root/include"
+	test -d /usr/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search /usr/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "$prefix" != "NONE" && \
+test -d "$prefix" && \
+ {
+	test -n "$verbose" && echo "	... testing for include-directories under $prefix"
+	test -d $prefix/include &&          cf_search="$cf_search $prefix/include"
+	test -d $prefix/include/$cf_ncuhdr_root &&       cf_search="$cf_search $prefix/include/$cf_ncuhdr_root"
+	test -d $prefix/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search $prefix/include/$cf_ncuhdr_root/include"
+	test -d $prefix/$cf_ncuhdr_root/include &&       cf_search="$cf_search $prefix/$cf_ncuhdr_root/include"
+	test -d $prefix/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search $prefix/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "/usr/local" != "$prefix" && \
+test -d "/usr/local" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for include-directories under /usr/local"
+	test -d /usr/local/include &&          cf_search="$cf_search /usr/local/include"
+	test -d /usr/local/include/$cf_ncuhdr_root &&       cf_search="$cf_search /usr/local/include/$cf_ncuhdr_root"
+	test -d /usr/local/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search /usr/local/include/$cf_ncuhdr_root/include"
+	test -d /usr/local/$cf_ncuhdr_root/include &&       cf_search="$cf_search /usr/local/$cf_ncuhdr_root/include"
+	test -d /usr/local/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search /usr/local/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "/opt" != "$prefix" && \
+test -d "/opt" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for include-directories under /opt"
+	test -d /opt/include &&          cf_search="$cf_search /opt/include"
+	test -d /opt/include/$cf_ncuhdr_root &&       cf_search="$cf_search /opt/include/$cf_ncuhdr_root"
+	test -d /opt/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search /opt/include/$cf_ncuhdr_root/include"
+	test -d /opt/$cf_ncuhdr_root/include &&       cf_search="$cf_search /opt/$cf_ncuhdr_root/include"
+	test -d /opt/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search /opt/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "$HOME" != "$prefix" && \
+test -d "$HOME" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for include-directories under $HOME"
+	test -d $HOME/include &&          cf_search="$cf_search $HOME/include"
+	test -d $HOME/include/$cf_ncuhdr_root &&       cf_search="$cf_search $HOME/include/$cf_ncuhdr_root"
+	test -d $HOME/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search $HOME/include/$cf_ncuhdr_root/include"
+	test -d $HOME/$cf_ncuhdr_root/include &&       cf_search="$cf_search $HOME/$cf_ncuhdr_root/include"
+	test -d $HOME/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search $HOME/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "$includedir" != NONE && \
+test "$includedir" != "/usr/include" && \
+test -d "$includedir" && {
+	test -d $includedir &&    cf_search="$cf_search $includedir"
+	test -d $includedir/$cf_ncuhdr_root && cf_search="$cf_search $includedir/$cf_ncuhdr_root"
+}
+
+test "$oldincludedir" != NONE && \
+test "$oldincludedir" != "/usr/include" && \
+test -d "$oldincludedir" && {
+	test -d $oldincludedir    && cf_search="$cf_search $oldincludedir"
+	test -d $oldincludedir/$cf_ncuhdr_root && cf_search="$cf_search $oldincludedir/$cf_ncuhdr_root"
+}
+
+
+	test -n "$verbose" && echo search path $cf_search
+	cf_save2_CPPFLAGS="$CPPFLAGS"
+	for cf_incdir in $cf_search
+	do
+		
+if test -n "$cf_incdir" ; then
+  for cf_add_incdir in $cf_incdir
+  do
+	while test $cf_add_incdir != /usr/include
+	do
+	  if test -d $cf_add_incdir
+	  then
+		cf_have_incdir=no
+		if test -n "$CFLAGS$CPPFLAGS" ; then
+		  # a loop is needed to ensure we can add subdirs of existing dirs
+		  for cf_test_incdir in $CFLAGS $CPPFLAGS ; do
+			if test ".$cf_test_incdir" = ".-I$cf_add_incdir" ; then
+			  cf_have_incdir=yes; break
+			fi
+		  done
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+          if test "$cf_add_incdir" = /usr/local/include ; then
+			if test "$GCC" = yes
+			then
+			  cf_save_CPPFLAGS=$CPPFLAGS
+			  CPPFLAGS="$CPPFLAGS -I$cf_add_incdir"
+			  cat > conftest.$ac_ext <<EOF
+#line 3410 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+printf("Hello")
+; return 0; }
+EOF
+if { (eval echo configure:3417: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_have_incdir=yes
+fi
+rm -f conftest*
+			  CPPFLAGS=$cf_save_CPPFLAGS
+			fi
+		  fi
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+		  test -n "$verbose" && echo "	adding $cf_add_incdir to include-path" 1>&6
+
+echo "${as_me-configure}:3434: testing adding $cf_add_incdir to include-path ..." 1>&5
+
+
+		  CPPFLAGS="-I$cf_add_incdir $CPPFLAGS"
+
+          cf_top_incdir=`echo $cf_add_incdir | sed -e 's%/include/.*$%/include%'`
+          test "$cf_top_incdir" = "$cf_add_incdir" && break
+          cf_add_incdir="$cf_top_incdir"
+		else
+		  break
+		fi
+	  fi
+	done
+  done
+fi
+
+		for cf_header in \
+			ncurses.h \
+			curses.h
+		do
+			
+	cat > conftest.$ac_ext <<EOF
+#line 3456 "configure"
+#include "confdefs.h"
+
+
+#include <$cf_header>
+int main() {
+
+#ifdef NCURSES_VERSION
+
+printf("%s\n", NCURSES_VERSION);
+#else
+#ifdef __NCURSES_H
+printf("old\n");
+#else
+	make an error
+#endif
+#endif
+	
+	
+; return 0; }
+EOF
+if { (eval echo configure:3477: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_ncurses_h2=$cf_header
+	
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_ncurses_h2=no
+fi
+rm -f conftest*
+
+			if test "$cf_cv_ncurses_h2" != no ; then
+				cf_cv_ncurses_h2=$cf_incdir/$cf_header
+				test -n "$verbose" && echo $ac_n "	... found $ac_c" 1>&6
+				break
+			fi
+			test -n "$verbose" && echo "	... tested $cf_incdir/$cf_header" 1>&6
+		done
+		CPPFLAGS="$cf_save2_CPPFLAGS"
+		test "$cf_cv_ncurses_h2" != no && break
+	done
+	test "$cf_cv_ncurses_h2" = no && { echo "configure: error: not found" 1>&2; exit 1; }
+	
+fi
+
+echo "$ac_t""$cf_cv_ncurses_h2" 1>&6
+
+	cf_1st_incdir=`echo $cf_cv_ncurses_h2 | sed -e 's%/[^/]*$%%'`
+	cf_cv_ncurses_header=`basename $cf_cv_ncurses_h2`
+	if test `basename $cf_1st_incdir` = $cf_ncuhdr_root ; then
+		cf_cv_ncurses_header=$cf_ncuhdr_root/$cf_cv_ncurses_header
+	fi
+	
+if test -n "$cf_1st_incdir" ; then
+  for cf_add_incdir in $cf_1st_incdir
+  do
+	while test $cf_add_incdir != /usr/include
+	do
+	  if test -d $cf_add_incdir
+	  then
+		cf_have_incdir=no
+		if test -n "$CFLAGS$CPPFLAGS" ; then
+		  # a loop is needed to ensure we can add subdirs of existing dirs
+		  for cf_test_incdir in $CFLAGS $CPPFLAGS ; do
+			if test ".$cf_test_incdir" = ".-I$cf_add_incdir" ; then
+			  cf_have_incdir=yes; break
+			fi
+		  done
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+          if test "$cf_add_incdir" = /usr/local/include ; then
+			if test "$GCC" = yes
+			then
+			  cf_save_CPPFLAGS=$CPPFLAGS
+			  CPPFLAGS="$CPPFLAGS -I$cf_add_incdir"
+			  cat > conftest.$ac_ext <<EOF
+#line 3535 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+printf("Hello")
+; return 0; }
+EOF
+if { (eval echo configure:3542: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_have_incdir=yes
+fi
+rm -f conftest*
+			  CPPFLAGS=$cf_save_CPPFLAGS
+			fi
+		  fi
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+		  test -n "$verbose" && echo "	adding $cf_add_incdir to include-path" 1>&6
+
+echo "${as_me-configure}:3559: testing adding $cf_add_incdir to include-path ..." 1>&5
+
+
+		  CPPFLAGS="-I$cf_add_incdir $CPPFLAGS"
+
+          cf_top_incdir=`echo $cf_add_incdir | sed -e 's%/include/.*$%/include%'`
+          test "$cf_top_incdir" = "$cf_add_incdir" && break
+          cf_add_incdir="$cf_top_incdir"
+		else
+		  break
+		fi
+	  fi
+	done
+  done
+fi
+
+
+fi
+
+# Set definitions to allow ifdef'ing for ncurses.h
+
+case $cf_cv_ncurses_header in # (vi
+*ncurses.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSES_H 1
+EOF
+
+	;;
+esac
+
+case $cf_cv_ncurses_header in # (vi
+ncurses/curses.h|ncurses/ncurses.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSES_NCURSES_H 1
+EOF
+
+	;;
+ncursesw/curses.h|ncursesw/ncurses.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSESW_NCURSES_H 1
+EOF
+
+	;;
+esac
+
+
+
+echo $ac_n "checking for terminfo header""... $ac_c" 1>&6
+echo "configure:3607: checking for terminfo header" >&5
+if eval "test \"`echo '$''{'cf_cv_term_header'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+case ${cf_cv_ncurses_header} in #(vi
+*/ncurses.h|*/ncursesw.h) #(vi
+	cf_term_header=`echo "$cf_cv_ncurses_header" | sed -e 's%ncurses[^.]*\.h$%term.h%'`
+	;;
+*)
+	cf_term_header=term.h
+	;;
+esac
+
+for cf_test in $cf_term_header "ncurses/term.h" "ncursesw/term.h"
+do
+cat > conftest.$ac_ext <<EOF
+#line 3624 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <$cf_test>
+
+int main() {
+int x = auto_left_margin
+; return 0; }
+EOF
+if { (eval echo configure:3634: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  
+	cf_cv_term_header="$cf_test"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+	cf_cv_term_header=unknown
+	
+fi
+rm -f conftest*
+	test "$cf_cv_term_header" != unknown && break
+done
+
+fi
+
+echo "$ac_t""$cf_cv_term_header" 1>&6
+
+# Set definitions to allow ifdef'ing to accommodate subdirectories
+
+case $cf_cv_term_header in # (vi
+*term.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_TERM_H 1
+EOF
+
+	;;
+esac
+
+case $cf_cv_term_header in # (vi
+ncurses/term.h) #(vi
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSES_TERM_H 1
+EOF
+
+	;;
+ncursesw/term.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSESW_TERM_H 1
+EOF
+
+	;;
+esac
+
+
+# some applications need this, but should check for NCURSES_VERSION
+cat >> confdefs.h <<\EOF
+#define NCURSES 1
+EOF
+
+
+
+echo $ac_n "checking for ncurses version""... $ac_c" 1>&6
+echo "configure:3689: checking for ncurses version" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_version'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cf_cv_ncurses_version=no
+	cf_tempfile=out$$
+	rm -f $cf_tempfile
+	if test "$cross_compiling" = yes; then
+  
+
+	# This will not work if the preprocessor splits the line after the
+	# Autoconf token.  The 'unproto' program does that.
+	cat > conftest.$ac_ext <<EOF
+#include <${cf_cv_ncurses_header-curses.h}>
+#undef Autoconf
+#ifdef NCURSES_VERSION
+Autoconf NCURSES_VERSION
+#else
+#ifdef __NCURSES_H
+Autoconf "old"
+#endif
+;
+#endif
+EOF
+	cf_try="$ac_cpp conftest.$ac_ext 2>&5 | grep '^Autoconf ' >conftest.out"
+	{ (eval echo configure:3715: \"$cf_try\") 1>&5; (eval $cf_try) 2>&5; }
+	if test -f conftest.out ; then
+		cf_out=`cat conftest.out | sed -e 's%^Autoconf %%' -e 's%^[^"]*"%%' -e 's%".*%%'`
+		test -n "$cf_out" && cf_cv_ncurses_version="$cf_out"
+		rm -f conftest.out
+	fi
+
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3724 "configure"
+#include "confdefs.h"
+
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <stdio.h>
+int main()
+{
+	FILE *fp = fopen("$cf_tempfile", "w");
+#ifdef NCURSES_VERSION
+# ifdef NCURSES_VERSION_PATCH
+	fprintf(fp, "%s.%d\n", NCURSES_VERSION, NCURSES_VERSION_PATCH);
+# else
+	fprintf(fp, "%s\n", NCURSES_VERSION);
+# endif
+#else
+# ifdef __NCURSES_H
+	fprintf(fp, "old\n");
+# else
+	make an error
+# endif
+#endif
+	${cf_cv_main_return-return}(0);
+}
+EOF
+if { (eval echo configure:3748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  
+	cf_cv_ncurses_version=`cat $cf_tempfile`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -fr conftest*
+fi
+
+	rm -f $cf_tempfile
+
+fi
+
+echo "$ac_t""$cf_cv_ncurses_version" 1>&6
+test "$cf_cv_ncurses_version" = no || cat >> confdefs.h <<\EOF
+#define NCURSES 1
+EOF
+
+
+
+	
+
+cf_nculib_root=ncurses
+	# This works, except for the special case where we find gpm, but
+	# ncurses is in a nonstandard location via $LIBS, and we really want
+	# to link gpm.
+cf_ncurses_LIBS=""
+cf_ncurses_SAVE="$LIBS"
+echo $ac_n "checking for Gpm_Open in -lgpm""... $ac_c" 1>&6
+echo "configure:3779: checking for Gpm_Open in -lgpm" >&5
+ac_lib_var=`echo gpm'_'Gpm_Open | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lgpm  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3787 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char Gpm_Open();
+
+int main() {
+Gpm_Open()
+; return 0; }
+EOF
+if { (eval echo configure:3798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  echo $ac_n "checking for initscr in -lgpm""... $ac_c" 1>&6
+echo "configure:3814: checking for initscr in -lgpm" >&5
+ac_lib_var=`echo gpm'_'initscr | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lgpm  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3822 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char initscr();
+
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:3833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="$cf_ncurses_SAVE"
+else
+  echo "$ac_t""no" 1>&6
+cf_ncurses_LIBS="-lgpm"
+fi
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+case $host_os in #(vi
+freebsd*)
+	# This is only necessary if you are linking against an obsolete
+	# version of ncurses (but it should do no harm, since it's static).
+	if test "$cf_nculib_root" = ncurses ; then
+		echo $ac_n "checking for tgoto in -lmytinfo""... $ac_c" 1>&6
+echo "configure:3865: checking for tgoto in -lmytinfo" >&5
+ac_lib_var=`echo mytinfo'_'tgoto | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lmytinfo  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3873 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char tgoto();
+
+int main() {
+tgoto()
+; return 0; }
+EOF
+if { (eval echo configure:3884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cf_ncurses_LIBS="-lmytinfo $cf_ncurses_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	fi
+	;;
+esac
+
+LIBS="$cf_ncurses_LIBS $LIBS"
+
+if ( test -n "$cf_cv_curses_dir" && test "$cf_cv_curses_dir" != "no" )
+then
+	
+if test -n "$cf_cv_curses_dir/lib" ; then
+  for cf_add_libdir in $cf_cv_curses_dir/lib
+  do
+    if test $cf_add_libdir = /usr/lib ; then
+      :
+    elif test -d $cf_add_libdir
+    then
+      cf_have_libdir=no
+      if test -n "$LDFLAGS$LIBS" ; then
+        # a loop is needed to ensure we can add subdirs of existing dirs
+        for cf_test_libdir in $LDFLAGS $LIBS ; do
+          if test ".$cf_test_libdir" = ".-L$cf_add_libdir" ; then
+            cf_have_libdir=yes; break
+          fi
+        done
+      fi
+      if test "$cf_have_libdir" = no ; then
+        test -n "$verbose" && echo "	adding $cf_add_libdir to library-path" 1>&6
+
+echo "${as_me-configure}:3932: testing adding $cf_add_libdir to library-path ..." 1>&5
+
+
+        LDFLAGS="-L$cf_add_libdir $LDFLAGS"
+      fi
+    fi
+  done
+fi
+
+	LIBS="-l$cf_nculib_root $LIBS"
+else
+	
+	eval 'cf_cv_have_lib_'$cf_nculib_root'=no'
+	cf_libdir=""
+	echo $ac_n "checking for initscr""... $ac_c" 1>&6
+echo "configure:3947: checking for initscr" >&5
+if eval "test \"`echo '$''{'ac_cv_func_initscr'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3952 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char initscr(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char initscr();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_initscr) || defined (__stub___initscr)
+choke me
+#else
+initscr();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_initscr=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_initscr=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'initscr`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  eval 'cf_cv_have_lib_'$cf_nculib_root'=yes'
+else
+  echo "$ac_t""no" 1>&6
+
+		cf_save_LIBS="$LIBS"
+		echo $ac_n "checking for initscr in -l$cf_nculib_root""... $ac_c" 1>&6
+echo "configure:3995: checking for initscr in -l$cf_nculib_root" >&5
+		LIBS="-l$cf_nculib_root $LIBS"
+		cat > conftest.$ac_ext <<EOF
+#line 3998 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:4005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+			 eval 'cf_cv_have_lib_'$cf_nculib_root'=yes'
+			
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+			cf_search=""
+
+
+test "/usr" != "$prefix" && \
+test -d "/usr" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for lib-directories under /usr"
+	test -d /usr/lib &&          cf_search="$cf_search /usr/lib"
+	test -d /usr/lib/$cf_nculib_root &&       cf_search="$cf_search /usr/lib/$cf_nculib_root"
+	test -d /usr/lib/$cf_nculib_root/lib &&    cf_search="$cf_search /usr/lib/$cf_nculib_root/lib"
+	test -d /usr/$cf_nculib_root/lib &&       cf_search="$cf_search /usr/$cf_nculib_root/lib"
+	test -d /usr/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search /usr/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+test "$prefix" != "NONE" && \
+test -d "$prefix" && \
+ {
+	test -n "$verbose" && echo "	... testing for lib-directories under $prefix"
+	test -d $prefix/lib &&          cf_search="$cf_search $prefix/lib"
+	test -d $prefix/lib/$cf_nculib_root &&       cf_search="$cf_search $prefix/lib/$cf_nculib_root"
+	test -d $prefix/lib/$cf_nculib_root/lib &&    cf_search="$cf_search $prefix/lib/$cf_nculib_root/lib"
+	test -d $prefix/$cf_nculib_root/lib &&       cf_search="$cf_search $prefix/$cf_nculib_root/lib"
+	test -d $prefix/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search $prefix/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+test "/usr/local" != "$prefix" && \
+test -d "/usr/local" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for lib-directories under /usr/local"
+	test -d /usr/local/lib &&          cf_search="$cf_search /usr/local/lib"
+	test -d /usr/local/lib/$cf_nculib_root &&       cf_search="$cf_search /usr/local/lib/$cf_nculib_root"
+	test -d /usr/local/lib/$cf_nculib_root/lib &&    cf_search="$cf_search /usr/local/lib/$cf_nculib_root/lib"
+	test -d /usr/local/$cf_nculib_root/lib &&       cf_search="$cf_search /usr/local/$cf_nculib_root/lib"
+	test -d /usr/local/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search /usr/local/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+test "/opt" != "$prefix" && \
+test -d "/opt" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for lib-directories under /opt"
+	test -d /opt/lib &&          cf_search="$cf_search /opt/lib"
+	test -d /opt/lib/$cf_nculib_root &&       cf_search="$cf_search /opt/lib/$cf_nculib_root"
+	test -d /opt/lib/$cf_nculib_root/lib &&    cf_search="$cf_search /opt/lib/$cf_nculib_root/lib"
+	test -d /opt/$cf_nculib_root/lib &&       cf_search="$cf_search /opt/$cf_nculib_root/lib"
+	test -d /opt/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search /opt/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+test "$HOME" != "$prefix" && \
+test -d "$HOME" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for lib-directories under $HOME"
+	test -d $HOME/lib &&          cf_search="$cf_search $HOME/lib"
+	test -d $HOME/lib/$cf_nculib_root &&       cf_search="$cf_search $HOME/lib/$cf_nculib_root"
+	test -d $HOME/lib/$cf_nculib_root/lib &&    cf_search="$cf_search $HOME/lib/$cf_nculib_root/lib"
+	test -d $HOME/$cf_nculib_root/lib &&       cf_search="$cf_search $HOME/$cf_nculib_root/lib"
+	test -d $HOME/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search $HOME/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+			for cf_libdir in $cf_search
+			do
+				echo $ac_n "checking for -l$cf_nculib_root in $cf_libdir""... $ac_c" 1>&6
+echo "configure:4081: checking for -l$cf_nculib_root in $cf_libdir" >&5
+				LIBS="-L$cf_libdir -l$cf_nculib_root $cf_save_LIBS"
+				cat > conftest.$ac_ext <<EOF
+#line 4084 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:4091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+			 		 eval 'cf_cv_have_lib_'$cf_nculib_root'=yes'
+					 break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+					 LIBS="$cf_save_LIBS"
+fi
+rm -f conftest*
+			done
+			
+fi
+rm -f conftest*
+		
+fi
+
+eval 'cf_found_library=$cf_cv_have_lib_'$cf_nculib_root
+
+if test $cf_found_library = no ; then
+	{ echo "configure: error: Cannot link $cf_nculib_root library" 1>&2; exit 1; }
+fi
+
+
+fi
+
+if test -n "$cf_ncurses_LIBS" ; then
+	echo $ac_n "checking if we can link $cf_nculib_root without $cf_ncurses_LIBS""... $ac_c" 1>&6
+echo "configure:4122: checking if we can link $cf_nculib_root without $cf_ncurses_LIBS" >&5
+	cf_ncurses_SAVE="$LIBS"
+	for p in $cf_ncurses_LIBS ; do
+		q=`echo $LIBS | sed -e "s%$p %%" -e "s%$p$%%"`
+		if test "$q" != "$LIBS" ; then
+			LIBS="$q"
+		fi
+	done
+	cat > conftest.$ac_ext <<EOF
+#line 4131 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr(); mousemask(0,0); tgoto((char *)0, 0, 0);
+; return 0; }
+EOF
+if { (eval echo configure:4138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+		 LIBS="$cf_ncurses_SAVE"
+fi
+rm -f conftest*
+fi
+
+
+cf_nculib_ROOT=`echo "HAVE_LIB$cf_nculib_root" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
+
+cat >> confdefs.h <<EOF
+#define $cf_nculib_ROOT 1
+EOF
+
+
+	;;
+ncursesw)
+	cf_cv_libtype=w
+	
+echo $ac_n "checking for multibyte character support""... $ac_c" 1>&6
+echo "configure:4164: checking for multibyte character support" >&5
+if eval "test \"`echo '$''{'cf_cv_utf8_lib'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cf_save_LIBS="$LIBS"
+	cat > conftest.$ac_ext <<EOF
+#line 4171 "configure"
+#include "confdefs.h"
+
+#include <stdlib.h>
+int main() {
+putwc(0,0);
+; return 0; }
+EOF
+if { (eval echo configure:4179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_utf8_lib=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  LIBS="-lutf8 $LIBS"
+	 cat > conftest.$ac_ext <<EOF
+#line 4188 "configure"
+#include "confdefs.h"
+
+#include <libutf8.h>
+int main() {
+putwc(0,0);
+; return 0; }
+EOF
+if { (eval echo configure:4196: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_utf8_lib=add-on
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_utf8_lib=no
+fi
+rm -f conftest*
+	LIBS="$cf_save_LIBS"
+
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$cf_cv_utf8_lib" 1>&6
+
+# HAVE_LIBUTF8_H is used by ncurses if curses.h is shared between
+# ncurses/ncursesw:
+if test "$cf_cv_utf8_lib" = "add-on" ; then
+	cat >> confdefs.h <<\EOF
+#define HAVE_LIBUTF8_H 1
+EOF
+
+	LIBS="-lutf8 $LIBS"
+fi
+
+	
+
+cf_ncuhdr_root=ncursesw
+
+test -n "$cf_cv_curses_dir" && \
+test "$cf_cv_curses_dir" != "no" && { \
+  
+if test -n "$cf_cv_curses_dir/include $cf_cv_curses_dir/include/$cf_ncuhdr_root" ; then
+  for cf_add_incdir in $cf_cv_curses_dir/include $cf_cv_curses_dir/include/$cf_ncuhdr_root
+  do
+	while test $cf_add_incdir != /usr/include
+	do
+	  if test -d $cf_add_incdir
+	  then
+		cf_have_incdir=no
+		if test -n "$CFLAGS$CPPFLAGS" ; then
+		  # a loop is needed to ensure we can add subdirs of existing dirs
+		  for cf_test_incdir in $CFLAGS $CPPFLAGS ; do
+			if test ".$cf_test_incdir" = ".-I$cf_add_incdir" ; then
+			  cf_have_incdir=yes; break
+			fi
+		  done
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+          if test "$cf_add_incdir" = /usr/local/include ; then
+			if test "$GCC" = yes
+			then
+			  cf_save_CPPFLAGS=$CPPFLAGS
+			  CPPFLAGS="$CPPFLAGS -I$cf_add_incdir"
+			  cat > conftest.$ac_ext <<EOF
+#line 4255 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+printf("Hello")
+; return 0; }
+EOF
+if { (eval echo configure:4262: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_have_incdir=yes
+fi
+rm -f conftest*
+			  CPPFLAGS=$cf_save_CPPFLAGS
+			fi
+		  fi
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+		  test -n "$verbose" && echo "	adding $cf_add_incdir to include-path" 1>&6
+
+echo "${as_me-configure}:4279: testing adding $cf_add_incdir to include-path ..." 1>&5
+
+
+		  CPPFLAGS="-I$cf_add_incdir $CPPFLAGS"
+
+          cf_top_incdir=`echo $cf_add_incdir | sed -e 's%/include/.*$%/include%'`
+          test "$cf_top_incdir" = "$cf_add_incdir" && break
+          cf_add_incdir="$cf_top_incdir"
+		else
+		  break
+		fi
+	  fi
+	done
+  done
+fi
+
+}
+
+echo $ac_n "checking for $cf_ncuhdr_root header in include-path""... $ac_c" 1>&6
+echo "configure:4298: checking for $cf_ncuhdr_root header in include-path" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cf_header_list="$cf_ncuhdr_root/curses.h $cf_ncuhdr_root/ncurses.h"
+	( test "$cf_ncuhdr_root" = ncurses || test "$cf_ncuhdr_root" = ncursesw ) && cf_header_list="$cf_header_list curses.h ncurses.h"
+	for cf_header in $cf_header_list
+	do
+		
+	cat > conftest.$ac_ext <<EOF
+#line 4309 "configure"
+#include "confdefs.h"
+
+
+#define _XOPEN_SOURCE_EXTENDED
+#undef  HAVE_LIBUTF8_H	/* in case we used CF_UTF8_LIB */
+#define HAVE_LIBUTF8_H	/* to force ncurses' header file to use cchar_t */
+
+#include <$cf_header>
+int main() {
+
+#ifdef NCURSES_VERSION
+
+#ifndef WACS_BSSB
+	make an error
+#endif
+
+printf("%s\n", NCURSES_VERSION);
+#else
+#ifdef __NCURSES_H
+printf("old\n");
+#else
+	make an error
+#endif
+#endif
+	
+	
+; return 0; }
+EOF
+if { (eval echo configure:4338: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_ncurses_h=$cf_header
+	
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_ncurses_h=no
+fi
+rm -f conftest*
+
+		test "$cf_cv_ncurses_h" != no && break
+	done
+
+fi
+
+echo "$ac_t""$cf_cv_ncurses_h" 1>&6
+
+
+
+if test "$cf_cv_ncurses_h" != no ; then
+	cf_cv_ncurses_header=$cf_cv_ncurses_h
+else
+
+echo $ac_n "checking for $cf_ncuhdr_root include-path""... $ac_c" 1>&6
+echo "configure:4364: checking for $cf_ncuhdr_root include-path" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_h2'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	test -n "$verbose" && echo
+	cf_search=""
+
+
+test "/usr" != "$prefix" && \
+test -d "/usr" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for include-directories under /usr"
+	test -d /usr/include &&          cf_search="$cf_search /usr/include"
+	test -d /usr/include/$cf_ncuhdr_root &&       cf_search="$cf_search /usr/include/$cf_ncuhdr_root"
+	test -d /usr/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search /usr/include/$cf_ncuhdr_root/include"
+	test -d /usr/$cf_ncuhdr_root/include &&       cf_search="$cf_search /usr/$cf_ncuhdr_root/include"
+	test -d /usr/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search /usr/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "$prefix" != "NONE" && \
+test -d "$prefix" && \
+ {
+	test -n "$verbose" && echo "	... testing for include-directories under $prefix"
+	test -d $prefix/include &&          cf_search="$cf_search $prefix/include"
+	test -d $prefix/include/$cf_ncuhdr_root &&       cf_search="$cf_search $prefix/include/$cf_ncuhdr_root"
+	test -d $prefix/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search $prefix/include/$cf_ncuhdr_root/include"
+	test -d $prefix/$cf_ncuhdr_root/include &&       cf_search="$cf_search $prefix/$cf_ncuhdr_root/include"
+	test -d $prefix/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search $prefix/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "/usr/local" != "$prefix" && \
+test -d "/usr/local" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for include-directories under /usr/local"
+	test -d /usr/local/include &&          cf_search="$cf_search /usr/local/include"
+	test -d /usr/local/include/$cf_ncuhdr_root &&       cf_search="$cf_search /usr/local/include/$cf_ncuhdr_root"
+	test -d /usr/local/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search /usr/local/include/$cf_ncuhdr_root/include"
+	test -d /usr/local/$cf_ncuhdr_root/include &&       cf_search="$cf_search /usr/local/$cf_ncuhdr_root/include"
+	test -d /usr/local/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search /usr/local/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "/opt" != "$prefix" && \
+test -d "/opt" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for include-directories under /opt"
+	test -d /opt/include &&          cf_search="$cf_search /opt/include"
+	test -d /opt/include/$cf_ncuhdr_root &&       cf_search="$cf_search /opt/include/$cf_ncuhdr_root"
+	test -d /opt/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search /opt/include/$cf_ncuhdr_root/include"
+	test -d /opt/$cf_ncuhdr_root/include &&       cf_search="$cf_search /opt/$cf_ncuhdr_root/include"
+	test -d /opt/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search /opt/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "$HOME" != "$prefix" && \
+test -d "$HOME" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for include-directories under $HOME"
+	test -d $HOME/include &&          cf_search="$cf_search $HOME/include"
+	test -d $HOME/include/$cf_ncuhdr_root &&       cf_search="$cf_search $HOME/include/$cf_ncuhdr_root"
+	test -d $HOME/include/$cf_ncuhdr_root/include &&    cf_search="$cf_search $HOME/include/$cf_ncuhdr_root/include"
+	test -d $HOME/$cf_ncuhdr_root/include &&       cf_search="$cf_search $HOME/$cf_ncuhdr_root/include"
+	test -d $HOME/$cf_ncuhdr_root/include/$cf_ncuhdr_root &&    cf_search="$cf_search $HOME/$cf_ncuhdr_root/include/$cf_ncuhdr_root"
+}
+
+
+test "$includedir" != NONE && \
+test "$includedir" != "/usr/include" && \
+test -d "$includedir" && {
+	test -d $includedir &&    cf_search="$cf_search $includedir"
+	test -d $includedir/$cf_ncuhdr_root && cf_search="$cf_search $includedir/$cf_ncuhdr_root"
+}
+
+test "$oldincludedir" != NONE && \
+test "$oldincludedir" != "/usr/include" && \
+test -d "$oldincludedir" && {
+	test -d $oldincludedir    && cf_search="$cf_search $oldincludedir"
+	test -d $oldincludedir/$cf_ncuhdr_root && cf_search="$cf_search $oldincludedir/$cf_ncuhdr_root"
+}
+
+
+	test -n "$verbose" && echo search path $cf_search
+	cf_save2_CPPFLAGS="$CPPFLAGS"
+	for cf_incdir in $cf_search
+	do
+		
+if test -n "$cf_incdir" ; then
+  for cf_add_incdir in $cf_incdir
+  do
+	while test $cf_add_incdir != /usr/include
+	do
+	  if test -d $cf_add_incdir
+	  then
+		cf_have_incdir=no
+		if test -n "$CFLAGS$CPPFLAGS" ; then
+		  # a loop is needed to ensure we can add subdirs of existing dirs
+		  for cf_test_incdir in $CFLAGS $CPPFLAGS ; do
+			if test ".$cf_test_incdir" = ".-I$cf_add_incdir" ; then
+			  cf_have_incdir=yes; break
+			fi
+		  done
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+          if test "$cf_add_incdir" = /usr/local/include ; then
+			if test "$GCC" = yes
+			then
+			  cf_save_CPPFLAGS=$CPPFLAGS
+			  CPPFLAGS="$CPPFLAGS -I$cf_add_incdir"
+			  cat > conftest.$ac_ext <<EOF
+#line 4477 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+printf("Hello")
+; return 0; }
+EOF
+if { (eval echo configure:4484: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_have_incdir=yes
+fi
+rm -f conftest*
+			  CPPFLAGS=$cf_save_CPPFLAGS
+			fi
+		  fi
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+		  test -n "$verbose" && echo "	adding $cf_add_incdir to include-path" 1>&6
+
+echo "${as_me-configure}:4501: testing adding $cf_add_incdir to include-path ..." 1>&5
+
+
+		  CPPFLAGS="-I$cf_add_incdir $CPPFLAGS"
+
+          cf_top_incdir=`echo $cf_add_incdir | sed -e 's%/include/.*$%/include%'`
+          test "$cf_top_incdir" = "$cf_add_incdir" && break
+          cf_add_incdir="$cf_top_incdir"
+		else
+		  break
+		fi
+	  fi
+	done
+  done
+fi
+
+		for cf_header in \
+			ncurses.h \
+			curses.h
+		do
+			
+	cat > conftest.$ac_ext <<EOF
+#line 4523 "configure"
+#include "confdefs.h"
+
+
+#include <$cf_header>
+int main() {
+
+#ifdef NCURSES_VERSION
+
+printf("%s\n", NCURSES_VERSION);
+#else
+#ifdef __NCURSES_H
+printf("old\n");
+#else
+	make an error
+#endif
+#endif
+	
+	
+; return 0; }
+EOF
+if { (eval echo configure:4544: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_ncurses_h2=$cf_header
+	
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_ncurses_h2=no
+fi
+rm -f conftest*
+
+			if test "$cf_cv_ncurses_h2" != no ; then
+				cf_cv_ncurses_h2=$cf_incdir/$cf_header
+				test -n "$verbose" && echo $ac_n "	... found $ac_c" 1>&6
+				break
+			fi
+			test -n "$verbose" && echo "	... tested $cf_incdir/$cf_header" 1>&6
+		done
+		CPPFLAGS="$cf_save2_CPPFLAGS"
+		test "$cf_cv_ncurses_h2" != no && break
+	done
+	test "$cf_cv_ncurses_h2" = no && { echo "configure: error: not found" 1>&2; exit 1; }
+	
+fi
+
+echo "$ac_t""$cf_cv_ncurses_h2" 1>&6
+
+	cf_1st_incdir=`echo $cf_cv_ncurses_h2 | sed -e 's%/[^/]*$%%'`
+	cf_cv_ncurses_header=`basename $cf_cv_ncurses_h2`
+	if test `basename $cf_1st_incdir` = $cf_ncuhdr_root ; then
+		cf_cv_ncurses_header=$cf_ncuhdr_root/$cf_cv_ncurses_header
+	fi
+	
+if test -n "$cf_1st_incdir" ; then
+  for cf_add_incdir in $cf_1st_incdir
+  do
+	while test $cf_add_incdir != /usr/include
+	do
+	  if test -d $cf_add_incdir
+	  then
+		cf_have_incdir=no
+		if test -n "$CFLAGS$CPPFLAGS" ; then
+		  # a loop is needed to ensure we can add subdirs of existing dirs
+		  for cf_test_incdir in $CFLAGS $CPPFLAGS ; do
+			if test ".$cf_test_incdir" = ".-I$cf_add_incdir" ; then
+			  cf_have_incdir=yes; break
+			fi
+		  done
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+          if test "$cf_add_incdir" = /usr/local/include ; then
+			if test "$GCC" = yes
+			then
+			  cf_save_CPPFLAGS=$CPPFLAGS
+			  CPPFLAGS="$CPPFLAGS -I$cf_add_incdir"
+			  cat > conftest.$ac_ext <<EOF
+#line 4602 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+printf("Hello")
+; return 0; }
+EOF
+if { (eval echo configure:4609: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_have_incdir=yes
+fi
+rm -f conftest*
+			  CPPFLAGS=$cf_save_CPPFLAGS
+			fi
+		  fi
+		fi
+
+		if test "$cf_have_incdir" = no ; then
+		  test -n "$verbose" && echo "	adding $cf_add_incdir to include-path" 1>&6
+
+echo "${as_me-configure}:4626: testing adding $cf_add_incdir to include-path ..." 1>&5
+
+
+		  CPPFLAGS="-I$cf_add_incdir $CPPFLAGS"
+
+          cf_top_incdir=`echo $cf_add_incdir | sed -e 's%/include/.*$%/include%'`
+          test "$cf_top_incdir" = "$cf_add_incdir" && break
+          cf_add_incdir="$cf_top_incdir"
+		else
+		  break
+		fi
+	  fi
+	done
+  done
+fi
+
+
+fi
+
+# Set definitions to allow ifdef'ing for ncurses.h
+
+case $cf_cv_ncurses_header in # (vi
+*ncurses.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSES_H 1
+EOF
+
+	;;
+esac
+
+case $cf_cv_ncurses_header in # (vi
+ncurses/curses.h|ncurses/ncurses.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSES_NCURSES_H 1
+EOF
+
+	;;
+ncursesw/curses.h|ncursesw/ncurses.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSESW_NCURSES_H 1
+EOF
+
+	;;
+esac
+
+
+
+echo $ac_n "checking for terminfo header""... $ac_c" 1>&6
+echo "configure:4674: checking for terminfo header" >&5
+if eval "test \"`echo '$''{'cf_cv_term_header'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+case ${cf_cv_ncurses_header} in #(vi
+*/ncurses.h|*/ncursesw.h) #(vi
+	cf_term_header=`echo "$cf_cv_ncurses_header" | sed -e 's%ncurses[^.]*\.h$%term.h%'`
+	;;
+*)
+	cf_term_header=term.h
+	;;
+esac
+
+for cf_test in $cf_term_header "ncurses/term.h" "ncursesw/term.h"
+do
+cat > conftest.$ac_ext <<EOF
+#line 4691 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <$cf_test>
+
+int main() {
+int x = auto_left_margin
+; return 0; }
+EOF
+if { (eval echo configure:4701: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  
+	cf_cv_term_header="$cf_test"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  
+	cf_cv_term_header=unknown
+	
+fi
+rm -f conftest*
+	test "$cf_cv_term_header" != unknown && break
+done
+
+fi
+
+echo "$ac_t""$cf_cv_term_header" 1>&6
+
+# Set definitions to allow ifdef'ing to accommodate subdirectories
+
+case $cf_cv_term_header in # (vi
+*term.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_TERM_H 1
+EOF
+
+	;;
+esac
+
+case $cf_cv_term_header in # (vi
+ncurses/term.h) #(vi
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSES_TERM_H 1
+EOF
+
+	;;
+ncursesw/term.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSESW_TERM_H 1
+EOF
+
+	;;
+esac
+
+
+# some applications need this, but should check for NCURSES_VERSION
+cat >> confdefs.h <<\EOF
+#define NCURSES 1
+EOF
+
+
+
+echo $ac_n "checking for ncurses version""... $ac_c" 1>&6
+echo "configure:4756: checking for ncurses version" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_version'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cf_cv_ncurses_version=no
+	cf_tempfile=out$$
+	rm -f $cf_tempfile
+	if test "$cross_compiling" = yes; then
+  
+
+	# This will not work if the preprocessor splits the line after the
+	# Autoconf token.  The 'unproto' program does that.
+	cat > conftest.$ac_ext <<EOF
+#include <${cf_cv_ncurses_header-curses.h}>
+#undef Autoconf
+#ifdef NCURSES_VERSION
+Autoconf NCURSES_VERSION
+#else
+#ifdef __NCURSES_H
+Autoconf "old"
+#endif
+;
+#endif
+EOF
+	cf_try="$ac_cpp conftest.$ac_ext 2>&5 | grep '^Autoconf ' >conftest.out"
+	{ (eval echo configure:4782: \"$cf_try\") 1>&5; (eval $cf_try) 2>&5; }
+	if test -f conftest.out ; then
+		cf_out=`cat conftest.out | sed -e 's%^Autoconf %%' -e 's%^[^"]*"%%' -e 's%".*%%'`
+		test -n "$cf_out" && cf_cv_ncurses_version="$cf_out"
+		rm -f conftest.out
+	fi
+
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4791 "configure"
+#include "confdefs.h"
+
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <stdio.h>
+int main()
+{
+	FILE *fp = fopen("$cf_tempfile", "w");
+#ifdef NCURSES_VERSION
+# ifdef NCURSES_VERSION_PATCH
+	fprintf(fp, "%s.%d\n", NCURSES_VERSION, NCURSES_VERSION_PATCH);
+# else
+	fprintf(fp, "%s\n", NCURSES_VERSION);
+# endif
+#else
+# ifdef __NCURSES_H
+	fprintf(fp, "old\n");
+# else
+	make an error
+# endif
+#endif
+	${cf_cv_main_return-return}(0);
+}
+EOF
+if { (eval echo configure:4815: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  
+	cf_cv_ncurses_version=`cat $cf_tempfile`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -fr conftest*
+fi
+
+	rm -f $cf_tempfile
+
+fi
+
+echo "$ac_t""$cf_cv_ncurses_version" 1>&6
+test "$cf_cv_ncurses_version" = no || cat >> confdefs.h <<\EOF
+#define NCURSES 1
+EOF
+
+
+
+	
+
+cf_nculib_root=ncursesw
+	# This works, except for the special case where we find gpm, but
+	# ncurses is in a nonstandard location via $LIBS, and we really want
+	# to link gpm.
+cf_ncurses_LIBS=""
+cf_ncurses_SAVE="$LIBS"
+echo $ac_n "checking for Gpm_Open in -lgpm""... $ac_c" 1>&6
+echo "configure:4846: checking for Gpm_Open in -lgpm" >&5
+ac_lib_var=`echo gpm'_'Gpm_Open | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lgpm  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4854 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char Gpm_Open();
+
+int main() {
+Gpm_Open()
+; return 0; }
+EOF
+if { (eval echo configure:4865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  echo $ac_n "checking for initscr in -lgpm""... $ac_c" 1>&6
+echo "configure:4881: checking for initscr in -lgpm" >&5
+ac_lib_var=`echo gpm'_'initscr | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lgpm  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4889 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char initscr();
+
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:4900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="$cf_ncurses_SAVE"
+else
+  echo "$ac_t""no" 1>&6
+cf_ncurses_LIBS="-lgpm"
+fi
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+case $host_os in #(vi
+freebsd*)
+	# This is only necessary if you are linking against an obsolete
+	# version of ncurses (but it should do no harm, since it's static).
+	if test "$cf_nculib_root" = ncurses ; then
+		echo $ac_n "checking for tgoto in -lmytinfo""... $ac_c" 1>&6
+echo "configure:4932: checking for tgoto in -lmytinfo" >&5
+ac_lib_var=`echo mytinfo'_'tgoto | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lmytinfo  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4940 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char tgoto();
+
+int main() {
+tgoto()
+; return 0; }
+EOF
+if { (eval echo configure:4951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cf_ncurses_LIBS="-lmytinfo $cf_ncurses_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	fi
+	;;
+esac
+
+LIBS="$cf_ncurses_LIBS $LIBS"
+
+if ( test -n "$cf_cv_curses_dir" && test "$cf_cv_curses_dir" != "no" )
+then
+	
+if test -n "$cf_cv_curses_dir/lib" ; then
+  for cf_add_libdir in $cf_cv_curses_dir/lib
+  do
+    if test $cf_add_libdir = /usr/lib ; then
+      :
+    elif test -d $cf_add_libdir
+    then
+      cf_have_libdir=no
+      if test -n "$LDFLAGS$LIBS" ; then
+        # a loop is needed to ensure we can add subdirs of existing dirs
+        for cf_test_libdir in $LDFLAGS $LIBS ; do
+          if test ".$cf_test_libdir" = ".-L$cf_add_libdir" ; then
+            cf_have_libdir=yes; break
+          fi
+        done
+      fi
+      if test "$cf_have_libdir" = no ; then
+        test -n "$verbose" && echo "	adding $cf_add_libdir to library-path" 1>&6
+
+echo "${as_me-configure}:4999: testing adding $cf_add_libdir to library-path ..." 1>&5
+
+
+        LDFLAGS="-L$cf_add_libdir $LDFLAGS"
+      fi
+    fi
+  done
+fi
+
+	LIBS="-l$cf_nculib_root $LIBS"
+else
+	
+	eval 'cf_cv_have_lib_'$cf_nculib_root'=no'
+	cf_libdir=""
+	echo $ac_n "checking for initscr""... $ac_c" 1>&6
+echo "configure:5014: checking for initscr" >&5
+if eval "test \"`echo '$''{'ac_cv_func_initscr'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5019 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char initscr(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char initscr();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_initscr) || defined (__stub___initscr)
+choke me
+#else
+initscr();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5042: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_initscr=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_initscr=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'initscr`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  eval 'cf_cv_have_lib_'$cf_nculib_root'=yes'
+else
+  echo "$ac_t""no" 1>&6
+
+		cf_save_LIBS="$LIBS"
+		echo $ac_n "checking for initscr in -l$cf_nculib_root""... $ac_c" 1>&6
+echo "configure:5062: checking for initscr in -l$cf_nculib_root" >&5
+		LIBS="-l$cf_nculib_root $LIBS"
+		cat > conftest.$ac_ext <<EOF
+#line 5065 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:5072: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+			 eval 'cf_cv_have_lib_'$cf_nculib_root'=yes'
+			
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+			cf_search=""
+
+
+test "/usr" != "$prefix" && \
+test -d "/usr" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for lib-directories under /usr"
+	test -d /usr/lib &&          cf_search="$cf_search /usr/lib"
+	test -d /usr/lib/$cf_nculib_root &&       cf_search="$cf_search /usr/lib/$cf_nculib_root"
+	test -d /usr/lib/$cf_nculib_root/lib &&    cf_search="$cf_search /usr/lib/$cf_nculib_root/lib"
+	test -d /usr/$cf_nculib_root/lib &&       cf_search="$cf_search /usr/$cf_nculib_root/lib"
+	test -d /usr/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search /usr/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+test "$prefix" != "NONE" && \
+test -d "$prefix" && \
+ {
+	test -n "$verbose" && echo "	... testing for lib-directories under $prefix"
+	test -d $prefix/lib &&          cf_search="$cf_search $prefix/lib"
+	test -d $prefix/lib/$cf_nculib_root &&       cf_search="$cf_search $prefix/lib/$cf_nculib_root"
+	test -d $prefix/lib/$cf_nculib_root/lib &&    cf_search="$cf_search $prefix/lib/$cf_nculib_root/lib"
+	test -d $prefix/$cf_nculib_root/lib &&       cf_search="$cf_search $prefix/$cf_nculib_root/lib"
+	test -d $prefix/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search $prefix/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+test "/usr/local" != "$prefix" && \
+test -d "/usr/local" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for lib-directories under /usr/local"
+	test -d /usr/local/lib &&          cf_search="$cf_search /usr/local/lib"
+	test -d /usr/local/lib/$cf_nculib_root &&       cf_search="$cf_search /usr/local/lib/$cf_nculib_root"
+	test -d /usr/local/lib/$cf_nculib_root/lib &&    cf_search="$cf_search /usr/local/lib/$cf_nculib_root/lib"
+	test -d /usr/local/$cf_nculib_root/lib &&       cf_search="$cf_search /usr/local/$cf_nculib_root/lib"
+	test -d /usr/local/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search /usr/local/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+test "/opt" != "$prefix" && \
+test -d "/opt" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for lib-directories under /opt"
+	test -d /opt/lib &&          cf_search="$cf_search /opt/lib"
+	test -d /opt/lib/$cf_nculib_root &&       cf_search="$cf_search /opt/lib/$cf_nculib_root"
+	test -d /opt/lib/$cf_nculib_root/lib &&    cf_search="$cf_search /opt/lib/$cf_nculib_root/lib"
+	test -d /opt/$cf_nculib_root/lib &&       cf_search="$cf_search /opt/$cf_nculib_root/lib"
+	test -d /opt/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search /opt/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+test "$HOME" != "$prefix" && \
+test -d "$HOME" && \
+(test $prefix = NONE || test -d $prefix) && {
+	test -n "$verbose" && echo "	... testing for lib-directories under $HOME"
+	test -d $HOME/lib &&          cf_search="$cf_search $HOME/lib"
+	test -d $HOME/lib/$cf_nculib_root &&       cf_search="$cf_search $HOME/lib/$cf_nculib_root"
+	test -d $HOME/lib/$cf_nculib_root/lib &&    cf_search="$cf_search $HOME/lib/$cf_nculib_root/lib"
+	test -d $HOME/$cf_nculib_root/lib &&       cf_search="$cf_search $HOME/$cf_nculib_root/lib"
+	test -d $HOME/$cf_nculib_root/lib/$cf_nculib_root &&    cf_search="$cf_search $HOME/$cf_nculib_root/lib/$cf_nculib_root"
+}
+
+
+			for cf_libdir in $cf_search
+			do
+				echo $ac_n "checking for -l$cf_nculib_root in $cf_libdir""... $ac_c" 1>&6
+echo "configure:5148: checking for -l$cf_nculib_root in $cf_libdir" >&5
+				LIBS="-L$cf_libdir -l$cf_nculib_root $cf_save_LIBS"
+				cat > conftest.$ac_ext <<EOF
+#line 5151 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr()
+; return 0; }
+EOF
+if { (eval echo configure:5158: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+			 		 eval 'cf_cv_have_lib_'$cf_nculib_root'=yes'
+					 break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+					 LIBS="$cf_save_LIBS"
+fi
+rm -f conftest*
+			done
+			
+fi
+rm -f conftest*
+		
+fi
+
+eval 'cf_found_library=$cf_cv_have_lib_'$cf_nculib_root
+
+if test $cf_found_library = no ; then
+	{ echo "configure: error: Cannot link $cf_nculib_root library" 1>&2; exit 1; }
+fi
+
+
+fi
+
+if test -n "$cf_ncurses_LIBS" ; then
+	echo $ac_n "checking if we can link $cf_nculib_root without $cf_ncurses_LIBS""... $ac_c" 1>&6
+echo "configure:5189: checking if we can link $cf_nculib_root without $cf_ncurses_LIBS" >&5
+	cf_ncurses_SAVE="$LIBS"
+	for p in $cf_ncurses_LIBS ; do
+		q=`echo $LIBS | sed -e "s%$p %%" -e "s%$p$%%"`
+		if test "$q" != "$LIBS" ; then
+			LIBS="$q"
+		fi
+	done
+	cat > conftest.$ac_ext <<EOF
+#line 5198 "configure"
+#include "confdefs.h"
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+initscr(); mousemask(0,0); tgoto((char *)0, 0, 0);
+; return 0; }
+EOF
+if { (eval echo configure:5205: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  echo "$ac_t""no" 1>&6
+		 LIBS="$cf_ncurses_SAVE"
+fi
+rm -f conftest*
+fi
+
+
+cf_nculib_ROOT=`echo "HAVE_LIB$cf_nculib_root" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
+
+cat >> confdefs.h <<EOF
+#define $cf_nculib_ROOT 1
+EOF
+
+
+	;;
+pdcurses) #(vi
+	if test "$no_x" = yes; then
+  # Not all programs may use this symbol, but it does not hurt to define it.
+  cat >> confdefs.h <<\EOF
+#define X_DISPLAY_MISSING 1
+EOF
+
+  X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+  if test -n "$x_includes"; then
+    X_CFLAGS="$X_CFLAGS -I$x_includes"
+  fi
+
+  # It would also be nice to do this for all -L options, not just this one.
+  if test -n "$x_libraries"; then
+    X_LIBS="$X_LIBS -L$x_libraries"
+    # For Solaris; some versions of Sun CC require a space after -R and
+    # others require no space.  Words are not sufficient . . . .
+    case "`(uname -sr) 2>/dev/null`" in
+    "SunOS 5"*)
+      echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
+echo "configure:5248: checking whether -R must be followed by a space" >&5
+      ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
+      cat > conftest.$ac_ext <<EOF
+#line 5251 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:5258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_R_nospace=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_R_nospace=no
+fi
+rm -f conftest*
+      if test $ac_R_nospace = yes; then
+	echo "$ac_t""no" 1>&6
+	X_LIBS="$X_LIBS -R$x_libraries"
+      else
+	LIBS="$ac_xsave_LIBS -R $x_libraries"
+	cat > conftest.$ac_ext <<EOF
+#line 5274 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:5281: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_R_space=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_R_space=no
+fi
+rm -f conftest*
+	if test $ac_R_space = yes; then
+	  echo "$ac_t""yes" 1>&6
+	  X_LIBS="$X_LIBS -R $x_libraries"
+	else
+	  echo "$ac_t""neither works" 1>&6
+	fi
+      fi
+      LIBS="$ac_xsave_LIBS"
+    esac
+  fi
+
+  # Check for system-dependent libraries X programs must link with.
+  # Do this before checking for the system-independent R6 libraries
+  # (-lICE), since we may need -lsocket or whatever for X linking.
+
+  if test "$ISC" = yes; then
+    X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+  else
+    # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+    # libraries were built with DECnet support.  And karl@cs.umb.edu says
+    # the Alpha needs dnet_stub (dnet does not exist).
+    echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
+echo "configure:5313: checking for dnet_ntoa in -ldnet" >&5
+ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldnet  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5321 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:5332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+      echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
+echo "configure:5354: checking for dnet_ntoa in -ldnet_stub" >&5
+ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldnet_stub  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5362 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:5373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+    # to get the SysV transport functions.
+    # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4)
+    # needs -lnsl.
+    # The nsl library prevents programs from opening the X display
+    # on Irix 5.2, according to dickey@clark.net.
+    echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:5402: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5407 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5430: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_gethostbyname=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_gethostbyname = no; then
+      echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:5451: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5459 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:5470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # lieder@skyler.mavd.honeywell.com says without -lsocket,
+    # socket/setsockopt and other routines are undefined under SCO ODT
+    # 2.0.  But -lsocket is broken on IRIX 5.2 (and is not necessary
+    # on later versions), says simon@lia.di.epfl.ch: it contains
+    # gethostby* variants that don't use the nameserver (or something).
+    # -lsocket must be given before -lnsl if both are needed.
+    # We assume that if connect needs -lnsl, so does gethostbyname.
+    echo $ac_n "checking for connect""... $ac_c" 1>&6
+echo "configure:5500: checking for connect" >&5
+if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5505 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+connect();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_connect=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_connect=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_connect = no; then
+      echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:5549: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5557 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+connect()
+; return 0; }
+EOF
+if { (eval echo configure:5568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
+    echo $ac_n "checking for remove""... $ac_c" 1>&6
+echo "configure:5592: checking for remove" >&5
+if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5597 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char remove(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char remove();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+remove();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_remove=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_remove=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_remove = no; then
+      echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
+echo "configure:5641: checking for remove in -lposix" >&5
+ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lposix  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5649 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char remove();
+
+int main() {
+remove()
+; return 0; }
+EOF
+if { (eval echo configure:5660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+    echo $ac_n "checking for shmat""... $ac_c" 1>&6
+echo "configure:5684: checking for shmat" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5689 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shmat(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shmat();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+shmat();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shmat=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shmat=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_shmat = no; then
+      echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
+echo "configure:5733: checking for shmat in -lipc" >&5
+ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lipc  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5741 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shmat();
+
+int main() {
+shmat()
+; return 0; }
+EOF
+if { (eval echo configure:5752: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+  fi
+
+  # Check for libraries that X11R6 Xt/Xaw programs need.
+  ac_save_LDFLAGS="$LDFLAGS"
+  test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+  # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+  # check for ICE first), but we must link in the order -lSM -lICE or
+  # we get undefined symbols.  So assume we have SM if we have ICE.
+  # These have to be linked with before -lX11, unlike the other
+  # libraries we check for below, so use a different variable.
+  #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+  echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
+echo "configure:5785: checking for IceConnectionNumber in -lICE" >&5
+ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5793 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char IceConnectionNumber();
+
+int main() {
+IceConnectionNumber()
+; return 0; }
+EOF
+if { (eval echo configure:5804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  LDFLAGS="$ac_save_LDFLAGS"
+
+fi
+
+
+
+
+
+# SYSTEM_NAME=`echo "$cf_cv_system_name"|tr ' ' -`
+
+cf_have_X_LIBS=no
+
+LDFLAGS="$X_LIBS $LDFLAGS"
+
+test -n "$verbose" && echo "	checking additions to CFLAGS" 1>&6
+
+echo "${as_me-configure}:5840: testing checking additions to CFLAGS ..." 1>&5
+
+
+cf_check_cflags="$CFLAGS"
+cf_check_cppflags="$CPPFLAGS"
+
+cf_fix_cppflags=no
+cf_new_cflags=
+cf_new_cppflags=
+cf_new_extra_cppflags=
+
+for cf_add_cflags in $X_CFLAGS
+do
+case $cf_fix_cppflags in
+no)
+	case $cf_add_cflags in #(vi
+	-undef|-nostdinc*|-I*|-D*|-U*|-E|-P|-C) #(vi
+		case $cf_add_cflags in
+		-D*)
+			cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^-D[^=]*='\''\"[^"]*//'`
+
+			test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+			&& test -z "${cf_tst_cflags}" \
+			&& cf_fix_cppflags=yes
+
+			if test $cf_fix_cppflags = yes ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			elif test "${cf_tst_cflags}" = "\"'" ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			fi
+			;;
+		esac
+		case "$CPPFLAGS" in
+		*$cf_add_cflags) #(vi
+			;;
+		*) #(vi
+			cf_new_cppflags="$cf_new_cppflags $cf_add_cflags"
+			;;
+		esac
+		;;
+	*)
+		cf_new_cflags="$cf_new_cflags $cf_add_cflags"
+		;;
+	esac
+	;;
+yes)
+	cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+
+	cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^[^"]*"'\''//'`
+
+	test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+	&& test -z "${cf_tst_cflags}" \
+	&& cf_fix_cppflags=no
+	;;
+esac
+done
+
+if test -n "$cf_new_cflags" ; then
+	test -n "$verbose" && echo "	add to \$CFLAGS $cf_new_cflags" 1>&6
+
+echo "${as_me-configure}:5902: testing add to \$CFLAGS $cf_new_cflags ..." 1>&5
+
+
+	CFLAGS="$CFLAGS $cf_new_cflags"
+fi
+
+if test -n "$cf_new_cppflags" ; then
+	test -n "$verbose" && echo "	add to \$CPPFLAGS $cf_new_cppflags" 1>&6
+
+echo "${as_me-configure}:5911: testing add to \$CPPFLAGS $cf_new_cppflags ..." 1>&5
+
+
+	CPPFLAGS="$cf_new_cppflags $CPPFLAGS"
+fi
+
+if test -n "$cf_new_extra_cppflags" ; then
+	test -n "$verbose" && echo "	add to \$EXTRA_CPPFLAGS $cf_new_extra_cppflags" 1>&6
+
+echo "${as_me-configure}:5920: testing add to \$EXTRA_CPPFLAGS $cf_new_extra_cppflags ..." 1>&5
+
+
+	EXTRA_CPPFLAGS="$cf_new_extra_cppflags $EXTRA_CPPFLAGS"
+fi
+
+
+
+
+if test "$cf_check_cflags" != "$CFLAGS" ; then
+cat > conftest.$ac_ext <<EOF
+#line 5931 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+printf("Hello world");
+; return 0; }
+EOF
+if { (eval echo configure:5938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  test -n "$verbose" && echo "	test-compile failed.  Undoing change to \$CFLAGS" 1>&6
+
+echo "${as_me-configure}:5946: testing test-compile failed.  Undoing change to \$CFLAGS ..." 1>&5
+
+
+	 if test "$cf_check_cppflags" != "$CPPFLAGS" ; then
+		 test -n "$verbose" && echo "	but keeping change to \$CPPFLAGS" 1>&6
+
+echo "${as_me-configure}:5952: testing but keeping change to \$CPPFLAGS ..." 1>&5
+
+
+	 fi
+	 CFLAGS="$cf_check_flags"
+fi
+rm -f conftest*
+fi
+
+
+echo $ac_n "checking for XOpenDisplay""... $ac_c" 1>&6
+echo "configure:5963: checking for XOpenDisplay" >&5
+if eval "test \"`echo '$''{'ac_cv_func_XOpenDisplay'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5968 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char XOpenDisplay(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char XOpenDisplay();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_XOpenDisplay) || defined (__stub___XOpenDisplay)
+choke me
+#else
+XOpenDisplay();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_XOpenDisplay=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_XOpenDisplay=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'XOpenDisplay`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+
+echo $ac_n "checking for XOpenDisplay in -lX11""... $ac_c" 1>&6
+echo "configure:6010: checking for XOpenDisplay in -lX11" >&5
+ac_lib_var=`echo X11'_'XOpenDisplay | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lX11 $X_PRE_LIBS $LIBS $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6018 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char XOpenDisplay();
+
+int main() {
+XOpenDisplay()
+; return 0; }
+EOF
+if { (eval echo configure:6029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="-lX11 $LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+echo $ac_n "checking for XtAppInitialize""... $ac_c" 1>&6
+echo "configure:6053: checking for XtAppInitialize" >&5
+if eval "test \"`echo '$''{'ac_cv_func_XtAppInitialize'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6058 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char XtAppInitialize(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char XtAppInitialize();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_XtAppInitialize) || defined (__stub___XtAppInitialize)
+choke me
+#else
+XtAppInitialize();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6081: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_XtAppInitialize=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_XtAppInitialize=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'XtAppInitialize`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+
+echo $ac_n "checking for XtAppInitialize in -lXt""... $ac_c" 1>&6
+echo "configure:6100: checking for XtAppInitialize in -lXt" >&5
+ac_lib_var=`echo Xt'_'XtAppInitialize | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lXt $X_PRE_LIBS $LIBS $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6108 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char XtAppInitialize();
+
+int main() {
+XtAppInitialize()
+; return 0; }
+EOF
+if { (eval echo configure:6119: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_LIBXT 1
+EOF
+
+	 cf_have_X_LIBS=Xt
+	 LIBS="-lXt $X_PRE_LIBS $LIBS $X_EXTRA_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+if test $cf_have_X_LIBS = no ; then
+	echo "configure: warning: Unable to successfully link X Toolkit library (-lXt) with
+test program.  You will have to check and add the proper libraries by hand
+to makefile." 1>&2
+fi
+
+
+cf_x_athena=${cf_x_athena-Xaw}
+
+echo $ac_n "checking if you want to link with Xaw 3d library""... $ac_c" 1>&6
+echo "configure:6157: checking if you want to link with Xaw 3d library" >&5
+withval=
+
+# Check whether --with-Xaw3d or --without-Xaw3d was given.
+if test "${with_Xaw3d+set}" = set; then
+  withval="$with_Xaw3d"
+  :
+fi
+
+if test "$withval" = yes ; then
+	cf_x_athena=Xaw3d
+	echo "$ac_t""yes" 1>&6
+else
+	echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking if you want to link with neXT Athena library""... $ac_c" 1>&6
+echo "configure:6174: checking if you want to link with neXT Athena library" >&5
+withval=
+
+# Check whether --with-neXtaw or --without-neXtaw was given.
+if test "${with_neXtaw+set}" = set; then
+  withval="$with_neXtaw"
+  :
+fi
+
+if test "$withval" = yes ; then
+	cf_x_athena=neXtaw
+	echo "$ac_t""yes" 1>&6
+else
+	echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking if you want to link with Athena-Plus library""... $ac_c" 1>&6
+echo "configure:6191: checking if you want to link with Athena-Plus library" >&5
+withval=
+
+# Check whether --with-XawPlus or --without-XawPlus was given.
+if test "${with_XawPlus+set}" = set; then
+  withval="$with_XawPlus"
+  :
+fi
+
+if test "$withval" = yes ; then
+	cf_x_athena=XawPlus
+	echo "$ac_t""yes" 1>&6
+else
+	echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for XextCreateExtension in -lXext""... $ac_c" 1>&6
+echo "configure:6208: checking for XextCreateExtension in -lXext" >&5
+ac_lib_var=`echo Xext'_'XextCreateExtension | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lXext  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6216 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char XextCreateExtension();
+
+int main() {
+XextCreateExtension()
+; return 0; }
+EOF
+if { (eval echo configure:6227: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="-lXext $LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+cf_x_athena_lib=""
+
+
+cf_x_athena_root=$cf_x_athena
+cf_x_athena_include=""
+
+for cf_path in default \
+	/usr/contrib/X11R6 \
+	/usr/contrib/X11R5 \
+	/usr/lib/X11R5 \
+	/usr/local
+do
+	if test -z "$cf_x_athena_include" ; then
+		cf_save="$CPPFLAGS"
+		cf_test=X11/$cf_x_athena_root/SimpleMenu.h
+		if test $cf_path != default ; then
+			CPPFLAGS="-I$cf_path/include $cf_save"
+			echo $ac_n "checking for $cf_test in $cf_path""... $ac_c" 1>&6
+echo "configure:6266: checking for $cf_test in $cf_path" >&5
+		else
+			echo $ac_n "checking for $cf_test""... $ac_c" 1>&6
+echo "configure:6269: checking for $cf_test" >&5
+		fi
+		cat > conftest.$ac_ext <<EOF
+#line 6272 "configure"
+#include "confdefs.h"
+
+#include <X11/Intrinsic.h>
+#include <$cf_test>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:6281: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_result=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_result=no
+fi
+rm -f conftest*
+		echo "$ac_t""$cf_result" 1>&6
+		if test "$cf_result" = yes ; then
+			cf_x_athena_include=$cf_path
+			break
+		else
+			CPPFLAGS="$cf_save"
+		fi
+	fi
+done
+
+if test -z "$cf_x_athena_include" ; then
+	echo "configure: warning: Unable to successfully find Athena header files with test program" 1>&2
+elif test "$cf_x_athena_include" != default ; then
+	CPPFLAGS="$CPPFLAGS -I$cf_x_athena_include"
+fi
+
+
+cf_x_athena_root=$cf_x_athena
+cf_x_athena_lib=""
+
+for cf_path in default \
+	/usr/contrib/X11R6 \
+	/usr/contrib/X11R5 \
+	/usr/lib/X11R5 \
+	/usr/local
+do
+	for cf_lib in \
+		"-l$cf_x_athena_root -lXmu" \
+		"-l$cf_x_athena_root -lXpm -lXmu" \
+		"-l${cf_x_athena_root}_s -lXmu_s"
+	do
+		if test -z "$cf_x_athena_lib" ; then
+			cf_save="$LIBS"
+			cf_test=XawSimpleMenuAddGlobalActions
+			if test $cf_path != default ; then
+				LIBS="-L$cf_path/lib $cf_lib $LIBS"
+				echo $ac_n "checking for $cf_lib in $cf_path""... $ac_c" 1>&6
+echo "configure:6328: checking for $cf_lib in $cf_path" >&5
+			else
+				LIBS="$cf_lib $LIBS"
+				echo $ac_n "checking for $cf_test in $cf_lib""... $ac_c" 1>&6
+echo "configure:6332: checking for $cf_test in $cf_lib" >&5
+			fi
+			cat > conftest.$ac_ext <<EOF
+#line 6335 "configure"
+#include "confdefs.h"
+
+int main() {
+$cf_test()
+; return 0; }
+EOF
+if { (eval echo configure:6342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_result=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_result=no
+fi
+rm -f conftest*
+			echo "$ac_t""$cf_result" 1>&6
+			if test "$cf_result" = yes ; then
+				cf_x_athena_lib="$cf_lib"
+				break
+			fi
+			LIBS="$cf_save"
+		fi
+	done
+done
+
+if test -z "$cf_x_athena_lib" ; then
+	{ echo "configure: error: Unable to successfully link Athena library (-l$cf_x_athena_root) with test program" 1>&2; exit 1; }
+fi
+
+
+cf_x_athena_LIBS=`echo "HAVE_LIB_$cf_x_athena" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
+
+cat >> confdefs.h <<EOF
+#define $cf_x_athena_LIBS 1
+EOF
+
+
+
+
+
+
+for ac_prog in xcurses-config
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:6383: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XCURSES_CONFIG'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$XCURSES_CONFIG" in
+  /*)
+  ac_cv_path_XCURSES_CONFIG="$XCURSES_CONFIG" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_XCURSES_CONFIG="$XCURSES_CONFIG" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_XCURSES_CONFIG="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+XCURSES_CONFIG="$ac_cv_path_XCURSES_CONFIG"
+if test -n "$XCURSES_CONFIG"; then
+  echo "$ac_t""$XCURSES_CONFIG" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$XCURSES_CONFIG" && break
+done
+test -n "$XCURSES_CONFIG" || XCURSES_CONFIG="none"
+
+
+if test "$XCURSES_CONFIG" != none ; then
+
+CPPFLAGS="`$XCURSES_CONFIG --cflags` $CPPFLAGS"
+LIBS="`$XCURSES_CONFIG --libs` $LIBS"
+
+cf_cv_lib_XCurses=yes
+
+else
+
+LDFLAGS="$LDFLAGS $X_LIBS"
+
+test -n "$verbose" && echo "	checking additions to CFLAGS" 1>&6
+
+echo "${as_me-configure}:6433: testing checking additions to CFLAGS ..." 1>&5
+
+
+cf_check_cflags="$CFLAGS"
+cf_check_cppflags="$CPPFLAGS"
+
+cf_fix_cppflags=no
+cf_new_cflags=
+cf_new_cppflags=
+cf_new_extra_cppflags=
+
+for cf_add_cflags in $X_CFLAGS
+do
+case $cf_fix_cppflags in
+no)
+	case $cf_add_cflags in #(vi
+	-undef|-nostdinc*|-I*|-D*|-U*|-E|-P|-C) #(vi
+		case $cf_add_cflags in
+		-D*)
+			cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^-D[^=]*='\''\"[^"]*//'`
+
+			test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+			&& test -z "${cf_tst_cflags}" \
+			&& cf_fix_cppflags=yes
+
+			if test $cf_fix_cppflags = yes ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			elif test "${cf_tst_cflags}" = "\"'" ; then
+				cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+				continue
+			fi
+			;;
+		esac
+		case "$CPPFLAGS" in
+		*$cf_add_cflags) #(vi
+			;;
+		*) #(vi
+			cf_new_cppflags="$cf_new_cppflags $cf_add_cflags"
+			;;
+		esac
+		;;
+	*)
+		cf_new_cflags="$cf_new_cflags $cf_add_cflags"
+		;;
+	esac
+	;;
+yes)
+	cf_new_extra_cppflags="$cf_new_extra_cppflags $cf_add_cflags"
+
+	cf_tst_cflags=`echo ${cf_add_cflags} |sed -e 's/^[^"]*"'\''//'`
+
+	test "${cf_add_cflags}" != "${cf_tst_cflags}" \
+	&& test -z "${cf_tst_cflags}" \
+	&& cf_fix_cppflags=no
+	;;
+esac
+done
+
+if test -n "$cf_new_cflags" ; then
+	test -n "$verbose" && echo "	add to \$CFLAGS $cf_new_cflags" 1>&6
+
+echo "${as_me-configure}:6495: testing add to \$CFLAGS $cf_new_cflags ..." 1>&5
+
+
+	CFLAGS="$CFLAGS $cf_new_cflags"
+fi
+
+if test -n "$cf_new_cppflags" ; then
+	test -n "$verbose" && echo "	add to \$CPPFLAGS $cf_new_cppflags" 1>&6
+
+echo "${as_me-configure}:6504: testing add to \$CPPFLAGS $cf_new_cppflags ..." 1>&5
+
+
+	CPPFLAGS="$cf_new_cppflags $CPPFLAGS"
+fi
+
+if test -n "$cf_new_extra_cppflags" ; then
+	test -n "$verbose" && echo "	add to \$EXTRA_CPPFLAGS $cf_new_extra_cppflags" 1>&6
+
+echo "${as_me-configure}:6513: testing add to \$EXTRA_CPPFLAGS $cf_new_extra_cppflags ..." 1>&5
+
+
+	EXTRA_CPPFLAGS="$cf_new_extra_cppflags $EXTRA_CPPFLAGS"
+fi
+
+
+
+
+if test "$cf_check_cflags" != "$CFLAGS" ; then
+cat > conftest.$ac_ext <<EOF
+#line 6524 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int main() {
+printf("Hello world");
+; return 0; }
+EOF
+if { (eval echo configure:6531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  test -n "$verbose" && echo "	test-compile failed.  Undoing change to \$CFLAGS" 1>&6
+
+echo "${as_me-configure}:6539: testing test-compile failed.  Undoing change to \$CFLAGS ..." 1>&5
+
+
+	 if test "$cf_check_cppflags" != "$CPPFLAGS" ; then
+		 test -n "$verbose" && echo "	but keeping change to \$CPPFLAGS" 1>&6
+
+echo "${as_me-configure}:6545: testing but keeping change to \$CPPFLAGS ..." 1>&5
+
+
+	 fi
+	 CFLAGS="$cf_check_flags"
+fi
+rm -f conftest*
+fi
+
+echo $ac_n "checking for XOpenDisplay in -lX11""... $ac_c" 1>&6
+echo "configure:6555: checking for XOpenDisplay in -lX11" >&5
+ac_lib_var=`echo X11'_'XOpenDisplay | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lX11 $X_PRE_LIBS $LIBS $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6563 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char XOpenDisplay();
+
+int main() {
+XOpenDisplay()
+; return 0; }
+EOF
+if { (eval echo configure:6574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="-lX11 $LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for XCurses library""... $ac_c" 1>&6
+echo "configure:6595: checking for XCurses library" >&5
+if eval "test \"`echo '$''{'cf_cv_lib_XCurses'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+LIBS="-lXCurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6602 "configure"
+#include "confdefs.h"
+
+#include <xcurses.h>
+char *XCursesProgramName = "test";
+
+int main() {
+XCursesExit();
+; return 0; }
+EOF
+if { (eval echo configure:6612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_lib_XCurses=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_lib_XCurses=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$cf_cv_lib_XCurses" 1>&6
+
+fi
+
+if test $cf_cv_lib_XCurses = yes ; then
+	cat >> confdefs.h <<\EOF
+#define UNIX 1
+EOF
+
+	cat >> confdefs.h <<\EOF
+#define XCURSES 1
+EOF
+
+	cat >> confdefs.h <<\EOF
+#define HAVE_XCURSES 1
+EOF
+
+else
+	{ echo "configure: error: Cannot link with XCurses" 1>&2; exit 1; }
+fi
+
+	;;
+esac
+
+
+
+case $cf_cv_screen in #(vi
+pdcurses) #(vi
+	;;
+*)
+	# look for curses-related libraries
+	echo $ac_n "checking for new_panel in -lpanel$cf_cv_libtype""... $ac_c" 1>&6
+echo "configure:6657: checking for new_panel in -lpanel$cf_cv_libtype" >&5
+ac_lib_var=`echo panel$cf_cv_libtype'_'new_panel | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lpanel$cf_cv_libtype  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6665 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char new_panel();
+
+int main() {
+new_panel()
+; return 0; }
+EOF
+if { (eval echo configure:6676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo panel$cf_cv_libtype | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lpanel$cf_cv_libtype $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	echo $ac_n "checking for menu_driver in -lmenu$cf_cv_libtype""... $ac_c" 1>&6
+echo "configure:6704: checking for menu_driver in -lmenu$cf_cv_libtype" >&5
+ac_lib_var=`echo menu$cf_cv_libtype'_'menu_driver | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lmenu$cf_cv_libtype  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6712 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char menu_driver();
+
+int main() {
+menu_driver()
+; return 0; }
+EOF
+if { (eval echo configure:6723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo menu$cf_cv_libtype | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lmenu$cf_cv_libtype $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	echo $ac_n "checking for form_driver in -lform$cf_cv_libtype""... $ac_c" 1>&6
+echo "configure:6751: checking for form_driver in -lform$cf_cv_libtype" >&5
+ac_lib_var=`echo form$cf_cv_libtype'_'form_driver | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lform$cf_cv_libtype  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6759 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char form_driver();
+
+int main() {
+form_driver()
+; return 0; }
+EOF
+if { (eval echo configure:6770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo form$cf_cv_libtype | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lform$cf_cv_libtype $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+	# look for curses-related headers
+	for ac_hdr in \
+		nc_alloc.h \
+		nomacros.h \
+		form.h \
+		menu.h \
+		panel.h \
+		
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:6809: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6814 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6819: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+	;;
+esac
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:6849: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6854 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:6871: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_type_signal=void
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:6891: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6896 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6904: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 6921 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 6939 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 6960 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:6971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:6995: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 7000 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:7009: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_time=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+  cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+for ac_hdr in \
+getopt.h \
+locale.h \
+stdarg.h \
+sys/ioctl.h \
+sys/select.h \
+sys/time.h \
+termios.h \
+unistd.h \
+
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:7042: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 7047 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:7052: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+for ac_func in \
+gettimeofday \
+mblen \
+mbrlen \
+mbrtowc \
+mbsrtowcs \
+mbstowcs \
+mbtowc \
+strdup \
+wcsrtombs \
+wcstombs \
+
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:7093: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 7098 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:7121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+echo $ac_n "checking if we must define _XOPEN_SOURCE_EXTENDED""... $ac_c" 1>&6
+echo "configure:7148: checking if we must define _XOPEN_SOURCE_EXTENDED" >&5
+if eval "test \"`echo '$''{'cf_cv_need_xopen_extension'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cat > conftest.$ac_ext <<EOF
+#line 7154 "configure"
+#include "confdefs.h"
+
+#include <stdlib.h>
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+
+	long x = winnstr(stdscr, "", 0);
+	int x1, y1;
+	getbegyx(stdscr, y1, x1)
+; return 0; }
+EOF
+if { (eval echo configure:7166: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_need_xopen_extension=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cat > conftest.$ac_ext <<EOF
+#line 7174 "configure"
+#include "confdefs.h"
+
+#define _XOPEN_SOURCE_EXTENDED
+#include <stdlib.h>
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+
+	long x = winnstr(stdscr, "", 0);
+	int x1, y1;
+	getbegyx(stdscr, y1, x1)
+; return 0; }
+EOF
+if { (eval echo configure:7187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_need_xopen_extension=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_need_xopen_extension=unknown
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$cf_cv_need_xopen_extension" 1>&6
+test $cf_cv_need_xopen_extension = yes && CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED"
+
+
+echo $ac_n "checking for term.h""... $ac_c" 1>&6
+echo "configure:7206: checking for term.h" >&5
+if eval "test \"`echo '$''{'cf_cv_term_header'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+
+# If we found <ncurses/curses.h>, look for <ncurses/term.h>, but always look
+# for <term.h> if we do not find the variant.
+for cf_header in \
+	`echo ${cf_cv_ncurses_header-curses.h} | sed -e 's%/.*%/%'`term.h \
+	term.h
+do
+	cat > conftest.$ac_ext <<EOF
+#line 7219 "configure"
+#include "confdefs.h"
+
+#include <${cf_cv_ncurses_header-curses.h}>
+#include <${cf_header}>
+int main() {
+WINDOW *x
+; return 0; }
+EOF
+if { (eval echo configure:7228: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_term_header=$cf_header
+	 break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_term_header=no
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$cf_cv_term_header" 1>&6
+
+case $cf_cv_term_header in #(vi
+term.h) #(vi
+	cat >> confdefs.h <<\EOF
+#define HAVE_TERM_H 1
+EOF
+
+	;;
+ncurses/term.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSES_TERM_H 1
+EOF
+
+	;;
+ncursesw/term.h)
+	cat >> confdefs.h <<\EOF
+#define HAVE_NCURSESW_TERM_H 1
+EOF
+
+	;;
+esac
+
+
+
+
+for cf_func in \
+chgat \
+color_set \
+filter \
+getbegx \
+getcurx \
+getmaxx \
+getnstr \
+getparx \
+getwin \
+mvvline \
+mvwvline \
+napms \
+putwin \
+resize_term \
+resizeterm \
+ripoffline \
+setupterm \
+slk_color \
+slk_init \
+termattrs \
+tgetent \
+tigetnum \
+tigetstr \
+typeahead \
+use_default_colors \
+vsscanf \
+wchgat \
+winsstr \
+wresize \
+
+do
+	
+cf_tr_func=`echo "$cf_func" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
+
+	echo $ac_n "checking for ${cf_func}""... $ac_c" 1>&6
+echo "configure:7305: checking for ${cf_func}" >&5
+	
+echo "${as_me-configure}:7307: testing ${cf_func} ..." 1>&5
+
+	if eval "test \"`echo '$''{'cf_cv_func_$cf_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+		eval cf_result='$ac_cv_func_'$cf_func
+		if test ".$cf_result" != ".no"; then
+			cat > conftest.$ac_ext <<EOF
+#line 7316 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_XCURSES
+#include <xcurses.h>
+char * XCursesProgramName = "test";
+#else
+#include <${cf_cv_ncurses_header-curses.h}>
+#if defined(NCURSES_VERSION) && defined(HAVE_NCURSESW_TERM_H)
+#include <ncursesw/term.h>
+#else
+#if defined(NCURSES_VERSION) && defined(HAVE_NCURSES_TERM_H)
+#include <ncurses/term.h>
+#else
+#ifdef HAVE_TERM_H
+#include <term.h>
+#endif
+#endif
+#endif
+#endif
+int main() {
+
+#ifndef ${cf_func}
+long foo = (long)(&${cf_func});
+${cf_cv_main_return-return}(foo == 0);
+#endif
+			
+; return 0; }
+EOF
+if { (eval echo configure:7345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_result=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_result=no
+fi
+rm -f conftest*
+		fi
+		eval 'cf_cv_func_'$cf_func'=$cf_result'
+	
+fi
+
+	# use the computed/retrieved cache-value:
+	eval 'cf_result=$cf_cv_func_'$cf_func
+	echo "$ac_t""$cf_result" 1>&6
+	if test $cf_result != no; then
+		cat >> confdefs.h <<EOF
+#define HAVE_${cf_tr_func} 1
+EOF
+
+	fi
+done
+
+
+echo $ac_n "checking for ncurses extended functions""... $ac_c" 1>&6
+echo "configure:7373: checking for ncurses extended functions" >&5
+if eval "test \"`echo '$''{'cf_cv_ncurses_ext_funcs'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cat > conftest.$ac_ext <<EOF
+#line 7379 "configure"
+#include "confdefs.h"
+
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+
+	(void) assume_default_colors (0, 0);
+	(void) curses_version ();
+	(void) define_key (0, 0);
+	(void) is_term_resized (0, 0);
+	(void) key_defined (0);
+	(void) keybound (0, 0);
+	(void) keyok (0, 0);
+	(void) resize_term (0, 0);
+	(void) resizeterm (0, 0);
+	(void) use_default_colors ();
+	(void) use_extended_names (0);
+	(void) wresize (0, 0, 0);
+; return 0; }
+EOF
+if { (eval echo configure:7399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_ncurses_ext_funcs=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_ncurses_ext_funcs=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$cf_cv_ncurses_ext_funcs" 1>&6
+test "$cf_cv_ncurses_ext_funcs" != no && cat >> confdefs.h <<\EOF
+#define NCURSES_EXT_FUNCS 1
+EOF
+
+
+echo $ac_n "checking for wide-character functions""... $ac_c" 1>&6
+echo "configure:7419: checking for wide-character functions" >&5
+if eval "test \"`echo '$''{'cf_cv_widechar_funcs'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cat > conftest.$ac_ext <<EOF
+#line 7425 "configure"
+#include "confdefs.h"
+
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+
+	static wchar_t src_wchar[2];
+	static cchar_t dst_cchar;
+	setcchar(&dst_cchar, src_wchar, A_NORMAL, 0, (void *) 0);
+	
+; return 0; }
+EOF
+if { (eval echo configure:7437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_widechar_funcs=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_widechar_funcs=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$cf_cv_widechar_funcs" 1>&6
+if test "$cf_cv_widechar_funcs" != no ; then
+	cat >> confdefs.h <<\EOF
+#define USE_WIDEC_SUPPORT 1
+EOF
+
+else
+	cat >> confdefs.h <<\EOF
+#define USE_WIDEC_SUPPORT 0
+EOF
+
+fi
+
+
+echo $ac_n "checking if sys/time.h works with sys/select.h""... $ac_c" 1>&6
+echo "configure:7465: checking if sys/time.h works with sys/select.h" >&5
+if eval "test \"`echo '$''{'cf_cv_sys_time_select'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cat > conftest.$ac_ext <<EOF
+#line 7471 "configure"
+#include "confdefs.h"
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:7486: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_cv_sys_time_select=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_cv_sys_time_select=no
+fi
+rm -f conftest*
+     
+fi
+
+echo "$ac_t""$cf_cv_sys_time_select" 1>&6
+test "$cf_cv_sys_time_select" = yes && cat >> confdefs.h <<\EOF
+#define HAVE_SYS_TIME_SELECT 1
+EOF
+
+
+
+echo $ac_n "checking for function curses_version""... $ac_c" 1>&6
+echo "configure:7507: checking for function curses_version" >&5
+if eval "test \"`echo '$''{'cf_cv_func_curses_version'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+if test "$cross_compiling" = yes; then
+  cf_cv_func_curses_version=unknown
+else
+  cat > conftest.$ac_ext <<EOF
+#line 7516 "configure"
+#include "confdefs.h"
+
+#include <${cf_cv_ncurses_header-curses.h}>
+int main()
+{
+	char temp[1024];
+	sprintf(temp, "%s\n", curses_version());
+	${cf_cv_main_return-return}(0);
+}
+
+EOF
+if { (eval echo configure:7528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  cf_cv_func_curses_version=yes
+
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  cf_cv_func_curses_version=no
+
+fi
+rm -fr conftest*
+fi
+
+rm -f core
+fi
+
+echo "$ac_t""$cf_cv_func_curses_version" 1>&6
+test "$cf_cv_func_curses_version" = yes && cat >> confdefs.h <<\EOF
+#define HAVE_CURSES_VERSION 1
+EOF
+
+
+
+echo $ac_n "checking for alternate character set array""... $ac_c" 1>&6
+echo "configure:7553: checking for alternate character set array" >&5
+if eval "test \"`echo '$''{'cf_cv_curses_acs_map'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cf_cv_curses_acs_map=unknown
+for name in acs_map _acs_map __acs_map _nc_acs_map
+do
+cat > conftest.$ac_ext <<EOF
+#line 7562 "configure"
+#include "confdefs.h"
+
+#include <${cf_cv_ncurses_header-curses.h}>
+
+int main() {
+
+$name['k'] = ACS_PLUS
+
+; return 0; }
+EOF
+if { (eval echo configure:7573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_curses_acs_map=$name; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$cf_cv_curses_acs_map" 1>&6
+
+test "$cf_cv_curses_acs_map" != unknown && cat >> confdefs.h <<EOF
+#define CURSES_ACS_ARRAY $cf_cv_curses_acs_map
+EOF
+
+
+
+echo $ac_n "checking for wide alternate character set array""... $ac_c" 1>&6
+echo "configure:7594: checking for wide alternate character set array" >&5
+if eval "test \"`echo '$''{'cf_cv_curses_wacs_map'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cf_cv_curses_wacs_map=unknown
+	for name in wacs_map _wacs_map __wacs_map _nc_wacs
+	do
+	cat > conftest.$ac_ext <<EOF
+#line 7603 "configure"
+#include "confdefs.h"
+
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+$name['k'] = *WACS_PLUS
+; return 0; }
+EOF
+if { (eval echo configure:7614: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  cf_cv_curses_wacs_map=$name
+	 break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+	done
+fi
+
+echo "$ac_t""$cf_cv_curses_wacs_map" 1>&6
+
+
+echo $ac_n "checking for type attr_t in ${cf_cv_ncurses_header-curses.h}""... $ac_c" 1>&6
+echo "configure:7630: checking for type attr_t in ${cf_cv_ncurses_header-curses.h}" >&5
+cat > conftest.$ac_ext <<EOF
+#line 7632 "configure"
+#include "confdefs.h"
+
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+
+attr_t foo
+
+; return 0; }
+EOF
+if { (eval echo configure:7645: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_result=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_result=no
+fi
+rm -f conftest*
+echo "$ac_t""$cf_result" 1>&6
+if test $cf_result = yes ; then
+	
+cf_result=`echo "have_type_attr_t" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
+
+	cat >> confdefs.h <<EOF
+#define $cf_result 1
+EOF
+
+else
+	cat >> confdefs.h <<EOF
+#define attr_t long
+EOF
+
+fi
+
+
+echo $ac_n "checking for type mbstate_t in ${cf_cv_ncurses_header-curses.h}""... $ac_c" 1>&6
+echo "configure:7673: checking for type mbstate_t in ${cf_cv_ncurses_header-curses.h}" >&5
+cat > conftest.$ac_ext <<EOF
+#line 7675 "configure"
+#include "confdefs.h"
+
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+#include <${cf_cv_ncurses_header-curses.h}>
+int main() {
+
+mbstate_t foo
+
+; return 0; }
+EOF
+if { (eval echo configure:7688: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  cf_result=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cf_result=no
+fi
+rm -f conftest*
+echo "$ac_t""$cf_result" 1>&6
+if test $cf_result = yes ; then
+	
+cf_result=`echo "have_type_mbstate_t" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
+
+	cat >> confdefs.h <<EOF
+#define $cf_result 1
+EOF
+
+else
+	cat >> confdefs.h <<EOF
+#define mbstate_t long
+EOF
+
+fi
+
+
+TEST_ARGS="$LIBS"
+LIBS=
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13.20030927"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile ncurses_cfg.h:ncurses_tst.hin" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@AWK@%$AWK%g
+s%@CC_G_OPT@%$CC_G_OPT%g
+s%@CC_SHARED_OPTS@%$CC_SHARED_OPTS%g
+s%@DFT_DEP_SUFFIX@%$DFT_DEP_SUFFIX%g
+s%@DFT_OBJ_SUBDIR@%$DFT_OBJ_SUBDIR%g
+s%@DFT_UPR_MODEL@%$DFT_UPR_MODEL%g
+s%@LD@%$LD%g
+s%@LDFLAGS_SHARED@%$LDFLAGS_SHARED%g
+s%@LDFLAGS_STATIC@%$LDFLAGS_STATIC%g
+s%@LD_MODEL@%$LD_MODEL%g
+s%@LD_SHARED_OPTS@%$LD_SHARED_OPTS%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@LIB_CLEAN@%$LIB_CLEAN%g
+s%@LIB_COMPILE@%$LIB_COMPILE%g
+s%@LIB_LINK@%$LIB_LINK%g
+s%@LINK_TESTS@%$LINK_TESTS%g
+s%@LINT@%$LINT%g
+s%@LINT_OPTS@%$LINT_OPTS%g
+s%@LOCAL_LDFLAGS@%$LOCAL_LDFLAGS%g
+s%@MATH_LIB@%$MATH_LIB%g
+s%@PTHREAD@%$PTHREAD%g
+s%@TEST_ARGS@%$TEST_ARGS%g
+s%@TEST_DEPS@%$TEST_DEPS%g
+s%@TEST_LIBS@%$TEST_LIBS%g
+s%@TINFO_ARGS@%$TINFO_ARGS%g
+s%@cf_cv_abi_version@%$cf_cv_abi_version%g
+s%@cf_cv_rel_version@%$cf_cv_rel_version%g
+s%@EXEEXT@%$EXEEXT%g
+s%@OBJEXT@%$OBJEXT%g
+s%@EXTRA_CPPFLAGS@%$EXTRA_CPPFLAGS%g
+s%@ECHO_LT@%$ECHO_LT%g
+s%@ECHO_LD@%$ECHO_LD%g
+s%@RULE_CC@%$RULE_CC%g
+s%@SHOW_CC@%$SHOW_CC%g
+s%@ECHO_CC@%$ECHO_CC%g
+s%@EXTRA_CFLAGS@%$EXTRA_CFLAGS%g
+s%@X_CFLAGS@%$X_CFLAGS%g
+s%@X_PRE_LIBS@%$X_PRE_LIBS%g
+s%@X_LIBS@%$X_LIBS%g
+s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g
+s%@XCURSES_CONFIG@%$XCURSES_CONFIG%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="ncurses_cfg.h:ncurses_tst.hin"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+
+# Transform confdefs.h into a list of #define's.  We won't use it as a sed
+# script, but as data to insert where we see @DEFS@.  We expect AC_SAVE_DEFS to
+# be either 'cat' or 'sort'.
+cat confdefs.h >conftest.vals
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+echo '  rm -f conftest.frag' >> $CONFIG_STATUS
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write chunks of a limited-size here document to conftest.frag.
+  echo '  cat >> conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+# Run sed to substitute the contents of conftest.frag into conftest.in at the
+# marker @DEFS@.
+echo '  cat >> conftest.edit <<CEOF
+/@DEFS@/r conftest.frag
+/@DEFS@/d
+CEOF
+sed -f conftest.edit conftest.in > conftest.out
+rm -f conftest.in
+mv conftest.out conftest.in
+rm -f conftest.edit conftest.frag
+' >> $CONFIG_STATUS
+
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+# Extra initialization commands, if any
+
+AWK="$AWK"
+ECHO_LD="$ECHO_LD"
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+# Extra commands, if any
+
+
+for cf_dir in .
+do
+	if test ! -d $srcdir/$cf_dir; then
+		continue
+	elif test -f $srcdir/$cf_dir/programs; then
+		$AWK -f $srcdir/mk-test.awk ECHO_LINK="$ECHO_LD" $srcdir/$cf_dir/programs >>$cf_dir/Makefile
+	fi
+done
+
+
+	cat >>Makefile <<TEST_EOF
+
+# These rules are generated so we do not rely on suffix rules, which do not
+# work consistently for different make-programs (the '\$(MODEL)/' confuses
+# some, and the '\$x' confuses others).
+TEST_EOF
+LIST=`sed -e 's/[ 	].*//' -e '/^[#@]/d' $srcdir/modules`
+for N in $LIST
+do
+	cat >>Makefile <<TEST_EOF
+
+\$(MODEL)/$N.o : $N.c \\
+	test.priv.h \\
+	ncurses_cfg.h
+	@echo compiling $N; \$(CC) -c \$(CFLAGS_DEFAULT) $N.c
+TEST_EOF
+done
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/test/configure.in b/test/configure.in
new file mode 100644
index 0000000..66985a4
--- /dev/null
+++ b/test/configure.in
@@ -0,0 +1,299 @@
+dnl***************************************************************************
+dnl Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+dnl                                                                          *
+dnl Permission is hereby granted, free of charge, to any person obtaining a  *
+dnl copy of this software and associated documentation files (the            *
+dnl "Software"), to deal in the Software without restriction, including      *
+dnl without limitation the rights to use, copy, modify, merge, publish,      *
+dnl distribute, distribute with modifications, sublicense, and/or sell       *
+dnl copies of the Software, and to permit persons to whom the Software is    *
+dnl furnished to do so, subject to the following conditions:                 *
+dnl                                                                          *
+dnl The above copyright notice and this permission notice shall be included  *
+dnl in all copies or substantial portions of the Software.                   *
+dnl                                                                          *
+dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+dnl IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+dnl DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+dnl OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+dnl THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+dnl                                                                          *
+dnl Except as contained in this notice, the name(s) of the above copyright   *
+dnl holders shall not be used in advertising or otherwise to promote the     *
+dnl sale, use or other dealings in this Software without prior written       *
+dnl authorization.                                                           *
+dnl***************************************************************************
+dnl
+dnl Author: Thomas E. Dickey 1996, etc.
+dnl
+dnl $Id: configure.in,v 1.67 2008/09/06 22:10:23 tom Exp $
+dnl This is a simple configuration-script for the ncurses test programs that
+dnl allows the test-directory to be separately configured against a reference
+dnl system (i.e., sysvr4 curses)
+dnl
+dnl If you're configuring ncurses, you shouldn't need to use this script.
+dnl It's only for testing purposes.
+dnl
+dnl See http://invisible-island.net/autoconf/ for additional information.
+dnl ---------------------------------------------------------------------------
+AC_PREREQ(2.13.20020210)
+AC_INIT(ncurses.c)
+AC_CONFIG_HEADER(ncurses_cfg.h:ncurses_tst.hin)
+
+CF_INHERIT_SCRIPT(config.guess)
+CF_INHERIT_SCRIPT(config.sub)
+CF_CHECK_CACHE
+
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_AWK
+
+dnl Things that we don't need (or must override) if we're not building ncurses
+CC_G_OPT="-g"					AC_SUBST(CC_G_OPT)
+CC_SHARED_OPTS=unknown			AC_SUBST(CC_SHARED_OPTS)
+CPPFLAGS="$CPPFLAGS"			AC_SUBST(CPPFLAGS)
+DFT_DEP_SUFFIX=""				AC_SUBST(DFT_DEP_SUFFIX)
+DFT_OBJ_SUBDIR=`pwd|sed -e's:.*/::'`	AC_SUBST(DFT_OBJ_SUBDIR)
+DFT_UPR_MODEL="NORMAL"			AC_SUBST(DFT_UPR_MODEL)
+LD="ld"							AC_SUBST(LD)
+LDFLAGS_SHARED=""				AC_SUBST(LDFLAGS_SHARED)
+LDFLAGS_STATIC=""				AC_SUBST(LDFLAGS_STATIC)
+LD_MODEL=""						AC_SUBST(LD_MODEL)
+LD_SHARED_OPTS=""				AC_SUBST(LD_SHARED_OPTS)
+LIBTOOL=""						AC_SUBST(LIBTOOL)
+LIB_CLEAN=""					AC_SUBST(LIB_CLEAN)
+LIB_COMPILE=""					AC_SUBST(LIB_COMPILE)
+LIB_LINK='${CC}'				AC_SUBST(LIB_LINK)
+LINK_TESTS=""					AC_SUBST(LINK_TESTS)
+LINT=lint						AC_SUBST(LINT)
+LINT_OPTS=""					AC_SUBST(LINT_OPTS)
+LOCAL_LDFLAGS=""				AC_SUBST(LOCAL_LDFLAGS)
+MATH_LIB="-lm"					AC_SUBST(MATH_LIB)
+PTHREAD="-lm"					AC_SUBST(PTHREAD)
+TEST_ARGS=""					AC_SUBST(TEST_ARGS)
+TEST_DEPS=""					AC_SUBST(TEST_DEPS)
+TEST_LIBS=""					AC_SUBST(TEST_LIBS)
+TINFO_ARGS='$(LIBS_CURSES)'		AC_SUBST(TINFO_ARGS)
+cf_cv_abi_version=""			AC_SUBST(cf_cv_abi_version)
+cf_cv_rel_version=""			AC_SUBST(cf_cv_rel_version)
+
+cf_cv_screen=curses
+cf_cv_libtype=
+
+AC_EXEEXT
+AC_OBJEXT
+
+CF_ANSI_CC_REQD
+CF_GCC_ATTRIBUTES
+CF_XOPEN_SOURCE
+AC_C_CONST
+CF_SIG_ATOMIC_T
+
+CF_DISABLE_ECHO
+CF_ENABLE_WARNINGS
+
+CF_WITH_CURSES_DIR
+
+dnl SunOS 4.x
+AC_ARG_WITH(5lib,
+	[  --with-5lib             use SunOS sysv-libraries],
+	[LIBS="-L/usr/5lib $LIBS"
+	 CPPFLAGS="$CPPFLAGS -I/usr/5include"])
+
+dnl ---------------------------------------------------------------------------
+dnl NcursesW, installed in conventional location
+AC_ARG_WITH(ncursesw,
+	[  --with-ncursesw         use wide ncurses-libraries (installed)],
+	[cf_cv_screen=ncursesw],[
+
+dnl Ncurses, installed in conventional location
+AC_ARG_WITH(ncurses,
+	[  --with-ncurses          use ncurses-libraries (installed)],
+	[cf_cv_screen=ncurses],[
+
+AC_ARG_WITH(pdcurses,
+	[  --with-pdcurses         compile/link with pdcurses X11 library],
+	[cf_cv_screen=pdcurses])])])
+
+case $cf_cv_screen in
+curses)
+	CF_CURSES_CPPFLAGS
+	CF_NCURSES_VERSION
+	CF_CURSES_LIBS
+	;;
+ncurses)
+	CF_NCURSES_CPPFLAGS
+	CF_NCURSES_LIBS
+	;;
+ncursesw)
+	cf_cv_libtype=w
+	CF_UTF8_LIB
+	CF_NCURSES_CPPFLAGS(ncursesw)
+	CF_NCURSES_LIBS(ncursesw)
+	;;
+pdcurses) #(vi
+	CF_PDCURSES_X11
+	;;
+esac
+
+dnl If we've not specified a library, assume we're using sysvr4 libraries
+dnl installed conventionally (e.g., SunOS 5.x - solaris).
+
+dnl Autoconf builds up the $LIBS in reverse order
+
+case $cf_cv_screen in #(vi
+pdcurses) #(vi
+	;;
+*)
+	# look for curses-related libraries
+	AC_CHECK_LIB(panel$cf_cv_libtype,new_panel)
+	AC_CHECK_LIB(menu$cf_cv_libtype,menu_driver)
+	AC_CHECK_LIB(form$cf_cv_libtype,form_driver)
+
+	# look for curses-related headers
+	AC_CHECK_HEADERS( \
+		nc_alloc.h \
+		nomacros.h \
+		form.h \
+		menu.h \
+		panel.h \
+		)
+	;;
+esac
+
+AC_TYPE_SIGNAL
+
+AC_STDC_HEADERS
+AC_HEADER_TIME
+AC_CHECK_HEADERS( \
+getopt.h \
+locale.h \
+stdarg.h \
+sys/ioctl.h \
+sys/select.h \
+sys/time.h \
+termios.h \
+unistd.h \
+)
+
+AC_CHECK_FUNCS( \
+gettimeofday \
+mblen \
+mbrlen \
+mbrtowc \
+mbsrtowcs \
+mbstowcs \
+mbtowc \
+strdup \
+wcsrtombs \
+wcstombs \
+)
+
+CF_CURSES_FUNCS( \
+chgat \
+color_set \
+filter \
+getbegx \
+getcurx \
+getmaxx \
+getnstr \
+getparx \
+getwin \
+mvvline \
+mvwvline \
+napms \
+putwin \
+resize_term \
+resizeterm \
+ripoffline \
+setupterm \
+slk_color \
+slk_init \
+termattrs \
+tgetent \
+tigetnum \
+tigetstr \
+typeahead \
+use_default_colors \
+vsscanf \
+wchgat \
+winsstr \
+wresize \
+)
+
+AC_CACHE_CHECK(for ncurses extended functions,cf_cv_ncurses_ext_funcs,[
+AC_TRY_LINK([
+#include <${cf_cv_ncurses_header-curses.h}>],
+[
+	(void) assume_default_colors (0, 0);
+	(void) curses_version ();
+	(void) define_key (0, 0);
+	(void) is_term_resized (0, 0);
+	(void) key_defined (0);
+	(void) keybound (0, 0);
+	(void) keyok (0, 0);
+	(void) resize_term (0, 0);
+	(void) resizeterm (0, 0);
+	(void) use_default_colors ();
+	(void) use_extended_names (0);
+	(void) wresize (0, 0, 0);],
+	[cf_cv_ncurses_ext_funcs=yes],
+	[cf_cv_ncurses_ext_funcs=no])
+])
+test "$cf_cv_ncurses_ext_funcs" != no && AC_DEFINE(NCURSES_EXT_FUNCS)
+
+AC_CACHE_CHECK(for wide-character functions,cf_cv_widechar_funcs,[
+AC_TRY_LINK([
+#include <${cf_cv_ncurses_header-curses.h}>],
+[
+	static wchar_t src_wchar[2];
+	static cchar_t dst_cchar;
+	setcchar(&dst_cchar, src_wchar, A_NORMAL, 0, (void *) 0);
+	],
+	[cf_cv_widechar_funcs=yes],
+	[cf_cv_widechar_funcs=no])
+])
+if test "$cf_cv_widechar_funcs" != no ; then
+	AC_DEFINE(USE_WIDEC_SUPPORT,1)
+else
+	AC_DEFINE(USE_WIDEC_SUPPORT,0)
+fi
+
+CF_SYS_TIME_SELECT
+CF_FUNC_CURSES_VERSION
+CF_CURSES_ACS_MAP
+CF_CURSES_WACS_MAP
+CF_CURSES_CHECK_TYPE(attr_t,long)
+CF_CURSES_CHECK_TYPE(mbstate_t,long)
+
+TEST_ARGS="$LIBS"
+LIBS=
+
+dnl ---------------------------------------------------------------------------
+
+AC_OUTPUT(Makefile,[
+CF_PRG_RULES([$srcdir/mk-test.awk ECHO_LINK="$ECHO_LD"], .)
+	cat >>Makefile <<TEST_EOF
+
+# These rules are generated so we do not rely on suffix rules, which do not
+# work consistently for different make-programs (the '\$(MODEL)/' confuses
+# some, and the '\$x' confuses others).
+TEST_EOF
+LIST=`sed -e 's/[[ 	]].*//' -e '/^[[#@]]/d' $srcdir/modules`
+for N in $LIST
+do
+	cat >>Makefile <<TEST_EOF
+
+\$(MODEL)/$N.o : $N.c \\
+	test.priv.h \\
+	ncurses_cfg.h
+	@echo compiling $N; \$(CC) -c \$(CFLAGS_DEFAULT) $N.c
+TEST_EOF
+done
+],[
+AWK="$AWK"
+ECHO_LD="$ECHO_LD"
+],cat)
diff --git a/test/demo_altkeys.c b/test/demo_altkeys.c
new file mode 100644
index 0000000..9d46ac0
--- /dev/null
+++ b/test/demo_altkeys.c
@@ -0,0 +1,163 @@
+/****************************************************************************
+ * Copyright (c) 2005-2006,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: demo_altkeys.c,v 1.8 2008/04/12 22:06:22 tom Exp $
+ *
+ * Demonstrate the define_key() function.
+ * Thomas Dickey - 2005/10/22
+ */
+
+#include <test.priv.h>
+
+#if defined(NCURSES_VERSION) && NCURSES_EXT_FUNCS
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#define MY_LOGFILE "demo_altkeys.log"
+#define MY_KEYS (KEY_MAX + 1)
+
+/*
+ * Log the most recently-written line to our logfile
+ */
+static void
+log_last_line(WINDOW *win)
+{
+    FILE *fp;
+    int y, x, n;
+    char temp[256];
+
+    if ((fp = fopen(MY_LOGFILE, "a")) != 0) {
+	int need = sizeof(temp) - 1;
+	if (need > COLS)
+	    need = COLS;
+	getyx(win, y, x);
+	wmove(win, y - 1, 0);
+	n = winnstr(win, temp, need);
+	while (n-- > 0) {
+	    if (isspace(UChar(temp[n])))
+		temp[n] = '\0';
+	    else
+		break;
+	}
+	wmove(win, y, x);
+	fprintf(fp, "%s\n", temp);
+	fclose(fp);
+    }
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    int n;
+    int ch;
+#if HAVE_GETTIMEOFDAY
+    int secs, msecs;
+    struct timeval current, previous;
+#endif
+
+    unlink(MY_LOGFILE);
+
+    newterm(0, stdout, stdin);
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    scrollok(stdscr, TRUE);
+    keypad(stdscr, TRUE);
+    move(0, 0);
+
+    /* we do the define_key() calls after keypad(), since the first call to
+     * keypad() initializes the corresponding data.
+     */
+    for (n = 0; n < 255; ++n) {
+	char temp[10];
+	sprintf(temp, "\033%c", n);
+	define_key(temp, n + MY_KEYS);
+    }
+    for (n = KEY_MIN; n < KEY_MAX; ++n) {
+	char *value;
+	if ((value = keybound(n, 0)) != 0) {
+	    char *temp = typeMalloc(char, strlen(value) + 2);
+	    sprintf(temp, "\033%s", value);
+	    define_key(temp, n + MY_KEYS);
+	    free(temp);
+	    free(value);
+	}
+    }
+
+#if HAVE_GETTIMEOFDAY
+    gettimeofday(&previous, 0);
+#endif
+
+    while ((ch = getch()) != ERR) {
+	bool escaped = (ch >= MY_KEYS);
+	const char *name = keyname(escaped ? (ch - MY_KEYS) : ch);
+
+#if HAVE_GETTIMEOFDAY
+	gettimeofday(&current, 0);
+	secs = current.tv_sec - previous.tv_sec;
+	msecs = (current.tv_usec - previous.tv_usec) / 1000;
+	if (msecs < 0) {
+	    msecs += 1000;
+	    --secs;
+	}
+	if (msecs >= 1000) {
+	    secs += msecs / 1000;
+	    msecs %= 1000;
+	}
+	printw("%6d.%03d ", secs, msecs);
+	previous = current;
+#endif
+	printw("Keycode %d, name %s%s\n",
+	       ch,
+	       escaped ? "ESC-" : "",
+	       name != 0 ? name : "<null>");
+	log_last_line(stdscr);
+	clrtoeol();
+	if (ch == 'q')
+	    break;
+    }
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/demo_defkey.c b/test/demo_defkey.c
new file mode 100644
index 0000000..195ef54
--- /dev/null
+++ b/test/demo_defkey.c
@@ -0,0 +1,282 @@
+/****************************************************************************
+ * Copyright (c) 2002-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: demo_defkey.c,v 1.19 2008/08/04 16:24:47 tom Exp $
+ *
+ * Demonstrate the define_key() function.
+ * Thomas Dickey - 2002/11/23
+ */
+
+#include <test.priv.h>
+
+#if defined(NCURSES_VERSION) && NCURSES_EXT_FUNCS
+
+#define MY_LOGFILE "demo_defkey.log"
+
+/*
+ * Log the most recently-written line to our logfile
+ */
+static void
+log_last_line(WINDOW *win)
+{
+    FILE *fp;
+    int y, x, n;
+    char temp[256];
+
+    if ((fp = fopen(MY_LOGFILE, "a")) != 0) {
+	int need = sizeof(temp) - 1;
+	if (need > COLS)
+	    need = COLS;
+	getyx(win, y, x);
+	wmove(win, y - 1, 0);
+	n = winnstr(win, temp, need);
+	while (n-- > 0) {
+	    if (isspace(UChar(temp[n])))
+		temp[n] = '\0';
+	    else
+		break;
+	}
+	wmove(win, y, x);
+	fprintf(fp, "%s\n", temp);
+	fclose(fp);
+    }
+}
+
+/*
+ * Convert a character to visible form.
+ */
+static char *
+visichar(int ch)
+{
+    static char temp[10];
+
+    ch = UChar(ch);
+    assert(ch >= 0 && ch < 256);
+    if (ch == '\\') {
+	strcpy(temp, "\\\\");
+    } else if (ch == '\033') {
+	strcpy(temp, "\\E");
+    } else if (ch < ' ') {
+	sprintf(temp, "\\%03o", ch);
+    } else if (ch >= 127) {
+	sprintf(temp, "\\%03o", ch);
+    } else {
+	sprintf(temp, "%c", ch);
+    }
+    return temp;
+}
+
+/*
+ * Convert a string to visible form.
+ */
+static char *
+visible(const char *string)
+{
+    char *result = 0;
+    unsigned need = 1;
+    int pass;
+    int n;
+
+    if (string != 0 && *string != '\0') {
+	for (pass = 0; pass < 2; ++pass) {
+	    for (n = 0; string[n] != '\0'; ++n) {
+		char temp[80];
+		strcpy(temp, visichar(string[n]));
+		if (pass)
+		    strcat(result, temp);
+		else
+		    need += strlen(temp);
+	    }
+	    if (!pass)
+		result = typeCalloc(char, need);
+	}
+    } else {
+	result = typeCalloc(char, 1);
+    }
+    return result;
+}
+
+static void
+really_define_key(WINDOW *win, const char *new_string, int code)
+{
+    int rc;
+    const char *code_name = keyname(code);
+    char *old_string;
+    char *vis_string = 0;
+    char temp[80];
+
+    if (code_name == 0) {
+	sprintf(temp, "Keycode %d", code);
+	code_name = temp;
+    }
+
+    if ((old_string = keybound(code, 0)) != 0) {
+	wprintw(win, "%s is %s\n",
+		code_name,
+		vis_string = visible(old_string));
+    } else {
+	wprintw(win, "%s is not bound\n",
+		code_name);
+    }
+    log_last_line(win);
+
+    if (vis_string != 0) {
+	free(vis_string);
+	vis_string = 0;
+    }
+
+    vis_string = visible(new_string);
+    if ((rc = key_defined(new_string)) > 0) {
+	wprintw(win, "%s was bound to %s\n", vis_string, keyname(rc));
+	log_last_line(win);
+    } else if (new_string != 0 && rc < 0) {
+	wprintw(win, "%s conflicts with longer strings\n", vis_string);
+	log_last_line(win);
+    }
+    rc = define_key(new_string, code);
+    if (rc == ERR) {
+	wprintw(win, "%s unchanged\n", code_name);
+	log_last_line(win);
+    } else if (new_string != 0) {
+	wprintw(win, "%s is now bound to %s\n",
+		vis_string,
+		code_name);
+	log_last_line(win);
+    } else if (old_string != 0) {
+	wprintw(win, "%s deleted\n", code_name);
+	log_last_line(win);
+    }
+    if (vis_string != 0)
+	free(vis_string);
+    if (old_string != 0)
+	free(old_string);
+}
+
+static void
+duplicate(WINDOW *win, NCURSES_CONST char *name, int code)
+{
+    char *value = tigetstr(name);
+
+    if (value != 0) {
+	const char *prefix = 0;
+	char temp[BUFSIZ];
+
+	if (!strncmp(value, "\033[", 2)) {
+	    prefix = "\033O";
+	} else if (!strncmp(value, "\033O", 2)) {
+	    prefix = "\033[";
+	}
+	if (prefix != 0) {
+	    sprintf(temp, "%s%s", prefix, value + 2);
+	    really_define_key(win, temp, code);
+	}
+    }
+}
+
+static void
+redefine(WINDOW *win, char *string, int code)
+{
+    really_define_key(win, string, code);
+}
+
+static void
+remove_definition(WINDOW *win, int code)
+{
+    really_define_key(win, 0, code);
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    char *fkeys[12];
+    int n;
+    int ch;
+    WINDOW *win;
+
+    unlink(MY_LOGFILE);
+
+    initscr();
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    printw("This demo is best on xterm: it reverses the definitions for f1-f12,\n");
+    printw("adds duplicate definitions for cursor application and normal modes,\n");
+    printw("and removes any definitions for the mini keypad.  Type any of those:\n");
+    refresh();
+
+    win = newwin(LINES - 3, COLS, 3, 0);
+    scrollok(win, TRUE);
+    keypad(win, TRUE);
+    wmove(win, 0, 0);
+
+    /* we do the define_key() calls after keypad(), since the first call to
+     * keypad() initializes the corresponding data.
+     */
+    for (n = 0; n < 12; ++n) {
+	char name[10];
+	sprintf(name, "kf%d", n + 1);
+	fkeys[n] = tigetstr(name);
+    }
+    for (n = 0; n < 12; ++n) {
+	redefine(win, fkeys[11 - n], KEY_F(n + 1));
+    }
+
+    duplicate(win, "kcub1", KEY_LEFT);
+    duplicate(win, "kcuu1", KEY_UP);
+    duplicate(win, "kcud1", KEY_DOWN);
+    duplicate(win, "kcuf1", KEY_RIGHT);
+
+    remove_definition(win, KEY_A1);
+    remove_definition(win, KEY_A3);
+    remove_definition(win, KEY_B2);
+    remove_definition(win, KEY_C1);
+    remove_definition(win, KEY_C3);
+
+    really_define_key(win, "\033O", 1023);
+
+    while ((ch = wgetch(win)) != ERR) {
+	const char *name = keyname(ch);
+	wprintw(win, "Keycode %d, name %s\n",
+		ch,
+		name != 0 ? name : "<null>");
+	log_last_line(win);
+	wclrtoeol(win);
+	if (ch == 'q')
+	    break;
+    }
+    endwin();
+    ExitProgram(EXIT_FAILURE);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/demo_forms.c b/test/demo_forms.c
new file mode 100644
index 0000000..0d6a571
--- /dev/null
+++ b/test/demo_forms.c
@@ -0,0 +1,538 @@
+/****************************************************************************
+ * Copyright (c) 2003-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: demo_forms.c,v 1.30 2008/10/18 20:38:20 tom Exp $
+ *
+ * Demonstrate a variety of functions from the form library.
+ * Thomas Dickey - 2003/4/26
+ */
+/*
+TYPE_ENUM			-
+TYPE_REGEXP			-
+dup_field			-
+field_init			-
+field_just			-
+field_term			-
+form_init			-
+form_opts			-
+form_opts_off			-
+form_opts_on			-
+form_request_by_name		-
+form_term			-
+form_userptr			-
+free_fieldtype			-
+link_field			-
+link_fieldtype			-
+move_field			-
+new_page			-
+pos_form_cursor			-
+set_field_init			-
+set_field_term			-
+set_fieldtype_arg		-
+set_fieldtype_choice		-
+set_form_fields			-
+set_form_init			-
+set_form_opts			-
+set_form_page			-
+set_form_term			-
+set_form_userptr		-
+set_max_field			-
+*/
+
+#include <test.priv.h>
+
+#if USE_LIBFORM
+
+#include <edit_field.h>
+
+static int d_option = 0;
+static int j_value = 0;
+static int m_value = 0;
+static int o_value = 0;
+static char *t_value = 0;
+
+static FIELD *
+make_label(int frow, int fcol, NCURSES_CONST char *label)
+{
+    FIELD *f = new_field(1, (int) strlen(label), frow, fcol, 0, 0);
+
+    if (f) {
+	set_field_buffer(f, 0, label);
+	set_field_opts(f, (int) (field_opts(f) & ~O_ACTIVE));
+    }
+    return (f);
+}
+
+/*
+ * Define each field with an extra one, for reflecting "actual" text.
+ */
+static FIELD *
+make_field(int frow, int fcol, int rows, int cols)
+{
+    FIELD *f = new_field(rows, cols, frow, fcol, o_value, 1);
+
+    if (f) {
+	set_field_back(f, A_UNDERLINE);
+	/*
+	 * If -j and -d options are combined, -j loses.  It is documented in
+	 * "Character User Interface Programming", page 12-15 that setting
+	 * O_STATIC off makes the form library ignore justification.
+	 */
+	set_field_just(f, j_value);
+	if (d_option) {
+	    if (has_colors()) {
+		set_field_fore(f, COLOR_PAIR(2));
+		set_field_back(f, A_UNDERLINE | COLOR_PAIR(3));
+	    } else {
+		set_field_fore(f, A_BOLD);
+	    }
+	    /*
+	     * The field_opts_off() call dumps core with Solaris curses,
+	     * but that is a known bug in Solaris' form library -TD
+	     */
+	    field_opts_off(f, O_STATIC);
+	    set_max_field(f, m_value);
+	}
+
+	/*
+	 * The userptr is used in edit_field.c's inactive_field().
+	 */
+	set_field_userptr(f, (void *) (long) field_back(f));
+	if (t_value)
+	    set_field_buffer(f, 0, t_value);
+    }
+    return (f);
+}
+
+static void
+display_form(FORM * f)
+{
+    WINDOW *w;
+    int rows, cols;
+
+    scale_form(f, &rows, &cols);
+
+    /*
+     * Put the form at the upper-left corner of the display, with just a box
+     * around it.
+     */
+    if ((w = newwin(rows + 2, cols + 4, 0, 0)) != (WINDOW *) 0) {
+	set_form_win(f, w);
+	set_form_sub(f, derwin(w, rows, cols, 1, 2));
+	box(w, 0, 0);
+	keypad(w, TRUE);
+    }
+
+    if (post_form(f) != E_OK)
+	wrefresh(w);
+}
+
+static void
+erase_form(FORM * f)
+{
+    WINDOW *w = form_win(f);
+    WINDOW *s = form_sub(f);
+
+    unpost_form(f);
+    werase(w);
+    wrefresh(w);
+    delwin(s);
+    delwin(w);
+}
+
+static void
+show_insert_mode(bool insert_mode)
+{
+    mvaddstr(5, 57, (insert_mode
+		     ? "form_status: insert "
+		     : "form_status: overlay"));
+}
+
+#define O_SELECTABLE (O_ACTIVE | O_VISIBLE)
+
+static FIELD *
+another_field(FORM * form, FIELD * field)
+{
+    FIELD **f = form_fields(form);
+    FIELD *result = 0;
+    int n;
+
+    for (n = 0; f[n] != 0; ++n) {
+	if (f[n] != field) {
+	    result = f[n];
+	    field_opts_on(result, O_SELECTABLE);
+	    break;
+	}
+    }
+    return result;
+}
+
+static int
+my_form_driver(FORM * form, int c)
+{
+    static bool insert_mode = TRUE;
+    FIELD *field;
+
+    switch (c) {
+    case MY_QUIT:
+	if (form_driver(form, REQ_VALIDATION) == E_OK)
+	    return (TRUE);
+	break;
+    case MY_HELP:
+	help_edit_field();
+	break;
+    case MY_EDT_MODE:
+	if ((field = current_field(form)) != 0) {
+	    set_current_field(form, another_field(form, field));
+	    if (field_opts(field) & O_EDIT) {
+		field_opts_off(field, O_EDIT);
+		set_field_status(field, 0);
+	    } else {
+		field_opts_on(field, O_EDIT);
+	    }
+	    set_current_field(form, field);
+	}
+	break;
+    case MY_INS_MODE:
+	/* there should be a form_status() function, but there is none */
+	if (!insert_mode) {
+	    if (form_driver(form, REQ_INS_MODE) == E_OK) {
+		insert_mode = TRUE;
+	    }
+	} else {
+	    if (form_driver(form, REQ_OVL_MODE) == E_OK) {
+		insert_mode = FALSE;
+	    }
+	}
+	show_insert_mode(insert_mode);
+	refresh();
+	break;
+    default:
+	beep();
+	break;
+    }
+    return (FALSE);
+}
+
+static void
+show_current_field(WINDOW *win, FORM * form)
+{
+    FIELD *field;
+    FIELDTYPE *type;
+    char *buffer;
+    int nbuf;
+    int field_rows, field_cols, field_max;
+
+    if (has_colors()) {
+	wbkgd(win, COLOR_PAIR(1));
+    }
+    werase(win);
+    wprintw(win, "Cursor: %d,%d", form->currow, form->curcol);
+    if (data_ahead(form))
+	waddstr(win, " ahead");
+    if (data_behind(form))
+	waddstr(win, " behind");
+    waddch(win, '\n');
+    if ((field = current_field(form)) != 0) {
+	wprintw(win, "Page %d%s, Field %d/%d%s:",
+		form_page(form),
+		new_page(field) ? "*" : "",
+		field_index(field), field_count(form),
+		field_arg(field) ? "(arg)" : "");
+	if ((type = field_type(field)) != 0) {
+	    if (type == TYPE_ALNUM)
+		waddstr(win, "ALNUM");
+	    else if (type == TYPE_ALPHA)
+		waddstr(win, "ALPHA");
+	    else if (type == TYPE_ENUM)
+		waddstr(win, "ENUM");
+	    else if (type == TYPE_INTEGER)
+		waddstr(win, "INTEGER");
+#ifdef NCURSES_VERSION
+	    else if (type == TYPE_IPV4)
+		waddstr(win, "IPV4");
+#endif
+	    else if (type == TYPE_NUMERIC)
+		waddstr(win, "NUMERIC");
+	    else if (type == TYPE_REGEXP)
+		waddstr(win, "REGEXP");
+	    else
+		waddstr(win, "other");
+	}
+
+	if (field_opts(field) & O_EDIT)
+	    waddstr(win, " editable");
+	else
+	    waddstr(win, " readonly");
+
+	if (field_status(field))
+	    waddstr(win, " modified");
+
+	if (dynamic_field_info(field, &field_rows, &field_cols, &field_max)
+	    != ERR) {
+	    wprintw(win, " size %dx%d (max %d)",
+		    field_rows, field_cols, field_max);
+	}
+
+	waddch(win, ' ');
+	wattrset(win, field_fore(field));
+	waddstr(win, "fore");
+	wattroff(win, field_fore(field));
+
+	waddch(win, '/');
+
+	wattrset(win, field_back(field));
+	waddstr(win, "back");
+	wattroff(win, field_back(field));
+
+	wprintw(win, ", pad '%c'",
+		field_pad(field));
+
+	waddstr(win, "\n");
+	for (nbuf = 0; nbuf <= 2; ++nbuf) {
+	    if ((buffer = field_buffer(field, nbuf)) != 0) {
+		wprintw(win, "buffer %d:", nbuf);
+		wattrset(win, A_REVERSE);
+		waddstr(win, buffer);
+		wattroff(win, A_REVERSE);
+		waddstr(win, "\n");
+	    }
+	}
+    }
+    wrefresh(win);
+}
+
+static void
+demo_forms(void)
+{
+    WINDOW *w;
+    FORM *form;
+    FIELD *f[100];		/* FIXME memset to zero */
+    int finished = 0, c;
+    unsigned n = 0;
+    int pg;
+    WINDOW *also;
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
+#endif
+
+    help_edit_field();
+
+    mvaddstr(4, 57, "Forms Entry Test");
+    show_insert_mode(TRUE);
+
+    refresh();
+
+    /* describe the form */
+    memset(f, 0, sizeof(f));
+    for (pg = 0; pg < 4; ++pg) {
+	char label[80];
+	sprintf(label, "Sample Form Page %d", pg + 1);
+	f[n++] = make_label(0, 15, label);
+	set_new_page(f[n - 1], TRUE);
+
+	switch (pg) {
+	default:
+	    f[n++] = make_label(2, 0, "Last Name");
+	    f[n++] = make_field(3, 0, 1, 18);
+	    set_field_type(f[n - 1], TYPE_ALPHA, 1);
+
+	    f[n++] = make_label(2, 20, "First Name");
+	    f[n++] = make_field(3, 20, 1, 12);
+	    set_field_type(f[n - 1], TYPE_ALPHA, 1);
+
+	    f[n++] = make_label(2, 34, "Middle Name");
+	    f[n++] = make_field(3, 34, 1, 12);
+	    set_field_type(f[n - 1], TYPE_ALPHA, 1);
+	    break;
+	case 1:
+	    f[n++] = make_label(2, 0, "Last Name");
+	    f[n++] = make_field(3, 0, 1, 18);
+	    set_field_type(f[n - 1], TYPE_ALPHA, 1);
+
+	    f[n++] = make_label(2, 20, "First Name");
+	    f[n++] = make_field(3, 20, 1, 12);
+	    set_field_type(f[n - 1], TYPE_ALPHA, 1);
+
+	    f[n++] = make_label(2, 34, "MI");
+	    f[n++] = make_field(3, 34, 1, 1);
+	    set_field_pad(f[n - 1], '?');
+	    set_field_type(f[n - 1], TYPE_ALPHA, 1);
+	    break;
+	case 2:
+	    f[n++] = make_label(2, 0, "Host Name");
+	    f[n++] = make_field(3, 0, 1, 18);
+	    set_field_type(f[n - 1], TYPE_ALNUM, 1);
+
+#ifdef NCURSES_VERSION
+	    f[n++] = make_label(2, 20, "IP Address");
+	    f[n++] = make_field(3, 20, 1, 12);
+	    set_field_type(f[n - 1], TYPE_IPV4, 1);
+#endif
+
+	    break;
+
+	case 3:
+	    f[n++] = make_label(2, 0, "Four digits");
+	    f[n++] = make_field(3, 0, 1, 18);
+	    set_field_type(f[n - 1], TYPE_INTEGER, 4, 0, 0);
+
+	    f[n++] = make_label(2, 20, "Numeric");
+	    f[n++] = make_field(3, 20, 1, 12);
+	    set_field_type(f[n - 1], TYPE_NUMERIC, 3, -10000.0, 100000000.0);
+
+	    break;
+	}
+
+	f[n++] = make_label(5, 0, "Comments");
+	f[n++] = make_field(6, 0, 4, 46);
+	set_field_buffer(f[n - 1], 0, "HELLO\nWORLD!");
+	set_field_buffer(f[n - 1], 1, "Hello\nWorld!");
+    }
+
+    f[n++] = (FIELD *) 0;
+
+    if ((form = new_form(f)) != 0) {
+
+	display_form(form);
+
+	w = form_win(form);
+	also = newwin(getmaxy(stdscr) - getmaxy(w), COLS, getmaxy(w), 0);
+	show_current_field(also, form);
+
+	while (!finished) {
+	    switch (edit_field(form, &c)) {
+	    case E_OK:
+		break;
+	    case E_UNKNOWN_COMMAND:
+		finished = my_form_driver(form, c);
+		break;
+	    default:
+		beep();
+		break;
+	    }
+	    show_current_field(also, form);
+	}
+
+	erase_form(form);
+
+	free_form(form);
+    }
+    for (c = 0; f[c] != 0; c++)
+	free_field(f[c]);
+    noraw();
+    nl();
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(0, (mmask_t *) 0);
+#endif
+}
+
+static void
+usage(void)
+{
+    static const char *tbl[] =
+    {
+	"Usage: demo_forms [options]"
+	,""
+	," -d        make fields dynamic"
+	," -j value  justify (1=left, 2=center, 3=right)"
+	," -m value  set maximum size of dynamic fields"
+	," -o value  specify number of offscreen rows in new_field()"
+	," -t value  specify text to fill fields initially"
+    };
+    unsigned int j;
+    for (j = 0; j < SIZEOF(tbl); ++j)
+	fprintf(stderr, "%s\n", tbl[j]);
+    exit(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int ch;
+
+    setlocale(LC_ALL, "");
+
+    while ((ch = getopt(argc, argv, "dj:m:o:t:")) != -1) {
+	switch (ch) {
+	case 'd':
+	    d_option = TRUE;
+	    break;
+	case 'j':
+	    j_value = atoi(optarg);
+	    if (j_value < NO_JUSTIFICATION
+		|| j_value > JUSTIFY_RIGHT)
+		usage();
+	    break;
+	case 'm':
+	    m_value = atoi(optarg);
+	    break;
+	case 'o':
+	    o_value = atoi(optarg);
+	    break;
+	case 't':
+	    t_value = optarg;
+	    break;
+	default:
+	    usage();
+
+	}
+    }
+
+    initscr();
+    cbreak();
+    noecho();
+    raw();
+    nonl();			/* lets us read ^M's */
+    intrflush(stdscr, FALSE);
+    keypad(stdscr, TRUE);
+
+    if (has_colors()) {
+	start_color();
+	init_pair(1, COLOR_WHITE, COLOR_BLUE);
+	init_pair(2, COLOR_GREEN, COLOR_BLACK);
+	init_pair(3, COLOR_CYAN, COLOR_BLACK);
+	bkgd(COLOR_PAIR(1));
+	refresh();
+    }
+
+    demo_forms();
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the curses form library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/demo_keyok.c b/test/demo_keyok.c
new file mode 100644
index 0000000..8724d98
--- /dev/null
+++ b/test/demo_keyok.c
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * Copyright (c) 2002-2003,2006 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: demo_keyok.c,v 1.5 2006/11/04 20:09:51 tom Exp $
+ *
+ * Demonstrate the keyok() function.
+ * Thomas Dickey - 2002/11/23
+ */
+
+#include <test.priv.h>
+
+#if defined(NCURSES_VERSION) && NCURSES_EXT_FUNCS
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    int lastch = ERR;
+    int ch;
+    WINDOW *win;
+
+    initscr();
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    printw("Typing any function key will disable it, but typing it twice in\n");
+    printw("a row will turn it back on (just for a demo).");
+    refresh();
+
+    win = newwin(LINES - 2, COLS, 2, 0);
+    scrollok(win, TRUE);
+    keypad(win, TRUE);
+    wmove(win, 0, 0);
+
+    while ((ch = wgetch(win)) != ERR) {
+	const char *name = keyname(ch);
+	wprintw(win, "Keycode %d, name %s\n",
+		ch,
+		name != 0 ? name : "<null>");
+	wclrtoeol(win);
+	wrefresh(win);
+	if (ch >= KEY_MIN) {
+	    keyok(ch, FALSE);
+	    lastch = ch;
+	} else if (lastch >= KEY_MIN) {
+	    keyok(lastch, TRUE);
+	}
+    }
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/demo_menus.c b/test/demo_menus.c
new file mode 100644
index 0000000..4d553e2
--- /dev/null
+++ b/test/demo_menus.c
@@ -0,0 +1,900 @@
+/****************************************************************************
+ * Copyright (c) 2005-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: demo_menus.c,v 1.28 2008/08/23 20:31:54 tom Exp $
+ *
+ * Demonstrate a variety of functions from the menu library.
+ * Thomas Dickey - 2005/4/9
+ */
+/*
+item_description		-
+item_init			-
+item_opts			-
+item_opts_off			-
+item_opts_on			-
+item_term			-
+item_userptr			-
+item_visible			-
+menu_back			-
+menu_fore			-
+menu_format			-
+menu_grey			-
+menu_init			-
+menu_opts			-
+menu_pad			-
+menu_request_by_name		-
+menu_request_name		-
+menu_sub			-
+menu_term			-
+menu_userptr			-
+set_current_item		-
+set_item_init			-
+set_item_opts			-
+set_item_term			-
+set_item_userptr		-
+set_menu_grey			-
+set_menu_init			-
+set_menu_items			-
+set_menu_opts			-
+set_menu_pad			-
+set_menu_pattern		-
+set_menu_spacing		-
+set_menu_term			-
+set_menu_userptr		-
+set_top_row			-
+top_row				-
+*/
+
+#include <test.priv.h>
+
+#if USE_LIBMENU
+
+#include <menu.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef NCURSES_VERSION
+#ifdef TRACE
+static unsigned save_trace = TRACE_ORDINARY | TRACE_CALLS;
+extern unsigned _nc_tracing;
+static MENU *mpTrace;
+#endif
+#else
+#undef TRACE
+#endif
+
+typedef enum {
+    eBanner = -1
+    ,eFile
+    ,eSelect
+#ifdef TRACE
+    ,eTrace
+#endif
+    ,eMAX
+} MenuNo;
+
+#define okMenuNo(n) (((n) > eBanner) && ((n) < eMAX))
+
+#define MENU_Y	1
+
+static MENU *mpBanner;
+static MENU *mpFile;
+static MENU *mpSelect;
+
+static bool loaded_file = FALSE;
+
+#if !HAVE_STRDUP
+#define strdup my_strdup
+static char *
+strdup(char *s)
+{
+    char *p = typeMalloc(char, strlen(s) + 1);
+    if (p)
+	strcpy(p, s);
+    return (p);
+}
+#endif /* not HAVE_STRDUP */
+
+/* Common function to allow ^T to toggle trace-mode in the middle of a test
+ * so that trace-files can be made smaller.
+ */
+static int
+wGetchar(WINDOW *win)
+{
+    int c;
+#ifdef TRACE
+    while ((c = wgetch(win)) == CTRL('T')) {
+	if (_nc_tracing) {
+	    save_trace = _nc_tracing;
+	    Trace(("TOGGLE-TRACING OFF"));
+	    _nc_tracing = 0;
+	} else {
+	    _nc_tracing = save_trace;
+	}
+	trace(_nc_tracing);
+	if (_nc_tracing)
+	    Trace(("TOGGLE-TRACING ON"));
+    }
+#else
+    c = wgetch(win);
+#endif
+    return c;
+}
+#define Getchar() wGetchar(stdscr)
+
+static int
+menu_virtualize(int c)
+{
+    int result;
+
+    if (c == '\n' || c == KEY_EXIT)
+	result = (MAX_COMMAND + 1);
+    else if (c == 'u')
+	result = (REQ_SCR_ULINE);
+    else if (c == 'd')
+	result = (REQ_SCR_DLINE);
+    else if (c == 'b' || c == KEY_NPAGE)
+	result = (REQ_SCR_UPAGE);
+    else if (c == 'f' || c == KEY_PPAGE)
+	result = (REQ_SCR_DPAGE);
+    else if (c == 'l' || c == KEY_LEFT || c == KEY_BTAB)
+	result = (REQ_LEFT_ITEM);
+    else if (c == 'n' || c == KEY_DOWN)
+	result = (REQ_NEXT_ITEM);
+    else if (c == 'p' || c == KEY_UP)
+	result = (REQ_PREV_ITEM);
+    else if (c == 'r' || c == KEY_RIGHT || c == '\t')
+	result = (REQ_RIGHT_ITEM);
+    else if (c == ' ')
+	result = (REQ_TOGGLE_ITEM);
+    else {
+	if (c != KEY_MOUSE)
+	    beep();
+	result = (c);
+    }
+    return result;
+}
+
+static int
+menu_getc(MENU * m)
+{
+    return wGetchar(menu_win(m));
+}
+
+static int
+menu_offset(MenuNo number)
+{
+    int result = 0;
+
+    if (okMenuNo(number)) {
+	int spc_desc, spc_rows, spc_cols;
+
+#ifdef NCURSES_VERSION
+	menu_spacing(mpBanner, &spc_desc, &spc_rows, &spc_cols);
+#else
+	spc_rows = 0;
+#endif
+
+	/* FIXME: MENU.itemlen seems the only way to get actual width of items */
+	result = (number - (eBanner + 1)) * (mpBanner->itemlen + spc_rows);
+    }
+    return result;
+}
+
+static MENU *
+menu_create(ITEM ** items, int count, int ncols, MenuNo number)
+{
+    MENU *result;
+    WINDOW *menuwin;
+    int mrows, mcols;
+    int y = okMenuNo(number) ? MENU_Y : 0;
+    int x = menu_offset(number);
+    int margin = (y == MENU_Y) ? 1 : 0;
+    int maxcol = (ncols + x) < COLS ? ncols : (COLS - x - 1);
+    int maxrow = (count + 1) / ncols;
+
+    if ((maxrow + y) >= (LINES - 4))
+	maxrow = LINES - 4 - y;
+
+    result = new_menu(items);
+
+    if (has_colors()) {
+	set_menu_fore(result, COLOR_PAIR(1));
+	set_menu_back(result, COLOR_PAIR(2));
+    }
+
+    set_menu_format(result, maxrow, maxcol);
+    scale_menu(result, &mrows, &mcols);
+
+    if (mcols + (2 * margin + x) >= COLS)
+	mcols = COLS - (2 * margin + x);
+
+#ifdef TRACE
+    if (number == eTrace)
+	menu_opts_off(result, O_ONEVALUE);
+    else
+	menu_opts_on(result, O_ONEVALUE);
+#endif
+
+    menuwin = newwin(mrows + (2 * margin), mcols + (2 * margin), y, x);
+    set_menu_win(result, menuwin);
+    keypad(menuwin, TRUE);
+    if (margin)
+	box(menuwin, 0, 0);
+
+    set_menu_sub(result, derwin(menuwin, mrows, mcols, margin, margin));
+
+    post_menu(result);
+
+    return result;
+}
+
+static void
+menu_destroy(MENU * m)
+{
+    int count;
+
+    Trace(("menu_destroy %p", m));
+    if (m != 0) {
+	ITEM **items = menu_items(m);
+	const char *blob = 0;
+
+	count = item_count(m);
+	Trace(("menu_destroy %p count %d", m, count));
+	if ((count > 0) && (m == mpSelect)) {
+	    blob = item_name(*items);
+	}
+
+	unpost_menu(m);
+	free_menu(m);
+
+	/* free the extra data allocated in build_select_menu() */
+	if ((count > 0) && (m == mpSelect)) {
+	    if (blob && loaded_file) {
+		Trace(("freeing blob %p", blob));
+		free((char *) blob);
+	    }
+	    free(items);
+	}
+#ifdef TRACE
+	if ((count > 0) && (m == mpTrace)) {
+	    ITEM **ip = items;
+	    while (*ip)
+		free(*ip++);
+	}
+#endif
+    }
+}
+
+/* force the given menu to appear */
+static void
+menu_display(MENU * m)
+{
+    touchwin(menu_win(m));
+    wrefresh(menu_win(m));
+}
+
+/*****************************************************************************/
+
+static void
+build_file_menu(MenuNo number)
+{
+    static CONST_MENUS char *labels[] =
+    {
+	"Exit",
+	(char *) 0
+    };
+    static ITEM *items[SIZEOF(labels)];
+
+    ITEM **ip = items;
+    CONST_MENUS char **ap;
+
+    for (ap = labels; *ap; ap++)
+	*ip++ = new_item(*ap, "");
+    *ip = (ITEM *) 0;
+
+    mpFile = menu_create(items, SIZEOF(labels) - 1, 1, number);
+}
+
+static int
+perform_file_menu(int cmd)
+{
+    return menu_driver(mpFile, cmd);
+}
+
+/*****************************************************************************/
+
+static void
+build_select_menu(MenuNo number, char *filename)
+{
+    static CONST_MENUS char *labels[] =
+    {
+	"Lions",
+	"Tigers",
+	"Bears",
+	"(Oh my!)",
+	"Newts",
+	"Platypi",
+	"Lemurs",
+	"(Oh really?!)",
+	"Leopards",
+	"Panthers",
+	"Pumas",
+	"Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
+	"Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs, Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
+	(char *) 0
+    };
+    static ITEM **items;
+
+    ITEM **ip;
+    CONST_MENUS char **ap = 0;
+    CONST_MENUS char **myList = 0;
+    unsigned count = 0;
+
+    if (filename != 0) {
+	struct stat sb;
+	if (stat(filename, &sb) == 0
+	    && (sb.st_mode & S_IFMT) == S_IFREG
+	    && sb.st_size != 0) {
+	    size_t size = (size_t) sb.st_size;
+	    unsigned j, k;
+	    char *blob = typeMalloc(char, size + 1);
+	    CONST_MENUS char **list = typeCalloc(CONST_MENUS char *, size + 1);
+
+	    items = typeCalloc(ITEM *, size + 1);
+	    Trace(("build_select_menu blob=%p, items=%p", blob, items));
+	    if (blob != 0 && list != 0) {
+		FILE *fp = fopen(filename, "r");
+		if (fp != 0) {
+		    if (fread(blob, sizeof(char), size, fp) == size) {
+			bool mark = TRUE;
+			for (j = k = 0; j < size; ++j) {
+			    if (mark) {
+				list[k++] = blob + j;
+				mark = FALSE;
+			    }
+			    if (blob[j] == '\n') {
+				blob[j] = '\0';
+				if (k > 0 && *list[k - 1] == '\0')
+				    --k;
+				mark = TRUE;
+			    } else if (blob[j] == '\t') {
+				blob[j] = ' ';	/* menu items are printable */
+			    }
+			}
+			list[k] = 0;
+			count = k;
+			ap = myList = list;
+		    }
+		    fclose(fp);
+		}
+		loaded_file = TRUE;
+	    }
+	}
+    }
+    if (ap == 0) {
+	count = SIZEOF(labels) - 1;
+	items = typeCalloc(ITEM *, count + 1);
+	ap = labels;
+    }
+
+    ip = items;
+    while (*ap != 0)
+	*ip++ = new_item(*ap++, "");
+    *ip = 0;
+
+    mpSelect = menu_create(items, (int) count, 1, number);
+    if (myList != 0)
+	free(myList);
+}
+
+static int
+perform_select_menu(int cmd)
+{
+    return menu_driver(mpSelect, cmd);
+}
+
+/*****************************************************************************/
+
+#ifdef TRACE
+#define T_TBL(name) { #name, name }
+static struct {
+    const char *name;
+    unsigned mask;
+} t_tbl[] = {
+
+    T_TBL(TRACE_DISABLE),
+	T_TBL(TRACE_TIMES),
+	T_TBL(TRACE_TPUTS),
+	T_TBL(TRACE_UPDATE),
+	T_TBL(TRACE_MOVE),
+	T_TBL(TRACE_CHARPUT),
+	T_TBL(TRACE_ORDINARY),
+	T_TBL(TRACE_CALLS),
+	T_TBL(TRACE_VIRTPUT),
+	T_TBL(TRACE_IEVENT),
+	T_TBL(TRACE_BITS),
+	T_TBL(TRACE_ICALLS),
+	T_TBL(TRACE_CCALLS),
+	T_TBL(TRACE_DATABASE),
+	T_TBL(TRACE_ATTRS),
+	T_TBL(TRACE_MAXIMUM),
+    {
+	(char *) 0, 0
+    }
+};
+
+static void
+build_trace_menu(MenuNo number)
+{
+    static ITEM *items[SIZEOF(t_tbl)];
+
+    ITEM **ip = items;
+    int n;
+
+    for (n = 0; t_tbl[n].name != 0; n++)
+	*ip++ = new_item(t_tbl[n].name, "");
+    *ip = (ITEM *) 0;
+
+    mpTrace = menu_create(items, SIZEOF(t_tbl) - 1, 2, number);
+}
+
+static char *
+tracetrace(unsigned tlevel)
+{
+    static char *buf;
+    int n;
+
+    if (buf == 0) {
+	size_t need = 12;
+	for (n = 0; t_tbl[n].name != 0; n++)
+	    need += strlen(t_tbl[n].name) + 2;
+	buf = typeMalloc(char, need);
+    }
+    sprintf(buf, "0x%02x = {", tlevel);
+    if (tlevel == 0) {
+	sprintf(buf + strlen(buf), "%s, ", t_tbl[0].name);
+    } else {
+	for (n = 1; t_tbl[n].name != 0; n++)
+	    if ((tlevel & t_tbl[n].mask) == t_tbl[n].mask) {
+		strcat(buf, t_tbl[n].name);
+		strcat(buf, ", ");
+	    }
+    }
+    if (buf[strlen(buf) - 2] == ',')
+	buf[strlen(buf) - 2] = '\0';
+    return (strcat(buf, "}"));
+}
+
+/* fake a dynamically reconfigurable menu using the 0th entry to deselect
+ * the others
+ */
+static bool
+update_trace_menu(MENU * m)
+{
+    ITEM **items;
+    ITEM *i, **p;
+    bool changed = FALSE;
+
+    items = menu_items(m);
+    i = current_item(m);
+    if (i == items[0]) {
+	if (item_value(i)) {
+	    for (p = items + 1; *p != 0; p++)
+		if (item_value(*p)) {
+		    set_item_value(*p, FALSE);
+		    changed = TRUE;
+		}
+	}
+    }
+    return changed;
+}
+
+static int
+perform_trace_menu(int cmd)
+/* interactively set the trace level */
+{
+    ITEM **ip;
+    unsigned newtrace;
+    int result;
+
+    for (ip = menu_items(mpTrace); *ip; ip++) {
+	unsigned mask = t_tbl[item_index(*ip)].mask;
+	if (mask == 0)
+	    set_item_value(*ip, _nc_tracing == 0);
+	else if ((mask & _nc_tracing) == mask)
+	    set_item_value(*ip, TRUE);
+    }
+
+    result = menu_driver(mpTrace, cmd);
+
+    if (result == E_OK) {
+	if (update_trace_menu(mpTrace) || cmd == REQ_TOGGLE_ITEM) {
+	    newtrace = 0;
+	    for (ip = menu_items(mpTrace); *ip; ip++) {
+		if (item_value(*ip))
+		    newtrace |= t_tbl[item_index(*ip)].mask;
+	    }
+	    trace(newtrace);
+	    Trace(("trace level interactively set to %s", tracetrace(_nc_tracing)));
+
+	    (void) mvprintw(LINES - 2, 0,
+			    "Trace level is %s\n", tracetrace(_nc_tracing));
+	    refresh();
+	}
+    }
+    return result;
+}
+#endif /* TRACE */
+
+/*****************************************************************************/
+
+static int
+menu_number(void)
+{
+    return item_index(current_item(mpBanner)) - (eBanner + 1);
+}
+
+static MENU *
+current_menu(void)
+{
+    MENU *result;
+
+    switch (menu_number()) {
+    case eFile:
+	result = mpFile;
+	break;
+    case eSelect:
+	result = mpSelect;
+	break;
+#ifdef TRACE
+    case eTrace:
+	result = mpTrace;
+	break;
+#endif
+    default:
+	result = 0;
+	break;
+    }
+    return result;
+}
+
+static void
+build_menus(char *filename)
+{
+    static CONST_MENUS char *labels[] =
+    {
+	"File",
+	"Select",
+#ifdef TRACE
+	"Trace",
+#endif
+	(char *) 0
+    };
+    static ITEM *items[SIZEOF(labels)];
+
+    ITEM **ip = items;
+    CONST_MENUS char **ap;
+
+    for (ap = labels; *ap; ap++)
+	*ip++ = new_item(*ap, "");
+    *ip = (ITEM *) 0;
+
+    mpBanner = menu_create(items, SIZEOF(labels) - 1, SIZEOF(labels) - 1, eBanner);
+    set_menu_mark(mpBanner, ">");
+
+    build_file_menu(eFile);
+    build_select_menu(eSelect, filename);
+#ifdef TRACE
+    build_trace_menu(eTrace);
+#endif
+}
+
+static int
+move_menu(MENU * menu, MENU * current, int by_y, int by_x)
+{
+    WINDOW *top_win = menu_win(menu);
+    WINDOW *sub_win = menu_sub(menu);
+    int y0, x0;
+    int y1, x1;
+    int result;
+
+    getbegyx(top_win, y0, x0);
+    y0 += by_y;
+    x0 += by_x;
+
+    getbegyx(sub_win, y1, x1);
+    y1 += by_y;
+    x1 += by_x;
+
+    if ((result = mvwin(top_win, y0, x0)) != ERR) {
+#if defined(NCURSES_VERSION_PATCH) && (NCURSES_VERSION_PATCH < 20060218)
+	sub_win->_begy = y1;
+	sub_win->_begx = x1;
+#else
+	mvwin(sub_win, y1, x1);
+#endif
+	if (menu == current) {
+	    touchwin(top_win);
+	    wnoutrefresh(top_win);
+	}
+    }
+    return result;
+}
+
+/*
+ * Move the menus around on the screen, to test mvwin().
+ */
+static void
+move_menus(MENU * current, int by_y, int by_x)
+{
+    if (move_menu(mpBanner, current, by_y, by_x) != ERR) {
+	erase();
+	wnoutrefresh(stdscr);
+	move_menu(mpFile, current, by_y, by_x);
+	move_menu(mpSelect, current, by_y, by_x);
+#ifdef TRACE
+	move_menu(mpTrace, current, by_y, by_x);
+#endif
+	doupdate();
+    }
+}
+
+static void
+show_status(int ch, MENU * menu)
+{
+    move(LINES - 1, 0);
+    printw("key %s, menu %d, mark %s, match %s",
+	   keyname(ch),
+	   menu_number(),
+	   menu_mark(menu),
+	   menu_pattern(menu));
+    clrtoeol();
+    refresh();
+}
+
+static void
+perform_menus(void)
+{
+    MENU *this_menu;
+    MENU *last_menu = mpFile;
+    int code = E_UNKNOWN_COMMAND;
+    int cmd;
+    int ch = ERR;
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
+#endif
+
+    menu_display(last_menu);
+
+    for (;;) {
+
+	if (ch != ERR)
+	    show_status(ch, last_menu);
+
+	ch = menu_getc(mpBanner);
+
+	/*
+	 * Provide for moving the menu around in the screen using shifted
+	 * cursor keys.
+	 */
+	switch (ch) {
+	case KEY_SF:
+	    move_menus(last_menu, 1, 0);
+	    continue;
+	case KEY_SR:
+	    move_menus(last_menu, -1, 0);
+	    continue;
+	case KEY_SLEFT:
+	    move_menus(last_menu, 0, -1);
+	    continue;
+	case KEY_SRIGHT:
+	    move_menus(last_menu, 0, 1);
+	    continue;
+	}
+	cmd = menu_virtualize(ch);
+
+	switch (cmd) {
+	    /*
+	     * The banner menu acts solely to select one of the other menus.
+	     * Move between its items, wrapping at the left/right limits.
+	     */
+	case REQ_LEFT_ITEM:
+	case REQ_RIGHT_ITEM:
+	    code = menu_driver(mpBanner, cmd);
+	    if (code == E_REQUEST_DENIED) {
+		if (menu_number() > 0)
+		    code = menu_driver(mpBanner, REQ_FIRST_ITEM);
+		else
+		    code = menu_driver(mpBanner, REQ_LAST_ITEM);
+	    }
+	    break;
+	default:
+	    switch (menu_number()) {
+	    case eFile:
+		code = perform_file_menu(cmd);
+		break;
+	    case eSelect:
+		code = perform_select_menu(cmd);
+		break;
+#ifdef TRACE
+	    case eTrace:
+		code = perform_trace_menu(cmd);
+		break;
+#endif
+	    }
+
+	    if ((code == E_REQUEST_DENIED) && (cmd == KEY_MOUSE)) {
+		code = menu_driver(mpBanner, cmd);
+	    }
+
+	    break;
+	}
+
+	if (code == E_OK) {
+	    this_menu = current_menu();
+	    if (this_menu != last_menu) {
+		move(1, 0);
+		clrtobot();
+		box(menu_win(this_menu), 0, 0);
+		refresh();
+
+		/* force the current menu to appear */
+		menu_display(this_menu);
+
+		last_menu = this_menu;
+	    }
+	}
+	wrefresh(menu_win(last_menu));
+	if (code == E_UNKNOWN_COMMAND
+	    || code == E_NOT_POSTED) {
+	    if (menu_number() == eFile)
+		break;
+	    beep();
+	}
+	if (code == E_REQUEST_DENIED)
+	    beep();
+	continue;
+    }
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(0, (mmask_t *) 0);
+#endif
+}
+
+static void
+destroy_menus(void)
+{
+    menu_destroy(mpFile);
+    menu_destroy(mpSelect);
+#ifdef TRACE
+    menu_destroy(mpTrace);
+#endif
+    menu_destroy(mpBanner);
+}
+
+#if HAVE_RIPOFFLINE
+static int
+rip_footer(WINDOW *win, int cols)
+{
+    wbkgd(win, A_REVERSE);
+    werase(win);
+    wmove(win, 0, 0);
+    wprintw(win, "footer: %d columns", cols);
+    wnoutrefresh(win);
+    return OK;
+}
+
+static int
+rip_header(WINDOW *win, int cols)
+{
+    wbkgd(win, A_REVERSE);
+    werase(win);
+    wmove(win, 0, 0);
+    wprintw(win, "header: %d columns", cols);
+    wnoutrefresh(win);
+    return OK;
+}
+#endif /* HAVE_RIPOFFLINE */
+
+static void
+usage(void)
+{
+    static const char *const tbl[] =
+    {
+	"Usage: demo_menus [options]"
+	,""
+	,"Options:"
+#if HAVE_RIPOFFLINE
+	,"  -f       rip-off footer line (can repeat)"
+	,"  -h       rip-off header line (can repeat)"
+#endif
+#ifdef TRACE
+	,"  -t mask  specify default trace-level (may toggle with ^T)"
+#endif
+    };
+    size_t n;
+    for (n = 0; n < SIZEOF(tbl); n++)
+	fprintf(stderr, "%s\n", tbl[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int c;
+
+    setlocale(LC_ALL, "");
+
+    while ((c = getopt(argc, argv, "a:de:fhmp:s:t:")) != -1) {
+	switch (c) {
+#if HAVE_RIPOFFLINE
+	case 'f':
+	    ripoffline(-1, rip_footer);
+	    break;
+	case 'h':
+	    ripoffline(1, rip_header);
+	    break;
+#endif /* HAVE_RIPOFFLINE */
+#ifdef TRACE
+	case 't':
+	    trace(strtoul(optarg, 0, 0));
+	    break;
+#endif
+	default:
+	    usage();
+	}
+    }
+
+    initscr();
+    noraw();
+    cbreak();
+    noecho();
+
+    if (has_colors()) {
+	start_color();
+	init_pair(1, COLOR_RED, COLOR_BLACK);
+	init_pair(2, COLOR_BLUE, COLOR_WHITE);
+    }
+    build_menus(argc > 1 ? argv[1] : 0);
+    perform_menus();
+    destroy_menus();
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the curses menu library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/demo_panels.c b/test/demo_panels.c
new file mode 100644
index 0000000..55593c0
--- /dev/null
+++ b/test/demo_panels.c
@@ -0,0 +1,816 @@
+/****************************************************************************
+ * Copyright (c) 2007,2008 Free Software Foundation, Inc.                   *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: demo_panels.c,v 1.33 2008/08/04 13:33:48 tom Exp $
+ *
+ * Demonstrate a variety of functions from the panel library.
+ */
+
+#include <test.priv.h>
+
+#if USE_LIBPANEL
+
+#include <panel.h>
+
+#define LAST_POS '@'
+#define TEMP_POS '>'
+
+typedef void (*InitPanel) (void);
+typedef void (*FillPanel) (PANEL *);
+
+static bool use_colors = FALSE;
+static bool unboxed = FALSE;
+static FILE *log_in;
+static FILE *log_out;
+
+static void
+close_input(void)
+{
+    if (log_in != 0) {
+	fclose(log_in);
+	log_in = 0;
+    }
+}
+
+static void
+close_output(void)
+{
+    if (log_out != 0) {
+	fclose(log_out);
+	log_out = 0;
+    }
+}
+
+static WINDOW *
+statusline(void)
+{
+    WINDOW *result = stdscr;
+
+    wmove(result, LINES - 1, 0);
+    wclrtoeol(result);
+    return result;
+}
+
+static void
+pflush(void)
+{
+    update_panels();
+    doupdate();
+}
+
+static void
+saywhat(NCURSES_CONST char *text)
+{
+    WINDOW *win = statusline();
+    if (text != 0 && *text != '\0') {
+	waddstr(win, text);
+	waddstr(win, "; ");
+    }
+    waddstr(win, "press any key to continue");
+}
+
+static void
+show_position(NCURSES_CONST char *text,
+	      NCURSES_CONST char *also,
+	      int which,
+	      int ypos,
+	      int xpos)
+{
+    WINDOW *win = statusline();
+
+    wprintw(win, "%s for panel %d now %d,%d%s", text, which, ypos, xpos, also);
+    wmove(stdscr, ypos, xpos);
+}
+
+static int
+get_position(NCURSES_CONST char *text,
+	     NCURSES_CONST char *also,
+	     int which,
+	     int *xpos,
+	     int *ypos)
+{
+    int result = 0;
+    int x1, y1;
+    char cmd;
+    WINDOW *win;
+
+    getyx(stdscr, y1, x1);
+    win = statusline();
+
+    show_position(text, also, which, y1, x1);
+
+    if (log_in != 0) {
+	if (fscanf(log_in, "%c%d,%d\n", &cmd, &y1, &x1) == 3) {
+	    switch (cmd) {
+	    case LAST_POS:
+		result = 1;
+		(void) wgetch(stdscr);
+		break;
+	    case TEMP_POS:
+		result = 0;
+		wrefresh(stdscr);
+		napms(100);
+		break;
+	    default:
+		result = -1;
+		break;
+	    }
+	} else {
+	    result = -1;
+	}
+    } else {
+
+	switch (wgetch(stdscr)) {
+	case QUIT:
+	case ESCAPE:
+	case ERR:
+	    result = -1;
+	    break;
+	case ' ':
+	    result = 1;
+	    break;
+	case KEY_UP:
+	    if (y1 > 0) {
+		--y1;
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_DOWN:
+	    if (y1 < getmaxy(stdscr)) {
+		++y1;
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_LEFT:
+	    if (x1 > 0) {
+		--x1;
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_RIGHT:
+	    if (x1 < getmaxx(stdscr)) {
+		++x1;
+	    } else {
+		beep();
+	    }
+	    break;
+	}
+    }
+
+    wmove(stdscr, y1, x1);
+    *ypos = y1;
+    *xpos = x1;
+
+    if (result >= 0) {
+	if (log_out)
+	    fprintf(log_out, "%c%d,%d\n",
+		    ((result > 0)
+		     ? LAST_POS
+		     : TEMP_POS),
+		    y1, x1);
+    }
+    return result;
+}
+
+static PANEL *
+mkpanel(short color, int rows, int cols, int tly, int tlx)
+{
+    WINDOW *win;
+    PANEL *pan = 0;
+    char *userdata = typeMalloc(char, 3);
+
+    if ((win = newwin(rows, cols, tly, tlx)) != 0) {
+	keypad(win, TRUE);
+	if ((pan = new_panel(win)) == 0) {
+	    delwin(win);
+	} else if (use_colors) {
+	    short fg = (short) ((color == COLOR_BLUE)
+				? COLOR_WHITE
+				: COLOR_BLACK);
+	    short bg = color;
+
+	    init_pair(color, fg, bg);
+	    wbkgdset(win, (chtype) (COLOR_PAIR(color) | ' '));
+	} else if (!unboxed) {
+	    wbkgdset(win, A_BOLD | ' ');
+	}
+    }
+    sprintf(userdata, "p%d", color % 8);
+    set_panel_userptr(pan, (NCURSES_CONST void *) userdata);
+    return pan;
+}
+
+static void
+my_remove_panel(PANEL ** pans, int which)
+{
+    if (pans[which] != 0) {
+	PANEL *pan = pans[which];
+	WINDOW *win = panel_window(pan);
+	char *user = (char *) panel_userptr(pan);
+
+	free(user);
+	del_panel(pan);
+	delwin(win);
+
+	pans[which] = 0;
+    }
+}
+
+#undef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define ABS(a)   ((a) < 0 ? -(a) : (a))
+
+static void
+my_create_panel(PANEL ** pans, int which, FillPanel myFill)
+{
+    PANEL *pan = 0;
+    int code;
+    short pair = (short) which;
+    short fg = (short) ((pair == COLOR_BLUE) ? COLOR_WHITE : COLOR_BLACK);
+    short bg = pair;
+    int x0, y0, x1, y1;
+
+    init_pair(pair, fg, bg);
+
+    /* remove the old panel, if any */
+    my_remove_panel(pans, which);
+
+    /* get the position of one corner */
+    wmove(stdscr, getmaxy(stdscr) / 2, getmaxx(stdscr) / 2);
+    getyx(stdscr, y0, x0);
+    while ((code = get_position("First corner", "", which, &x0, &y0)) == 0) {
+	;
+    }
+
+    if (code > 0) {
+	char also[80];
+	sprintf(also, " (first %d,%d)", y0, x0);
+	/* get the position of the opposite corner */
+	while ((code = get_position("Opposite corner",
+				    also, which, &x1, &y1)) == 0) {
+	    ;
+	}
+
+	if (code > 0) {
+	    int tly = MIN(y0, y1);
+	    int tlx = MIN(x0, x1);
+	    pan = mkpanel(pair, ABS(y1 - y0) + 1, ABS(x1 - x0) + 1, tly, tlx);
+	    /* finish */
+	    myFill(pan);
+	    pans[which] = pan;
+	    pflush();
+	    wmove(stdscr, y1, x1);
+	}
+    }
+}
+
+static void
+my_move_panel(PANEL ** pans, int which, bool continuous)
+{
+    if (pans[which] != 0) {
+	int code;
+	int y0, x0;
+	int y1, x1;
+	WINDOW *win = panel_window(pans[which]);
+	char also[80];
+
+	getbegyx(win, y0, x0);
+	sprintf(also, " (start %d,%d)", y0, x0);
+	wmove(stdscr, y0, x0);
+	while ((code = get_position("Move panel", also, which, &x1, &y1)) == 0) {
+	    if (continuous) {
+		move_panel(pans[which], y1, x1);
+		pflush();
+	    }
+	}
+	if (code > 0) {
+	    move_panel(pans[which], y1, x1);
+	}
+    }
+}
+
+static void
+my_resize_panel(PANEL ** pans, int which, FillPanel myFill)
+{
+    if (pans[which] != 0) {
+	int code;
+	int y0, x0;
+	int y1, x1;
+	WINDOW *win = panel_window(pans[which]);
+	char also[80];
+
+	getbegyx(win, y0, x0);
+	sprintf(also, " (start %d,%d)", y0, x0);
+	wmove(stdscr, y0, x0);
+	while ((code = get_position("Resize panel",
+				    also, which, &x1, &y1)) == 0) {
+	    ;
+	}
+	if (code > 0) {
+	    WINDOW *next = newwin(ABS(y1 - y0) + 1,
+				  ABS(x1 - x0) + 1,
+				  MIN(y0, y1),
+				  MIN(x0, x1));
+	    if (next != 0) {
+		keypad(next, TRUE);
+		if (use_colors) {
+		    wbkgdset(next, (chtype) (COLOR_PAIR(which) | ' '));
+		} else if (!unboxed) {
+		    wbkgdset(next, A_BOLD | ' ');
+		}
+		replace_panel(pans[which], next);
+		myFill(pans[which]);
+		delwin(win);
+	    }
+	}
+    }
+}
+
+static void
+init_panel(void)
+{
+    register int y, x;
+
+    for (y = 0; y < LINES - 1; y++) {
+	for (x = 0; x < COLS; x++)
+	    wprintw(stdscr, "%d", (y + x) % 10);
+    }
+}
+
+static void
+fill_panel(PANEL * pan)
+{
+    WINDOW *win = panel_window(pan);
+    const char *userptr = (const char *) panel_userptr(pan);
+    int num = (userptr && *userptr) ? userptr[1] : '?';
+    int y, x;
+
+    wmove(win, 1, 1);
+    wprintw(win, "-pan%c-", num);
+    wclrtoeol(win);
+    box(win, 0, 0);
+    for (y = 2; y < getmaxy(win) - 1; y++) {
+	for (x = 1; x < getmaxx(win) - 1; x++) {
+	    wmove(win, y, x);
+	    waddch(win, UChar(num));
+	}
+    }
+}
+
+static void
+fill_unboxed(PANEL * pan)
+{
+    WINDOW *win = panel_window(pan);
+    const char *userptr = (const char *) panel_userptr(pan);
+    int num = (userptr && *userptr) ? userptr[1] : '?';
+    int y, x;
+
+    for (y = 0; y < getmaxy(win); y++) {
+	for (x = 0; x < getmaxx(win); x++) {
+	    wmove(win, y, x);
+	    waddch(win, UChar(num));
+	}
+    }
+}
+
+#if USE_WIDEC_SUPPORT
+static void
+make_fullwidth_digit(cchar_t *target, int digit)
+{
+    wchar_t source[2];
+
+    source[0] = digit + 0xff10;
+    source[1] = 0;
+    setcchar(target, source, A_NORMAL, 0, 0);
+}
+
+static void
+init_wide_panel(void)
+{
+    int digit;
+    cchar_t temp[10];
+
+    for (digit = 0; digit < 10; ++digit)
+	make_fullwidth_digit(&temp[digit], digit);
+
+    do {
+	int y, x;
+	getyx(stdscr, y, x);
+	digit = (y + x / 2) % 10;
+    } while (add_wch(&temp[digit]) != ERR);
+}
+
+static void
+fill_wide_panel(PANEL * pan)
+{
+    WINDOW *win = panel_window(pan);
+    int num = ((const char *) panel_userptr(pan))[1];
+    int y, x;
+
+    wmove(win, 1, 1);
+    wprintw(win, "-pan%c-", num);
+    wclrtoeol(win);
+    box(win, 0, 0);
+    for (y = 2; y < getmaxy(win) - 1; y++) {
+	for (x = 1; x < getmaxx(win) - 1; x++) {
+	    wmove(win, y, x);
+	    waddch(win, UChar(num));
+	}
+    }
+}
+#endif
+
+#define MAX_PANELS 5
+
+static int
+which_panel(PANEL * px[MAX_PANELS + 1], PANEL * pan)
+{
+    int result = 0;
+    int j;
+
+    for (j = 1; j <= MAX_PANELS; ++j) {
+	if (px[j] == pan) {
+	    result = j;
+	    break;
+	}
+    }
+    return result;
+}
+
+static void
+show_panels(PANEL * px[MAX_PANELS + 1])
+{
+    static const char *help[] =
+    {
+	"",
+	"Commands are letter/digit pairs.  Digits are the panel number.",
+	"",
+	"  b - put the panel on the bottom of the stack",
+	"  c - create the panel",
+	"  d - delete the panel",
+	"  h - hide the panel",
+	"  m - move the panel (M for continuous move)",
+	"  r - resize the panel",
+	"  s - show the panel",
+	"  b - put the panel on the top of the stack"
+    };
+
+    struct {
+	bool valid;
+	bool hidden;
+	PANEL *above;
+	PANEL *below;
+    } table[MAX_PANELS + 1];
+
+    WINDOW *win;
+    PANEL *pan;
+    int j;
+
+    for (j = 1; j <= MAX_PANELS; ++j) {
+	table[j].valid = (px[j] != 0);
+	if (table[j].valid) {
+	    table[j].hidden = panel_hidden(px[j]);
+	    table[j].above = panel_above(px[j]);
+	    table[j].below = panel_below(px[j]);
+	}
+    }
+
+    if ((win = newwin(LINES - 1, COLS, 0, 0)) != 0) {
+	keypad(win, TRUE);
+	if ((pan = new_panel(win)) != 0) {
+	    werase(win);
+	    mvwprintw(win, 0, 0, "Panels:\n");
+	    for (j = 1; j <= MAX_PANELS; ++j) {
+		if (table[j].valid) {
+		    wprintw(win, " %d:", j);
+		    if (table[j].hidden) {
+			waddstr(win, " hidden");
+		    } else {
+			if (table[j].above) {
+			    wprintw(win, " above %d",
+				    which_panel(px, table[j].above));
+			}
+			if (table[j].below) {
+			    wprintw(win, "%s below %d",
+				    table[j].above ? "," : "",
+				    which_panel(px, table[j].below));
+			}
+		    }
+		    waddch(win, '\n');
+		}
+	    }
+	    for (j = 0; j < (int) SIZEOF(help); ++j) {
+		if (wprintw(win, "%s\n", help[j]) == ERR)
+		    break;
+	    }
+	    wgetch(win);
+	    del_panel(pan);
+	    pflush();
+	}
+	delwin(win);
+    }
+}
+
+#define wrapper(func) \
+static int my_##func(PANEL *pan) \
+{ \
+    int code = ERR; \
+    if (pan != 0) { \
+	code = func(pan); \
+    } \
+    return code; \
+}
+/* *INDENT-OFF* */
+wrapper(bottom_panel)
+wrapper(hide_panel)
+wrapper(show_panel)
+wrapper(top_panel)
+/* *INDENT-ON* */
+
+static void
+do_panel(PANEL * px[MAX_PANELS + 1],
+	 NCURSES_CONST char *cmd,
+	 FillPanel myFill)
+{
+    int which = cmd[1] - '0';
+
+    if (which < 1 || which > MAX_PANELS) {
+	beep();
+	return;
+    }
+
+    if (log_in != 0) {
+	pflush();
+    }
+
+    saywhat(cmd);
+    switch (*cmd) {
+    case 'b':
+	my_bottom_panel(px[which]);
+	break;
+    case 'c':
+	my_create_panel(px, which, myFill);
+	break;
+    case 'd':
+	my_remove_panel(px, which);
+	break;
+    case 'h':
+	my_hide_panel(px[which]);
+	break;
+    case 'm':
+	my_move_panel(px, which, FALSE);
+	break;
+    case 'M':
+	my_move_panel(px, which, TRUE);
+	break;
+    case 'r':
+	my_resize_panel(px, which, myFill);
+	break;
+    case 's':
+	my_show_panel(px[which]);
+	break;
+    case 't':
+	my_top_panel(px[which]);
+	break;
+    }
+}
+
+static bool
+ok_letter(int ch)
+{
+    return isalpha(UChar(ch)) && strchr("bcdhmMrst", ch) != 0;
+}
+
+static bool
+ok_digit(int ch)
+{
+    return isdigit(UChar(ch)) && (ch >= '1') && (ch - '0' <= MAX_PANELS);
+}
+
+/*
+ * A command consists of one or more letter/digit pairs separated by a space.
+ * Digits are limited to 1..MAX_PANELS.
+ *
+ * End the command with a newline.  Reject other characters.
+ */
+static bool
+get_command(PANEL * px[MAX_PANELS + 1], char *buffer, int limit)
+{
+    int length = 0;
+    int y0, x0;
+    int c0, ch;
+    WINDOW *win;
+
+    getyx(stdscr, y0, x0);
+    win = statusline();
+    waddstr(win, "Command:");
+    buffer[length = 0] = '\0';
+
+    if (log_in != 0) {
+	if (fgets(buffer, limit - 3, log_in) != 0) {
+	    length = (int) strlen(buffer);
+	    while (length > 0 && isspace(UChar(buffer[length - 1])))
+		buffer[--length] = '\0';
+	    waddstr(win, buffer);
+	} else {
+	    close_input();
+	}
+	(void) wgetch(win);
+    } else {
+	c0 = 0;
+	for (;;) {
+	    ch = wgetch(win);
+	    if (ch == ERR || ch == QUIT || ch == ESCAPE) {
+		buffer[0] = '\0';
+		break;
+	    } else if (ch == CTRL('L')) {
+		wrefresh(curscr);
+	    } else if (ch == '\n' || ch == KEY_ENTER) {
+		break;
+	    } else if (ch == '?') {
+		show_panels(px);
+	    } else if (length + 3 < limit) {
+		if (ch >= KEY_MIN) {
+		    beep();
+		} else if (ok_letter(UChar(ch))) {
+		    if (isalpha(UChar(c0))) {
+			beep();
+		    } else if (isdigit(UChar(c0))) {
+			wprintw(win, " %c", ch);
+			buffer[length++] = ' ';
+			buffer[length++] = (char) (c0 = ch);
+		    } else {
+			wprintw(win, "%c", ch);
+			buffer[length++] = (char) (c0 = ch);
+		    }
+		} else if (ok_digit(ch)) {
+		    if (isalpha(UChar(c0))) {
+			wprintw(win, "%c", ch);
+			buffer[length++] = (char) (c0 = ch);
+		    } else {
+			beep();
+		    }
+		} else if (ch == ' ') {
+		    if (isdigit(UChar(c0))) {
+			wprintw(win, "%c", ch);
+			buffer[length++] = (char) (c0 = ch);
+		    } else {
+			beep();
+		    }
+		} else {
+		    beep();
+		}
+	    } else {
+		beep();
+	    }
+	}
+    }
+
+    wmove(stdscr, y0, x0);
+
+    buffer[length] = '\0';
+    if (log_out && length) {
+	fprintf(log_out, "%s\n", buffer);
+    }
+    return (length != 0);
+}
+
+static void
+demo_panels(InitPanel myInit, FillPanel myFill)
+{
+    int itmp;
+    PANEL *px[MAX_PANELS + 1];
+    char buffer[BUFSIZ];
+
+    scrollok(stdscr, FALSE);	/* we don't want stdscr to scroll! */
+    refresh();
+
+    myInit();
+    memset(px, 0, sizeof(px));
+
+    while (get_command(px, buffer, sizeof(buffer))) {
+	int limit = (int) strlen(buffer);
+	for (itmp = 0; itmp < limit; itmp += 3) {
+	    do_panel(px, buffer + itmp, myFill);
+	}
+	pflush();
+    }
+#if NO_LEAKS
+    for (itmp = 1; itmp <= MAX_PANELS; ++itmp) {
+	my_remove_panel(px, itmp);
+    }
+#endif
+}
+
+static void
+usage(void)
+{
+    static const char *const tbl[] =
+    {
+	"Usage: demo_panels [options]"
+	,""
+	,"Options:"
+	,"  -i file  read commands from file"
+	,"  -o file  record commands in file"
+	,"  -m       do not use colors"
+#if USE_WIDEC_SUPPORT
+	,"  -w       use wide-characters in panels and background"
+#endif
+	,"  -x       do not enclose panels in boxes"
+    };
+    size_t n;
+    for (n = 0; n < SIZEOF(tbl); n++)
+	fprintf(stderr, "%s\n", tbl[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int c;
+    bool monochrome = FALSE;
+    InitPanel myInit = init_panel;
+    FillPanel myFill = fill_panel;
+
+    setlocale(LC_ALL, "");
+
+    while ((c = getopt(argc, argv, "i:o:mwx")) != -1) {
+	switch (c) {
+	case 'i':
+	    log_in = fopen(optarg, "r");
+	    break;
+	case 'o':
+	    log_out = fopen(optarg, "w");
+	    break;
+	case 'm':
+	    monochrome = TRUE;
+	    break;
+#if USE_WIDEC_SUPPORT
+	case 'w':
+	    myInit = init_wide_panel;
+	    myFill = fill_wide_panel;
+	    break;
+#endif
+	case 'x':
+	    unboxed = TRUE;
+	    break;
+	default:
+	    usage();
+	}
+    }
+    if (unboxed)
+	myFill = fill_unboxed;
+
+    initscr();
+    cbreak();
+    noecho();
+    keypad(stdscr, TRUE);
+
+    use_colors = monochrome ? FALSE : has_colors();
+    if (use_colors)
+	start_color();
+
+    demo_panels(myInit, myFill);
+    endwin();
+
+    close_input();
+    close_output();
+
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the curses panel library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/demo_termcap.c b/test/demo_termcap.c
new file mode 100644
index 0000000..3e85648
--- /dev/null
+++ b/test/demo_termcap.c
@@ -0,0 +1,171 @@
+/****************************************************************************
+ * Copyright (c) 2005-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * Author: Thomas E. Dickey
+ *
+ * $Id: demo_termcap.c,v 1.7 2008/02/09 18:08:36 tom Exp $
+ *
+ * A simple demo of the termcap interface.
+ */
+#define USE_TINFO
+#include <test.priv.h>
+
+#if HAVE_TGETENT
+
+#define isCapName(c) (isgraph(c) && strchr("^#=:\\", c) == 0)
+
+static void
+dumpit(char *cap)
+{
+    /*
+     * One of the limitations of the termcap interface is that the library
+     * cannot determine the size of the buffer passed via tgetstr(), nor the
+     * amount of space remaining.  This demo simply reuses the whole buffer
+     * for each call; a normal termcap application would try to use the buffer
+     * to hold all of the strings extracted from the terminal entry.
+     */
+    char area[1024], *ap = area;
+    char *str;
+    int num;
+
+    if ((str = tgetstr(cap, &ap)) != 0) {
+	/*
+	 * Note that the strings returned are mostly terminfo format, since
+	 * ncurses does not convert except for a handful of special cases.
+	 */
+	printf("str %s = ", cap);
+	while (*str != 0) {
+	    int ch = UChar(*str++);
+	    switch (ch) {
+	    case '\177':
+		fputs("^?", stdout);
+		break;
+	    case '\033':
+		fputs("\\E", stdout);
+		break;
+	    case '\b':
+		fputs("\\b", stdout);
+		break;
+	    case '\f':
+		fputs("\\f", stdout);
+		break;
+	    case '\n':
+		fputs("\\n", stdout);
+		break;
+	    case '\r':
+		fputs("\\r", stdout);
+		break;
+	    case ' ':
+		fputs("\\s", stdout);
+		break;
+	    case '\t':
+		fputs("\\t", stdout);
+		break;
+	    case '^':
+		fputs("\\^", stdout);
+		break;
+	    case ':':
+		fputs("\\072", stdout);
+		break;
+	    case '\\':
+		fputs("\\\\", stdout);
+		break;
+	    default:
+		if (isgraph(ch))
+		    fputc(ch, stdout);
+		else if (ch < 32)
+		    printf("^%c", ch + '@');
+		else
+		    printf("\\%03o", ch);
+		break;
+	    }
+	}
+	printf("\n");
+    } else if ((num = tgetnum(cap)) >= 0) {
+	printf("num %s = %d\n", cap, num);
+    } else if ((num = tgetflag(cap)) > 0) {
+	printf("flg %s\n", cap);
+    }
+    fflush(stdout);
+}
+
+static void
+demo_termcap(char *name)
+{
+    char buffer[1024];
+
+    printf("Terminal type %s\n", name);
+    if (tgetent(buffer, name) >= 0) {
+	char cap[3];
+	int c1, c2;
+
+	cap[2] = 0;
+	for (c1 = 0; c1 < 256; ++c1) {
+	    cap[0] = c1;
+	    if (isCapName(c1)) {
+		for (c2 = 0; c2 < 256; ++c2) {
+		    cap[1] = c2;
+		    if (isCapName(c2)) {
+			dumpit(cap);
+		    }
+		}
+	    }
+	}
+    }
+}
+
+int
+main(int argc, char *argv[])
+{
+    int n;
+    char *name;
+
+    if (argc > 1) {
+	for (n = 1; n < argc; ++n) {
+	    demo_termcap(argv[n]);
+	}
+    } else if ((name = getenv("TERM")) != 0) {
+	demo_termcap(name);
+    } else {
+	static char dumb[] = "dumb";
+	demo_termcap(dumb);
+    }
+
+    ExitProgram(EXIT_SUCCESS);
+}
+
+#else
+int
+main(int argc GCC_UNUSED,
+     char *argv[]GCC_UNUSED)
+{
+    printf("This program requires termcap\n");
+    exit(EXIT_FAILURE);
+}
+#endif
diff --git a/test/ditto.c b/test/ditto.c
new file mode 100644
index 0000000..b8aebac
--- /dev/null
+++ b/test/ditto.c
@@ -0,0 +1,421 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * Author: Thomas E. Dickey (1998-on)
+ *
+ * $Id: ditto.c,v 1.32 2008/08/04 13:21:41 tom Exp $
+ *
+ * The program illustrates how to set up multiple screens from a single
+ * program.
+ *
+ * If openpty() is supported, the command line parameters are titles for
+ * the windows showing each screen's data.
+ *
+ * If openpty() is not supported, you must invoke the program by specifying
+ * another terminal on the same machine by specifying its device, e.g.,
+ *	ditto /dev/ttyp1
+ */
+#include <test.priv.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
+
+#ifdef USE_XTERM_PTY
+#include USE_OPENPTY_HEADER
+#endif
+
+#define MAX_FIFO 256
+
+#define THIS_FIFO(n) ((n) % MAX_FIFO)
+#define NEXT_FIFO(n) THIS_FIFO((n) + 1)
+
+typedef struct {
+    unsigned long sequence;
+    int head;
+    int tail;
+    int data[MAX_FIFO];
+} FIFO;
+
+typedef struct {
+    unsigned long sequence;
+} PEEK;
+
+/*
+ * Data "owned" for a single screen.  Each screen is divided into windows that
+ * show the text read from each terminal.  Input from a given screen will also
+ * be read into one window per screen.
+ */
+typedef struct {
+    FILE *input;
+    FILE *output;
+    SCREEN *screen;		/* this screen - curses internal data */
+    int which1;			/* this screen's index in DITTO[] array */
+    int length;			/* length of windows[] and peeks[] */
+    char **titles;		/* per-window titles */
+    WINDOW **windows;		/* display data from each screen */
+    PEEK *peeks;		/* indices for each screen's fifo */
+    FIFO fifo;			/* fifo for this screen */
+#ifdef USE_PTHREADS
+    pthread_t thread;
+#endif
+} DITTO;
+
+/*
+ * Structure used to pass multiple parameters via the use_screen()
+ * single-parameter interface.
+ */
+typedef struct {
+    int source;			/* which screen did character come from */
+    int target;			/* which screen is character going to */
+    DITTO *ditto;		/* data for all screens */
+} DDATA;
+
+static void
+failed(const char *s)
+{
+    perror(s);
+    ExitProgram(EXIT_FAILURE);
+}
+
+static void
+usage(void)
+{
+    fprintf(stderr, "usage: ditto [terminal1 ...]\n");
+    ExitProgram(EXIT_FAILURE);
+}
+
+/* Add to the head of the fifo, checking for overflow. */
+static void
+put_fifo(FIFO * fifo, int value)
+{
+    int next = NEXT_FIFO(fifo->head);
+    if (next == fifo->tail)
+	fifo->tail = NEXT_FIFO(fifo->tail);
+    fifo->data[next] = value;
+    fifo->head = next;
+    fifo->sequence += 1;
+}
+
+/* Get data from the tail (oldest part) of the fifo, returning -1 if no data.
+ * Since each screen can peek into the fifo, we do not update the tail index,
+ * but modify the peek-index.
+ *
+ * FIXME - test/workaround for case where fifo gets more than a buffer
+ * ahead of peek.
+ */
+static int
+peek_fifo(FIFO * fifo, PEEK * peek)
+{
+    int result = -1;
+    if (peek->sequence < fifo->sequence) {
+	peek->sequence += 1;
+	result = fifo->data[THIS_FIFO(peek->sequence)];
+    }
+    return result;
+}
+
+static FILE *
+open_tty(char *path)
+{
+    FILE *fp;
+#ifdef USE_XTERM_PTY
+    int amaster;
+    int aslave;
+    char slave_name[1024];
+    char s_option[sizeof(slave_name) + 80];
+    char *leaf;
+
+    if (openpty(&amaster, &aslave, slave_name, 0, 0) != 0
+	|| strlen(slave_name) > sizeof(slave_name) - 1)
+	failed("openpty");
+    if ((leaf = strrchr(slave_name, '/')) == 0) {
+	errno = EISDIR;
+	failed(slave_name);
+    }
+    sprintf(s_option, "-S%s/%d", slave_name, aslave);
+    if (fork()) {
+	execlp("xterm", "xterm", s_option, "-title", path, (char *) 0);
+	_exit(0);
+    }
+    fp = fdopen(amaster, "r+");
+    if (fp == 0)
+	failed(path);
+#else
+    struct stat sb;
+
+    if (stat(path, &sb) < 0)
+	failed(path);
+    if ((sb.st_mode & S_IFMT) != S_IFCHR) {
+	errno = ENOTTY;
+	failed(path);
+    }
+    fp = fopen(path, "r+");
+    if (fp == 0)
+	failed(path);
+    printf("opened %s\n", path);
+#endif
+    assert(fp != 0);
+    return fp;
+}
+
+static void
+init_screen(SCREEN *sp GCC_UNUSED, void *arg)
+{
+    DITTO *target = (DITTO *) arg;
+    int high, wide;
+    int k;
+
+    cbreak();
+    noecho();
+    scrollok(stdscr, TRUE);
+    box(stdscr, 0, 0);
+
+    target->windows = typeCalloc(WINDOW *, (size_t) target->length);
+    target->peeks = typeCalloc(PEEK, (size_t) target->length);
+
+    high = (LINES - 2) / target->length;
+    wide = (COLS - 2);
+    for (k = 0; k < target->length; ++k) {
+	WINDOW *outer = newwin(high, wide, 1 + (high * k), 1);
+	WINDOW *inner = derwin(outer, high - 2, wide - 2, 1, 1);
+
+	box(outer, 0, 0);
+	mvwaddstr(outer, 0, 2, target->titles[k]);
+	wnoutrefresh(outer);
+
+	scrollok(inner, TRUE);
+	keypad(inner, TRUE);
+#ifndef USE_PTHREADS
+	nodelay(inner, TRUE);
+#endif
+
+	target->windows[k] = inner;
+    }
+    doupdate();
+}
+
+static void
+open_screen(DITTO * target, char **source, int length, int which1)
+{
+    if (which1 != 0) {
+	target->input =
+	    target->output = open_tty(source[which1]);
+    } else {
+	target->input = stdin;
+	target->output = stdout;
+    }
+
+    target->which1 = which1;
+    target->titles = source;
+    target->length = length;
+    target->screen = newterm((char *) 0,	/* assume $TERM is the same */
+			     target->output,
+			     target->input);
+
+    if (target->screen == 0)
+	failed("newterm");
+
+    (void) USING_SCREEN(target->screen, init_screen, target);
+}
+
+static int
+close_screen(SCREEN *sp GCC_UNUSED, void *arg GCC_UNUSED)
+{
+    (void) sp;
+    (void) arg;
+    return endwin();
+}
+
+/*
+ * Read data from the 'source' screen.
+ */
+static int
+read_screen(SCREEN *sp GCC_UNUSED, void *arg)
+{
+    DDATA *data = (DDATA *) arg;
+    DITTO *ditto = &(data->ditto[data->source]);
+    WINDOW *win = ditto->windows[data->source];
+    int ch = wgetch(win);
+
+    if (ch > 0 && ch < 256)
+	put_fifo(&(ditto->fifo), ch);
+    else
+	ch = ERR;
+
+    return ch;
+}
+
+/*
+ * Write all of the data that's in fifos for the 'target' screen.
+ */
+static int
+write_screen(SCREEN *sp GCC_UNUSED, void *arg GCC_UNUSED)
+{
+    DDATA *data = (DDATA *) arg;
+    DITTO *ditto = &(data->ditto[data->target]);
+    bool changed = FALSE;
+    int which;
+
+    for (which = 0; which < ditto->length; ++which) {
+	WINDOW *win = ditto->windows[which];
+	FIFO *fifo = &(data->ditto[which].fifo);
+	PEEK *peek = &(ditto->peeks[which]);
+	int ch;
+
+	while ((ch = peek_fifo(fifo, peek)) > 0) {
+	    changed = TRUE;
+
+	    waddch(win, (chtype) ch);
+	    wnoutrefresh(win);
+	}
+    }
+
+    if (changed)
+	doupdate();
+    return OK;
+}
+
+static void
+show_ditto(DITTO * data, int count, DDATA * ddata)
+{
+    int n;
+
+    for (n = 0; n < count; n++) {
+	ddata->target = n;
+	USING_SCREEN(data[n].screen, write_screen, (void *) ddata);
+    }
+}
+
+#ifdef USE_PTHREADS
+static void *
+handle_screen(void *arg)
+{
+    DDATA ddata;
+    int ch;
+
+    memset(&ddata, 0, sizeof(ddata));
+    ddata.ditto = (DITTO *) arg;
+    ddata.source = ddata.ditto->which1;
+    ddata.ditto -= ddata.source;	/* -> base of array */
+
+    for (;;) {
+	ch = read_screen(ddata.ditto->screen, &ddata);
+	if (ch == CTRL('D')) {
+	    int later = (ddata.source ? ddata.source : -1);
+	    int j;
+
+	    for (j = ddata.ditto->length - 1; j > 0; --j) {
+		if (j != later) {
+		    pthread_cancel(ddata.ditto[j].thread);
+		}
+	    }
+	    if (later > 0) {
+		pthread_cancel(ddata.ditto[later].thread);
+	    }
+	    break;
+	}
+	show_ditto(ddata.ditto, ddata.ditto->length, &ddata);
+    }
+    return NULL;
+}
+#endif
+
+int
+main(int argc, char *argv[])
+{
+    int j;
+    DITTO *data;
+#ifndef USE_PTHREADS
+    int count;
+#endif
+
+    if (argc <= 1)
+	usage();
+
+    if ((data = typeCalloc(DITTO, (size_t) argc)) == 0)
+	failed("calloc data");
+
+    for (j = 0; j < argc; j++) {
+	open_screen(&data[j], argv, argc, j);
+    }
+
+#ifdef USE_PTHREADS
+    /*
+     * For multi-threaded operation, set up a reader for each of the screens.
+     * That uses blocking I/O rather than polling for input, so no calls to
+     * napms() are needed.
+     */
+    for (j = 0; j < argc; j++) {
+	(void) pthread_create(&(data[j].thread), NULL, handle_screen, &data[j]);
+    }
+    pthread_join(data[1].thread, NULL);
+#else
+    /*
+     * Loop, reading characters from any of the inputs and writing to all
+     * of the screens.
+     */
+    for (count = 0;; ++count) {
+	DDATA ddata;
+	int ch;
+	int which = (count % argc);
+
+	napms(20);
+
+	ddata.source = which;
+	ddata.ditto = data;
+
+	ch = USING_SCREEN(data[which].screen, read_screen, &ddata);
+	if (ch == CTRL('D')) {
+	    break;
+	} else if (ch != ERR) {
+	    show_ditto(data, argc, &ddata);
+	}
+    }
+#endif
+
+    /*
+     * Cleanup and exit
+     */
+    for (j = argc - 1; j >= 0; j--) {
+	USING_SCREEN(data[j].screen, close_screen, 0);
+	fprintf(data[j].output, "**Closed\r\n");
+
+	/*
+	 * Closing before a delscreen() helps ncurses determine that there
+	 * is no valid output buffer, and can remove the setbuf() data.
+	 */
+	fflush(data[j].output);
+	fclose(data[j].output);
+	delscreen(data[j].screen);
+    }
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/dots.c b/test/dots.c
new file mode 100644
index 0000000..2d64718
--- /dev/null
+++ b/test/dots.c
@@ -0,0 +1,162 @@
+/****************************************************************************
+ * Copyright (c) 1999-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * Author: Thomas E. Dickey <dickey@clark.net> 1999
+ *
+ * $Id: dots.c,v 1.17 2008/02/09 18:08:50 tom Exp $
+ *
+ * A simple demo of the terminfo interface.
+ */
+#define USE_TINFO
+#include <test.priv.h>
+
+#if HAVE_SETUPTERM
+
+#include <time.h>
+
+#define valid(s) ((s != 0) && s != (char *)-1)
+
+static bool interrupted = FALSE;
+static long total_chars = 0;
+static time_t started;
+
+static int
+outc(TPUTS_ARG c)
+{
+    if (interrupted) {
+	char tmp = c;
+	write(STDOUT_FILENO, &tmp, 1);
+    } else {
+	putc(c, stdout);
+    }
+    return 0;
+}
+
+static bool
+outs(char *s)
+{
+    if (valid(s)) {
+	tputs(s, 1, outc);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+static void
+cleanup(void)
+{
+    outs(exit_attribute_mode);
+    if (!outs(orig_colors))
+	outs(orig_pair);
+    outs(clear_screen);
+    outs(cursor_normal);
+
+    printf("\n\n%ld total chars, rate %.2f/sec\n",
+	   total_chars,
+	   ((double) (total_chars) / (time((time_t *) 0) - started)));
+}
+
+static void
+onsig(int n GCC_UNUSED)
+{
+    interrupted = TRUE;
+}
+
+static float
+ranf(void)
+{
+    long r = (rand() & 077777);
+    return ((float) r / 32768.);
+}
+
+int
+main(
+	int argc GCC_UNUSED,
+	char *argv[]GCC_UNUSED)
+{
+    int x, y, z, p;
+    float r;
+    float c;
+
+    CATCHALL(onsig);
+
+    srand((unsigned) time(0));
+    setupterm((char *) 0, 1, (int *) 0);
+    outs(clear_screen);
+    outs(cursor_invisible);
+    if (max_colors > 1) {
+	if (!valid(set_a_foreground)
+	    || !valid(set_a_background)
+	    || (!valid(orig_colors) && !valid(orig_pair)))
+	    max_colors = -1;
+    }
+
+    r = (float) (lines - 4);
+    c = (float) (columns - 4);
+    started = time((time_t *) 0);
+
+    while (!interrupted) {
+	x = (int) (c * ranf()) + 2;
+	y = (int) (r * ranf()) + 2;
+	p = (ranf() > 0.9) ? '*' : ' ';
+
+	tputs(tparm3(cursor_address, y, x), 1, outc);
+	if (max_colors > 0) {
+	    z = (int) (ranf() * max_colors);
+	    if (ranf() > 0.01) {
+		tputs(tparm2(set_a_foreground, z), 1, outc);
+	    } else {
+		tputs(tparm2(set_a_background, z), 1, outc);
+		napms(1);
+	    }
+	} else if (valid(exit_attribute_mode)
+		   && valid(enter_reverse_mode)) {
+	    if (ranf() <= 0.01) {
+		outs((ranf() > 0.6)
+		     ? enter_reverse_mode
+		     : exit_attribute_mode);
+		napms(1);
+	    }
+	}
+	outc(p);
+	fflush(stdout);
+	++total_chars;
+    }
+    cleanup();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(int argc GCC_UNUSED,
+     char *argv[]GCC_UNUSED)
+{
+    fprintf(stderr, "This program requires terminfo\n");
+    exit(EXIT_FAILURE);
+}
+#endif
diff --git a/test/dots_mvcur.c b/test/dots_mvcur.c
new file mode 100644
index 0000000..f023023
--- /dev/null
+++ b/test/dots_mvcur.c
@@ -0,0 +1,171 @@
+/****************************************************************************
+ * Copyright (c) 1999-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * Author: Thomas E. Dickey - 2007
+ *
+ * $Id: dots_mvcur.c,v 1.2 2008/02/09 18:08:57 tom Exp $
+ *
+ * A simple demo of the terminfo interface, and mvcur.
+ */
+#define USE_TINFO
+#include <test.priv.h>
+
+#if HAVE_SETUPTERM
+
+#include <time.h>
+
+#define valid(s) ((s != 0) && s != (char *)-1)
+
+static bool interrupted = FALSE;
+static long total_chars = 0;
+static time_t started;
+
+static int
+outc(TPUTS_ARG c)
+{
+    if (interrupted) {
+	char tmp = c;
+	write(STDOUT_FILENO, &tmp, 1);
+    } else {
+	putc(c, stdout);
+    }
+    return 0;
+}
+
+static bool
+outs(char *s)
+{
+    if (valid(s)) {
+	tputs(s, 1, outc);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+static void
+cleanup(void)
+{
+    outs(exit_attribute_mode);
+    if (!outs(orig_colors))
+	outs(orig_pair);
+    outs(clear_screen);
+    outs(cursor_normal);
+
+    printf("\n\n%ld total chars, rate %.2f/sec\n",
+	   total_chars,
+	   ((double) (total_chars) / (time((time_t *) 0) - started)));
+}
+
+static void
+onsig(int n GCC_UNUSED)
+{
+    interrupted = TRUE;
+}
+
+static float
+ranf(void)
+{
+    long r = (rand() & 077777);
+    return ((float) r / 32768.);
+}
+
+int
+main(
+	int argc GCC_UNUSED,
+	char *argv[]GCC_UNUSED)
+{
+    int x0 = 1, y0 = 1;
+    int x, y, z, p;
+    float r;
+    float c;
+    SCREEN *sp;
+
+    CATCHALL(onsig);
+
+    srand((unsigned) time(0));
+    sp = newterm((char *) 0, stdout, stdin);
+    outs(clear_screen);
+    outs(cursor_home);
+    outs(cursor_invisible);
+    if (max_colors > 1) {
+	if (!valid(set_a_foreground)
+	    || !valid(set_a_background)
+	    || (!valid(orig_colors) && !valid(orig_pair)))
+	    max_colors = -1;
+    }
+
+    r = (float) (lines - 4);
+    c = (float) (columns - 4);
+    started = time((time_t *) 0);
+
+    while (!interrupted) {
+	x = (int) (c * ranf()) + 2;
+	y = (int) (r * ranf()) + 2;
+	p = (ranf() > 0.9) ? '*' : ' ';
+
+	if (mvcur(y0, x0, y, x) != ERR) {
+	    x0 = x;
+	    y0 = y;
+	}
+
+	if (max_colors > 0) {
+	    z = (int) (ranf() * max_colors);
+	    if (ranf() > 0.01) {
+		tputs(tparm2(set_a_foreground, z), 1, outc);
+	    } else {
+		tputs(tparm2(set_a_background, z), 1, outc);
+		napms(1);
+	    }
+	} else if (valid(exit_attribute_mode)
+		   && valid(enter_reverse_mode)) {
+	    if (ranf() <= 0.01) {
+		outs((ranf() > 0.6)
+		     ? enter_reverse_mode
+		     : exit_attribute_mode);
+		napms(1);
+	    }
+	}
+	outc(p);
+	fflush(stdout);
+	++total_chars;
+    }
+    cleanup();
+    endwin();
+    delscreen(sp);
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(int argc GCC_UNUSED,
+     char *argv[]GCC_UNUSED)
+{
+    fprintf(stderr, "This program requires terminfo\n");
+    exit(EXIT_FAILURE);
+}
+#endif
diff --git a/test/echochar.c b/test/echochar.c
new file mode 100644
index 0000000..d4de7ee
--- /dev/null
+++ b/test/echochar.c
@@ -0,0 +1,158 @@
+/****************************************************************************
+ * Copyright (c) 2006-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: echochar.c,v 1.6 2008/04/12 22:06:04 tom Exp $
+ *
+ * Demonstrate the echochar function (compare to dots.c).
+ * Thomas Dickey - 2006/11/4
+ */
+
+#include <test.priv.h>
+
+#include <time.h>
+
+#define valid(s) ((s != 0) && s != (char *)-1)
+
+static bool interrupted = FALSE;
+static long total_chars = 0;
+static time_t started;
+
+static void
+cleanup(void)
+{
+    endwin();
+
+    printf("\n\n%ld total chars, rate %.2f/sec\n",
+	   total_chars,
+	   ((double) (total_chars) / (time((time_t *) 0) - started)));
+}
+
+static void
+onsig(int n GCC_UNUSED)
+{
+    interrupted = TRUE;
+}
+
+static float
+ranf(void)
+{
+    long r = (rand() & 077777);
+    return ((float) r / 32768.);
+}
+
+static void
+set_color(char *my_pairs, int fg, int bg)
+{
+    int pair = (fg * COLORS) + bg;
+    if (!my_pairs[pair]) {
+	init_pair(pair, fg, bg);
+    }
+    attron(COLOR_PAIR(pair));
+}
+
+int
+main(
+	int argc GCC_UNUSED,
+	char *argv[]GCC_UNUSED)
+{
+    int ch, x, y, z, p;
+    float r;
+    float c;
+    bool use_colors;
+    bool opt_r = FALSE;
+    char *my_pairs = 0;
+    int last_fg = 0;
+    int last_bg = 0;
+
+    while ((ch = getopt(argc, argv, "r")) != -1) {
+	switch (ch) {
+	case 'r':
+	    opt_r = TRUE;
+	    break;
+	default:
+	    fprintf(stderr, "usage: echochar [-r]\n");
+	    ExitProgram(EXIT_FAILURE);
+	}
+    }
+
+    CATCHALL(onsig);
+    initscr();
+
+    use_colors = has_colors();
+    if (use_colors) {
+	start_color();
+	if (COLOR_PAIRS > 0) {
+	    my_pairs = typeCalloc(char, COLOR_PAIRS);
+	}
+	use_colors = (my_pairs != 0);
+    }
+
+    srand((unsigned) time(0));
+
+    curs_set(0);
+
+    r = (float) (LINES - 4);
+    c = (float) (COLS - 4);
+    started = time((time_t *) 0);
+
+    while (!interrupted) {
+	x = (int) (c * ranf()) + 2;
+	y = (int) (r * ranf()) + 2;
+	p = (ranf() > 0.9) ? '*' : ' ';
+
+	move(y, x);
+	if (use_colors > 0) {
+	    z = (int) (ranf() * COLORS);
+	    if (ranf() > 0.01) {
+		set_color(my_pairs, z, last_bg);
+		last_fg = z;
+	    } else {
+		set_color(my_pairs, last_fg, z);
+		last_bg = z;
+		napms(1);
+	    }
+	} else {
+	    if (ranf() <= 0.01) {
+		if (ranf() > 0.6)
+		    attron(A_REVERSE);
+		else
+		    attroff(A_REVERSE);
+		napms(1);
+	    }
+	}
+	if (opt_r) {
+	    addch(UChar(p));
+	    refresh();
+	} else {
+	    echochar(UChar(p));
+	}
+	++total_chars;
+    }
+    cleanup();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/edit_field.c b/test/edit_field.c
new file mode 100644
index 0000000..b240028
--- /dev/null
+++ b/test/edit_field.c
@@ -0,0 +1,461 @@
+/****************************************************************************
+ * Copyright (c) 2003-2006,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: edit_field.c,v 1.14 2008/10/18 20:40:20 tom Exp $
+ *
+ * A wrapper for form_driver() which keeps track of the user's editing changes
+ * for each field, and makes the result available as a null-terminated string
+ * in field_buffer(field,1).
+ *
+ * Thomas Dickey - 2003/4/26.
+ */
+
+#include <test.priv.h>
+
+#if USE_LIBFORM
+
+#include <edit_field.h>
+
+static struct {
+    int code;
+    int result;
+    const char *help;
+} commands[] = {
+
+    {
+	CTRL('A'), REQ_NEXT_CHOICE, ""
+    },
+    {
+	CTRL('B'), REQ_PREV_WORD, "go to previous word"
+    },
+    {
+	CTRL('C'), REQ_CLR_EOL, "clear to end of line"
+    },
+    {
+	CTRL('D'), REQ_DOWN_FIELD, "move downward to field"
+    },
+    {
+	CTRL('E'), REQ_END_FIELD, "go to end of field"
+    },
+    {
+	CTRL('F'), REQ_NEXT_PAGE, "go to next page"
+    },
+    {
+	CTRL('G'), REQ_DEL_WORD, "delete current word"
+    },
+    {
+	CTRL('H'), REQ_DEL_PREV, "delete previous character"
+    },
+    {
+	CTRL('I'), REQ_INS_CHAR, "insert character"
+    },
+    {
+	CTRL('K'), REQ_CLR_EOF, "clear to end of field"
+    },
+    {
+	CTRL('L'), REQ_LEFT_FIELD, "go to field to left"
+    },
+    {
+	CTRL('M'), REQ_NEW_LINE, "insert/overlay new line"
+    },
+    {
+	CTRL('N'), REQ_NEXT_FIELD, "go to next field"
+    },
+    {
+	CTRL('O'), REQ_INS_LINE, "insert blank line at cursor"
+    },
+    {
+	CTRL('P'), REQ_PREV_FIELD, "go to previous field"
+    },
+    {
+	CTRL('Q'), MY_QUIT, "exit form"
+    },
+    {
+	CTRL('R'), REQ_RIGHT_FIELD, "go to field to right"
+    },
+    {
+	CTRL('S'), REQ_BEG_FIELD, "go to beginning of field"
+    },
+    {
+	CTRL('T'), MY_EDT_MODE, "toggle O_EDIT mode, clear field status",
+    },
+    {
+	CTRL('U'), REQ_UP_FIELD, "move upward to field"
+    },
+    {
+	CTRL('V'), REQ_DEL_CHAR, "delete character"
+    },
+    {
+	CTRL('W'), REQ_NEXT_WORD, "go to next word"
+    },
+    {
+	CTRL('X'), REQ_CLR_FIELD, "clear field"
+    },
+    {
+	CTRL('Y'), REQ_DEL_LINE, "delete line"
+    },
+    {
+	CTRL('Z'), REQ_PREV_CHOICE, ""
+    },
+    {
+	CTRL('['), MY_QUIT, "exit form"
+    },
+    {
+	CTRL(']'), MY_INS_MODE, "toggle REQ_INS_MODE/REQ_OVL_MODE",
+    },
+    {
+	KEY_F(1), MY_HELP, "show this screen",
+    },
+    {
+	KEY_BACKSPACE, REQ_DEL_PREV, "delete previous character"
+    },
+    {
+	KEY_DOWN, REQ_DOWN_CHAR, "move down 1 character"
+    },
+    {
+	KEY_END, REQ_LAST_FIELD, "go to last field"
+    },
+    {
+	KEY_HOME, REQ_FIRST_FIELD, "go to first field"
+    },
+    {
+	KEY_LEFT, REQ_LEFT_CHAR, "move left 1 character"
+    },
+    {
+	KEY_LL, REQ_LAST_FIELD, "go to last field"
+    },
+    {
+	KEY_NEXT, REQ_NEXT_FIELD, "go to next field"
+    },
+    {
+	KEY_NPAGE, REQ_NEXT_PAGE, "go to next page"
+    },
+    {
+	KEY_PPAGE, REQ_PREV_PAGE, "go to previous page"
+    },
+    {
+	KEY_PREVIOUS, REQ_PREV_FIELD, "go to previous field"
+    },
+    {
+	KEY_RIGHT, REQ_RIGHT_CHAR, "move right 1 character"
+    },
+    {
+	KEY_UP, REQ_UP_CHAR, "move up 1 character"
+    }
+};
+
+static WINDOW *old_window;
+
+static void
+begin_popup(void)
+{
+    doupdate();
+    old_window = dupwin(curscr);
+}
+
+static void
+end_popup(void)
+{
+    touchwin(old_window);
+    wnoutrefresh(old_window);
+    doupdate();
+    delwin(old_window);
+}
+
+/*
+ * Display a temporary window listing the keystroke-commands we recognize.
+ */
+void
+help_edit_field(void)
+{
+    int x0 = 4;
+    int y0 = 2;
+    int y1 = 0;
+    int y2 = 0;
+    int wide = COLS - ((x0 + 1) * 2);
+    int high = LINES - ((y0 + 1) * 2);
+    WINDOW *help = newwin(high, wide, y0, x0);
+    WINDOW *data = newpad(2 + SIZEOF(commands), wide - 4);
+    unsigned n;
+    int ch = ERR;
+
+    begin_popup();
+
+    keypad(help, TRUE);
+    keypad(data, TRUE);
+    waddstr(data, "Defined form edit/traversal keys:\n");
+    for (n = 0; n < SIZEOF(commands); ++n) {
+	const char *name;
+#ifdef NCURSES_VERSION
+	if ((name = form_request_name(commands[n].result)) == 0)
+#endif
+	    name = commands[n].help;
+	wprintw(data, "%s -- %s\n",
+		keyname(commands[n].code),
+		name != 0 ? name : commands[n].help);
+    }
+    waddstr(data, "Arrow keys move within a field as you would expect.");
+    y2 = getcury(data);
+
+    do {
+	switch (ch) {
+	case KEY_HOME:
+	    y1 = 0;
+	    break;
+	case KEY_END:
+	    y1 = y2;
+	    break;
+	case KEY_PREVIOUS:
+	case KEY_PPAGE:
+	    if (y1 > 0) {
+		y1 -= high / 2;
+		if (y1 < 0)
+		    y1 = 0;
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_NEXT:
+	case KEY_NPAGE:
+	    if (y1 < y2) {
+		y1 += high / 2;
+		if (y1 >= y2)
+		    y1 = y2;
+	    } else {
+		beep();
+	    }
+	    break;
+	case CTRL('P'):
+	case KEY_UP:
+	    if (y1 > 0)
+		--y1;
+	    else
+		beep();
+	    break;
+	case CTRL('N'):
+	case KEY_DOWN:
+	    if (y1 < y2)
+		++y1;
+	    else
+		beep();
+	    break;
+	default:
+	    beep();
+	    break;
+	case ERR:
+	    break;
+	}
+	werase(help);
+	box(help, 0, 0);
+	wnoutrefresh(help);
+	pnoutrefresh(data, y1, 0, y0 + 1, x0 + 1, high, wide);
+	doupdate();
+    } while ((ch = wgetch(data)) != ERR && ch != QUIT && ch != ESCAPE);
+    werase(help);
+    wrefresh(help);
+    delwin(help);
+    delwin(data);
+
+    end_popup();
+}
+
+static int
+offset_in_field(FORM * form)
+{
+    FIELD *field = current_field(form);
+    return form->curcol + form->currow * field->dcols;
+}
+
+static void
+inactive_field(FIELD * f)
+{
+    void *ptr = field_userptr(f);
+    set_field_back(f, (chtype) ptr);
+}
+
+int
+edit_field(FORM * form, int *result)
+{
+    int ch = wgetch(form_win(form));
+    int status;
+    FIELD *before;
+    unsigned n;
+    char lengths[80];
+    int length;
+    char *buffer;
+    int before_row = form->currow;
+    int before_col = form->curcol;
+    int before_off = offset_in_field(form);
+
+    before = current_field(form);
+    set_field_back(before, A_NORMAL);
+    if (ch <= KEY_MAX) {
+	set_field_back(before, A_REVERSE);
+    } else if (ch <= MAX_FORM_COMMAND) {
+	inactive_field(before);
+    }
+
+    *result = ch;
+    for (n = 0; n < SIZEOF(commands); ++n) {
+	if (commands[n].code == ch) {
+	    *result = commands[n].result;
+	    break;
+	}
+    }
+
+    status = form_driver(form, *result);
+
+    if (status == E_OK) {
+	bool modified = TRUE;
+
+	length = 0;
+	if ((buffer = field_buffer(before, 1)) != 0)
+	    length = atoi(buffer);
+	if (length < before_off)
+	    length = before_off;
+	switch (*result) {
+	case REQ_CLR_EOF:
+	    length = before_off;
+	    break;
+	case REQ_CLR_EOL:
+	    if (before_row + 1 == before->rows)
+		length = before_off;
+	    break;
+	case REQ_CLR_FIELD:
+	    length = 0;
+	    break;
+	case REQ_DEL_CHAR:
+	    if (length > before_off)
+		--length;
+	    break;
+	case REQ_DEL_PREV:
+	    if (length > 0) {
+		if (before_col > 0) {
+		    --length;
+		} else if (before_row > 0) {
+		    length -= before->cols + before_col;
+		}
+	    }
+	    break;
+	case REQ_NEW_LINE:
+	    length += before->cols;
+	    break;
+#if 0
+	    /* FIXME: finish these */
+	case REQ_DEL_LINE:	/* delete line */
+	case REQ_DEL_WORD:	/* delete word at cursor */
+	case REQ_INS_CHAR:	/* insert blank char at cursor */
+	case REQ_INS_LINE:	/* insert blank line at cursor */
+	case REQ_INS_MODE:	/* begin insert mode */
+	case REQ_OVL_MODE:	/* begin overlay mode */
+#endif
+	    /* ignore all of the motion commands */
+	case REQ_SCR_BCHAR:	/* FALLTHRU */
+	case REQ_SCR_BHPAGE:	/* FALLTHRU */
+	case REQ_SCR_BLINE:	/* FALLTHRU */
+	case REQ_SCR_BPAGE:	/* FALLTHRU */
+	case REQ_SCR_FCHAR:	/* FALLTHRU */
+	case REQ_SCR_FHPAGE:	/* FALLTHRU */
+	case REQ_SCR_FLINE:	/* FALLTHRU */
+	case REQ_SCR_FPAGE:	/* FALLTHRU */
+	case REQ_SCR_HBHALF:	/* FALLTHRU */
+	case REQ_SCR_HBLINE:	/* FALLTHRU */
+	case REQ_SCR_HFHALF:	/* FALLTHRU */
+	case REQ_SCR_HFLINE:	/* FALLTHRU */
+	case REQ_BEG_FIELD:	/* FALLTHRU */
+	case REQ_BEG_LINE:	/* FALLTHRU */
+	case REQ_DOWN_CHAR:	/* FALLTHRU */
+	case REQ_DOWN_FIELD:	/* FALLTHRU */
+	case REQ_END_FIELD:	/* FALLTHRU */
+	case REQ_END_LINE:	/* FALLTHRU */
+	case REQ_FIRST_FIELD:	/* FALLTHRU */
+	case REQ_FIRST_PAGE:	/* FALLTHRU */
+	case REQ_LAST_FIELD:	/* FALLTHRU */
+	case REQ_LAST_PAGE:	/* FALLTHRU */
+	case REQ_LEFT_CHAR:	/* FALLTHRU */
+	case REQ_LEFT_FIELD:	/* FALLTHRU */
+	case REQ_NEXT_CHAR:	/* FALLTHRU */
+	case REQ_NEXT_CHOICE:	/* FALLTHRU */
+	case REQ_NEXT_FIELD:	/* FALLTHRU */
+	case REQ_NEXT_LINE:	/* FALLTHRU */
+	case REQ_NEXT_PAGE:	/* FALLTHRU */
+	case REQ_NEXT_WORD:	/* FALLTHRU */
+	case REQ_PREV_CHAR:	/* FALLTHRU */
+	case REQ_PREV_CHOICE:	/* FALLTHRU */
+	case REQ_PREV_FIELD:	/* FALLTHRU */
+	case REQ_PREV_LINE:	/* FALLTHRU */
+	case REQ_PREV_PAGE:	/* FALLTHRU */
+	case REQ_PREV_WORD:	/* FALLTHRU */
+	case REQ_RIGHT_CHAR:	/* FALLTHRU */
+	case REQ_RIGHT_FIELD:	/* FALLTHRU */
+	case REQ_SFIRST_FIELD:	/* FALLTHRU */
+	case REQ_SLAST_FIELD:	/* FALLTHRU */
+	case REQ_SNEXT_FIELD:	/* FALLTHRU */
+	case REQ_SPREV_FIELD:	/* FALLTHRU */
+	case REQ_UP_CHAR:	/* FALLTHRU */
+	case REQ_UP_FIELD:	/* FALLTHRU */
+	case REQ_VALIDATION:	/* FALLTHRU */
+	    modified = FALSE;
+	    break;
+
+	default:
+	    modified = FALSE;
+	    if (ch >= MIN_FORM_COMMAND) {
+		beep();
+	    } else if (isprint(ch)) {
+		modified = TRUE;
+	    }
+	    break;
+	}
+
+	/*
+	 * If we do not force a re-validation, then field_buffer 0 will
+	 * be lagging by one character.
+	 */
+	if (modified && form_driver(form, REQ_VALIDATION) == E_OK && *result
+	    < MIN_FORM_COMMAND)
+	    ++length;
+
+	sprintf(lengths, "%d", length);
+	set_field_buffer(before, 1, lengths);
+    }
+
+    if (current_field(form) != before)
+	inactive_field(before);
+    return status;
+}
+#else
+
+extern void no_edit_field(void);
+
+void
+no_edit_field(void)
+{
+}
+
+#endif
diff --git a/test/edit_field.h b/test/edit_field.h
new file mode 100644
index 0000000..6e917c2
--- /dev/null
+++ b/test/edit_field.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ * Copyright (c) 2003-2004,2005 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: edit_field.h,v 1.5 2006/06/03 16:38:57 tom Exp $
+ *
+ * Interface of edit_field.c
+ */
+
+#ifndef EDIT_FORM_H_incl
+#define EDIT_FORM_H_incl 1
+
+#include <form.h>
+
+#define EDIT_FIELD(c) (MAX_FORM_COMMAND + c)
+
+#define MY_HELP		EDIT_FIELD('h')
+#define MY_QUIT		EDIT_FIELD('q')
+#define MY_EDT_MODE	EDIT_FIELD('e')
+#define MY_INS_MODE	EDIT_FIELD('t')
+
+extern void help_edit_field(void);
+extern int edit_field(FORM * form, int *result);
+
+#endif /* EDIT_FORM_H_incl */
diff --git a/test/filter.c b/test/filter.c
new file mode 100644
index 0000000..bdcea36
--- /dev/null
+++ b/test/filter.c
@@ -0,0 +1,130 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * Author:  Thomas E. Dickey <dickey@clark.net> 1998
+ *
+ * $Id: filter.c,v 1.11 2006/12/09 16:53:47 tom Exp $
+ */
+#include <test.priv.h>
+
+#if HAVE_FILTER
+
+/*
+ * An example of the 'filter()' function in ncurses, this program prompts
+ * for commands and executes them (like a command shell).  It illustrates
+ * how ncurses can be used to implement programs that are not full-screen.
+ *
+ * Ncurses differs slightly from SVr4 curses.  The latter does not flush its
+ * state when exiting program mode, so the attributes on the command lines of
+ * this program 'bleed' onto the executed commands.  Rather than use the
+ * reset_shell_mode() and reset_prog_mode() functions, we could invoke endwin()
+ * and refresh(), but that does not work any better.
+ */
+
+static int
+new_command(char *buffer, int length, attr_t underline)
+{
+    int code;
+
+    attron(A_BOLD);
+    printw("Command: ");
+    attron(underline);
+    code = getnstr(buffer, length);
+    /*
+     * If this returns anything except ERR/OK, it would be one of ncurses's
+     * extensions.  Fill the buffer with something harmless that the shell
+     * will execute as a comment.
+     */
+#ifdef KEY_EVENT
+    if (code == KEY_EVENT)
+	strcpy(buffer, "# event!");
+#endif
+#ifdef KEY_RESIZE
+    if (code == KEY_RESIZE) {
+	strcpy(buffer, "# resize!");
+	getch();
+    }
+#endif
+    attroff(underline);
+    attroff(A_BOLD);
+    printw("\n");
+
+    return code;
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    char buffer[80];
+    attr_t underline;
+
+    setlocale(LC_ALL, "");
+
+    filter();
+    (void) newterm((char *) 0, stdout, stdin);
+    cbreak();
+    keypad(stdscr, TRUE);
+
+    if (has_colors()) {
+	int background = COLOR_BLACK;
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() != ERR)
+	    background = -1;
+#endif
+	init_pair(1, COLOR_CYAN, background);
+	underline = COLOR_PAIR(1);
+    } else {
+	underline = A_UNDERLINE;
+    }
+
+    while (new_command(buffer, sizeof(buffer) - 1, underline) != ERR
+	   && strlen(buffer) != 0) {
+	reset_shell_mode();
+	printf("\n");
+	fflush(stdout);
+	system(buffer);
+	reset_prog_mode();
+	touchwin(stdscr);
+	erase();
+	refresh();
+    }
+    printw("done");
+    refresh();
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the filter function\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif /* HAVE_FILTER */
diff --git a/test/firework.c b/test/firework.c
new file mode 100644
index 0000000..1337e97
--- /dev/null
+++ b/test/firework.c
@@ -0,0 +1,196 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: firework.c,v 1.24 2006/05/20 15:36:08 tom Exp $
+ */
+#include <test.priv.h>
+
+#include <time.h>
+
+static int my_bg = COLOR_BLACK;
+
+static void
+cleanup(void)
+{
+    curs_set(1);
+    endwin();
+}
+
+static RETSIGTYPE
+onsig(int n GCC_UNUSED)
+{
+    cleanup();
+    ExitProgram(EXIT_FAILURE);
+}
+
+static void
+showit(void)
+{
+    int ch;
+    napms(120);
+    if ((ch = getch()) != ERR) {
+#ifdef KEY_RESIZE
+	if (ch == KEY_RESIZE) {
+	    erase();
+	} else
+#endif
+	if (ch == 'q') {
+	    cleanup();
+	    ExitProgram(EXIT_SUCCESS);
+	} else if (ch == 's') {
+	    nodelay(stdscr, FALSE);
+	} else if (ch == ' ') {
+	    nodelay(stdscr, TRUE);
+	}
+    }
+}
+
+static int
+get_colour(chtype *bold)
+{
+    int attr;
+    attr = (rand() % 16) + 1;
+
+    *bold = A_NORMAL;
+    if (attr > 8) {
+	*bold = A_BOLD;
+	attr &= 7;
+    }
+    return (attr);
+}
+
+static
+void
+explode(int row, int col)
+{
+    chtype bold;
+    erase();
+    mvprintw(row, col, "-");
+    showit();
+
+    init_pair(1, get_colour(&bold), my_bg);
+    attrset(COLOR_PAIR(1) | bold);
+    mvprintw(row - 1, col - 1, " - ");
+    mvprintw(row + 0, col - 1, "-+-");
+    mvprintw(row + 1, col - 1, " - ");
+    showit();
+
+    init_pair(1, get_colour(&bold), my_bg);
+    attrset(COLOR_PAIR(1) | bold);
+    mvprintw(row - 2, col - 2, " --- ");
+    mvprintw(row - 1, col - 2, "-+++-");
+    mvprintw(row + 0, col - 2, "-+#+-");
+    mvprintw(row + 1, col - 2, "-+++-");
+    mvprintw(row + 2, col - 2, " --- ");
+    showit();
+
+    init_pair(1, get_colour(&bold), my_bg);
+    attrset(COLOR_PAIR(1) | bold);
+    mvprintw(row - 2, col - 2, " +++ ");
+    mvprintw(row - 1, col - 2, "++#++");
+    mvprintw(row + 0, col - 2, "+# #+");
+    mvprintw(row + 1, col - 2, "++#++");
+    mvprintw(row + 2, col - 2, " +++ ");
+    showit();
+
+    init_pair(1, get_colour(&bold), my_bg);
+    attrset(COLOR_PAIR(1) | bold);
+    mvprintw(row - 2, col - 2, "  #  ");
+    mvprintw(row - 1, col - 2, "## ##");
+    mvprintw(row + 0, col - 2, "#   #");
+    mvprintw(row + 1, col - 2, "## ##");
+    mvprintw(row + 2, col - 2, "  #  ");
+    showit();
+
+    init_pair(1, get_colour(&bold), my_bg);
+    attrset(COLOR_PAIR(1) | bold);
+    mvprintw(row - 2, col - 2, " # # ");
+    mvprintw(row - 1, col - 2, "#   #");
+    mvprintw(row + 0, col - 2, "     ");
+    mvprintw(row + 1, col - 2, "#   #");
+    mvprintw(row + 2, col - 2, " # # ");
+    showit();
+}
+
+int
+main(
+	int argc GCC_UNUSED,
+	char *argv[]GCC_UNUSED)
+{
+    int start, end, row, diff, flag = 0, direction;
+    unsigned seed;
+
+    CATCHALL(onsig);
+
+    initscr();
+    noecho();
+    cbreak();
+    keypad(stdscr, TRUE);
+    nodelay(stdscr, TRUE);
+
+    if (has_colors()) {
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() == OK)
+	    my_bg = -1;
+#endif
+    }
+    curs_set(0);
+
+    seed = time((time_t *) 0);
+    srand(seed);
+    for (;;) {
+	do {
+	    start = rand() % (COLS - 3);
+	    end = rand() % (COLS - 3);
+	    start = (start < 2) ? 2 : start;
+	    end = (end < 2) ? 2 : end;
+	    direction = (start > end) ? -1 : 1;
+	    diff = abs(start - end);
+	} while (diff < 2 || diff >= LINES - 2);
+	attrset(A_NORMAL);
+	for (row = 0; row < diff; row++) {
+	    mvprintw(LINES - row, start + (row * direction),
+		     (direction < 0) ? "\\" : "/");
+	    if (flag++) {
+		showit();
+		erase();
+		flag = 0;
+	    }
+	}
+	if (flag++) {
+	    showit();
+	    flag = 0;
+	}
+	seed = time((time_t *) 0);
+	srand(seed);
+	explode(LINES - row, start + (diff * direction));
+	erase();
+	showit();
+    }
+}
diff --git a/test/firstlast.c b/test/firstlast.c
new file mode 100644
index 0000000..a767640
--- /dev/null
+++ b/test/firstlast.c
@@ -0,0 +1,116 @@
+/****************************************************************************
+ * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * This test was written by Alexander V. Lukyanov to demonstrate difference
+ * between ncurses 4.1 and SVR4 curses
+ *
+ * $Id: firstlast.c,v 1.5 2006/04/01 19:03:18 tom Exp $
+ */
+
+#include <test.priv.h>
+
+static void
+fill(WINDOW *w, const char *str)
+{
+    const char *s;
+    for (;;) {
+	for (s = str; *s; s++) {
+	    if (waddch(w, UChar(*s)) == ERR) {
+		wmove(w, 0, 0);
+		return;
+	    }
+	}
+    }
+}
+
+int
+main(int argc GCC_UNUSED,
+     char *argv[]GCC_UNUSED)
+{
+    WINDOW *large, *small;
+    initscr();
+    noecho();
+
+    large = newwin(20, 60, 2, 10);
+    small = newwin(10, 30, 7, 25);
+
+    /* test 1 - addch */
+    fill(large, "LargeWindow");
+
+    refresh();
+    wrefresh(large);
+    wrefresh(small);
+
+    mvwaddstr(small, 5, 5, "   Test <place to change> String   ");
+    wrefresh(small);
+    getch();
+
+    touchwin(large);
+    wrefresh(large);
+
+    mvwaddstr(small, 5, 5, "   Test <***************> String   ");
+    wrefresh(small);
+
+    /* DIFFERENCE! */
+    getch();
+
+    /* test 2: erase */
+    erase();
+    refresh();
+    getch();
+
+    /* test 3: clrtoeol */
+    werase(small);
+    wrefresh(small);
+    touchwin(large);
+    wrefresh(large);
+    wmove(small, 5, 0);
+    waddstr(small, " clrtoeol>");
+    wclrtoeol(small);
+    wrefresh(small);
+
+    /* DIFFERENCE! */ ;
+    getch();
+
+    /* test 4: clrtobot */
+    werase(small);
+    wrefresh(small);
+    touchwin(large);
+    wrefresh(large);
+    wmove(small, 5, 3);
+    waddstr(small, " clrtobot>");
+    wclrtobot(small);
+    wrefresh(small);
+
+    /* DIFFERENCE! */
+    getch();
+
+    endwin();
+
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/foldkeys.c b/test/foldkeys.c
new file mode 100644
index 0000000..180f151
--- /dev/null
+++ b/test/foldkeys.c
@@ -0,0 +1,264 @@
+/****************************************************************************
+ * Copyright (c) 2006 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * Author: Thomas E. Dickey, 2006
+ *
+ * $Id: foldkeys.c,v 1.3 2006/12/09 16:54:07 tom Exp $
+ *
+ * Demonstrate a method for altering key definitions at runtime.
+ *
+ * This program reads the key definitions, merging those which have xterm-style
+ * modifiers into their equivalents which have no modifiers.  It does this
+ * merging only for the keys which are defined in the terminal description.
+ */
+
+#include <test.priv.h>
+
+#if defined(NCURSES_VERSION) && NCURSES_EXT_FUNCS
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#define MY_LOGFILE "demo_foldkeys.log"
+#define MY_KEYS (KEY_MAX + 1)
+
+/*
+ * Log the most recently-written line to our logfile
+ */
+static void
+log_last_line(WINDOW *win)
+{
+    FILE *fp;
+    int y, x, n;
+    char temp[256];
+
+    if ((fp = fopen(MY_LOGFILE, "a")) != 0) {
+	int need = sizeof(temp) - 1;
+	if (need > COLS)
+	    need = COLS;
+	getyx(win, y, x);
+	wmove(win, y - 1, 0);
+	n = winnstr(win, temp, need);
+	while (n-- > 0) {
+	    if (isspace(UChar(temp[n])))
+		temp[n] = '\0';
+	    else
+		break;
+	}
+	wmove(win, y, x);
+	fprintf(fp, "%s\n", temp);
+	fclose(fp);
+    }
+}
+
+/*
+ * ncurses has no API for telling what the actual last key-code is.  That is
+ * a secret because the codes past KEY_MAX are computed at run-time and may
+ * differ depending on the previous calls to newterm(), etc.  It is unlikely
+ * that one could have more than a thousand key definitions...
+ */
+#define MAX_KEYS 2000
+
+typedef struct {
+    const char *name;
+    const char *value;
+    int code;
+    int state;
+} KeyInfo;
+
+static void
+demo_foldkeys(void)
+{
+    KeyInfo info[MAX_KEYS];
+    int info_len = 0;
+    int merged = 0;
+    int code;
+    int j, k;
+
+    /*
+     * Tell ncurses that we want to use function keys.  That will make it add
+     * any user-defined keys that appear in the terminfo.
+     */
+    keypad(stdscr, TRUE);
+
+    /*
+     * List the predefined keys using the strnames[] array.
+     */
+    for (code = 0; code < STRCOUNT; ++code) {
+	NCURSES_CONST char *name = strnames[code];
+	NCURSES_CONST char *value = tigetstr(name);
+	if (value != 0 && value != (NCURSES_CONST char *) -1) {
+	    info[info_len].name = strnames[code];
+	    info[info_len].code = key_defined(value);
+	    info[info_len].value = value;
+	    info[info_len].state = 0;
+	    if (info[info_len].code > 0)
+		++info_len;
+	}
+    }
+
+    /*
+     * We can get the names for user-defined keys from keyname().  It returns
+     * a name like KEY_foo for the predefined keys, which tigetstr() does not
+     * understand.
+     */
+    for (code = KEY_MAX; code < MAX_KEYS; ++code) {
+	NCURSES_CONST char *name = keyname(code);
+	if (name != 0) {
+	    info[info_len].name = name;
+	    info[info_len].code = code;
+	    info[info_len].value = tigetstr(name);
+	    info[info_len].state = 0;
+	    ++info_len;
+	}
+    }
+    printw("Initially %d key definitions\n", info_len);
+
+    /*
+     * Look for keys that have xterm-style modifiers.
+     */
+    for (j = 0; j < info_len; ++j) {
+	int first, second;
+	char final[2];
+	char *value;
+	if (info[j].state == 0
+	    && sscanf(info[j].value,
+		      "\033[%d;%d%c",
+		      &first,
+		      &second,
+		      final) == 3
+	    && *final != ';'
+	    && (value = strdup(info[j].value)) != 0) {
+	    sprintf(value, "\033[%d%c", first, *final);
+	    for (k = 0; k < info_len; ++k) {
+		if (info[k].state == 0
+		    && !strcmp(info[k].value, value)) {
+		    info[j].state = 1;
+		    break;
+		}
+	    }
+	    if (info[j].state == 0) {
+		sprintf(value, "\033O%c", *final);
+		for (k = 0; k < info_len; ++k) {
+		    if (info[k].state == 0
+			&& !strcmp(info[k].value, value)) {
+			info[j].state = 1;
+			break;
+		    }
+		}
+	    }
+	    if (info[j].state == 1) {
+		if ((define_key(info[j].value, info[k].code)) != ERR) {
+		    printw("map %s to %s\n", info[j].value, info[k].value);
+		    keyok(info[j].code, FALSE);
+		    ++merged;
+		} else {
+		    printw("? cannot define_key %d:%s\n", j, info[j].value);
+		}
+	    } else {
+		printw("? cannot merge %d:%s\n", j, info[j].value);
+	    }
+	    free(value);
+	}
+    }
+    printw("Merged to %d key definitions\n", info_len - merged);
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    int ch;
+#if HAVE_GETTIMEOFDAY
+    int secs, msecs;
+    struct timeval current, previous;
+#endif
+
+    unlink(MY_LOGFILE);
+
+    newterm(0, stdout, stdin);
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    scrollok(stdscr, TRUE);
+    keypad(stdscr, TRUE);
+    move(0, 0);
+
+    demo_foldkeys();
+
+#if HAVE_GETTIMEOFDAY
+    gettimeofday(&previous, 0);
+#endif
+
+    while ((ch = getch()) != ERR) {
+	bool escaped = (ch >= MY_KEYS);
+	const char *name = keyname(escaped ? (ch - MY_KEYS) : ch);
+
+#if HAVE_GETTIMEOFDAY
+	gettimeofday(&current, 0);
+	secs = current.tv_sec - previous.tv_sec;
+	msecs = (current.tv_usec - previous.tv_usec) / 1000;
+	if (msecs < 0) {
+	    msecs += 1000;
+	    --secs;
+	}
+	if (msecs >= 1000) {
+	    secs += msecs / 1000;
+	    msecs %= 1000;
+	}
+	printw("%6d.%03d ", secs, msecs);
+	previous = current;
+#endif
+	printw("Keycode %d, name %s%s\n",
+	       ch,
+	       escaped ? "ESC-" : "",
+	       name != 0 ? name : "<null>");
+	log_last_line(stdscr);
+	clrtoeol();
+	if (ch == 'q')
+	    break;
+    }
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/gdc.6 b/test/gdc.6
new file mode 100644
index 0000000..ed3a4f1
--- /dev/null
+++ b/test/gdc.6
@@ -0,0 +1,64 @@
+.\"***************************************************************************
+.\" Copyright (c) 1998-2003,2006 Free Software Foundation, Inc.              *
+.\"                                                                          *
+.\" Permission is hereby granted, free of charge, to any person obtaining a  *
+.\" copy of this software and associated documentation files (the            *
+.\" "Software"), to deal in the Software without restriction, including      *
+.\" without limitation the rights to use, copy, modify, merge, publish,      *
+.\" distribute, distribute with modifications, sublicense, and/or sell       *
+.\" copies of the Software, and to permit persons to whom the Software is    *
+.\" furnished to do so, subject to the following conditions:                 *
+.\"                                                                          *
+.\" The above copyright notice and this permission notice shall be included  *
+.\" in all copies or substantial portions of the Software.                   *
+.\"                                                                          *
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+.\" IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+.\" DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+.\" OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+.\" THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+.\"                                                                          *
+.\" Except as contained in this notice, the name(s) of the above copyright   *
+.\" holders shall not be used in advertising or otherwise to promote the     *
+.\" sale, use or other dealings in this Software without prior written       *
+.\" authorization.                                                           *
+.\"***************************************************************************
+.\"
+.\" $Id: gdc.6,v 1.3 2006/04/22 23:02:15 tom Exp $
+.TH GDC 6
+.SH NAME
+gdc \- grand digital clock (curses)
+.SH SYNOPSIS
+.B gdc
+[-n] [
+[-s] [
+.I n
+]
+.SH DESCRIPTION
+.I Gdc
+runs a digital clock made of reverse-video blanks on a terminal screen.
+If the terminal supports color, the clock is drawn in red.
+You can make the clock stop, pause or resume by pressing a ``q'',
+``s'' or space, respectively.
+.SH OPTIONS
+.TP
+.B -n
+redirects input to /dev/null, making it ignore the stop/pause commands.
+You can still stop it by pressing the interrupt key.
+.TP
+.B -s
+makes digits scroll as they change.
+When running on a fast display, the program breaks up the scrolling into
+subsecond repaints, making the operation appear smooth.
+.PP
+With an optional numeric argument
+.I num
+it stops after
+.I num
+seconds.
+Normally it runs "forever" (counting down from 2 billion seconds).
+.SH AUTHOR
+Amos Shapir, modified for curses by John Lupien.
+Improvements for ncurses by Thomas Dickey.
diff --git a/test/gdc.c b/test/gdc.c
new file mode 100644
index 0000000..ef220fe
--- /dev/null
+++ b/test/gdc.c
@@ -0,0 +1,351 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * Grand digital clock for curses compatible terminals
+ * Usage: gdc [-s] [n]   -- run for n seconds (default infinity)
+ * Flags: -s: scroll
+ *
+ * modified 10-18-89 for curses (jrl)
+ * 10-18-89 added signal handling
+ *
+ * $Id: gdc.c,v 1.31 2008/08/03 23:58:42 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <time.h>
+
+#define YBASE	10
+#define XBASE	10
+#define XLENGTH	54
+#define YDEPTH	5
+
+#define PAIR_DIGITS 1
+#define PAIR_OTHERS 2
+#define PAIR_FRAMES 3
+
+static short disp[11] =
+{
+    075557, 011111, 071747, 071717, 055711,
+    074717, 074757, 071111, 075757, 075717, 002020
+};
+static long older[6], next[6], newer[6], mask;
+
+static int sigtermed = 0;
+static bool redirected = FALSE;
+static bool hascolor = FALSE;
+
+static RETSIGTYPE
+sighndl(int signo)
+{
+    signal(signo, sighndl);
+    sigtermed = signo;
+    if (redirected) {
+	endwin();
+	ExitProgram(EXIT_FAILURE);
+    }
+}
+
+static void
+drawbox(bool scrolling)
+{
+    chtype bottom[XLENGTH + 1];
+    int n;
+
+    if (hascolor)
+	attrset(COLOR_PAIR(PAIR_FRAMES));
+
+    mvaddch(YBASE - 1, XBASE - 1, ACS_ULCORNER);
+    hline(ACS_HLINE, XLENGTH);
+    mvaddch(YBASE - 1, XBASE + XLENGTH, ACS_URCORNER);
+
+    mvaddch(YBASE + YDEPTH, XBASE - 1, ACS_LLCORNER);
+    if ((mvinchnstr(YBASE + YDEPTH, XBASE, bottom, XLENGTH)) != ERR) {
+	for (n = 0; n < XLENGTH; n++) {
+	    if (!scrolling)
+		bottom[n] &= ~A_COLOR;
+	    bottom[n] = ACS_HLINE | (bottom[n] & (A_ATTRIBUTES | A_COLOR));
+	}
+	mvaddchnstr(YBASE + YDEPTH, XBASE, bottom, XLENGTH);
+    }
+    mvaddch(YBASE + YDEPTH, XBASE + XLENGTH, ACS_LRCORNER);
+
+    move(YBASE, XBASE - 1);
+    vline(ACS_VLINE, YDEPTH);
+
+    move(YBASE, XBASE + XLENGTH);
+    vline(ACS_VLINE, YDEPTH);
+
+    if (hascolor)
+	attrset(COLOR_PAIR(PAIR_OTHERS));
+}
+
+static void
+standt(int on)
+{
+    if (on) {
+	if (hascolor) {
+	    attron(COLOR_PAIR(PAIR_DIGITS));
+	} else {
+	    attron(A_STANDOUT);
+	}
+    } else {
+	if (hascolor) {
+	    attron(COLOR_PAIR(PAIR_OTHERS));
+	} else {
+	    attroff(A_STANDOUT);
+	}
+    }
+}
+
+static void
+set(int t, int n)
+{
+    int i, m;
+
+    m = 7 << n;
+    for (i = 0; i < 5; i++) {
+	next[i] |= ((disp[t] >> ((4 - i) * 3)) & 07) << n;
+	mask |= (next[i] ^ older[i]) & m;
+    }
+    if (mask & m)
+	mask |= m;
+}
+
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+	"Usage: gdc [options] [count]"
+	,""
+	,"Options:"
+	,"  -n  redirect input to /dev/null"
+	,"  -s  scroll each number into place, rather than flipping"
+	,""
+	,"If you specify a count, gdc runs for that number of seconds"
+    };
+    unsigned j;
+    for (j = 0; j < SIZEOF(msg); j++)
+	fprintf(stderr, "%s\n", msg[j]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+    time_t now;
+    struct tm *tm;
+    long t, a;
+    int i, j, s, k;
+    int count = 0;
+    FILE *ofp = stdout;
+    FILE *ifp = stdin;
+    bool scrol = FALSE;
+
+    setlocale(LC_ALL, "");
+
+    CATCHALL(sighndl);
+
+    while ((k = getopt(argc, argv, "sn")) != -1) {
+	switch (k) {
+	case 's':
+	    scrol = TRUE;
+	    break;
+	case 'n':
+	    ifp = fopen("/dev/null", "r");
+	    redirected = TRUE;
+	    break;
+	default:
+	    usage();
+	}
+    }
+    if (optind < argc) {
+	count = atoi(argv[optind++]);
+	assert(count >= 0);
+    }
+    if (optind < argc)
+	usage();
+
+    if (redirected) {
+	char *name = getenv("TERM");
+	if (name == 0
+	    || newterm(name, ofp, ifp) == 0) {
+	    fprintf(stderr, "cannot open terminal\n");
+	    ExitProgram(EXIT_FAILURE);
+	}
+
+    } else {
+	initscr();
+    }
+    cbreak();
+    noecho();
+    nodelay(stdscr, 1);
+    curs_set(0);
+
+    hascolor = has_colors();
+
+    if (hascolor) {
+	int bg = COLOR_BLACK;
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() == OK)
+	    bg = -1;
+#endif
+	init_pair(PAIR_DIGITS, COLOR_BLACK, COLOR_RED);
+	init_pair(PAIR_OTHERS, COLOR_RED, bg);
+	init_pair(PAIR_FRAMES, COLOR_WHITE, bg);
+	attrset(COLOR_PAIR(PAIR_OTHERS));
+    }
+
+  restart:
+    for (j = 0; j < 5; j++)
+	older[j] = newer[j] = next[j] = 0;
+
+    clear();
+    drawbox(FALSE);
+
+    do {
+	char buf[30];
+
+	time(&now);
+	tm = localtime(&now);
+
+	mask = 0;
+	set(tm->tm_sec % 10, 0);
+	set(tm->tm_sec / 10, 4);
+	set(tm->tm_min % 10, 10);
+	set(tm->tm_min / 10, 14);
+	set(tm->tm_hour % 10, 20);
+	set(tm->tm_hour / 10, 24);
+	set(10, 7);
+	set(10, 17);
+
+	for (k = 0; k < 6; k++) {
+	    if (scrol) {
+		for (i = 0; i < 5; i++)
+		    newer[i] = (newer[i] & ~mask) | (newer[i + 1] & mask);
+		newer[5] = (newer[5] & ~mask) | (next[k] & mask);
+	    } else
+		newer[k] = (newer[k] & ~mask) | (next[k] & mask);
+	    next[k] = 0;
+	    for (s = 1; s >= 0; s--) {
+		standt(s);
+		for (i = 0; i < 6; i++) {
+		    if ((a = (newer[i] ^ older[i]) & (s ? newer : older)[i])
+			!= 0) {
+			for (j = 0, t = 1 << 26; t; t >>= 1, j++) {
+			    if (a & t) {
+				if (!(a & (t << 1))) {
+				    move(YBASE + i, XBASE + 2 * j);
+				}
+				addstr("  ");
+			    }
+			}
+		    }
+		    if (!s) {
+			older[i] = newer[i];
+		    }
+		}
+		if (!s) {
+		    if (scrol)
+			drawbox(TRUE);
+		    refresh();
+		    /*
+		     * If we're scrolling, space out the refreshes to fake
+		     * movement.  That's 7 frames, or 6 intervals, which would
+		     * be 166 msec if we spread it out over a second.  It looks
+		     * better (but will work on a slow terminal, e.g., less
+		     * than 9600bd) to squeeze that into a half-second, and use
+		     * half of 170 msec to ensure that the program doesn't eat
+		     * a lot of time when asking what time it is, at the top of
+		     * this loop -T.Dickey
+		     */
+		    if (scrol)
+			napms(85);
+		}
+	    }
+	}
+
+	/* this depends on the detailed format of ctime(3) */
+	(void) strcpy(buf, ctime(&now));
+	(void) strcpy(buf + 10, buf + 19);
+	mvaddstr(16, 30, buf);
+
+	move(6, 0);
+	drawbox(FALSE);
+	refresh();
+
+	/*
+	 * If we're not scrolling, wait 1000 msec (1 sec).  Use napms() rather
+	 * than sleep() because the latter does odd things on some systems,
+	 * e.g., suspending output as well.
+	 */
+	if (scrol)
+	    napms(500);
+	else
+	    napms(1000);
+
+	/*
+	 * This is a safe way to check if we're interrupted - making the signal
+	 * handler set a flag that we can check.  Since we're running
+	 * nodelay(), the wgetch() call returns immediately, and in particular
+	 * will return an error if interrupted.  This works only if we can
+	 * read from the input, of course.
+	 */
+	switch (wgetch(stdscr)) {
+	case 'q':
+	    count = 1;
+	    break;
+	case 's':
+	    nodelay(stdscr, FALSE);
+	    break;
+	case ' ':
+	    nodelay(stdscr, TRUE);
+	    break;
+#ifdef KEY_RESIZE
+	case KEY_RESIZE:
+#endif
+	case '?':
+	    goto restart;
+	case ERR:
+	    if (sigtermed) {
+		standend();
+		endwin();
+		fprintf(stderr, "gdc terminated by signal %d\n", sigtermed);
+		ExitProgram(EXIT_FAILURE);
+	    }
+	    /* FALLTHRU */
+	default:
+	    continue;
+	}
+    } while (--count);
+    standend();
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/hanoi.c b/test/hanoi.c
new file mode 100644
index 0000000..bd0fb10
--- /dev/null
+++ b/test/hanoi.c
@@ -0,0 +1,334 @@
+/****************************************************************************
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ *	Name: Towers of Hanoi.
+ *
+ *	Desc:
+ *		This is a playable copy of towers of hanoi.
+ *		Its sole purpose is to demonstrate my Amiga Curses package.
+ *		This program should compile on any system that has Curses.
+ *		'hanoi'		will give a manual game with 7 playing pieces.
+ *		'hanoi n'	will give a manual game with n playing pieces.
+ *		'hanoi n a' will give an auto solved game with n playing pieces.
+ *
+ *	Author: Simon J Raybould	(sie@fulcrum.bt.co.uk).
+ * 	(This version has been slightly modified by the ncurses maintainers.)
+ *
+ *	Date: 05.Nov.90
+ *
+ * $Id: hanoi.c,v 1.27 2008/08/04 10:57:59 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#define NPEGS			3	/* This is not configurable !! */
+#define MINTILES		3
+#define MAXTILES		9
+#define DEFAULTTILES		7
+#define TOPLINE			6
+#define BASELINE		16
+#define STATUSLINE		(LINES-3)
+#define LEFTPEG			19
+#define MIDPEG			39
+#define RIGHTPEG		59
+
+#define LENTOIND(x)		(((x)-1)/2)
+#define OTHER(a,b)		(3-((a)+(b)))
+
+struct Peg {
+    size_t Length[MAXTILES];
+    int Count;
+};
+
+static struct Peg Pegs[NPEGS];
+static int PegPos[] =
+{LEFTPEG, MIDPEG, RIGHTPEG};
+static int TileColour[] =
+{
+    COLOR_GREEN,		/* Length 3 */
+    COLOR_MAGENTA,		/* Length 5 */
+    COLOR_RED,			/* Length 7 */
+    COLOR_BLUE,			/* Length 9 */
+    COLOR_CYAN,			/* Length 11 */
+    COLOR_YELLOW,		/* Length 13 */
+    COLOR_GREEN,		/* Length 15 */
+    COLOR_MAGENTA,		/* Length 17 */
+    COLOR_RED,			/* Length 19 */
+};
+static int NMoves = 0;
+static bool AutoFlag = FALSE;
+
+static void InitTiles(int NTiles);
+static void DisplayTiles(void);
+static void MakeMove(int From, int To);
+static void AutoMove(int From, int To, int Num);
+static void Usage(void);
+static int Solved(int NumTiles);
+static int GetMove(int *From, int *To);
+static int InvalidMove(int From, int To);
+
+int
+main(int argc, char **argv)
+{
+    int NTiles, FromCol, ToCol;
+
+    setlocale(LC_ALL, "");
+
+    switch (argc) {
+    case 1:
+	NTiles = DEFAULTTILES;
+	break;
+    case 2:
+	NTiles = atoi(argv[1]);
+	if (NTiles > MAXTILES || NTiles < MINTILES) {
+	    fprintf(stderr, "Range %d to %d\n", MINTILES, MAXTILES);
+	    ExitProgram(EXIT_FAILURE);
+	}
+	break;
+    case 3:
+	if (strcmp(argv[2], "a")) {
+	    Usage();
+	    ExitProgram(EXIT_FAILURE);
+	}
+	NTiles = atoi(argv[1]);
+	if (NTiles > MAXTILES || NTiles < MINTILES) {
+	    fprintf(stderr, "Range %d to %d\n", MINTILES, MAXTILES);
+	    ExitProgram(EXIT_FAILURE);
+	}
+	AutoFlag = TRUE;
+	break;
+    default:
+	Usage();
+	ExitProgram(EXIT_FAILURE);
+    }
+#ifdef TRACE
+    trace(TRACE_MAXIMUM);
+#endif
+    initscr();
+    if (has_colors()) {
+	int i;
+	int bg = COLOR_BLACK;
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() == OK)
+	    bg = -1;
+#endif
+	for (i = 0; i < 9; i++)
+	    init_pair(i + 1, bg, TileColour[i]);
+    }
+    cbreak();
+    if (LINES < 24) {
+	endwin();
+	fprintf(stderr, "Min screen length 24 lines\n");
+	ExitProgram(EXIT_FAILURE);
+    }
+    if (AutoFlag) {
+	curs_set(0);
+	leaveok(stdscr, TRUE);	/* Attempt to remove cursor */
+    }
+    InitTiles(NTiles);
+    DisplayTiles();
+    if (AutoFlag) {
+	do {
+	    noecho();
+	    AutoMove(0, 2, NTiles);
+	} while (!Solved(NTiles));
+	sleep(2);
+    } else {
+	echo();
+	for (;;) {
+	    if (GetMove(&FromCol, &ToCol))
+		break;
+	    if (InvalidMove(FromCol, ToCol)) {
+		mvaddstr(STATUSLINE, 0, "Invalid Move !!");
+		refresh();
+		beep();
+		continue;
+	    }
+	    MakeMove(FromCol, ToCol);
+	    if (Solved(NTiles)) {
+		mvprintw(STATUSLINE, 0,
+			 "Well Done !! You did it in %d moves", NMoves);
+		refresh();
+		sleep(5);
+		break;
+	    }
+	}
+    }
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+
+static int
+InvalidMove(int From, int To)
+{
+    if (From >= NPEGS)
+	return TRUE;
+    if (From < 0)
+	return TRUE;
+    if (To >= NPEGS)
+	return TRUE;
+    if (To < 0)
+	return TRUE;
+    if (From == To)
+	return TRUE;
+    if (!Pegs[From].Count)
+	return TRUE;
+    if (Pegs[To].Count &&
+	Pegs[From].Length[Pegs[From].Count - 1] >
+	Pegs[To].Length[Pegs[To].Count - 1])
+	return TRUE;
+    return FALSE;
+}
+
+static void
+InitTiles(int NTiles)
+{
+    int Size, SlotNo;
+
+    for (Size = NTiles * 2 + 1, SlotNo = 0; Size >= 3; Size -= 2)
+	Pegs[0].Length[SlotNo++] = Size;
+
+    Pegs[0].Count = NTiles;
+    Pegs[1].Count = 0;
+    Pegs[2].Count = 0;
+}
+
+static void
+DisplayTiles(void)
+{
+    int Line, peg, SlotNo;
+    char TileBuf[BUFSIZ];
+
+    erase();
+    mvaddstr(1, 24, "T O W E R S   O F   H A N O I");
+    mvaddstr(3, 34, "SJR 1990");
+    mvprintw(19, 5, "Moves : %d", NMoves);
+    attrset(A_REVERSE);
+    mvaddstr(BASELINE, 8,
+	     "                                                               ");
+
+    for (Line = TOPLINE; Line < BASELINE; Line++) {
+	mvaddch(Line, LEFTPEG, ' ');
+	mvaddch(Line, MIDPEG, ' ');
+	mvaddch(Line, RIGHTPEG, ' ');
+    }
+    mvaddch(BASELINE, LEFTPEG, '1');
+    mvaddch(BASELINE, MIDPEG, '2');
+    mvaddch(BASELINE, RIGHTPEG, '3');
+    attrset(A_NORMAL);
+
+    /* Draw tiles */
+    for (peg = 0; peg < NPEGS; peg++) {
+	for (SlotNo = 0; SlotNo < Pegs[peg].Count; SlotNo++) {
+	    unsigned len = Pegs[peg].Length[SlotNo];
+	    if (len < sizeof(TileBuf) - 1 && len < (unsigned) PegPos[peg]) {
+		memset(TileBuf, ' ', len);
+		TileBuf[len] = '\0';
+		if (has_colors())
+		    attrset(COLOR_PAIR(LENTOIND(len)));
+		else
+		    attrset(A_REVERSE);
+		mvaddstr(BASELINE - (SlotNo + 1),
+			 (int) (PegPos[peg] - len / 2),
+			 TileBuf);
+	    }
+	}
+    }
+    attrset(A_NORMAL);
+    refresh();
+}
+
+static int
+GetMove(int *From, int *To)
+{
+    mvaddstr(STATUSLINE, 0, "Next move ('q' to quit) from ");
+    clrtoeol();
+    refresh();
+    if ((*From = getch()) == 'q')
+	return TRUE;
+    *From -= ('0' + 1);
+    addstr(" to ");
+    clrtoeol();
+    refresh();
+
+    if ((*To = getch()) == 'q')
+	return TRUE;
+    *To -= ('0' + 1);
+    refresh();
+    if (!AutoFlag)
+	napms(500);
+
+    move(STATUSLINE, 0);
+    clrtoeol();
+    refresh();
+    return FALSE;
+}
+
+static void
+MakeMove(int From, int To)
+{
+    Pegs[From].Count--;
+    Pegs[To].Length[Pegs[To].Count] = Pegs[From].Length[Pegs[From].Count];
+    Pegs[To].Count++;
+    NMoves++;
+    DisplayTiles();
+}
+
+static void
+AutoMove(int From, int To, int Num)
+{
+    if (Num == 1) {
+	MakeMove(From, To);
+	napms(500);
+	return;
+    }
+    AutoMove(From, OTHER(From, To), Num - 1);
+    MakeMove(From, To);
+    napms(500);
+    AutoMove(OTHER(From, To), To, Num - 1);
+}
+
+static int
+Solved(int NumTiles)
+{
+    int i;
+
+    for (i = 1; i < NPEGS; i++)
+	if (Pegs[i].Count == NumTiles)
+	    return TRUE;
+    return FALSE;
+}
+
+static void
+Usage(void)
+{
+    fprintf(stderr, "Usage: hanoi [<No Of Tiles>] [a]\n");
+    fprintf(stderr,
+	    "The 'a' option causes the tower to be solved automatically\n");
+}
diff --git a/test/hashtest.c b/test/hashtest.c
new file mode 100644
index 0000000..6e1b00b
--- /dev/null
+++ b/test/hashtest.c
@@ -0,0 +1,246 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * hashtest.c -- test hash mapping
+ *
+ * Generate timing statistics for vertical-motion optimization.
+ *
+ * $Id: hashtest.c,v 1.29 2008/08/16 17:26:44 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#define LO_CHAR ' '
+#define HI_CHAR '~'
+
+static bool continuous = FALSE;
+static bool reverse_loops = FALSE;
+static bool single_step = FALSE;
+static bool extend_corner = FALSE;
+static int foot_lines = 0;
+static int head_lines = 0;
+
+static void
+cleanup(void)
+{
+    move(LINES - 1, 0);
+    clrtoeol();
+    refresh();
+    endwin();
+}
+
+static RETSIGTYPE
+finish(int sig GCC_UNUSED)
+{
+    cleanup();
+    ExitProgram(EXIT_FAILURE);
+}
+
+static void
+genlines(int base)
+{
+    int i, j;
+
+#if USE_TRACE
+    if (base == 'a')
+	Trace(("Resetting screen"));
+    else
+	Trace(("Painting `%c' screen", base));
+#endif
+
+    /* Do this so writes to lower-right corner don't cause a spurious
+     * scrolling operation.  This _shouldn't_ break the scrolling
+     * optimization, since that's computed in the refresh() call.
+     */
+    scrollok(stdscr, FALSE);
+
+    move(0, 0);
+    for (i = 0; i < head_lines; i++)
+	for (j = 0; j < COLS; j++)
+	    addch(UChar((j % 8 == 0) ? ('A' + j / 8) : '-'));
+
+    move(head_lines, 0);
+    for (i = head_lines; i < LINES - foot_lines; i++) {
+	chtype c = (base - LO_CHAR + i) % (HI_CHAR - LO_CHAR + 1) + LO_CHAR;
+	int hi = (extend_corner || (i < LINES - 1)) ? COLS : COLS - 1;
+	for (j = 0; j < hi; j++)
+	    addch(c);
+    }
+
+    for (i = LINES - foot_lines; i < LINES; i++) {
+	move(i, 0);
+	for (j = 0; j < (extend_corner ? COLS : COLS - 1); j++)
+	    addch(UChar((j % 8 == 0) ? ('A' + j / 8) : '-'));
+    }
+
+    scrollok(stdscr, TRUE);
+    if (single_step) {
+	move(LINES - 1, 0);
+	getch();
+    } else
+	refresh();
+}
+
+static void
+one_cycle(int ch)
+{
+    if (continuous) {
+	genlines(ch);
+    } else if (ch != 'a') {
+	genlines('a');
+	genlines(ch);
+    }
+}
+
+static void
+run_test(bool optimized GCC_UNUSED)
+{
+    char ch;
+    int lo = continuous ? LO_CHAR : 'a' - LINES;
+    int hi = continuous ? HI_CHAR : 'a' + LINES;
+
+    if (lo < LO_CHAR)
+	lo = LO_CHAR;
+    if (hi > HI_CHAR)
+	hi = HI_CHAR;
+
+#if defined(TRACE) || defined(NCURSES_TEST)
+    if (optimized) {
+	Trace(("With hash mapping"));
+	_nc_optimize_enable |= OPTIMIZE_HASHMAP;
+    } else {
+	Trace(("Without hash mapping"));
+	_nc_optimize_enable &= ~OPTIMIZE_HASHMAP;
+    }
+#endif
+
+    if (reverse_loops)
+	for (ch = hi; ch >= lo; ch--)
+	    one_cycle(ch);
+    else
+	for (ch = lo; ch <= hi; ch++)
+	    one_cycle(ch);
+}
+
+static void
+usage(void)
+{
+    static const char *const tbl[] =
+    {
+	"Usage: hashtest [options]"
+	,""
+	,"Options:"
+	,"  -c      continuous (don't reset between refresh's)"
+	,"  -f num  leave 'num' lines constant for footer"
+	,"  -h num  leave 'num' lines constant for header"
+	,"  -l num  repeat test 'num' times"
+	,"  -n      test the normal optimizer"
+	,"  -o      test the hashed optimizer"
+	,"  -r      reverse the loops"
+	,"  -s      single-step"
+	,"  -x      assume lower-right corner extension"
+    };
+    size_t n;
+
+    for (n = 0; n < SIZEOF(tbl); n++)
+	fprintf(stderr, "%s\n", tbl[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int c;
+    int test_loops = 1;
+    int test_normal = FALSE;
+    int test_optimize = FALSE;
+
+    setlocale(LC_ALL, "");
+
+    while ((c = getopt(argc, argv, "cf:h:l:norsx")) != -1) {
+	switch (c) {
+	case 'c':
+	    continuous = TRUE;
+	    break;
+	case 'f':
+	    foot_lines = atoi(optarg);
+	    break;
+	case 'h':
+	    head_lines = atoi(optarg);
+	    break;
+	case 'l':
+	    test_loops = atoi(optarg);
+	    assert(test_loops >= 0);
+	    break;
+	case 'n':
+	    test_normal = TRUE;
+	    break;
+	case 'o':
+	    test_optimize = TRUE;
+	    break;
+	case 'r':
+	    reverse_loops = TRUE;
+	    break;
+	case 's':
+	    single_step = TRUE;
+	    break;
+	case 'x':
+	    extend_corner = TRUE;
+	    break;
+	default:
+	    usage();
+	}
+    }
+    if (!test_normal && !test_optimize) {
+	test_normal = TRUE;
+	test_optimize = TRUE;
+    }
+#if USE_TRACE
+    trace(TRACE_TIMES);
+#endif
+
+    CATCHALL(finish);		/* arrange interrupts to terminate */
+
+    (void) initscr();		/* initialize the curses library */
+    keypad(stdscr, TRUE);	/* enable keyboard mapping */
+    (void) nonl();		/* tell curses not to do NL->CR/NL on output */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+    scrollok(stdscr, TRUE);
+
+    while (test_loops-- > 0) {
+	if (test_normal)
+	    run_test(FALSE);
+	if (test_optimize)
+	    run_test(TRUE);
+    }
+
+    cleanup();			/* we're done */
+    ExitProgram(EXIT_SUCCESS);
+}
+/* hashtest.c ends here */
diff --git a/test/inch_wide.c b/test/inch_wide.c
new file mode 100644
index 0000000..25af426
--- /dev/null
+++ b/test/inch_wide.c
@@ -0,0 +1,279 @@
+/****************************************************************************
+ * Copyright (c) 2007 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: inch_wide.c,v 1.6 2007/07/21 18:37:38 tom Exp $
+ */
+/*
+       int in_wch(cchar_t *wcval);
+       int mvin_wch(int y, int x, cchar_t *wcval);
+       int mvwin_wch(WINDOW *win, int y, int x, cchar_t *wcval);
+       int win_wch(WINDOW *win, cchar_t *wcval);
+       int in_wchstr(cchar_t *wchstr);
+       int in_wchnstr(cchar_t *wchstr, int n);
+       int win_wchstr(WINDOW *win, cchar_t *wchstr);
+       int win_wchnstr(WINDOW *win, cchar_t *wchstr, int n);
+       int mvin_wchstr(int y, int x, cchar_t *wchstr);
+       int mvin_wchnstr(int y, int x, cchar_t *wchstr, int n);
+       int mvwin_wchstr(WINDOW *win, int y, int x, cchar_t *wchstr);
+       int mvwin_wchnstr(WINDOW *win, int y, int x, cchar_t *wchstr, int n);
+*/
+
+#include <test.priv.h>
+
+#if USE_WIDEC_SUPPORT
+
+#define BASE_Y 7
+#define MAX_COLS 1024
+
+static bool
+Quit(int ch)
+{
+    return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
+}
+
+static int
+test_inchs(int level, char **argv, WINDOW *chrwin, WINDOW *strwin)
+{
+    WINDOW *txtbox = 0;
+    WINDOW *txtwin = 0;
+    FILE *fp;
+    int j;
+    int txt_x = 0, txt_y = 0;
+    int base_y;
+    int limit;
+    cchar_t ch;
+    cchar_t text[MAX_COLS];
+
+    if (argv[level] == 0) {
+	beep();
+	return FALSE;
+    }
+
+    if (level > 1) {
+	txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
+	box(txtbox, 0, 0);
+	wnoutrefresh(txtbox);
+
+	txtwin = derwin(txtbox,
+			getmaxy(txtbox) - 2,
+			getmaxx(txtbox) - 2,
+			1, 1);
+	base_y = 0;
+    } else {
+	txtwin = stdscr;
+	base_y = BASE_Y;
+    }
+
+    keypad(txtwin, TRUE);	/* enable keyboard mapping */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    txt_y = base_y;
+    txt_x = 0;
+    wmove(txtwin, txt_y, txt_x);
+
+    if ((fp = fopen(argv[level], "r")) != 0) {
+	while ((j = fgetc(fp)) != EOF) {
+	    if (waddch(txtwin, UChar(j)) != OK) {
+		break;
+	    }
+	}
+	fclose(fp);
+    } else {
+	wprintw(txtwin, "Cannot open:\n%s", argv[1]);
+    }
+
+    while (!Quit(j = mvwgetch(txtwin, txt_y, txt_x))) {
+	switch (j) {
+	case KEY_DOWN:
+	case 'j':
+	    if (txt_y < getmaxy(txtwin) - 1)
+		txt_y++;
+	    else
+		beep();
+	    break;
+	case KEY_UP:
+	case 'k':
+	    if (txt_y > base_y)
+		txt_y--;
+	    else
+		beep();
+	    break;
+	case KEY_LEFT:
+	case 'h':
+	    if (txt_x > 0)
+		txt_x--;
+	    else
+		beep();
+	    break;
+	case KEY_RIGHT:
+	case 'l':
+	    if (txt_x < getmaxx(txtwin) - 1)
+		txt_x++;
+	    else
+		beep();
+	    break;
+	case 'w':
+	    test_inchs(level + 1, argv, chrwin, strwin);
+	    if (txtbox != 0) {
+		touchwin(txtbox);
+		wnoutrefresh(txtbox);
+	    } else {
+		touchwin(txtwin);
+		wnoutrefresh(txtwin);
+	    }
+	    break;
+	default:
+	    beep();
+	    break;
+	}
+
+	mvwprintw(chrwin, 0, 0, "char:");
+	wclrtoeol(chrwin);
+
+	if (txtwin != stdscr) {
+	    wmove(txtwin, txt_y, txt_x);
+	    if (win_wch(txtwin, &ch) != ERR) {
+		if (wadd_wch(chrwin, &ch) != ERR) {
+		    for (j = txt_x + 1; j < getmaxx(txtwin); ++j) {
+			if (mvwin_wch(txtwin, txt_y, j, &ch) != ERR) {
+			    if (wadd_wch(chrwin, &ch) == ERR) {
+				break;
+			    }
+			} else {
+			    break;
+			}
+		    }
+		}
+	    }
+	} else {
+	    move(txt_y, txt_x);
+	    if (in_wch(&ch) != ERR) {
+		if (wadd_wch(chrwin, &ch) != ERR) {
+		    for (j = txt_x + 1; j < getmaxx(txtwin); ++j) {
+			if (mvin_wch(txt_y, j, &ch) != ERR) {
+			    if (wadd_wch(chrwin, &ch) == ERR) {
+				break;
+			    }
+			} else {
+			    break;
+			}
+		    }
+		}
+	    }
+	}
+	wnoutrefresh(chrwin);
+
+	mvwprintw(strwin, 0, 0, "text:");
+	wclrtobot(strwin);
+
+	limit = getmaxx(strwin) - 5;
+
+	if (txtwin != stdscr) {
+	    wmove(txtwin, txt_y, txt_x);
+	    if (win_wchstr(txtwin, text) != ERR) {
+		mvwadd_wchstr(strwin, 0, 5, text);
+	    }
+
+	    wmove(txtwin, txt_y, txt_x);
+	    if (win_wchnstr(txtwin, text, limit) != ERR) {
+		mvwadd_wchstr(strwin, 1, 5, text);
+	    }
+
+	    if (mvwin_wchstr(txtwin, txt_y, txt_x, text) != ERR) {
+		mvwadd_wchstr(strwin, 2, 5, text);
+	    }
+
+	    if (mvwin_wchnstr(txtwin, txt_y, txt_x, text, limit) != ERR) {
+		mvwadd_wchstr(strwin, 3, 5, text);
+	    }
+	} else {
+	    move(txt_y, txt_x);
+	    if (in_wchstr(text) != ERR) {
+		mvwadd_wchstr(strwin, 0, 5, text);
+	    }
+
+	    move(txt_y, txt_x);
+	    if (in_wchnstr(text, limit) != ERR) {
+		mvwadd_wchstr(strwin, 1, 5, text);
+	    }
+
+	    if (mvin_wchstr(txt_y, txt_x, text) != ERR) {
+		mvwadd_wchstr(strwin, 2, 5, text);
+	    }
+
+	    if (mvin_wchnstr(txt_y, txt_x, text, limit) != ERR) {
+		mvwadd_wchstr(strwin, 3, 5, text);
+	    }
+	}
+
+	wnoutrefresh(strwin);
+    }
+    if (level > 1) {
+	delwin(txtwin);
+	delwin(txtbox);
+    }
+    return TRUE;
+}
+
+int
+main(int argc, char *argv[])
+{
+    WINDOW *chrbox;
+    WINDOW *chrwin;
+    WINDOW *strwin;
+
+    setlocale(LC_ALL, "");
+
+    if (argc < 2) {
+	fprintf(stderr, "usage: %s file\n", argv[0]);
+	return EXIT_FAILURE;
+    }
+
+    initscr();
+
+    chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
+    box(chrbox, 0, 0);
+    wnoutrefresh(chrbox);
+
+    chrwin = derwin(chrbox, 1, COLS - 2, 1, 1);
+    strwin = derwin(chrbox, 4, COLS - 2, 2, 1);
+
+    test_inchs(1, argv, chrwin, strwin);
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the wide-ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/inchs.c b/test/inchs.c
new file mode 100644
index 0000000..180d324
--- /dev/null
+++ b/test/inchs.c
@@ -0,0 +1,272 @@
+/****************************************************************************
+ * Copyright (c) 2007 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: inchs.c,v 1.9 2007/07/21 19:01:43 tom Exp $
+ *
+ * Author: Thomas E Dickey
+ */
+/*
+       chtype inch(void);
+       chtype winch(WINDOW *win);
+       chtype mvinch(int y, int x);
+       chtype mvwinch(WINDOW *win, int y, int x);
+       int inchstr(chtype *chstr);
+       int inchnstr(chtype *chstr, int n);
+       int winchstr(WINDOW *win, chtype *chstr);
+       int winchnstr(WINDOW *win, chtype *chstr, int n);
+       int mvinchstr(int y, int x, chtype *chstr);
+       int mvinchnstr(int y, int x, chtype *chstr, int n);
+       int mvwinchstr(WINDOW *win, int y, int x, chtype *chstr);
+       int mvwinchnstr(WINDOW *win, int y, int x, chtype *chstr, int n);
+*/
+
+#include <test.priv.h>
+
+#define BASE_Y 7
+#define MAX_COLS 1024
+
+static bool
+Quit(int ch)
+{
+    return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
+}
+
+static int
+test_inchs(int level, char **argv, WINDOW *chrwin, WINDOW *strwin)
+{
+    WINDOW *txtbox = 0;
+    WINDOW *txtwin = 0;
+    FILE *fp;
+    int ch, j;
+    int txt_x = 0, txt_y = 0;
+    int base_y;
+    int limit;
+    chtype text[MAX_COLS];
+
+    if (argv[level] == 0) {
+	beep();
+	return FALSE;
+    }
+
+    if (level > 1) {
+	txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
+	box(txtbox, 0, 0);
+	wnoutrefresh(txtbox);
+
+	txtwin = derwin(txtbox,
+			getmaxy(txtbox) - 2,
+			getmaxx(txtbox) - 2,
+			1, 1);
+	base_y = 0;
+    } else {
+	txtwin = stdscr;
+	base_y = BASE_Y;
+    }
+
+    keypad(txtwin, TRUE);	/* enable keyboard mapping */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    txt_y = base_y;
+    txt_x = 0;
+    wmove(txtwin, txt_y, txt_x);
+
+    if ((fp = fopen(argv[level], "r")) != 0) {
+	while ((j = fgetc(fp)) != EOF) {
+	    if (waddch(txtwin, UChar(j)) != OK) {
+		break;
+	    }
+	}
+	fclose(fp);
+    } else {
+	wprintw(txtwin, "Cannot open:\n%s", argv[1]);
+    }
+
+    while (!Quit(j = mvwgetch(txtwin, txt_y, txt_x))) {
+	switch (j) {
+	case KEY_DOWN:
+	case 'j':
+	    if (txt_y < getmaxy(txtwin) - 1)
+		txt_y++;
+	    else
+		beep();
+	    break;
+	case KEY_UP:
+	case 'k':
+	    if (txt_y > base_y)
+		txt_y--;
+	    else
+		beep();
+	    break;
+	case KEY_LEFT:
+	case 'h':
+	    if (txt_x > 0)
+		txt_x--;
+	    else
+		beep();
+	    break;
+	case KEY_RIGHT:
+	case 'l':
+	    if (txt_x < getmaxx(txtwin) - 1)
+		txt_x++;
+	    else
+		beep();
+	    break;
+	case 'w':
+	    test_inchs(level + 1, argv, chrwin, strwin);
+	    if (txtbox != 0) {
+		touchwin(txtbox);
+		wnoutrefresh(txtbox);
+	    } else {
+		touchwin(txtwin);
+		wnoutrefresh(txtwin);
+	    }
+	    break;
+	default:
+	    beep();
+	    break;
+	}
+
+	mvwprintw(chrwin, 0, 0, "char:");
+	wclrtoeol(chrwin);
+
+	if (txtwin != stdscr) {
+	    wmove(txtwin, txt_y, txt_x);
+
+	    if ((ch = winch(txtwin)) != ERR) {
+		if (waddch(chrwin, (chtype) ch) != ERR) {
+		    for (j = txt_x + 1; j < getmaxx(txtwin); ++j) {
+			if ((ch = mvwinch(txtwin, txt_y, j)) != ERR) {
+			    if (waddch(chrwin, (chtype) ch) == ERR) {
+				break;
+			    }
+			} else {
+			    break;
+			}
+		    }
+		}
+	    }
+	} else {
+	    move(txt_y, txt_x);
+
+	    if ((ch = inch()) != ERR) {
+		if (waddch(chrwin, (chtype) ch) != ERR) {
+		    for (j = txt_x + 1; j < getmaxx(txtwin); ++j) {
+			if ((ch = mvinch(txt_y, j)) != ERR) {
+			    if (waddch(chrwin, (chtype) ch) == ERR) {
+				break;
+			    }
+			} else {
+			    break;
+			}
+		    }
+		}
+	    }
+	}
+	wnoutrefresh(chrwin);
+
+	mvwprintw(strwin, 0, 0, "text:");
+	wclrtobot(strwin);
+
+	limit = getmaxx(strwin) - 5;
+
+	if (txtwin != stdscr) {
+	    wmove(txtwin, txt_y, txt_x);
+	    if (winchstr(txtwin, text) != ERR) {
+		mvwaddchstr(strwin, 0, 5, text);
+	    }
+
+	    wmove(txtwin, txt_y, txt_x);
+	    if (winchnstr(txtwin, text, limit) != ERR) {
+		mvwaddchstr(strwin, 1, 5, text);
+	    }
+
+	    if (mvwinchstr(txtwin, txt_y, txt_x, text) != ERR) {
+		mvwaddchstr(strwin, 2, 5, text);
+	    }
+
+	    if (mvwinchnstr(txtwin, txt_y, txt_x, text, limit) != ERR) {
+		mvwaddchstr(strwin, 3, 5, text);
+	    }
+	} else {
+	    move(txt_y, txt_x);
+	    if (inchstr(text) != ERR) {
+		mvwaddchstr(strwin, 0, 5, text);
+	    }
+
+	    move(txt_y, txt_x);
+	    if (inchnstr(text, limit) != ERR) {
+		mvwaddchstr(strwin, 1, 5, text);
+	    }
+
+	    if (mvinchstr(txt_y, txt_x, text) != ERR) {
+		mvwaddchstr(strwin, 2, 5, text);
+	    }
+
+	    if (mvinchnstr(txt_y, txt_x, text, limit) != ERR) {
+		mvwaddchstr(strwin, 3, 5, text);
+	    }
+	}
+
+	wnoutrefresh(strwin);
+    }
+    if (level > 1) {
+	delwin(txtwin);
+	delwin(txtbox);
+    }
+    return TRUE;
+}
+
+int
+main(int argc, char *argv[])
+{
+    WINDOW *chrbox;
+    WINDOW *chrwin;
+    WINDOW *strwin;
+
+    setlocale(LC_ALL, "");
+
+    if (argc < 2) {
+	fprintf(stderr, "usage: %s file\n", argv[0]);
+	return EXIT_FAILURE;
+    }
+
+    initscr();
+
+    chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
+    box(chrbox, 0, 0);
+    wnoutrefresh(chrbox);
+
+    chrwin = derwin(chrbox, 1, COLS - 2, 1, 1);
+    strwin = derwin(chrbox, 4, COLS - 2, 2, 1);
+
+    test_inchs(1, argv, chrwin, strwin);
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/ins_wide.c b/test/ins_wide.c
new file mode 100644
index 0000000..33dafe4
--- /dev/null
+++ b/test/ins_wide.c
@@ -0,0 +1,525 @@
+/****************************************************************************
+ * Copyright (c) 2002-2006,2007 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: ins_wide.c,v 1.9 2007/07/21 17:41:55 tom Exp $
+ *
+ * Demonstrate the wins_wstr() and wins_wch functions.
+ * Thomas Dickey - 2002/11/23
+ *
+ * Note: to provide inputs for *ins_wch(), we use setcchar().  A quirk of the
+ * X/Open definition for that function is that the string contains no
+ * characters with negative width.  Any control character (such as tab) falls
+ * into that category.  So it follows that *ins_wch() cannot render a tab
+ * character because there is no legal way to construct a cchar_t containing
+ * one.  X/Open does not document this, and it would be logical to assume that
+ * *ins_wstr() has the same limitation, but it uses a wchar_t string directly,
+ * and does not document how tabs are handled.
+ */
+
+#include <test.priv.h>
+
+#if USE_WIDEC_SUPPORT
+
+/* definitions to make it simpler to compare with inserts.c */
+#define InsNStr    ins_nwstr
+#define InsStr     ins_wstr
+#define MvInsNStr  mvins_nwstr
+#define MvInsStr   mvins_wstr
+#define MvWInsNStr mvwins_nwstr
+#define MvWInsStr  mvwins_wstr
+#define WInsNStr   wins_nwstr
+#define WInsStr    wins_wstr
+
+#define MY_TABSIZE 8
+
+typedef enum {
+    oDefault = 0,
+    oMove = 1,
+    oWindow = 2,
+    oMoveWindow = 3
+} Options;
+
+static bool m_opt = FALSE;
+static bool w_opt = FALSE;
+static int n_opt = -1;
+
+static void
+legend(WINDOW *win, int level, Options state, wchar_t *buffer, int length)
+{
+    NCURSES_CONST char *showstate;
+
+    switch (state) {
+    default:
+    case oDefault:
+	showstate = "";
+	break;
+    case oMove:
+	showstate = " (mvXXX)";
+	break;
+    case oWindow:
+	showstate = " (winXXX)";
+	break;
+    case oMoveWindow:
+	showstate = " (mvwinXXX)";
+	break;
+    }
+
+    wmove(win, 0, 0);
+    wprintw(win,
+	    "The Strings/Chars displays should match.  Enter any characters, except:\n");
+    wprintw(win,
+	    "down-arrow or ^N to repeat on next line, 'w' for inner window, 'q' to exit.\n");
+    wclrtoeol(win);
+    wprintw(win, "Level %d,%s inserted %d characters <", level,
+	    showstate, length);
+    waddwstr(win, buffer);
+    waddstr(win, ">");
+}
+
+static int
+ColOf(wchar_t *buffer, int length, int margin)
+{
+    int n;
+    int result;
+
+    for (n = 0, result = margin + 1; n < length; ++n) {
+	int ch = buffer[n];
+	switch (ch) {
+	case '\n':
+	    /* actually newline should clear the remainder of the line
+	     * and move to the next line - but that seems a little awkward
+	     * in this example.
+	     */
+	case '\r':
+	    result = 0;
+	    break;
+	case '\b':
+	    if (result > 0)
+		--result;
+	    break;
+	case '\t':
+	    result += (MY_TABSIZE - (result % MY_TABSIZE));
+	    break;
+	case '\177':
+	    result += 2;
+	    break;
+	default:
+	    result += wcwidth(ch);
+	    if (ch < 32)
+		++result;
+	    break;
+	}
+    }
+    return result;
+}
+
+static int
+ConvertCh(chtype source, cchar_t *target)
+{
+    wchar_t tmp_wchar[2];
+
+    tmp_wchar[0] = source;
+    tmp_wchar[1] = 0;
+    if (setcchar(target, tmp_wchar, A_NORMAL, 0, (void *) 0) == ERR) {
+	beep();
+	return FALSE;
+    }
+    return TRUE;
+}
+
+static int
+MvWInsCh(WINDOW *win, int y, int x, chtype ch)
+{
+    int code;
+    cchar_t tmp_cchar;
+
+    if (ConvertCh(ch, &tmp_cchar)) {
+	code = mvwins_wch(win, y, x, &tmp_cchar);
+    } else {
+	code = mvwinsch(win, y, x, ch);
+    }
+    return code;
+}
+
+static int
+MvInsCh(int y, int x, chtype ch)
+{
+    int code;
+    cchar_t tmp_cchar;
+
+    if (ConvertCh(ch, &tmp_cchar)) {
+	code = mvins_wch(y, x, &tmp_cchar);
+    } else {
+	code = mvinsch(y, x, ch);
+    }
+    return code;
+}
+
+static int
+WInsCh(WINDOW *win, chtype ch)
+{
+    int code;
+    cchar_t tmp_cchar;
+
+    if (ConvertCh(ch, &tmp_cchar)) {
+	code = wins_wch(win, &tmp_cchar);
+    } else {
+	code = winsch(win, ch);
+    }
+    return code;
+}
+
+static int
+InsCh(chtype ch)
+{
+    int code;
+    cchar_t tmp_cchar;
+
+    if (ConvertCh(ch, &tmp_cchar)) {
+	code = ins_wch(&tmp_cchar);
+    } else {
+	code = insch(ch);
+    }
+    return code;
+}
+
+#define LEN(n) ((length - (n) > n_opt) ? n_opt : (length - (n)))
+static void
+test_inserts(int level)
+{
+    static bool first = TRUE;
+
+    wint_t ch;
+    int code;
+    int limit;
+    int row = 1;
+    int col;
+    int row2, col2;
+    int length;
+    wchar_t buffer[BUFSIZ];
+    WINDOW *look = 0;
+    WINDOW *work = 0;
+    WINDOW *show = 0;
+    int margin = (2 * MY_TABSIZE) - 1;
+    Options option = ((m_opt ? oMove : oDefault)
+		      | ((w_opt || (level > 0)) ? oWindow : oDefault));
+
+    if (first) {
+	static char cmd[80];
+	setlocale(LC_ALL, "");
+
+	putenv(strcpy(cmd, "TABSIZE=8"));
+
+	initscr();
+	(void) cbreak();	/* take input chars one at a time, no wait for \n */
+	(void) noecho();	/* don't echo input */
+	keypad(stdscr, TRUE);
+    }
+
+    limit = LINES - 5;
+    if (level > 0) {
+	look = newwin(limit, COLS - (2 * (level - 1)), 0, level - 1);
+	work = newwin(limit - 2, COLS - (2 * level), 1, level);
+	show = newwin(4, COLS, limit + 1, 0);
+	box(look, 0, 0);
+	wnoutrefresh(look);
+	limit -= 2;
+    } else {
+	work = stdscr;
+	show = derwin(stdscr, 4, COLS, limit + 1, 0);
+    }
+    keypad(work, TRUE);
+
+    for (col = margin + 1; col < COLS; col += MY_TABSIZE)
+	mvwvline(work, row, col, '.', limit - 2);
+
+    mvwvline(work, row, margin, ACS_VLINE, limit - 2);
+    mvwvline(work, row, margin + 1, ACS_VLINE, limit - 2);
+    limit /= 2;
+
+    mvwaddstr(work, 1, 2, "String");
+    mvwaddstr(work, limit + 1, 2, "Chars");
+    wnoutrefresh(work);
+
+    buffer[length = 0] = '\0';
+    legend(show, level, option, buffer, length);
+    wnoutrefresh(show);
+
+    doupdate();
+
+    /*
+     * Show the characters inserted in color, to distinguish from those that
+     * are shifted.
+     */
+    if (has_colors()) {
+	start_color();
+	init_pair(1, COLOR_WHITE, COLOR_BLUE);
+	wbkgdset(work, COLOR_PAIR(1) | ' ');
+    }
+
+    while ((code = wget_wch(work, &ch)) != ERR) {
+
+	if (code == KEY_CODE_YES) {
+	    switch (ch) {
+	    case KEY_DOWN:
+		ch = CTRL('N');
+		break;
+	    case KEY_BACKSPACE:
+		ch = '\b';
+		break;
+	    default:
+		beep();
+		continue;
+	    }
+	} else if (code == ERR) {
+	    beep();
+	    break;
+	}
+	if (ch == 'q')
+	    break;
+
+	wmove(work, row, margin + 1);
+	switch (ch) {
+	case 'w':
+	    test_inserts(level + 1);
+
+	    touchwin(look);
+	    touchwin(work);
+	    touchwin(show);
+
+	    wnoutrefresh(look);
+	    wnoutrefresh(work);
+	    wnoutrefresh(show);
+
+	    doupdate();
+	    break;
+	case CTRL('N'):
+	    if (row < limit) {
+		++row;
+		/* put the whole string in, all at once */
+		col2 = margin + 1;
+		switch (option) {
+		case oDefault:
+		    if (n_opt > 1) {
+			for (col = 0; col < length; col += n_opt) {
+			    col2 = ColOf(buffer, col, margin);
+			    if (move(row, col2) != ERR) {
+				InsNStr(buffer + col, LEN(col));
+			    }
+			}
+		    } else {
+			if (move(row, col2) != ERR) {
+			    InsStr(buffer);
+			}
+		    }
+		    break;
+		case oMove:
+		    if (n_opt > 1) {
+			for (col = 0; col < length; col += n_opt) {
+			    col2 = ColOf(buffer, col, margin);
+			    MvInsNStr(row, col2, buffer + col, LEN(col));
+			}
+		    } else {
+			MvInsStr(row, col2, buffer);
+		    }
+		    break;
+		case oWindow:
+		    if (n_opt > 1) {
+			for (col = 0; col < length; col += n_opt) {
+			    col2 = ColOf(buffer, col, margin);
+			    if (wmove(work, row, col2) != ERR) {
+				WInsNStr(work, buffer + col, LEN(col));
+			    }
+			}
+		    } else {
+			if (wmove(work, row, col2) != ERR) {
+			    WInsStr(work, buffer);
+			}
+		    }
+		    break;
+		case oMoveWindow:
+		    if (n_opt > 1) {
+			for (col = 0; col < length; col += n_opt) {
+			    col2 = ColOf(buffer, col, margin);
+			    MvWInsNStr(work, row, col2, buffer + col, LEN(col));
+			}
+		    } else {
+			MvWInsStr(work, row, col2, buffer);
+		    }
+		    break;
+		}
+
+		/* do the corresponding single-character insertion */
+		row2 = limit + row;
+		for (col = 0; col < length; ++col) {
+		    col2 = ColOf(buffer, col, margin);
+		    switch (option) {
+		    case oDefault:
+			if (move(row2, col2) != ERR) {
+			    InsCh((chtype) buffer[col]);
+			}
+			break;
+		    case oMove:
+			MvInsCh(row2, col2, (chtype) buffer[col]);
+			break;
+		    case oWindow:
+			if (wmove(work, row2, col2) != ERR) {
+			    WInsCh(work, (chtype) buffer[col]);
+			}
+			break;
+		    case oMoveWindow:
+			MvWInsCh(work, row2, col2, (chtype) buffer[col]);
+			break;
+		    }
+		}
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_BACKSPACE:
+	    ch = '\b';
+	    /* FALLTHRU */
+	default:
+	    buffer[length++] = ch;
+	    buffer[length] = '\0';
+
+	    /* put the string in, one character at a time */
+	    col = ColOf(buffer, length - 1, margin);
+	    switch (option) {
+	    case oDefault:
+		if (move(row, col) != ERR) {
+		    InsStr(buffer + length - 1);
+		}
+		break;
+	    case oMove:
+		MvInsStr(row, col, buffer + length - 1);
+		break;
+	    case oWindow:
+		if (wmove(work, row, col) != ERR) {
+		    WInsStr(work, buffer + length - 1);
+		}
+		break;
+	    case oMoveWindow:
+		MvWInsStr(work, row, col, buffer + length - 1);
+		break;
+	    }
+
+	    /* do the corresponding single-character insertion */
+	    switch (option) {
+	    case oDefault:
+		if (move(limit + row, col) != ERR) {
+		    InsCh(ch);
+		}
+		break;
+	    case oMove:
+		MvInsCh(limit + row, col, ch);
+		break;
+	    case oWindow:
+		if (wmove(work, limit + row, col) != ERR) {
+		    WInsCh(work, ch);
+		}
+		break;
+	    case oMoveWindow:
+		MvWInsCh(work, limit + row, col, ch);
+		break;
+	    }
+
+	    wnoutrefresh(work);
+
+	    legend(show, level, option, buffer, length);
+	    wnoutrefresh(show);
+
+	    doupdate();
+	    break;
+	}
+    }
+    if (level > 0) {
+	delwin(show);
+	delwin(work);
+	delwin(look);
+    }
+}
+
+static void
+usage(void)
+{
+    static const char *tbl[] =
+    {
+	"Usage: inserts [options]"
+	,""
+	,"Options:"
+	,"  -n NUM  limit string-inserts to NUM bytes on ^N replay"
+	,"  -m      perform wmove/move separately from insert-functions"
+	,"  -w      use window-parameter even when stdscr would be implied"
+    };
+    unsigned n;
+    for (n = 0; n < SIZEOF(tbl); ++n)
+	fprintf(stderr, "%s\n", tbl[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    int ch;
+
+    setlocale(LC_ALL, "");
+
+    while ((ch = getopt(argc, argv, "mn:w")) != -1) {
+	switch (ch) {
+	case 'm':
+	    m_opt = TRUE;
+	    break;
+	case 'n':
+	    n_opt = atoi(optarg);
+	    if (n_opt == 0)
+		n_opt = -1;
+	    break;
+	case 'w':
+	    w_opt = TRUE;
+	    break;
+	default:
+	    usage();
+	    break;
+	}
+    }
+    if (optind < argc)
+	usage();
+
+    test_inserts(0);
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the wide-ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/inserts.c b/test/inserts.c
new file mode 100644
index 0000000..458788a
--- /dev/null
+++ b/test/inserts.c
@@ -0,0 +1,440 @@
+/****************************************************************************
+ * Copyright (c) 2002-2006,2007 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: inserts.c,v 1.18 2007/07/21 17:41:55 tom Exp $
+ *
+ * Demonstrate the winsstr() and winsch functions.
+ * Thomas Dickey - 2002/10/19
+ */
+
+#include <test.priv.h>
+
+#if HAVE_WINSSTR
+
+#define InsNStr    insnstr
+#define InsStr     insstr
+#define MvInsNStr  mvinsnstr
+#define MvInsStr   mvinsstr
+#define MvWInsNStr mvwinsnstr
+#define MvWInsStr  mvwinsstr
+#define WInsNStr   winsnstr
+#define WInsStr    winsstr
+
+#define InsCh      insch
+#define MvInsCh    mvinsch
+#define MvWInsCh   mvwinsch
+#define WInsCh     winsch
+
+#define MY_TABSIZE 8
+
+typedef enum {
+    oDefault = 0,
+    oMove = 1,
+    oWindow = 2,
+    oMoveWindow = 3
+} Options;
+
+static bool m_opt = FALSE;
+static bool w_opt = FALSE;
+static int n_opt = -1;
+
+static void
+legend(WINDOW *win, int level, Options state, char *buffer, int length)
+{
+    NCURSES_CONST char *showstate;
+
+    switch (state) {
+    default:
+    case oDefault:
+	showstate = "";
+	break;
+    case oMove:
+	showstate = " (mvXXX)";
+	break;
+    case oWindow:
+	showstate = " (winXXX)";
+	break;
+    case oMoveWindow:
+	showstate = " (mvwinXXX)";
+	break;
+    }
+
+    wmove(win, 0, 0);
+    wprintw(win,
+	    "The Strings/Chars displays should match.  Enter any characters, except:\n");
+    wprintw(win,
+	    "down-arrow or ^N to repeat on next line, 'w' for inner window, 'q' to exit.\n");
+    wclrtoeol(win);
+    wprintw(win, "Level %d,%s inserted %d characters <%s>", level,
+	    showstate, length, buffer);
+}
+
+static int
+ColOf(char *buffer, int length, int margin)
+{
+    int n;
+    int result;
+
+    for (n = 0, result = margin + 1; n < length; ++n) {
+	int ch = UChar(buffer[n]);
+	switch (ch) {
+	case '\n':
+	    /* actually newline should clear the remainder of the line
+	     * and move to the next line - but that seems a little awkward
+	     * in this example.
+	     */
+	case '\r':
+	    result = 0;
+	    break;
+	case '\b':
+	    if (result > 0)
+		--result;
+	    break;
+	case '\t':
+	    result += (MY_TABSIZE - (result % MY_TABSIZE));
+	    break;
+	case '\177':
+	    result += 2;
+	    break;
+	default:
+	    ++result;
+	    if (ch < 32)
+		++result;
+	    break;
+	}
+    }
+    return result;
+}
+
+#define LEN(n) ((length - (n) > n_opt) ? n_opt : (length - (n)))
+static void
+test_inserts(int level)
+{
+    static bool first = TRUE;
+
+    int ch;
+    int limit;
+    int row = 1;
+    int col;
+    int row2, col2;
+    int length;
+    char buffer[BUFSIZ];
+    WINDOW *look = 0;
+    WINDOW *work = 0;
+    WINDOW *show = 0;
+    int margin = (2 * MY_TABSIZE) - 1;
+    Options option = (Options) ((unsigned) (m_opt
+					    ? oMove
+					    : oDefault)
+				| (unsigned) ((w_opt || (level > 0))
+					      ? oWindow
+					      : oDefault));
+
+    if (first) {
+	static char cmd[80];
+	setlocale(LC_ALL, "");
+
+	putenv(strcpy(cmd, "TABSIZE=8"));
+
+	initscr();
+	(void) cbreak();	/* take input chars one at a time, no wait for \n */
+	(void) noecho();	/* don't echo input */
+	keypad(stdscr, TRUE);
+    }
+
+    limit = LINES - 5;
+    if (level > 0) {
+	look = newwin(limit, COLS - (2 * (level - 1)), 0, level - 1);
+	work = newwin(limit - 2, COLS - (2 * level), 1, level);
+	show = newwin(4, COLS, limit + 1, 0);
+	box(look, 0, 0);
+	wnoutrefresh(look);
+	limit -= 2;
+    } else {
+	work = stdscr;
+	show = derwin(stdscr, 4, COLS, limit + 1, 0);
+    }
+    keypad(work, TRUE);
+
+    for (col = margin + 1; col < COLS; col += MY_TABSIZE)
+	mvwvline(work, row, col, '.', limit - 2);
+
+    mvwvline(work, row, margin, ACS_VLINE, limit - 2);
+    mvwvline(work, row, margin + 1, ACS_VLINE, limit - 2);
+    limit /= 2;
+
+    mvwaddstr(work, 1, 2, "String");
+    mvwaddstr(work, limit + 1, 2, "Chars");
+    wnoutrefresh(work);
+
+    buffer[length = 0] = '\0';
+    legend(show, level, option, buffer, length);
+    wnoutrefresh(show);
+
+    doupdate();
+
+    /*
+     * Show the characters inserted in color, to distinguish from those that
+     * are shifted.
+     */
+    if (has_colors()) {
+	start_color();
+	init_pair(1, COLOR_WHITE, COLOR_BLUE);
+	wbkgdset(work, COLOR_PAIR(1) | ' ');
+    }
+
+    while ((ch = wgetch(work)) != 'q') {
+	if (ch == ERR) {
+	    beep();
+	    break;
+	}
+	wmove(work, row, margin + 1);
+	switch (ch) {
+	case 'w':
+	    test_inserts(level + 1);
+
+	    touchwin(look);
+	    touchwin(work);
+	    touchwin(show);
+
+	    wnoutrefresh(look);
+	    wnoutrefresh(work);
+	    wnoutrefresh(show);
+
+	    doupdate();
+	    break;
+	case CTRL('N'):
+	case KEY_DOWN:
+	    if (row < limit) {
+		++row;
+		/* put the whole string in, all at once */
+		col2 = margin + 1;
+		switch (option) {
+		case oDefault:
+		    if (n_opt > 1) {
+			for (col = 0; col < length; col += n_opt) {
+			    col2 = ColOf(buffer, col, margin);
+			    if (move(row, col2) != ERR) {
+				InsNStr(buffer + col, LEN(col));
+			    }
+			}
+		    } else {
+			if (move(row, col2) != ERR) {
+			    InsStr(buffer);
+			}
+		    }
+		    break;
+		case oMove:
+		    if (n_opt > 1) {
+			for (col = 0; col < length; col += n_opt) {
+			    col2 = ColOf(buffer, col, margin);
+			    MvInsNStr(row, col2, buffer + col, LEN(col));
+			}
+		    } else {
+			MvInsStr(row, col2, buffer);
+		    }
+		    break;
+		case oWindow:
+		    if (n_opt > 1) {
+			for (col = 0; col < length; col += n_opt) {
+			    col2 = ColOf(buffer, col, margin);
+			    if (wmove(work, row, col2) != ERR) {
+				WInsNStr(work, buffer + col, LEN(col));
+			    }
+			}
+		    } else {
+			if (wmove(work, row, col2) != ERR) {
+			    WInsStr(work, buffer);
+			}
+		    }
+		    break;
+		case oMoveWindow:
+		    if (n_opt > 1) {
+			for (col = 0; col < length; col += n_opt) {
+			    col2 = ColOf(buffer, col, margin);
+			    MvWInsNStr(work, row, col2, buffer + col, LEN(col));
+			}
+		    } else {
+			MvWInsStr(work, row, col2, buffer);
+		    }
+		    break;
+		}
+
+		/* do the corresponding single-character insertion */
+		row2 = limit + row;
+		for (col = 0; col < length; ++col) {
+		    col2 = ColOf(buffer, col, margin);
+		    switch (option) {
+		    case oDefault:
+			if (move(row2, col2) != ERR) {
+			    InsCh(UChar(buffer[col]));
+			}
+			break;
+		    case oMove:
+			MvInsCh(row2, col2, UChar(buffer[col]));
+			break;
+		    case oWindow:
+			if (wmove(work, row2, col2) != ERR) {
+			    WInsCh(work, UChar(buffer[col]));
+			}
+			break;
+		    case oMoveWindow:
+			MvWInsCh(work, row2, col2, UChar(buffer[col]));
+			break;
+		    }
+		}
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_BACKSPACE:
+	    ch = '\b';
+	    /* FALLTHRU */
+	default:
+	    if (ch <= 0 || ch > 255) {
+		beep();
+		break;
+	    }
+	    buffer[length++] = ch;
+	    buffer[length] = '\0';
+
+	    /* put the string in, one character at a time */
+	    col = ColOf(buffer, length - 1, margin);
+	    switch (option) {
+	    case oDefault:
+		if (move(row, col) != ERR) {
+		    InsStr(buffer + length - 1);
+		}
+		break;
+	    case oMove:
+		MvInsStr(row, col, buffer + length - 1);
+		break;
+	    case oWindow:
+		if (wmove(work, row, col) != ERR) {
+		    WInsStr(work, buffer + length - 1);
+		}
+		break;
+	    case oMoveWindow:
+		MvWInsStr(work, row, col, buffer + length - 1);
+		break;
+	    }
+
+	    /* do the corresponding single-character insertion */
+	    switch (option) {
+	    case oDefault:
+		if (move(limit + row, col) != ERR) {
+		    InsCh(UChar(ch));
+		}
+		break;
+	    case oMove:
+		MvInsCh(limit + row, col, UChar(ch));
+		break;
+	    case oWindow:
+		if (wmove(work, limit + row, col) != ERR) {
+		    WInsCh(work, UChar(ch));
+		}
+		break;
+	    case oMoveWindow:
+		MvWInsCh(work, limit + row, col, UChar(ch));
+		break;
+	    }
+
+	    wnoutrefresh(work);
+
+	    legend(show, level, option, buffer, length);
+	    wnoutrefresh(show);
+
+	    doupdate();
+	    break;
+	}
+    }
+    if (level > 0) {
+	delwin(show);
+	delwin(work);
+	delwin(look);
+    }
+}
+
+static void
+usage(void)
+{
+    static const char *tbl[] =
+    {
+	"Usage: inserts [options]"
+	,""
+	,"Options:"
+	,"  -n NUM  limit string-inserts to NUM bytes on ^N replay"
+	,"  -m      perform wmove/move separately from insert-functions"
+	,"  -w      use window-parameter even when stdscr would be implied"
+    };
+    unsigned n;
+    for (n = 0; n < SIZEOF(tbl); ++n)
+	fprintf(stderr, "%s\n", tbl[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    int ch;
+
+    setlocale(LC_ALL, "");
+
+    while ((ch = getopt(argc, argv, "mn:w")) != -1) {
+	switch (ch) {
+	case 'm':
+	    m_opt = TRUE;
+	    break;
+	case 'n':
+	    n_opt = atoi(optarg);
+	    if (n_opt == 0)
+		n_opt = -1;
+	    break;
+	case 'w':
+	    w_opt = TRUE;
+	    break;
+	default:
+	    usage();
+	    break;
+	}
+    }
+    if (optind < argc)
+	usage();
+
+    test_inserts(0);
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the winsstr function\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif /* HAVE_WINSSTR */
diff --git a/test/key_names.c b/test/key_names.c
new file mode 100644
index 0000000..ba45656
--- /dev/null
+++ b/test/key_names.c
@@ -0,0 +1,93 @@
+/****************************************************************************
+ * Copyright (c) 2007,2008 Free Software Foundation, Inc.                   *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: key_names.c,v 1.4 2008/10/11 20:22:37 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#if USE_WIDEC_SUPPORT
+
+static void
+usage(void)
+{
+    fprintf(stderr, "Usage: key_names [-m] [-s]\n");
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int n;
+
+    bool do_setup = FALSE;
+    bool do_meta = FALSE;
+
+    setlocale(LC_ALL, "");
+
+    while ((n = getopt(argc, argv, "ms")) != -1) {
+	switch (n) {
+	case 'm':
+	    do_meta = TRUE;
+	    break;
+	case 's':
+	    do_setup = TRUE;
+	    break;
+	default:
+	    usage();
+	    /* NOTREACHED */
+	}
+    }
+
+    if (do_setup) {
+	/*
+	 * Get the terminfo entry into memory, and tell ncurses that we want to
+	 * use function keys.  That will make it add any user-defined keys that
+	 * appear in the terminfo.
+	 */
+	newterm(getenv("TERM"), stderr, stdin);
+	keypad(stdscr, TRUE);
+	if (do_meta)
+	    meta(stdscr, TRUE);
+	endwin();
+    }
+    for (n = -1; n < KEY_MAX + 512; n++) {
+	const char *result = key_name(n);
+	if (result != 0)
+	    printf("%d(%5o):%s\n", n, n, result);
+    }
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the wide-ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/keynames.c b/test/keynames.c
new file mode 100644
index 0000000..26cfa87
--- /dev/null
+++ b/test/keynames.c
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: keynames.c,v 1.9 2008/10/11 20:22:37 tom Exp $
+ */
+
+#include <test.priv.h>
+
+static void
+usage(void)
+{
+    fprintf(stderr, "Usage: keynames [-m] [-s]\n");
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int n;
+    bool do_setup = FALSE;
+    bool do_meta = FALSE;
+
+    setlocale(LC_ALL, "");
+
+    while ((n = getopt(argc, argv, "ms")) != -1) {
+	switch (n) {
+	case 'm':
+	    do_meta = TRUE;
+	    break;
+	case 's':
+	    do_setup = TRUE;
+	    break;
+	default:
+	    usage();
+	    /* NOTREACHED */
+	}
+    }
+
+    if (do_setup) {
+	/*
+	 * Get the terminfo entry into memory, and tell ncurses that we want to
+	 * use function keys.  That will make it add any user-defined keys that
+	 * appear in the terminfo.
+	 */
+	newterm(getenv("TERM"), stderr, stdin);
+	keypad(stdscr, TRUE);
+	if (do_meta)
+	    meta(stdscr, TRUE);
+	endwin();
+    }
+
+    for (n = -1; n < KEY_MAX + 512; n++) {
+	const char *result = keyname(n);
+	if (result != 0)
+	    printf("%d(%5o):%s\n", n, n, result);
+    }
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/knight.c b/test/knight.c
new file mode 100644
index 0000000..f9ba1dc
--- /dev/null
+++ b/test/knight.c
@@ -0,0 +1,727 @@
+/****************************************************************************
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * Knight's Tour - a brain game
+ *
+ * The original of this game was anonymous.  It had an unbelievably bogus
+ * interface, you actually had to enter square coordinates!  Redesign by
+ * Eric S. Raymond <esr@snark.thyrsus.com> July 22 1995.  Mouse support
+ * added September 20th 1995.
+ *
+ * $Id: knight.c,v 1.28 2008/08/03 23:04:26 tom Exp $
+ */
+
+#include <test.priv.h>
+
+/* board size */
+#define BDEPTH	8
+#define BWIDTH	8
+
+/* where to start the instructions */
+#define INSTRY	2
+#define INSTRX	35
+
+/* corner of board */
+#define BOARDY	2
+#define BOARDX	0
+
+/* notification line */
+#define NOTIFYY	21
+
+/* virtual color values */
+#define TRAIL_COLOR	1
+#define PLUS_COLOR	2
+#define MINUS_COLOR	3
+
+#define CX(x)		(2 + 4 * (x))
+#define CY(y)		(1 + 2 * (y))
+#define cellmove(y, x)	wmove(boardwin, CY(y), CX(x))
+#define CXINV(x)	(((x) - 1) / 4)
+#define CYINV(y)	(((y) - 2) / 2)
+
+typedef struct {
+    short x, y;
+} cell;
+
+static WINDOW *boardwin;	/* the board window */
+static WINDOW *helpwin;		/* the help window */
+static WINDOW *msgwin;		/* the message window */
+static cell history[BDEPTH * BWIDTH + 1];	/* choice history */
+static chtype minus = '-';	/* possible-move character */
+static chtype oldch;
+static chtype plus = '+';	/* cursor hot-spot character */
+static chtype trail = '#';	/* trail character */
+static int movecount;		/* count of moves so far */
+static int trialcount;		/* count of trials so far */
+static short board[BDEPTH][BWIDTH];	/* the squares */
+/* *INDENT-OFF* */
+static const struct {
+    int y;
+    int x;
+} offsets[] = {
+    {  2,  1 },
+    {  1,  2 },
+    { -1,  2 },
+    { -2,  1 },
+    { -2, -1 },
+    { -1, -2 },
+    {  1, -2 },
+    {  2, -1 },
+};
+/* *INDENT-ON* */
+
+static void
+init_program(void)
+{
+    setlocale(LC_ALL, "");
+
+    srand((unsigned) getpid());
+    initscr();
+    cbreak();			/* immediate char return */
+    noecho();			/* no immediate echo */
+    boardwin = newwin(BDEPTH * 2 + 1, BWIDTH * 4 + 1, BOARDY, BOARDX);
+    helpwin = newwin(0, 0, INSTRY, INSTRX);
+    msgwin = newwin(1, INSTRX - 1, NOTIFYY, 0);
+    scrollok(msgwin, TRUE);
+    keypad(boardwin, TRUE);
+
+    if (has_colors()) {
+	int bg = COLOR_BLACK;
+
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() == OK)
+	    bg = -1;
+#endif
+
+	(void) init_pair(TRAIL_COLOR, COLOR_CYAN, bg);
+	(void) init_pair(PLUS_COLOR, COLOR_RED, bg);
+	(void) init_pair(MINUS_COLOR, COLOR_GREEN, bg);
+
+	trail |= COLOR_PAIR(TRAIL_COLOR);
+	plus |= COLOR_PAIR(PLUS_COLOR);
+	minus |= COLOR_PAIR(MINUS_COLOR);
+    }
+#ifdef NCURSES_MOUSE_VERSION
+    (void) mousemask(BUTTON1_CLICKED, (mmask_t *) NULL);
+#endif /* NCURSES_MOUSE_VERSION */
+
+    oldch = minus;
+}
+
+static void
+help1(void)
+/* game explanation -- initial help screen */
+{
+    (void) waddstr(helpwin, "Knight's move is a solitaire puzzle.  Your\n");
+    (void) waddstr(helpwin, "objective is to visit each square of the  \n");
+    (void) waddstr(helpwin, "chessboard exactly once by making knight's\n");
+    (void) waddstr(helpwin, "moves (one square right or left followed  \n");
+    (void) waddstr(helpwin, "by two squares up or down, or two squares \n");
+    (void) waddstr(helpwin, "right or left followed by one square up or\n");
+    (void) waddstr(helpwin, "down).  You may start anywhere.\n\n");
+
+    (void) waddstr(helpwin, "Use arrow keys to move the cursor around.\n");
+    (void) waddstr(helpwin, "When you want to move your knight to the \n");
+    (void) waddstr(helpwin, "cursor location, press <space> or Enter.\n");
+    (void) waddstr(helpwin, "Illegal moves will be rejected with an  \n");
+    (void) waddstr(helpwin, "audible beep.\n\n");
+    (void) waddstr(helpwin, "The program will detect if you solve the\n");
+    (void) waddstr(helpwin, "puzzle; also inform you when you run out\n");
+    (void) waddstr(helpwin, "of legal moves.\n\n");
+
+    (void) mvwaddstr(helpwin, NOTIFYY - INSTRY, 0,
+		     "Press `?' to go to keystroke help.");
+}
+
+static void
+help2(void)
+/* keystroke help screen */
+{
+    (void) waddstr(helpwin, "Possible moves are shown with `-'.\n\n");
+
+    (void) waddstr(helpwin, "You can move around with the arrow keys or\n");
+    (void) waddstr(helpwin, "with the rogue/hack movement keys.  Other\n");
+    (void) waddstr(helpwin, "commands allow you to undo moves or redraw.\n");
+    (void) waddstr(helpwin, "Your mouse may work; try left-button to\n");
+    (void) waddstr(helpwin, "move to the square under the pointer.\n\n");
+
+    (void) waddstr(helpwin, "x,q -- exit             y k u    7 8 9\n");
+    (void) waddstr(helpwin, "r -- redraw screen       \\|/      \\|/ \n");
+    (void) waddstr(helpwin, "bksp -- undo move       h-+-l    4-+-6\n");
+    (void) waddstr(helpwin, "a -- autojump            /|\\      /|\\ \n");
+    (void) waddstr(helpwin, "                        b j n    1 2 3\n");
+
+    (void) waddstr(helpwin, "\nYou can place your knight on the selected\n");
+    (void) waddstr(helpwin, "square with spacebar, Enter, or the keypad\n");
+    (void) waddstr(helpwin, "center key.  Use F/B to review the path.\n");
+
+    (void) mvwaddstr(helpwin, NOTIFYY - INSTRY, 0,
+		     "Press `?' to go to game explanation");
+}
+
+static void
+show_help(bool * keyhelp)
+{
+    werase(helpwin);
+    if (*keyhelp) {
+	help1();
+	*keyhelp = FALSE;
+    } else {
+	help2();
+	*keyhelp = TRUE;
+    }
+    wrefresh(helpwin);
+}
+
+static bool
+chksqr(int r1, int c1)
+{
+    if ((r1 < 0) || (r1 > BDEPTH - 1))
+	return (FALSE);
+    if ((c1 < 0) || (c1 > BWIDTH - 1))
+	return (FALSE);
+    return ((!board[r1][c1]) ? TRUE : FALSE);
+}
+
+static bool
+chkmoves(int rw, int col)
+/* check to see if valid moves are available */
+{
+    unsigned n;
+
+    for (n = 0; n < SIZEOF(offsets); n++)
+	if (chksqr(rw + offsets[n].y, col + offsets[n].x))
+	    return (TRUE);
+    return (FALSE);
+}
+
+static void
+dosquares(void)
+{
+    int i, j;
+
+    mvaddstr(0, 20, "KNIGHT'S MOVE -- a logical solitaire");
+
+    move(BOARDY, BOARDX);
+    waddch(boardwin, ACS_ULCORNER);
+    for (j = 0; j < 7; j++) {
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_TTEE);
+    }
+    waddch(boardwin, ACS_HLINE);
+    waddch(boardwin, ACS_HLINE);
+    waddch(boardwin, ACS_HLINE);
+    waddch(boardwin, ACS_URCORNER);
+
+    for (i = 1; i < BDEPTH; i++) {
+	move(BOARDY + i * 2 - 1, BOARDX);
+	waddch(boardwin, ACS_VLINE);
+	for (j = 0; j < BWIDTH; j++) {
+	    waddch(boardwin, ' ');
+	    waddch(boardwin, ' ');
+	    waddch(boardwin, ' ');
+	    waddch(boardwin, ACS_VLINE);
+	}
+	move(BOARDY + i * 2, BOARDX);
+	waddch(boardwin, ACS_LTEE);
+	for (j = 0; j < BWIDTH - 1; j++) {
+	    waddch(boardwin, ACS_HLINE);
+	    waddch(boardwin, ACS_HLINE);
+	    waddch(boardwin, ACS_HLINE);
+	    waddch(boardwin, ACS_PLUS);
+	}
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_RTEE);
+    }
+
+    move(BOARDY + i * 2 - 1, BOARDX);
+    waddch(boardwin, ACS_VLINE);
+    for (j = 0; j < BWIDTH; j++) {
+	waddch(boardwin, ' ');
+	waddch(boardwin, ' ');
+	waddch(boardwin, ' ');
+	waddch(boardwin, ACS_VLINE);
+    }
+
+    move(BOARDY + i * 2, BOARDX);
+    waddch(boardwin, ACS_LLCORNER);
+    for (j = 0; j < BWIDTH - 1; j++) {
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_HLINE);
+	waddch(boardwin, ACS_BTEE);
+    }
+    waddch(boardwin, ACS_HLINE);
+    waddch(boardwin, ACS_HLINE);
+    waddch(boardwin, ACS_HLINE);
+    waddch(boardwin, ACS_LRCORNER);
+}
+
+static void
+mark_possibles(int prow, int pcol, chtype mark)
+{
+    unsigned n;
+
+    for (n = 0; n < SIZEOF(offsets); n++) {
+	if (chksqr(prow + offsets[n].y, pcol + offsets[n].x)) {
+	    cellmove(prow + offsets[n].y, pcol + offsets[n].x);
+	    waddch(boardwin, mark);
+	}
+    }
+}
+
+static void
+find_next_move(int *y, int *x)
+{
+    unsigned j, k;
+    int found = -1;
+    int first = -1;
+    int next = 0;
+    int oldy, oldx;
+    int newy, newx;
+
+    if (movecount > 1) {
+	oldy = history[movecount - 1].y;
+	oldx = history[movecount - 1].x;
+	for (j = 0; j < SIZEOF(offsets) * 2; j++) {
+	    k = j % SIZEOF(offsets);
+	    newy = oldy + offsets[k].y;
+	    newx = oldx + offsets[k].x;
+	    if (chksqr(newy, newx)) {
+		if (first < 0)
+		    first = k;
+		if (newy == *y
+		    && newx == *x) {
+		    found = k;
+		} else if (found >= 0) {
+		    next = k;
+		    break;
+		}
+	    }
+	}
+	if (found < 0)
+	    next = first;
+	if (next >= 0) {
+	    *y = oldy + offsets[next].y;
+	    *x = oldx + offsets[next].x;
+	}
+    } else {
+	beep();
+    }
+}
+
+static void
+unmarkcell(int row, int column)
+{
+    cellmove(row, column);
+    waddch(boardwin, '\b');
+    waddch(boardwin, ' ');
+    waddch(boardwin, minus);
+    waddch(boardwin, ' ');
+}
+
+static void
+markcell(chtype tchar, int row, int column)
+{
+    cellmove(row, column);
+    waddch(boardwin, '\b');
+    waddch(boardwin, tchar);
+    waddch(boardwin, tchar);
+    waddch(boardwin, tchar);
+}
+
+static void
+drawmove(chtype tchar, int oldy, int oldx, int row, int column)
+/* place the stars, update board & currents */
+{
+    if (movecount <= 1) {
+	int i, j;
+
+	for (i = 0; i < BDEPTH; i++) {
+	    for (j = 0; j < BWIDTH; j++) {
+		if (movecount == 0) {
+		    unmarkcell(i, j);
+		} else {
+		    cellmove(i, j);
+		    if (winch(boardwin) == minus)
+			waddch(boardwin, movecount ? ' ' : minus);
+		}
+	    }
+	}
+    } else {
+	markcell(tchar, oldy, oldx);
+	mark_possibles(oldy, oldx, ' ');
+    }
+
+    if (row >= 0 && column >= 0) {
+	markcell(trail, row, column);
+	mark_possibles(row, column, minus);
+	board[row][column] = TRUE;
+    }
+
+    wprintw(msgwin, "\nMove %d", movecount);
+    if (trialcount != movecount)
+	wprintw(msgwin, " (%d tries)", trialcount);
+    wclrtoeol(msgwin);
+}
+
+static int
+iabs(int num)
+{
+    if (num < 0)
+	return (-num);
+    else
+	return (num);
+}
+
+static bool
+evalmove(int row, int column)
+/* evaluate move */
+{
+    if (movecount == 1)
+	return (TRUE);
+    else if (board[row][column] == TRUE) {
+	waddstr(msgwin, "\nYou've already been there.");
+	return (FALSE);
+    } else {
+	int rdif = iabs(row - history[movecount - 1].y);
+	int cdif = iabs(column - history[movecount - 1].x);
+
+	if (!((rdif == 1) && (cdif == 2)) && !((rdif == 2) && (cdif == 1))) {
+	    waddstr(msgwin, "\nThat's not a legal knight's move.");
+	    return (FALSE);
+	}
+    }
+
+    return (TRUE);
+}
+
+static int
+completed(void)
+{
+    int i, j, count = 0;
+
+    for (i = 0; i < BDEPTH; i++)
+	for (j = 0; j < BWIDTH; j++)
+	    if (board[i][j] != 0)
+		count += 1;
+    return (count == (BWIDTH * BDEPTH) ? -1 : count);
+}
+
+static void
+no_previous_move(void)
+{
+    waddstr(msgwin, "\nNo previous move.");
+    beep();
+}
+
+static void
+play(void)
+/* play the game */
+{
+    bool keyhelp;		/* TRUE if keystroke help is up */
+    int i, j, count;
+    int lastcol = 0;		/* last location visited */
+    int lastrow = 0;
+    int ny = 0, nx = 0;
+    int review = 0;		/* review history */
+    int rw = 0, col = 0;	/* current row and column */
+
+    do {
+	/* clear screen and draw board */
+	werase(boardwin);
+	werase(helpwin);
+	werase(msgwin);
+	dosquares();
+	help1();
+	wnoutrefresh(stdscr);
+	wnoutrefresh(helpwin);
+	wnoutrefresh(msgwin);
+	wnoutrefresh(boardwin);
+	doupdate();
+
+	movecount = 0;
+	for (i = 0; i < BDEPTH; i++) {
+	    for (j = 0; j < BWIDTH; j++) {
+		board[i][j] = FALSE;
+		unmarkcell(i, j);
+	    }
+	}
+	memset(history, 0, sizeof(history));
+	history[0].y = history[0].x = -1;
+	history[1].y = history[1].x = -1;
+	lastrow = lastcol = -2;
+	movecount = 1;
+	trialcount = 1;
+	keyhelp = FALSE;
+	show_help(&keyhelp);
+
+	for (;;) {
+	    if (rw != lastrow || col != lastcol) {
+		if (lastrow >= 0 && lastcol >= 0) {
+		    cellmove(lastrow, lastcol);
+		    if (board[lastrow][lastcol])
+			waddch(boardwin, trail);
+		    else
+			waddch(boardwin, oldch);
+		}
+
+		cellmove(rw, col);
+		oldch = winch(boardwin);
+
+		lastrow = rw;
+		lastcol = col;
+	    }
+	    cellmove(rw, col);
+	    waddch(boardwin, plus);
+	    cellmove(rw, col);
+
+	    wrefresh(msgwin);
+
+	    switch (wgetch(boardwin)) {
+	    case 'k':
+	    case '8':
+	    case KEY_UP:
+		ny = rw + BDEPTH - 1;
+		nx = col;
+		break;
+	    case 'j':
+	    case '2':
+	    case KEY_DOWN:
+		ny = rw + 1;
+		nx = col;
+		break;
+	    case 'h':
+	    case '4':
+	    case KEY_LEFT:
+		ny = rw;
+		nx = col + BWIDTH - 1;
+		break;
+	    case 'l':
+	    case '6':
+	    case KEY_RIGHT:
+		ny = rw;
+		nx = col + 1;
+		break;
+	    case 'y':
+	    case '7':
+	    case KEY_A1:
+		ny = rw + BDEPTH - 1;
+		nx = col + BWIDTH - 1;
+		break;
+	    case 'b':
+	    case '1':
+	    case KEY_C1:
+		ny = rw + 1;
+		nx = col + BWIDTH - 1;
+		break;
+	    case 'u':
+	    case '9':
+	    case KEY_A3:
+		ny = rw + BDEPTH - 1;
+		nx = col + 1;
+		break;
+	    case 'n':
+	    case '3':
+	    case KEY_C3:
+		ny = rw + 1;
+		nx = col + 1;
+		break;
+
+#ifdef NCURSES_MOUSE_VERSION
+	    case KEY_MOUSE:
+		{
+		    MEVENT myevent;
+
+		    getmouse(&myevent);
+		    if (myevent.y >= CY(0) && myevent.y <= CY(BDEPTH)
+			&& myevent.x >= CX(0) && myevent.x <= CX(BWIDTH)) {
+			nx = CXINV(myevent.x);
+			ny = CYINV(myevent.y);
+			ungetch('\n');
+			break;
+		    } else {
+			beep();
+			continue;
+		    }
+		}
+#endif /* NCURSES_MOUSE_VERSION */
+
+	    case KEY_B2:
+	    case '\n':
+	    case ' ':
+		review = 0;
+		if (evalmove(rw, col)) {
+		    drawmove(trail,
+			     history[movecount - 1].y,
+			     history[movecount - 1].x,
+			     rw, col);
+		    history[movecount].y = rw;
+		    history[movecount].x = col;
+		    movecount++;
+		    trialcount++;
+
+		    if (!chkmoves(rw, col)) {
+			if (completed() < 0) {
+			    waddstr(msgwin, "\nYou won.");
+			} else {
+			    waddstr(msgwin,
+				    "\nNo further moves are possible.");
+			}
+		    }
+		} else {
+		    beep();
+		}
+		break;
+
+	    case KEY_UNDO:
+	    case KEY_BACKSPACE:
+	    case '\b':
+		review = 0;
+		if (movecount <= 0) {
+		    no_previous_move();
+		} else if (movecount <= 1) {
+		    ny = history[movecount].y;
+		    nx = history[movecount].x;
+		    if (nx < 0 || ny < 0) {
+			ny = lastrow;
+			nx = lastcol;
+		    }
+		    movecount = 0;
+		    board[ny][nx] = FALSE;
+		    oldch = minus;
+		    drawmove(' ', ny, nx, -1, -1);
+		    movecount = 1;
+		    trialcount = 1;
+		    no_previous_move();
+		} else {
+		    int oldy = history[movecount - 1].y;
+		    int oldx = history[movecount - 1].x;
+
+		    if (!board[rw][col]) {
+			cellmove(rw, col);
+			waddch(boardwin, ' ');
+		    }
+
+		    board[oldy][oldx] = FALSE;
+		    --movecount;
+		    ny = history[movecount - 1].y;
+		    nx = history[movecount - 1].x;
+		    if (nx < 0 || ny < 0) {
+			ny = oldy;
+			nx = oldx;
+		    }
+		    drawmove(' ', oldy, oldx, ny, nx);
+
+		    /* avoid problems if we just changed the current cell */
+		    cellmove(lastrow, lastcol);
+		    oldch = winch(boardwin);
+		}
+		break;
+
+	    case 'a':
+		nx = col;
+		ny = rw;
+		find_next_move(&ny, &nx);
+		break;
+
+	    case 'F':
+		if (review > 0) {
+		    review--;
+		    ny = history[movecount - review - 1].y;
+		    nx = history[movecount - review - 1].x;
+		} else {
+		    beep();
+		}
+		break;
+
+	    case 'B':
+		if (review < movecount - 2) {
+		    review++;
+		    ny = history[movecount - review - 1].y;
+		    nx = history[movecount - review - 1].x;
+		} else {
+		    beep();
+		}
+		break;
+
+	    case KEY_REDO:
+	    case '\f':
+	    case 'r':
+		clearok(curscr, TRUE);
+		wnoutrefresh(stdscr);
+		wnoutrefresh(boardwin);
+		wnoutrefresh(msgwin);
+		wnoutrefresh(helpwin);
+		doupdate();
+		break;
+
+	    case 'q':
+	    case 'x':
+		goto dropout;
+
+	    case '?':
+		show_help(&keyhelp);
+		break;
+
+	    default:
+		beep();
+		break;
+	    }
+
+	    col = nx % BWIDTH;
+	    rw = ny % BDEPTH;
+	}
+
+      dropout:
+	if ((count = completed()) < 0)
+	    wprintw(msgwin, "\nYou won.  Care to try again? ");
+	else
+	    wprintw(msgwin, "\n%d squares filled.  Try again? ", count);
+	wclrtoeol(msgwin);
+    } while
+	(tolower(wgetch(msgwin)) == 'y');
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    init_program();
+
+    play();
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+
+/* knight.c ends here */
diff --git a/test/linux-color.dat b/test/linux-color.dat
new file mode 100644
index 0000000..528b3f0
--- /dev/null
+++ b/test/linux-color.dat
@@ -0,0 +1,48 @@
+##############################################################################
+# Copyright (c) 2004,2006 Free Software Foundation, Inc.                     #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+# $Id: linux-color.dat,v 1.2 2006/04/22 21:40:00 tom Exp $
+# These values are derived from linux/drivers/char/vt.c (default_red[],
+# default_grn[] and default_blu[]), commented
+/* the default colour table, for VGA+ colour systems */
+scale:255
+0:	  0	  0	  0
+1:	170	  0	  0
+2:	  0	170	  0
+3:	170	 85	  0
+4:	  0	  0	170
+5:	170	  0	170
+6:	  0	170	170
+7:	170	170	170
+8:	 85	 85	 85
+9:	255	 85	 85
+10:	 85	255	 85
+11:	255	255	 85
+12:	 85	 85	255
+13:	255	 85	255
+14:	 85	255	255
+15:	255	255	255
diff --git a/test/listused.sh b/test/listused.sh
new file mode 100755
index 0000000..525f712
--- /dev/null
+++ b/test/listused.sh
@@ -0,0 +1,182 @@
+#!/bin/sh
+##############################################################################
+# Copyright (c) 2003,2006 Free Software Foundation, Inc.                     #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+# $Id: listused.sh,v 1.7 2006/06/03 16:39:37 tom Exp $
+# A very simple script to list entrypoints that are used by either a test
+# program, or within the libraries.  This relies on the output format of 'nm',
+# and assumes that the libraries are configured with TRACE defined, and using
+# these options:
+#	--disable-macros
+#	--enable-widec
+# Static libraries are used, to provide some filtering based on internal usage
+# of the different symbols.
+
+# keep the sorting independent of locale:
+if test "${LANGUAGE+set}"    = set; then LANGUAGE=C;    export LANGUAGE;    fi
+if test "${LANG+set}"        = set; then LANG=C;        export LANG;        fi
+if test "${LC_ALL+set}"      = set; then LC_ALL=C;      export LC_ALL;      fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+if test "${LC_COLLATE+set}"  = set; then LC_COLLATE=C;  export LC_COLLATE;  fi
+
+NM_OPTS=
+
+if test ! -d ../objects ; then
+	echo "? need objects to run this script"
+	exit 1
+elif test ! -d ../lib ; then
+	echo "? need libraries to run this script"
+	exit 1
+fi
+
+PROGS=
+for name in `(echo "test:";sort modules; echo "progs:";sort ../progs/modules) |sed -e 's/[ 	].*//' -e '/^[#@]/d'`
+do
+	case $name in
+	*:)
+		PROGS="$PROGS $name"
+		;;
+	*)
+		NAME=../objects/${name}.o
+		if test -f $NAME
+		then
+			PROGS="$PROGS $NAME"
+		fi
+		;;
+	esac
+done
+
+# For each library -
+for lib in ../lib/*.a
+do
+	LIB=`basename $lib .a`
+	case $LIB in
+	*_*|*+*)
+		continue
+		;;
+	esac
+
+	tmp=`echo $LIB|sed -e 's/w$//'`
+	echo
+	echo "${tmp}:"
+	echo $tmp |sed -e 's/./-/g'
+	# Construct a list of public externals provided by the library.
+	WANT=`nm $NM_OPTS $lib |\
+		sed	-e 's/^[^ ]*//' \
+			-e 's/^ *//' \
+			-e '/^[ a-z] /d' \
+			-e '/:$/d' \
+			-e '/^$/d' \
+			-e '/^U /d' \
+			-e 's/^[A-Z] //' \
+			-e '/^_/d' |\
+		sort -u`
+	# List programs which use that external.
+	for name in $WANT
+	do
+		HAVE=
+		tags=
+		last=
+		for prog in $PROGS
+		do
+			case $prog in
+			*:)
+				tags=$prog
+				;;
+			*)
+				TEST=`nm $NM_OPTS $prog |\
+					sed	-e 's/^[^ ]*//' \
+						-e 's/^ *//' \
+						-e '/^[ a-z] /d' \
+						-e '/:$/d' \
+						-e '/^$/d' \
+						-e 's/^[A-Z] //' \
+						-e '/^_/d' \
+						-e 's/^'${name}'$/_/' \
+						-e '/^[^_]/d'`
+				if test -n "$TEST"
+				then
+					have=`basename $prog .o`
+					if test -n "$HAVE"
+					then
+						if test "$last" = "$tags"
+						then
+							HAVE="$HAVE $have"
+						else
+							HAVE="$HAVE $tags $have"
+						fi
+					else
+						HAVE="$tags $have"
+					fi
+					last="$tags"
+				fi
+				;;
+			esac
+		done
+		# if we did not find a program using it directly, see if it
+		# is used within a library.
+		if test -z "$HAVE"
+		then
+			for tmp in ../lib/*.a
+			do 
+				case $tmp in
+				*_*|*+*)
+					continue
+					;;
+				esac
+				TEST=`nm $NM_OPTS $tmp |\
+					sed	-e 's/^[^ ]*//' \
+						-e 's/^ *//' \
+						-e '/^[ a-z] /d' \
+						-e '/:$/d' \
+						-e '/^$/d' \
+						-e '/^[A-TV-Z] /d' \
+						-e 's/^[A-Z] //' \
+						-e '/^_/d' \
+						-e 's/^'${name}'$/_/' \
+						-e '/^[^_]/d'`
+				if test -n "$TEST"
+				then
+					tmp=`basename $tmp .a |sed -e 's/w$//'`
+					HAVE=`echo $tmp | sed -e 's/lib/lib: /'`
+					break
+				fi
+			done
+		fi
+		test -z "$HAVE" && HAVE="-"
+		lenn=`expr 39 - length $name`
+		lenn=`expr $lenn / 8`
+		tabs=
+		while test $lenn != 0
+		do
+			tabs="${tabs}	"
+			lenn=`expr $lenn - 1`
+		done
+		echo "${name}${tabs}${HAVE}"
+	done
+done
diff --git a/test/lrtest.c b/test/lrtest.c
new file mode 100644
index 0000000..e40b0c1
--- /dev/null
+++ b/test/lrtest.c
@@ -0,0 +1,182 @@
+/****************************************************************************
+ * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * Test lower-right-hand corner access
+ *
+ * originally by Eric S. Raymond <esr@thyrsus.com>, written for animation
+ * and resizing -T.Dickey
+ *
+ * This can't be part of the ncurses test-program, because ncurses rips off the
+ * bottom line to do labels.
+ *
+ * $Id: lrtest.c,v 1.21 2005/12/31 16:51:53 tom Exp $
+ */
+
+#include <test.priv.h>
+
+typedef struct {
+    int y, x, mode, dir, inc;
+    chtype value;
+} MARK;
+
+/*
+ * Make a couple of markers go 'round the border to demonstrate that we can
+ * really write to all positions properly.
+ */
+static void
+show(MARK *m)
+{
+    mvaddch(m->y, m->x, m->value);
+    if (m->mode == 0) {		/* along the x-direction */
+	m->x += m->inc;
+	if (m->x >= COLS) {
+	    m->x = COLS - 1;
+	    m->inc = -m->dir * m->inc;
+	    m->y += m->inc;
+	    m->mode = 1;
+	} else if (m->x < 0) {
+	    m->x = 0;
+	    m->inc = -m->dir * m->inc;
+	    m->y += m->inc;
+	    m->mode = 1;
+	}
+    } else {			/* along the y-direction */
+	m->y += m->inc;
+	if (m->y >= LINES) {
+	    m->y = LINES - 1;
+	    m->inc = m->dir * m->inc;
+	    m->x += m->inc;
+	    m->mode = 0;
+	} else if (m->y < 0) {
+	    m->y = 0;
+	    m->inc = m->dir * m->inc;
+	    m->x += m->inc;
+	    m->mode = 0;
+	}
+    }
+}
+
+int
+main(
+	int argc GCC_UNUSED,
+	char *argv[]GCC_UNUSED)
+{
+    static MARK marks[] =
+    {
+	{0, 0, 0, -1, 1, '+' | A_BOLD},
+	{0, 0, 1, 1, 2, 'X'},
+	{0, 0, 1, -1, 3, 'Y'},
+	{0, 8, 0, -1, 1, '+' | A_BOLD},
+	{0, 9, 0, -1, 1, '+' | A_BOLD},
+	{1, 0, 1, 1, 1, '*' | A_REVERSE},
+	{2, 0, 1, 1, 1, '*' | A_REVERSE}
+    };
+
+    setlocale(LC_ALL, "");
+
+    initscr();
+    noecho();
+    cbreak();
+    nodelay(stdscr, TRUE);
+    curs_set(0);
+
+#ifdef KEY_RESIZE
+    keypad(stdscr, TRUE);
+  restart:
+#endif
+    move(LINES / 2 - 1, 4);
+    if (!(has_ic()
+#if HAVE_SETUPTERM
+    /* see PutCharLR() */
+	  || auto_right_margin
+	  || (enter_am_mode && exit_am_mode)
+#endif
+	)) {
+	addstr("Your terminal lacks the capabilities needed to address the\n");
+	move(LINES / 2, 4);
+	addstr("lower-right-hand corner of the screen.\n");
+    } else {
+	addstr("This is a test of access to the lower right corner.\n");
+	move(LINES / 2, 4);
+	addstr("If the top of the box is missing, the test failed.\n");
+	move(LINES / 2 + 1, 4);
+	addstr("Please report this (with a copy of your terminfo entry).\n");
+	move(LINES / 2 + 2, 4);
+	addstr("to the ncurses maintainers, at bug-ncurses@gnu.org.\n");
+    }
+
+    for (;;) {
+	int ch;
+	unsigned n;
+
+	box(stdscr, 0, 0);
+	for (n = 0; n < SIZEOF(marks); n++) {
+	    show(&marks[n]);
+	}
+
+	if ((ch = getch()) > 0) {
+	    if (ch == 'q')
+		break;
+	    else if (ch == 's')
+		nodelay(stdscr, FALSE);
+	    else if (ch == ' ')
+		nodelay(stdscr, TRUE);
+#ifdef TRACE
+	    else if (ch == 'T')
+		trace(0);
+	    else if (ch == 't')
+		trace(TRACE_CALLS | TRACE_ICALLS | TRACE_UPDATE);
+#endif
+#ifdef KEY_RESIZE
+	    else if (ch == KEY_RESIZE) {
+		for (n = 0; n < SIZEOF(marks); n++) {
+		    if (marks[n].mode == 0) {	/* moving along x-direction */
+			if (marks[n].y)
+			    marks[n].y = LINES - 1;
+		    } else {
+			if (marks[n].x)
+			    marks[n].x = COLS - 1;
+		    }
+		}
+		flash();
+		erase();
+		wrefresh(curscr);
+		goto restart;
+	    }
+#endif
+	}
+	napms(50);
+	refresh();
+    }
+
+    curs_set(1);
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+
+/* lrtest.c ends here */
diff --git a/test/mk-test.awk b/test/mk-test.awk
new file mode 100644
index 0000000..9be0361
--- /dev/null
+++ b/test/mk-test.awk
@@ -0,0 +1,111 @@
+# $Id: mk-test.awk,v 1.5 2007/01/20 21:28:47 tom Exp $
+##############################################################################
+# Copyright (c) 2006,2007 Free Software Foundation, Inc.                     #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+#
+# Author: Thomas E. Dickey
+#
+# generate Makefile for ncurses tests.
+BEGIN	{
+		first = 1;
+		count = 0;
+	}
+/^#/	{
+		next;
+	}
+/^$/	{
+		next;
+	}
+	{
+		if (first) {
+			print "# generated by mk-test.awk\n";
+			first = 0;
+		}
+		progs[count] = $1;
+		flags[count] = $2;
+		using[count] = $3;
+		files[count] = "";
+		for (n = 4; n <= NF; ++n) {
+			files[count] = sprintf("%s $(MODEL)/%s$o", files[count], $n);
+		}
+		count = count + 1;
+	}
+END	{
+	for (n = 0; n < count; ++n) {
+		if (n == 0) {
+			printf "TESTS\t= ";
+		} else {
+			printf "\t  ";
+		}
+		printf "$(destdir)%s$x", progs[n];
+		if (n < count - 1) {
+			printf " \\";
+		}
+		print "";
+	}
+	print	""
+	print	"all: $(TESTS)"
+	print	""
+	print	"sources:"
+	print	""
+	print	"tags:"
+	print	"	ctags *.[ch]"
+	print	""
+	print	"libs \\"
+	print	"install \\"
+	print	"install.libs \\"
+	print	"install.test:"
+	print	""
+	print	"uninstall:"
+	print	"uninstall.libs:"
+	print	"uninstall.test:"
+	print	""
+	print	"mostlyclean ::"
+	print	"	-rm -f core tags TAGS *~ *.bak *.i *.ln *.atac trace"
+	print	""
+	print	"clean :: mostlyclean"
+	print	"	-sh -c \"if test -n '$x' ; then $(MAKE) clean x=''; fi\""
+	print	"	-rm -rf *$o screendump *.lis $(TESTS) .libs"
+	print	""
+	print	"distclean :: clean"
+	print	"	-rm -f Makefile ncurses_cfg.h config.*"
+	print	""
+	print	"realclean :: distclean"
+	print	""
+	print	"lint:"
+	print	"	sh -c 'for N in $(TESTS); do echo LINT:$$N; $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/$$N.c $(LINT_LIBS); done'"
+
+	if (ECHO_LINK != "") {
+		ECHO_LINK="@ echo linking $@ ... ;"
+	}
+	for (n = 0; n < count; ++n) {
+		print "";
+		printf "$(destdir)%s$x:%s %s\n", progs[n], files[n], using[n];
+		printf "\t%s$(LINK) -o $@%s %s\n", ECHO_LINK, files[n], flags[n];
+	}
+
+	}
diff --git a/test/modules b/test/modules
new file mode 100644
index 0000000..2b55566
--- /dev/null
+++ b/test/modules
@@ -0,0 +1,89 @@
+# $Id: modules,v 1.36 2007/08/18 17:57:08 tom Exp $
+##############################################################################
+# Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.                #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+#
+# Author: Thomas E. Dickey	1997-on
+#
+# Test-Program modules
+
+@ base
+background	progs		$(srcdir)	$(HEADER_DEPS)
+blue		progs		$(srcdir)	$(HEADER_DEPS)
+bs		progs		$(srcdir)	$(HEADER_DEPS)
+cardfile	progs		$(srcdir)	$(HEADER_DEPS)	../include/panel.h ../include/form.h
+chgat		progs		$(srcdir)	$(HEADER_DEPS)
+color_set	progs		$(srcdir)	$(HEADER_DEPS)
+demo_altkeys	progs		$(srcdir)	$(HEADER_DEPS)
+demo_defkey	progs		$(srcdir)	$(HEADER_DEPS)
+demo_forms	progs		$(srcdir)	$(HEADER_DEPS)	../include/form.h $(srcdir)/edit_field.h
+demo_keyok	progs		$(srcdir)	$(HEADER_DEPS)
+demo_menus	progs		$(srcdir)	$(HEADER_DEPS)	../include/menu.h
+demo_panels	progs		$(srcdir)	$(HEADER_DEPS)	../include/panel.h
+demo_termcap	progs		$(srcdir)	$(HEADER_DEPS)
+ditto		progs		$(srcdir)	$(HEADER_DEPS)
+dots		progs		$(srcdir)	$(HEADER_DEPS)
+dots_mvcur	progs		$(srcdir)	$(HEADER_DEPS)
+echochar	progs		$(srcdir)	$(HEADER_DEPS)
+edit_field	progs		$(srcdir)	$(HEADER_DEPS)	$(srcdir)/edit_field.h
+filter		progs		$(srcdir)	$(HEADER_DEPS)	../include/form.h
+firework	progs		$(srcdir)	$(HEADER_DEPS)
+firstlast	progs		$(srcdir)	$(HEADER_DEPS)
+foldkeys	progs		$(srcdir)	$(HEADER_DEPS)
+gdc		progs		$(srcdir)	$(HEADER_DEPS)
+hanoi		progs		$(srcdir)	$(HEADER_DEPS)
+hashtest	progs		$(srcdir)	$(HEADER_DEPS)
+inch_wide	progs		$(srcdir)	$(HEADER_DEPS)
+inchs		progs		$(srcdir)	$(HEADER_DEPS)
+ins_wide	progs		$(srcdir)	$(HEADER_DEPS)
+inserts		progs		$(srcdir)	$(HEADER_DEPS)
+key_names	progs		$(srcdir)	$(HEADER_DEPS)
+keynames	progs		$(srcdir)	$(HEADER_DEPS)
+knight		progs		$(srcdir)	$(HEADER_DEPS)
+lrtest		progs		$(srcdir)	$(HEADER_DEPS)
+movewindow	progs		$(srcdir)	$(HEADER_DEPS)
+ncurses		progs		$(srcdir)	$(HEADER_DEPS)	../include/panel.h ../include/menu.h ../include/form.h
+newdemo		progs		$(srcdir)	$(HEADER_DEPS)
+railroad	progs		$(srcdir)	$(HEADER_DEPS)
+rain		progs		$(srcdir)	$(HEADER_DEPS)
+redraw		progs		$(srcdir)	$(HEADER_DEPS)
+savescreen	progs		$(srcdir)	$(HEADER_DEPS)
+tclock		progs		$(srcdir)	$(HEADER_DEPS)
+test_arrays	progs		$(srcdir)	$(HEADER_DEPS)
+test_get_wstr	progs		$(srcdir)	$(HEADER_DEPS)
+test_getstr	progs		$(srcdir)	$(HEADER_DEPS)
+test_instr	progs		$(srcdir)	$(HEADER_DEPS)
+test_inwstr	progs		$(srcdir)	$(HEADER_DEPS)
+test_opaque	progs		$(srcdir)	$(HEADER_DEPS)
+testaddch	progs		$(srcdir)	$(HEADER_DEPS)
+testcurs	progs		$(srcdir)	$(HEADER_DEPS)
+testscanw	progs		$(srcdir)	$(HEADER_DEPS)
+view		progs		$(srcdir)	$(HEADER_DEPS)
+worm		progs		$(srcdir)	$(HEADER_DEPS)
+xmas		progs		$(srcdir)	$(HEADER_DEPS)
+
+# vile:makemode
diff --git a/test/movewindow.c b/test/movewindow.c
new file mode 100644
index 0000000..d826e58
--- /dev/null
+++ b/test/movewindow.c
@@ -0,0 +1,639 @@
+/****************************************************************************
+ * Copyright (c) 2006-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: movewindow.c,v 1.22 2008/04/12 22:01:41 tom Exp $
+ *
+ * Demonstrate move functions for windows and derived windows from the curses
+ * library.
+ *
+ * Thomas Dickey - 2006/2/11
+ */
+/*
+derwin
+mvderwin
+subwin
+mvwin
+ */
+
+#include <test.priv.h>
+#include <stdarg.h>
+
+#ifdef HAVE_XCURSES
+#undef derwin
+#endif
+
+#ifdef NCURSES_VERSION
+#define CONST_FMT const
+#else
+#define CONST_FMT		/* nothing */
+#endif
+
+#undef LINE_MAX
+
+#define LINE_MIN	2
+#define LINE_MAX	(LINES - 2)
+#define COL_MIN		2
+#define COL_MAX		(COLS - 2)
+
+typedef struct {
+    int y, x;
+} PAIR;
+
+typedef struct {
+    WINDOW *parent;		/* need this since WINDOW->_parent is not portable */
+    WINDOW *child;		/* the actual value */
+} FRAME;
+
+static void head_line(CONST_FMT char *fmt,...) GCC_PRINTFLIKE(1, 2);
+static void tail_line(CONST_FMT char *fmt,...) GCC_PRINTFLIKE(1, 2);
+
+static unsigned num_windows;
+static FRAME *all_windows;
+
+static void
+message(int lineno, CONST_FMT char *fmt, va_list argp)
+{
+    int y, x;
+
+    getyx(stdscr, y, x);
+    move(lineno, 0);
+    clrtoeol();
+
+#ifdef HAVE_XCURSES
+    {
+	char buffer[1024];
+	vsprintf(buffer, fmt, argp);
+	addstr(buffer);
+    }
+#else
+    vwprintw(stdscr, fmt, argp);
+#endif
+
+    move(y, x);
+    refresh();
+}
+
+static void
+head_line(CONST_FMT char *fmt,...)
+{
+    va_list argp;
+
+    va_start(argp, fmt);
+    message(0, fmt, argp);
+    va_end(argp);
+}
+
+static void
+tail_line(CONST_FMT char *fmt,...)
+{
+    va_list argp;
+
+    va_start(argp, fmt);
+    message(LINES - 1, fmt, argp);
+    va_end(argp);
+}
+
+/*
+ * Arrow keys move cursor, return location at current on non-arrow key.
+ */
+static PAIR *
+selectcell(WINDOW *parent, int uli, int ulj, int lri, int lrj)
+{
+    static PAIR res;		/* result cell */
+    int si = lri - uli + 1;	/* depth of the select area */
+    int sj = lrj - ulj + 1;	/* width of the select area */
+    int i = 0, j = 0;		/* offsets into the select area */
+
+    res.y = uli;
+    res.x = ulj;
+    for (;;) {
+	tail_line("Upper left [%2d,%2d] Lower right [%2d,%2d] -> %d,%d",
+		  uli, ulj,
+		  lri, lrj,
+		  uli + i, ulj + j);
+	wmove(parent, uli + i, ulj + j);
+
+	switch (wgetch(parent)) {
+	case KEY_UP:
+	    i += si - 1;
+	    break;
+	case KEY_DOWN:
+	    i++;
+	    break;
+	case KEY_LEFT:
+	    j += sj - 1;
+	    break;
+	case KEY_RIGHT:
+	    j++;
+	    break;
+	case QUIT:
+	case ESCAPE:
+	    return ((PAIR *) 0);
+#ifdef NCURSES_MOUSE_VERSION
+	case KEY_MOUSE:
+	    {
+		MEVENT event;
+
+		getmouse(&event);
+		if (event.y > uli && event.x > ulj) {
+		    i = event.y - uli;
+		    j = event.x - ulj;
+		} else {
+		    beep();
+		    break;
+		}
+	    }
+	    /* FALLTHRU */
+#endif
+	default:
+	    res.y = uli + i;
+	    res.x = ulj + j;
+	    return (&res);
+	}
+	i %= si;
+	j %= sj;
+    }
+}
+
+/*
+ * Ask user for a window definition.
+ */
+static bool
+getwindow(WINDOW *parent, PAIR * ul, PAIR * lr)
+{
+    int min_col = (parent == stdscr) ? COL_MIN : 0;
+    int max_col = (parent == stdscr) ? COL_MAX : getmaxx(parent);
+    int min_line = (parent == stdscr) ? LINE_MIN : 0;
+    int max_line = (parent == stdscr) ? LINE_MAX : getmaxy(parent);
+    PAIR *tmp;
+    bool result = FALSE;
+
+    head_line("Use arrows to move cursor, anything else to mark corner 1");
+    if ((tmp = selectcell(parent, min_line, min_col, max_line, max_col)) != 0) {
+	*ul = *tmp;
+	mvwaddch(parent, ul->y, ul->x, '*');
+
+	head_line("Use arrows to move cursor, anything else to mark corner 2");
+	if ((tmp = selectcell(parent, ul->y, ul->x, max_line, max_col)) != 0) {
+	    *lr = *tmp;
+	    mvwaddch(parent, lr->y, lr->x, '*');
+	    wmove(parent, lr->y, lr->x);
+	    wsyncdown(parent);
+	    wrefresh(parent);
+	    result = (lr->y != ul->y && lr->x != ul->x);
+	}
+    }
+    head_line("done");
+    return result;
+}
+
+/*
+ * Draw a box inside the given window.
+ */
+static void
+box_inside(WINDOW *win)
+{
+    int y0, x0;
+    int y1, x1;
+
+    getyx(win, y0, x0);
+    getmaxyx(win, y1, x1);
+
+    mvwhline(win, 0, 0, ACS_HLINE, x1);
+    mvwhline(win, y1 - 1, 0, ACS_HLINE, x1);
+
+    mvwvline(win, 0, 0, ACS_VLINE, y1);
+    mvwvline(win, 0, x1 - 1, ACS_VLINE, y1);
+
+    mvwaddch(win, 0, 0, ACS_ULCORNER);
+    mvwaddch(win, y1 - 1, 0, ACS_LLCORNER);
+    mvwaddch(win, 0, x1 - 1, ACS_URCORNER);
+    mvwaddch(win, y1 - 1, x1 - 1, ACS_LRCORNER);
+
+    wsyncdown(win);
+    wmove(win, y0, x0);
+    wrefresh(win);
+}
+
+/*
+ * Add a window to our list.
+ */
+static void
+add_window(WINDOW *parent, WINDOW *child)
+{
+    static unsigned have = 0;
+    unsigned need = ((num_windows + 1) | 31) + 1;
+
+    keypad(child, TRUE);
+    if (need > have) {
+	all_windows = typeRealloc(FRAME, need, all_windows);
+    }
+    all_windows[num_windows].parent = parent;
+    all_windows[num_windows].child = child;
+    num_windows++;
+}
+
+static int
+window2num(WINDOW *win)
+{
+    int n;
+    int result = -1;
+    for (n = 0; n < (int) num_windows; ++n) {
+	if (win == all_windows[n].child) {
+	    result = n;
+	    break;
+	}
+    }
+    return result;
+}
+
+static WINDOW *
+parent_of(WINDOW *win)
+{
+    WINDOW *result = 0;
+    int n = window2num(win);
+    if (n >= 0)
+	result = all_windows[n].parent;
+    return result;
+}
+
+static void
+repaint_one(WINDOW *win)
+{
+    touchwin(win);
+    wnoutrefresh(win);
+}
+
+static void
+refresh_all(WINDOW *win)
+{
+    unsigned n;
+
+    for (n = 0; n < num_windows; ++n) {
+	if (all_windows[n].child != win) {
+	    repaint_one(all_windows[n].child);
+	}
+    }
+
+    repaint_one(win);
+    doupdate();
+}
+
+static WINDOW *
+next_window(WINDOW *win)
+{
+    WINDOW *result = win;
+    int n = window2num(win);
+
+    if (n++ >= 0) {
+	result = all_windows[n % num_windows].child;
+	wmove(result, 0, 0);
+	wrefresh(result);
+    }
+    return result;
+}
+
+static WINDOW *
+prev_window(WINDOW *win)
+{
+    WINDOW *result = win;
+    int n = window2num(win);
+
+    if (n-- >= 0) {
+	if (n < 0)
+	    n = num_windows - 1;
+	result = all_windows[n % num_windows].child;
+	wmove(result, 0, 0);
+	wrefresh(result);
+    }
+    return result;
+}
+
+static void
+recur_move_window(WINDOW *parent, int dy, int dx)
+{
+    unsigned n;
+
+    for (n = 0; n < num_windows; ++n) {
+	if (all_windows[n].parent == parent) {
+	    int y0, x0;
+
+	    getbegyx(all_windows[n].child, y0, x0);
+	    mvwin(all_windows[n].child, y0 + dy, x0 + dx);
+	    recur_move_window(all_windows[n].child, dy, dx);
+	}
+    }
+}
+
+/*
+ * test mvwin().
+ */
+static bool
+move_window(WINDOW *win, bool recur)
+{
+    WINDOW *parent = parent_of(win);
+    bool result = FALSE;
+
+    if (parent != 0) {
+	bool top = (parent == stdscr);
+	int min_col = top ? COL_MIN : 0;
+	int max_col = top ? COL_MAX : getmaxx(parent);
+	int min_line = top ? LINE_MIN : 0;
+	int max_line = top ? LINE_MAX : getmaxy(parent);
+	PAIR *tmp;
+
+	head_line("Select new position for %swindow", top ? "" : "sub");
+
+	if ((tmp = selectcell(parent,
+			      min_line, min_col,
+			      max_line, max_col)) != 0) {
+	    int y0, x0;
+	    getbegyx(parent, y0, x0);
+	    /*
+	     * Note:  Moving a subwindow has the effect of moving a viewport
+	     * around the screen.  The parent window retains the contents of
+	     * the subwindow in the original location, but the viewport will
+	     * show the contents (again) at the new location.  So it will look
+	     * odd when testing.
+	     */
+	    if (mvwin(win, y0 + tmp->y, x0 + tmp->x) != ERR) {
+		if (recur) {
+		    recur_move_window(win, tmp->y, tmp->x);
+		}
+		refresh_all(win);
+		doupdate();
+		result = TRUE;
+	    }
+	}
+    }
+    return result;
+}
+
+/*
+ * test mvderwin().
+ */
+static bool
+move_subwin(WINDOW *win)
+{
+    WINDOW *parent = parent_of(win);
+    bool result = FALSE;
+
+    if (parent != 0) {
+	bool top = (parent == stdscr);
+	if (!top) {
+	    int min_col = top ? COL_MIN : 0;
+	    int max_col = top ? COL_MAX : getmaxx(parent);
+	    int min_line = top ? LINE_MIN : 0;
+	    int max_line = top ? LINE_MAX : getmaxy(parent);
+	    PAIR *tmp;
+
+	    head_line("Select new position for subwindow");
+
+	    if ((tmp = selectcell(parent,
+				  min_line, min_col,
+				  max_line, max_col)) != 0) {
+		int y0, x0;
+		getbegyx(parent, y0, x0);
+		if (mvderwin(win, y0 + tmp->y, x0 + tmp->x) != ERR) {
+		    refresh_all(win);
+		    doupdate();
+		    result = TRUE;
+		}
+	    }
+	}
+    }
+    return result;
+}
+
+static void
+fill_window(WINDOW *win, chtype ch)
+{
+    int y, x;
+    int y0, x0;
+    int y1, x1;
+
+    getyx(win, y0, x0);
+    getmaxyx(win, y1, x1);
+    for (y = 0; y < y1; ++y) {
+	for (x = 0; x < x1; ++x) {
+	    mvwaddch(win, y, x, ch);
+	}
+    }
+    wsyncdown(win);
+    wmove(win, y0, x0);
+    wrefresh(win);
+}
+
+#define lines_of(ul,lr)	(lr.y - ul.y + 1)
+#define cols_of(ul,lr)	(lr.x - ul.x + 1)
+#define pair_of(ul)	ul.y, ul.x
+
+static WINDOW *
+create_my_window(WINDOW *current)
+{
+    PAIR ul, lr;
+    WINDOW *result = 0;
+
+    if (getwindow(stdscr, &ul, &lr)) {
+	result = newwin(lines_of(ul, lr), cols_of(ul, lr), pair_of(ul));
+	if (result != 0) {
+	    fill_window(result, 'c');
+	    add_window(stdscr, result);
+	}
+    }
+    if (result == 0)
+	result = current;
+    return result;
+}
+
+static WINDOW *
+create_my_derwin(WINDOW *parent)
+{
+    PAIR ul, lr;
+    WINDOW *result = 0;
+
+    if (getwindow(parent, &ul, &lr)) {
+	result = derwin(parent, lines_of(ul, lr), cols_of(ul, lr), pair_of(ul));
+	if (result != 0) {
+	    fill_window(result, 'd');
+	    add_window(parent, result);
+	}
+    }
+    if (result == 0)
+	result = parent;
+    return result;
+}
+
+static WINDOW *
+create_my_subwin(WINDOW *parent)
+{
+    PAIR ul, lr;
+    WINDOW *result = 0;
+
+    if (getwindow(parent, &ul, &lr)) {
+	result = subwin(parent,
+			lines_of(ul, lr),
+			cols_of(ul, lr),
+			ul.y + getbegy(parent),
+			ul.x + getbegx(parent));
+	if (result != 0) {
+	    fill_window(result, 's');
+	    add_window(parent, result);
+	}
+    }
+    if (result == 0)
+	result = parent;
+    return result;
+}
+
+static void
+show_help(WINDOW *current)
+{
+    /* *INDENT-OFF* */
+    static struct {
+	int	key;
+	CONST_FMT char * msg;
+    } help[] = {
+	{ '?',		"Show this screen" },
+	{ 'b',		"Draw a box inside the current window" },
+	{ 'c',		"Create a new window" },
+	{ 'd',		"Create a new derived window" },
+	{ 'f',		"Fill the current window with the next character" },
+	{ 'm',		"Move the current window" },
+	{ 'M',		"Move the current window (and its children)" },
+	{ 'q',		"Quit" },
+	{ 's',		"Create a new subwindow" },
+	{ 't',		"Move the current subwindow (moves content)" },
+	{ CTRL('L'),	"Repaint all windows, doing current one last" },
+	{ CTRL('N'),	"Cursor to next window" },
+	{ CTRL('P'),	"Cursor to previous window" },
+    };
+    /* *INDENT-ON* */
+
+    WINDOW *mywin = newwin(LINES, COLS, 0, 0);
+    int row;
+
+    for (row = 0; row < LINES - 2 && row < (int) SIZEOF(help); ++row) {
+	wmove(mywin, row + 1, 1);
+	wprintw(mywin, "%s", keyname(help[row].key));
+	wmove(mywin, row + 1, 20);
+	wprintw(mywin, "%s", help[row].msg);
+    }
+    box_inside(mywin);
+    wmove(mywin, 1, 1);
+    wgetch(mywin);
+    delwin(mywin);
+    refresh_all(current);
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    WINDOW *current_win;
+    int ch;
+    bool done = FALSE;
+
+    initscr();
+    cbreak();
+    noecho();
+    nonl();
+    intrflush(stdscr, FALSE);
+
+    add_window(0, current_win = stdscr);
+
+#ifdef NCURSES_MOUSE_VERSION
+    (void) mousemask(BUTTON1_CLICKED, (mmask_t *) NULL);
+#endif /* NCURSES_MOUSE_VERSION */
+
+    while (!done && (ch = wgetch(current_win)) != ERR) {
+	switch (ch) {
+	case '?':
+	    show_help(current_win);
+	    break;
+	case 'b':
+	    box_inside(current_win);
+	    break;
+	case 'c':
+	    current_win = create_my_window(current_win);
+	    break;
+	case 'd':
+	    current_win = create_my_derwin(current_win);
+	    break;
+	case 'f':
+	    fill_window(current_win, (chtype) wgetch(current_win));
+	    break;
+	case 'm':
+	case 'M':
+	    if (!move_window(current_win, (ch == 'M'))) {
+		tail_line("error");
+		continue;
+	    }
+	    break;
+	case 'q':
+	    done = TRUE;
+	    break;
+	case 's':
+	    current_win = create_my_subwin(current_win);
+	    break;
+	case 't':
+	    if (!move_subwin(current_win)) {
+		tail_line("error");
+		continue;
+	    }
+	    break;
+	case CTRL('L'):
+	    refresh_all(current_win);
+	    break;
+	case CTRL('N'):
+	    current_win = next_window(current_win);
+	    break;
+	case CTRL('P'):
+	    current_win = prev_window(current_win);
+	    break;
+#if 0
+	    /* want to allow cursor to move around the current window too */
+	    /* want to test the resizing of windows and subwindows too */
+	    /* want to allow deleting a window also */
+#endif
+	default:
+	    tail_line("unrecognized key (use '?' for help)");
+	    beep();
+	    continue;
+	}
+	tail_line("size [%d,%d] begin [%d,%d] parent [%d,%d]",
+		  getmaxy(current_win),
+		  getmaxx(current_win),
+		  getbegy(current_win),
+		  getbegx(current_win),
+		  getpary(current_win),
+		  getparx(current_win));
+	wmove(current_win, 0, 0);
+    }
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/ncurses.c b/test/ncurses.c
new file mode 100644
index 0000000..3fd7dfa
--- /dev/null
+++ b/test/ncurses.c
@@ -0,0 +1,6571 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/****************************************************************************
+
+NAME
+   ncurses.c --- ncurses library exerciser
+
+SYNOPSIS
+   ncurses
+
+DESCRIPTION
+   An interactive test module for the ncurses library.
+
+AUTHOR
+   Author: Eric S. Raymond <esr@snark.thyrsus.com> 1993
+           Thomas E. Dickey (beginning revision 1.27 in 1996).
+
+$Id: ncurses.c,v 1.329 2008/09/27 14:34:58 tom Exp $
+
+***************************************************************************/
+
+#include <test.priv.h>
+
+#ifdef __hpux
+#undef mvwdelch			/* HPUX 11.23 macro will not compile */
+#endif
+
+#if HAVE_GETTIMEOFDAY
+#if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT
+#include <sys/time.h>
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#endif
+
+#if USE_LIBPANEL
+#include <panel.h>
+#endif
+
+#if USE_LIBMENU
+#include <menu.h>
+#endif
+
+#if USE_LIBFORM
+#include <form.h>
+#endif
+
+#ifdef NCURSES_VERSION
+
+#define NCURSES_CONST_PARAM const void
+
+#ifdef TRACE
+static unsigned save_trace = TRACE_ORDINARY | TRACE_ICALLS | TRACE_CALLS;
+extern unsigned _nc_tracing;
+#endif
+
+#else
+
+#define NCURSES_CONST_PARAM char
+
+#define mmask_t chtype		/* not specified in XSI */
+
+#ifndef ACS_S3
+#ifdef CURSES_ACS_ARRAY
+#define ACS_S3          (CURSES_ACS_ARRAY['p'])		/* scan line 3 */
+#define ACS_S7          (CURSES_ACS_ARRAY['r'])		/* scan line 7 */
+#define ACS_LEQUAL      (CURSES_ACS_ARRAY['y'])		/* less/equal */
+#define ACS_GEQUAL      (CURSES_ACS_ARRAY['z'])		/* greater/equal */
+#define ACS_PI          (CURSES_ACS_ARRAY['{'])		/* Pi */
+#define ACS_NEQUAL      (CURSES_ACS_ARRAY['|'])		/* not equal */
+#define ACS_STERLING    (CURSES_ACS_ARRAY['}'])		/* UK pound sign */
+#else
+#define ACS_S3          (A_ALTCHARSET + 'p')	/* scan line 3 */
+#define ACS_S7          (A_ALTCHARSET + 'r')	/* scan line 7 */
+#define ACS_LEQUAL      (A_ALTCHARSET + 'y')	/* less/equal */
+#define ACS_GEQUAL      (A_ALTCHARSET + 'z')	/* greater/equal */
+#define ACS_PI          (A_ALTCHARSET + '{')	/* Pi */
+#define ACS_NEQUAL      (A_ALTCHARSET + '|')	/* not equal */
+#define ACS_STERLING    (A_ALTCHARSET + '}')	/* UK pound sign */
+#endif
+#endif /* ACS_S3 */
+
+#ifdef CURSES_WACS_ARRAY
+#define WACS_S3         (&(CURSES_WACS_ARRAY['p']))	/* scan line 3 */
+#define WACS_S7         (&(CURSES_WACS_ARRAY['r']))	/* scan line 7 */
+#define WACS_LEQUAL     (&(CURSES_WACS_ARRAY['y']))	/* less/equal */
+#define WACS_GEQUAL     (&(CURSES_WACS_ARRAY['z']))	/* greater/equal */
+#define WACS_PI         (&(CURSES_WACS_ARRAY['{']))	/* Pi */
+#define WACS_NEQUAL     (&(CURSES_WACS_ARRAY['|']))	/* not equal */
+#define WACS_STERLING   (&(CURSES_WACS_ARRAY['}']))	/* UK pound sign */
+#endif
+
+#endif
+
+#if HAVE_WCSRTOMBS
+#define count_wchars(src, len, state)      wcsrtombs(0,   &src, len, state)
+#define trans_wchars(dst, src, len, state) wcsrtombs(dst, &src, len, state)
+#define reset_wchars(state) memset(&state, 0, sizeof(state))
+#elif HAVE_WCSTOMBS && HAVE_MBTOWC && HAVE_MBLEN
+#define count_wchars(src, len, state)      wcstombs(0,   src, len)
+#define trans_wchars(dst, src, len, state) wcstombs(dst, src, len)
+#define reset_wchars(state) mblen(NULL, 0), mbtowc(NULL, NULL, 0)
+#define state_unused
+#endif
+
+#if HAVE_MBSRTOWCS
+#define count_mbytes(src, len, state)      mbsrtowcs(0,   &src, len, state)
+#define trans_mbytes(dst, src, len, state) mbsrtowcs(dst, &src, len, state)
+#define reset_mbytes(state) memset(&state, 0, sizeof(state))
+#elif HAVE_MBSTOWCS && HAVE_MBTOWC && HAVE_MBLEN
+#define count_mbytes(src, len, state)      mbstowcs(0,   src, len)
+#define trans_mbytes(dst, src, len, state) mbstowcs(dst, src, len)
+#define reset_mbytes(state) mblen(NULL, 0), mbtowc(NULL, NULL, 0)
+#define state_unused
+#endif
+
+#define ToggleAcs(temp,real) temp = ((temp == real) ? 0 : real)
+
+#define P(string)	printw("%s\n", string)
+
+#define BLANK		' '	/* this is the background character */
+
+#undef max_colors
+static int max_colors;		/* the actual number of colors we'll use */
+static int min_colors;		/* the minimum color code */
+static bool use_colors;		/* true if we use colors */
+
+#undef max_pairs
+static int max_pairs;		/* ...and the number of color pairs */
+
+typedef struct {
+    short red;
+    short green;
+    short blue;
+} RGB_DATA;
+
+static RGB_DATA *all_colors;
+
+static void main_menu(bool);
+
+/* The behavior of mvhline, mvvline for negative/zero length is unspecified,
+ * though we can rely on negative x/y values to stop the macro.
+ */
+static void
+do_h_line(int y, int x, chtype c, int to)
+{
+    if ((to) > (x))
+	mvhline(y, x, c, (to) - (x));
+}
+
+static void
+do_v_line(int y, int x, chtype c, int to)
+{
+    if ((to) > (y))
+	mvvline(y, x, c, (to) - (y));
+}
+
+static void
+Repaint(void)
+{
+    touchwin(stdscr);
+    touchwin(curscr);
+    wrefresh(curscr);
+}
+
+static bool
+isQuit(int c)
+{
+    return ((c) == QUIT || (c) == ESCAPE);
+}
+#define case_QUIT	QUIT: case ESCAPE
+
+/* Common function to allow ^T to toggle trace-mode in the middle of a test
+ * so that trace-files can be made smaller.
+ */
+static int
+wGetchar(WINDOW *win)
+{
+    int c;
+#ifdef TRACE
+    while ((c = wgetch(win)) == CTRL('T')) {
+	if (_nc_tracing) {
+	    save_trace = _nc_tracing;
+	    Trace(("TOGGLE-TRACING OFF"));
+	    _nc_tracing = 0;
+	} else {
+	    _nc_tracing = save_trace;
+	}
+	trace(_nc_tracing);
+	if (_nc_tracing)
+	    Trace(("TOGGLE-TRACING ON"));
+    }
+#else
+    c = wgetch(win);
+#endif
+    return c;
+}
+#define Getchar() wGetchar(stdscr)
+
+/* replaces wgetnstr(), since we want to be able to edit values */
+static void
+wGetstring(WINDOW *win, char *buffer, int limit)
+{
+    int y0, x0, x, ch;
+    bool done = FALSE;
+
+    echo();
+    getyx(win, y0, x0);
+    wattrset(win, A_REVERSE);
+
+    x = (int) strlen(buffer);
+    while (!done) {
+	if (x > (int) strlen(buffer))
+	    x = (int) strlen(buffer);
+	wmove(win, y0, x0);
+	wprintw(win, "%-*s", limit, buffer);
+	wmove(win, y0, x0 + x);
+	switch (ch = wGetchar(win)) {
+	case '\n':
+	case KEY_ENTER:
+	    done = TRUE;
+	    break;
+	case CTRL('U'):
+	    *buffer = '\0';
+	    break;
+	case '\b':
+	case KEY_BACKSPACE:
+	case KEY_DC:
+	    if (x > 0) {
+		int j;
+		for (j = --x; (buffer[j] = buffer[j + 1]) != '\0'; ++j) {
+		    ;
+		}
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_LEFT:
+	    if (x > 0) {
+		--x;
+	    } else {
+		flash();
+	    }
+	    break;
+	case KEY_RIGHT:
+	    ++x;
+	    break;
+	default:
+	    if (!isprint(ch) || ch >= KEY_MIN) {
+		beep();
+	    } else if ((int) strlen(buffer) < limit) {
+		int j;
+		for (j = (int) strlen(buffer) + 1; j > x; --j) {
+		    buffer[j] = buffer[j - 1];
+		}
+		buffer[x++] = (char) ch;
+	    } else {
+		flash();
+	    }
+	}
+    }
+
+    wattroff(win, A_REVERSE);
+    wmove(win, y0, x0);
+    noecho();
+}
+
+#if USE_WIDEC_SUPPORT
+static wchar_t
+fullwidth_of(int ch)
+{
+    return (ch + 0xff10 - '0');
+}
+
+static void
+make_fullwidth_text(wchar_t *target, const char *source)
+{
+    int ch;
+    while ((ch = *source++) != 0) {
+	*target++ = fullwidth_of(ch);
+    }
+    *target = 0;
+}
+
+static void
+make_narrow_text(wchar_t *target, const char *source)
+{
+    int ch;
+    while ((ch = *source++) != 0) {
+	*target++ = ch;
+    }
+    *target = 0;
+}
+
+static void
+make_fullwidth_digit(cchar_t *target, int digit)
+{
+    wchar_t source[2];
+
+    source[0] = fullwidth_of(digit + '0');
+    source[1] = 0;
+    setcchar(target, source, A_NORMAL, 0, 0);
+}
+
+static int
+wGet_wchar(WINDOW *win, wint_t *result)
+{
+    int c;
+#ifdef TRACE
+    while ((c = wget_wch(win, result)) == CTRL('T')) {
+	if (_nc_tracing) {
+	    save_trace = _nc_tracing;
+	    Trace(("TOGGLE-TRACING OFF"));
+	    _nc_tracing = 0;
+	} else {
+	    _nc_tracing = save_trace;
+	}
+	trace(_nc_tracing);
+	if (_nc_tracing)
+	    Trace(("TOGGLE-TRACING ON"));
+    }
+#else
+    c = wget_wch(win, result);
+#endif
+    return c;
+}
+#define Get_wchar(result) wGet_wchar(stdscr, result)
+
+/* replaces wgetn_wstr(), since we want to be able to edit values */
+static void
+wGet_wstring(WINDOW *win, wchar_t *buffer, int limit)
+{
+    int y0, x0, x;
+    wint_t ch;
+    bool done = FALSE;
+    bool fkey = FALSE;
+
+    echo();
+    getyx(win, y0, x0);
+    wattrset(win, A_REVERSE);
+
+    x = (int) wcslen(buffer);
+    while (!done) {
+	if (x > (int) wcslen(buffer))
+	    x = (int) wcslen(buffer);
+
+	/* clear the "window' */
+	wmove(win, y0, x0);
+	wprintw(win, "%*s", limit, " ");
+
+	/* write the existing buffer contents */
+	wmove(win, y0, x0);
+	waddnwstr(win, buffer, limit);
+
+	/* positions the cursor past character 'x' */
+	wmove(win, y0, x0);
+	waddnwstr(win, buffer, x);
+
+	switch (wGet_wchar(win, &ch)) {
+	case KEY_CODE_YES:
+	    fkey = TRUE;
+	    switch (ch) {
+	    case KEY_ENTER:
+		ch = '\n';
+		fkey = FALSE;
+		break;
+	    case KEY_BACKSPACE:
+	    case KEY_DC:
+		ch = '\b';
+		fkey = FALSE;
+		break;
+	    case KEY_LEFT:
+	    case KEY_RIGHT:
+		break;
+	    default:
+		ch = (wint_t) -1;
+		break;
+	    }
+	    break;
+	case OK:
+	    fkey = FALSE;
+	    break;
+	default:
+	    ch = (wint_t) -1;
+	    fkey = TRUE;
+	    break;
+	}
+
+	switch (ch) {
+	case '\n':
+	    done = TRUE;
+	    break;
+	case CTRL('U'):
+	    *buffer = '\0';
+	    break;
+	case '\b':
+	    if (x > 0) {
+		int j;
+		for (j = --x; (buffer[j] = buffer[j + 1]) != '\0'; ++j) {
+		    ;
+		}
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_LEFT:
+	    if (x > 0) {
+		--x;
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_RIGHT:
+	    ++x;
+	    break;
+	default:
+	    if (fkey) {
+		beep();
+	    } else if ((int) wcslen(buffer) < limit) {
+		int j;
+		for (j = (int) wcslen(buffer) + 1; j > x; --j) {
+		    buffer[j] = buffer[j - 1];
+		}
+		buffer[x++] = (wchar_t) ch;
+	    } else {
+		beep();
+	    }
+	}
+    }
+
+    wattroff(win, A_REVERSE);
+    wmove(win, y0, x0);
+    noecho();
+}
+
+#endif
+
+static void
+Pause(void)
+{
+    move(LINES - 1, 0);
+    addstr("Press any key to continue... ");
+    (void) Getchar();
+}
+
+static void
+Cannot(const char *what)
+{
+    printw("\nThis %s terminal %s\n\n", getenv("TERM"), what);
+    Pause();
+}
+
+static void
+ShellOut(bool message)
+{
+    if (message)
+	addstr("Shelling out...");
+    def_prog_mode();
+    endwin();
+    system("sh");
+    if (message)
+	addstr("returned from shellout.\n");
+    refresh();
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+/*
+ * This function is the same as _tracemouse(), but we cannot count on that
+ * being available in the non-debug library.
+ */
+static const char *
+mouse_decode(MEVENT const *ep)
+{
+    static char buf[80 + (5 * 10) + (32 * 15)];
+
+    (void) sprintf(buf, "id %2d  at (%2d, %2d, %2d) state %4lx = {",
+		   ep->id, ep->x, ep->y, ep->z, (unsigned long) ep->bstate);
+
+#define SHOW(m, s) if ((ep->bstate & m)==m) {strcat(buf,s); strcat(buf, ", ");}
+
+    SHOW(BUTTON1_RELEASED, "release-1");
+    SHOW(BUTTON1_PRESSED, "press-1");
+    SHOW(BUTTON1_CLICKED, "click-1");
+    SHOW(BUTTON1_DOUBLE_CLICKED, "doubleclick-1");
+    SHOW(BUTTON1_TRIPLE_CLICKED, "tripleclick-1");
+#if NCURSES_MOUSE_VERSION == 1
+    SHOW(BUTTON1_RESERVED_EVENT, "reserved-1");
+#endif
+
+    SHOW(BUTTON2_RELEASED, "release-2");
+    SHOW(BUTTON2_PRESSED, "press-2");
+    SHOW(BUTTON2_CLICKED, "click-2");
+    SHOW(BUTTON2_DOUBLE_CLICKED, "doubleclick-2");
+    SHOW(BUTTON2_TRIPLE_CLICKED, "tripleclick-2");
+#if NCURSES_MOUSE_VERSION == 1
+    SHOW(BUTTON2_RESERVED_EVENT, "reserved-2");
+#endif
+
+    SHOW(BUTTON3_RELEASED, "release-3");
+    SHOW(BUTTON3_PRESSED, "press-3");
+    SHOW(BUTTON3_CLICKED, "click-3");
+    SHOW(BUTTON3_DOUBLE_CLICKED, "doubleclick-3");
+    SHOW(BUTTON3_TRIPLE_CLICKED, "tripleclick-3");
+#if NCURSES_MOUSE_VERSION == 1
+    SHOW(BUTTON3_RESERVED_EVENT, "reserved-3");
+#endif
+
+    SHOW(BUTTON4_RELEASED, "release-4");
+    SHOW(BUTTON4_PRESSED, "press-4");
+    SHOW(BUTTON4_CLICKED, "click-4");
+    SHOW(BUTTON4_DOUBLE_CLICKED, "doubleclick-4");
+    SHOW(BUTTON4_TRIPLE_CLICKED, "tripleclick-4");
+#if NCURSES_MOUSE_VERSION == 1
+    SHOW(BUTTON4_RESERVED_EVENT, "reserved-4");
+#endif
+
+#if NCURSES_MOUSE_VERSION == 2
+    SHOW(BUTTON5_RELEASED, "release-5");
+    SHOW(BUTTON5_PRESSED, "press-5");
+    SHOW(BUTTON5_CLICKED, "click-5");
+    SHOW(BUTTON5_DOUBLE_CLICKED, "doubleclick-5");
+    SHOW(BUTTON5_TRIPLE_CLICKED, "tripleclick-5");
+#endif
+
+    SHOW(BUTTON_CTRL, "ctrl");
+    SHOW(BUTTON_SHIFT, "shift");
+    SHOW(BUTTON_ALT, "alt");
+    SHOW(ALL_MOUSE_EVENTS, "all-events");
+    SHOW(REPORT_MOUSE_POSITION, "position");
+
+#undef SHOW
+
+    if (buf[strlen(buf) - 1] == ' ')
+	buf[strlen(buf) - 2] = '\0';
+    (void) strcat(buf, "}");
+    return (buf);
+}
+#endif /* NCURSES_MOUSE_VERSION */
+
+/****************************************************************************
+ *
+ * Character input test
+ *
+ ****************************************************************************/
+
+static void
+setup_getch(WINDOW *win, bool flags[])
+{
+    keypad(win, flags['k']);	/* should be redundant, but for testing */
+    meta(win, flags['m']);	/* force this to a known state */
+    if (flags['e'])
+	echo();
+    else
+	noecho();
+}
+
+static void
+wgetch_help(WINDOW *win, bool flags[])
+{
+    static const char *help[] =
+    {
+	"e  -- toggle echo mode"
+	,"g  -- triggers a getstr test"
+	,"k  -- toggle keypad/literal mode"
+	,"m  -- toggle meta (7-bit/8-bit) mode"
+	,"^q -- quit"
+	,"s  -- shell out\n"
+	,"w  -- create a new window"
+#ifdef SIGTSTP
+	,"z  -- suspend this process"
+#endif
+    };
+    int y, x;
+    unsigned chk = ((SIZEOF(help) + 1) / 2);
+    unsigned n;
+
+    getyx(win, y, x);
+    move(0, 0);
+    printw("Type any key to see its %s value.  Also:\n",
+	   flags['k'] ? "keypad" : "literal");
+    for (n = 0; n < SIZEOF(help); ++n) {
+	int row = 1 + (int) (n % chk);
+	int col = (n >= chk) ? COLS / 2 : 0;
+	int flg = ((strstr(help[n], "toggle") != 0)
+		   && (flags[UChar(*help[n])] != FALSE));
+	if (flg)
+	    standout();
+	mvprintw(row, col, "%s", help[n]);
+	if (col == 0)
+	    clrtoeol();
+	if (flg)
+	    standend();
+    }
+    wrefresh(stdscr);
+    wmove(win, y, x);
+}
+
+static void
+wgetch_wrap(WINDOW *win, int first_y)
+{
+    int last_y = getmaxy(win) - 1;
+    int y = getcury(win) + 1;
+
+    if (y >= last_y)
+	y = first_y;
+    wmove(win, y, 0);
+    wclrtoeol(win);
+}
+
+#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
+typedef struct {
+    WINDOW *text;
+    WINDOW *frame;
+} WINSTACK;
+
+static WINSTACK *winstack = 0;
+static unsigned len_winstack = 0;
+
+static void
+forget_boxes(void)
+{
+    if (winstack != 0) {
+	free(winstack);
+    }
+    winstack = 0;
+    len_winstack = 0;
+}
+
+static void
+remember_boxes(unsigned level, WINDOW *txt_win, WINDOW *box_win)
+{
+    unsigned need = (level + 1) * 2;
+
+    assert(level < COLS);
+
+    if (winstack == 0) {
+	len_winstack = 20;
+	winstack = typeMalloc(WINSTACK, len_winstack);
+    } else if (need >= len_winstack) {
+	len_winstack = need;
+	winstack = typeRealloc(WINSTACK, len_winstack, winstack);
+    }
+    winstack[level].text = txt_win;
+    winstack[level].frame = box_win;
+}
+
+#if USE_SOFTKEYS && (NCURSES_VERSION_PATCH < 20071229) && NCURSES_EXT_FUNCS
+static void
+slk_repaint(void)
+{
+    /* this chunk is now done in resize_term() */
+    slk_touch();
+    slk_clear();
+    slk_noutrefresh();
+}
+
+#else
+#define slk_repaint()		/* nothing */
+#endif
+
+/*
+ * For wgetch_test(), we create pairs of windows - one for a box, one for text.
+ * Resize both and paint the box in the parent.
+ */
+static void
+resize_boxes(unsigned level, WINDOW *win)
+{
+    unsigned n;
+    int base = 5;
+    int high = LINES - base;
+    int wide = COLS;
+
+    touchwin(stdscr);
+    wnoutrefresh(stdscr);
+
+    slk_repaint();
+
+    for (n = 0; n < level; ++n) {
+	wresize(winstack[n].frame, high, wide);
+	wresize(winstack[n].text, high - 2, wide - 2);
+	high -= 2;
+	wide -= 2;
+	werase(winstack[n].text);
+	box(winstack[n].frame, 0, 0);
+	wnoutrefresh(winstack[n].frame);
+	wprintw(winstack[n].text,
+		"size %dx%d\n",
+		getmaxy(winstack[n].text),
+		getmaxx(winstack[n].text));
+	wnoutrefresh(winstack[n].text);
+	if (winstack[n].text == win)
+	    break;
+    }
+    doupdate();
+}
+#else
+#define forget_boxes()		/* nothing */
+#define remember_boxes(level,text,frame)	/* nothing */
+#endif
+
+static void
+wgetch_test(unsigned level, WINDOW *win, int delay)
+{
+    char buf[BUFSIZ];
+    int first_y, first_x;
+    int c;
+    int incount = 0;
+    bool flags[256];
+    bool blocking = (delay < 0);
+
+    memset(flags, FALSE, sizeof(flags));
+    flags[UChar('k')] = (win == stdscr);
+
+    setup_getch(win, flags);
+    wtimeout(win, delay);
+    getyx(win, first_y, first_x);
+
+    wgetch_help(win, flags);
+    wsetscrreg(win, first_y, getmaxy(win) - 1);
+    scrollok(win, TRUE);
+
+    for (;;) {
+	while ((c = wGetchar(win)) == ERR) {
+	    incount++;
+	    if (blocking) {
+		(void) wprintw(win, "%05d: input error", incount);
+		break;
+	    } else {
+		(void) wprintw(win, "%05d: input timed out", incount);
+	    }
+	    wgetch_wrap(win, first_y);
+	}
+	if (c == ERR && blocking) {
+	    wprintw(win, "ERR");
+	    wgetch_wrap(win, first_y);
+	} else if (isQuit(c)) {
+	    break;
+	} else if (c == 'e') {
+	    flags[UChar('e')] = !flags[UChar('e')];
+	    setup_getch(win, flags);
+	    wgetch_help(win, flags);
+	} else if (c == 'g') {
+	    waddstr(win, "getstr test: ");
+	    echo();
+	    wgetnstr(win, buf, sizeof(buf) - 1);
+	    noecho();
+	    wprintw(win, "I saw %d characters:\n\t`%s'.", (int) strlen(buf), buf);
+	    wclrtoeol(win);
+	    wgetch_wrap(win, first_y);
+	} else if (c == 'k') {
+	    flags[UChar('k')] = !flags[UChar('k')];
+	    setup_getch(win, flags);
+	    wgetch_help(win, flags);
+	} else if (c == 'm') {
+	    flags[UChar('m')] = !flags[UChar('m')];
+	    setup_getch(win, flags);
+	    wgetch_help(win, flags);
+	} else if (c == 's') {
+	    ShellOut(TRUE);
+	} else if (c == 'w') {
+	    int high = getmaxy(win) - 1 - first_y + 1;
+	    int wide = getmaxx(win) - first_x;
+	    int old_y, old_x;
+	    int new_y = first_y + getbegy(win);
+	    int new_x = first_x + getbegx(win);
+
+	    getyx(win, old_y, old_x);
+	    if (high > 2 && wide > 2) {
+		WINDOW *wb = newwin(high, wide, new_y, new_x);
+		WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1);
+
+		box(wb, 0, 0);
+		wrefresh(wb);
+		wmove(wi, 0, 0);
+		remember_boxes(level, wi, wb);
+		wgetch_test(level + 1, wi, delay);
+		delwin(wi);
+		delwin(wb);
+
+		wgetch_help(win, flags);
+		wmove(win, old_y, old_x);
+		touchwin(win);
+		wrefresh(win);
+		doupdate();
+	    }
+#ifdef SIGTSTP
+	} else if (c == 'z') {
+	    kill(getpid(), SIGTSTP);
+#endif
+	} else {
+	    wprintw(win, "Key pressed: %04o ", c);
+#ifdef NCURSES_MOUSE_VERSION
+	    if (c == KEY_MOUSE) {
+		int y, x;
+		MEVENT event;
+
+		getmouse(&event);
+		wprintw(win, "KEY_MOUSE, %s", mouse_decode(&event));
+		getyx(win, y, x);
+		move(event.y, event.x);
+		addch('*');
+		wmove(win, y, x);
+	    } else
+#endif /* NCURSES_MOUSE_VERSION */
+	    if (c >= KEY_MIN) {
+#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
+		if (c == KEY_RESIZE) {
+		    resize_boxes(level, win);
+		}
+#endif
+		(void) waddstr(win, keyname(c));
+	    } else if (c > 0x80) {
+		unsigned c2 = (unsigned) (c & 0x7f);
+		if (isprint(c2))
+		    (void) wprintw(win, "M-%c", UChar(c2));
+		else
+		    (void) wprintw(win, "M-%s", unctrl(c2));
+		waddstr(win, " (high-half character)");
+	    } else {
+		if (isprint(c))
+		    (void) wprintw(win, "%c (ASCII printable character)", c);
+		else
+		    (void) wprintw(win, "%s (ASCII control character)",
+				   unctrl(UChar(c)));
+	    }
+	    wgetch_wrap(win, first_y);
+	}
+    }
+
+    wtimeout(win, -1);
+}
+
+static int
+begin_getch_test(void)
+{
+    char buf[BUFSIZ];
+    int delay;
+
+    refresh();
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
+#endif
+
+    (void) printw("Delay in 10ths of a second (<CR> for blocking input)? ");
+    echo();
+    getnstr(buf, sizeof(buf) - 1);
+    noecho();
+    nonl();
+
+    if (isdigit(UChar(buf[0]))) {
+	delay = atoi(buf) * 100;
+    } else {
+	delay = -1;
+    }
+    raw();
+    move(5, 0);
+    return delay;
+}
+
+static void
+finish_getch_test(void)
+{
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(0, (mmask_t *) 0);
+#endif
+    erase();
+    noraw();
+    nl();
+    endwin();
+}
+
+static void
+getch_test(void)
+{
+    int delay = begin_getch_test();
+
+    slk_restore();
+    wgetch_test(0, stdscr, delay);
+    forget_boxes();
+    finish_getch_test();
+}
+
+#if USE_WIDEC_SUPPORT
+/*
+ * For wget_wch_test(), we create pairs of windows - one for a box, one for text.
+ * Resize both and paint the box in the parent.
+ */
+#if defined(KEY_RESIZE) && HAVE_WRESIZE
+static void
+resize_wide_boxes(unsigned level, WINDOW *win)
+{
+    unsigned n;
+    int base = 5;
+    int high = LINES - base;
+    int wide = COLS;
+
+    touchwin(stdscr);
+    wnoutrefresh(stdscr);
+
+    slk_repaint();
+
+    for (n = 0; n < level; ++n) {
+	wresize(winstack[n].frame, high, wide);
+	wresize(winstack[n].text, high - 2, wide - 2);
+	high -= 2;
+	wide -= 2;
+	werase(winstack[n].text);
+	box_set(winstack[n].frame, 0, 0);
+	wnoutrefresh(winstack[n].frame);
+	wprintw(winstack[n].text,
+		"size %dx%d\n",
+		getmaxy(winstack[n].text),
+		getmaxx(winstack[n].text));
+	wnoutrefresh(winstack[n].text);
+	if (winstack[n].text == win)
+	    break;
+    }
+    doupdate();
+}
+#endif /* KEY_RESIZE */
+
+static char *
+wcstos(const wchar_t *src)
+{
+    int need;
+    char *result = 0;
+    const wchar_t *tmp = src;
+#ifndef state_unused
+    mbstate_t state;
+#endif
+
+    reset_wchars(state);
+    if ((need = (int) count_wchars(tmp, 0, &state)) > 0) {
+	unsigned have = (unsigned) need;
+	if ((result = typeCalloc(char, have + 1)) != 0) {
+	    tmp = src;
+	    if (trans_wchars(result, tmp, have, &state) != have) {
+		free(result);
+		result = 0;
+	    }
+	}
+    }
+    return result;
+}
+
+static void
+wget_wch_test(unsigned level, WINDOW *win, int delay)
+{
+    wchar_t wchar_buf[BUFSIZ];
+    wint_t wint_buf[BUFSIZ];
+    int first_y, first_x;
+    wint_t c;
+    int incount = 0;
+    bool flags[256];
+    bool blocking = (delay < 0);
+    int y, x, code;
+    char *temp;
+
+    memset(flags, FALSE, sizeof(flags));
+    flags[UChar('k')] = (win == stdscr);
+
+    setup_getch(win, flags);
+    wtimeout(win, delay);
+    getyx(win, first_y, first_x);
+
+    wgetch_help(win, flags);
+    wsetscrreg(win, first_y, getmaxy(win) - 1);
+    scrollok(win, TRUE);
+
+    for (;;) {
+	while ((code = wGet_wchar(win, &c)) == ERR) {
+	    incount++;
+	    if (blocking) {
+		(void) wprintw(win, "%05d: input error", incount);
+		break;
+	    } else {
+		(void) wprintw(win, "%05d: input timed out", incount);
+	    }
+	    wgetch_wrap(win, first_y);
+	}
+	if (code == ERR && blocking) {
+	    wprintw(win, "ERR");
+	    wgetch_wrap(win, first_y);
+	} else if (isQuit((int) c)) {
+	    break;
+	} else if (c == 'e') {
+	    flags[UChar('e')] = !flags[UChar('e')];
+	    setup_getch(win, flags);
+	    wgetch_help(win, flags);
+	} else if (c == 'g') {
+	    waddstr(win, "getstr test: ");
+	    echo();
+	    code = wgetn_wstr(win, wint_buf, sizeof(wint_buf) - 1);
+	    noecho();
+	    if (code == ERR) {
+		wprintw(win, "wgetn_wstr returns an error.");
+	    } else {
+		int n;
+		for (n = 0; (wchar_buf[n] = (wchar_t) wint_buf[n]) != 0; ++n) {
+		    ;
+		}
+		if ((temp = wcstos(wchar_buf)) != 0) {
+		    wprintw(win, "I saw %d characters:\n\t`%s'.",
+			    (int) wcslen(wchar_buf), temp);
+		    free(temp);
+		} else {
+		    wprintw(win, "I saw %d characters (cannot convert).",
+			    (int) wcslen(wchar_buf));
+		}
+	    }
+	    wclrtoeol(win);
+	    wgetch_wrap(win, first_y);
+	} else if (c == 'k') {
+	    flags[UChar('k')] = !flags[UChar('k')];
+	    setup_getch(win, flags);
+	    wgetch_help(win, flags);
+	} else if (c == 'm') {
+	    flags[UChar('m')] = !flags[UChar('m')];
+	    setup_getch(win, flags);
+	    wgetch_help(win, flags);
+	} else if (c == 's') {
+	    ShellOut(TRUE);
+	} else if (c == 'w') {
+	    int high = getmaxy(win) - 1 - first_y + 1;
+	    int wide = getmaxx(win) - first_x;
+	    int old_y, old_x;
+	    int new_y = first_y + getbegy(win);
+	    int new_x = first_x + getbegx(win);
+
+	    getyx(win, old_y, old_x);
+	    if (high > 2 && wide > 2) {
+		WINDOW *wb = newwin(high, wide, new_y, new_x);
+		WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1);
+
+		box_set(wb, 0, 0);
+		wrefresh(wb);
+		wmove(wi, 0, 0);
+		remember_boxes(level, wi, wb);
+		wget_wch_test(level + 1, wi, delay);
+		delwin(wi);
+		delwin(wb);
+
+		wgetch_help(win, flags);
+		wmove(win, old_y, old_x);
+		touchwin(win);
+		wrefresh(win);
+	    }
+#ifdef SIGTSTP
+	} else if (c == 'z') {
+	    kill(getpid(), SIGTSTP);
+#endif
+	} else {
+	    wprintw(win, "Key pressed: %04o ", (int) c);
+#ifdef NCURSES_MOUSE_VERSION
+	    if (c == KEY_MOUSE) {
+		MEVENT event;
+
+		getmouse(&event);
+		wprintw(win, "KEY_MOUSE, %s", mouse_decode(&event));
+		getyx(win, y, x);
+		move(event.y, event.x);
+		addch('*');
+		wmove(win, y, x);
+	    } else
+#endif /* NCURSES_MOUSE_VERSION */
+	    if (code == KEY_CODE_YES) {
+#if defined(KEY_RESIZE) && HAVE_WRESIZE
+		if (c == KEY_RESIZE) {
+		    resize_wide_boxes(level, win);
+		}
+#endif
+		(void) waddstr(win, key_name((wchar_t) c));
+	    } else {
+		if (c < 256 && iscntrl(c)) {
+		    (void) wprintw(win, "%s (control character)", unctrl(c));
+		} else {
+		    wchar_t c2 = (wchar_t) c;
+		    waddnwstr(win, &c2, 1);
+		    (void) wprintw(win, " = %#x (printable character)", (unsigned) c);
+		}
+	    }
+	    wgetch_wrap(win, first_y);
+	}
+    }
+
+    wtimeout(win, -1);
+}
+
+static void
+get_wch_test(void)
+{
+    int delay = begin_getch_test();
+
+    slk_restore();
+    wget_wch_test(0, stdscr, delay);
+    forget_boxes();
+    finish_getch_test();
+}
+#endif
+
+/****************************************************************************
+ *
+ * Character attributes test
+ *
+ ****************************************************************************/
+
+#if HAVE_SETUPTERM || HAVE_TGETENT
+#define get_ncv() TIGETNUM("ncv","NC")
+#define get_xmc() TIGETNUM("xmc","sg")
+#else
+#define get_ncv() -1
+#define get_xmc() -1
+#endif
+
+#if !HAVE_TERMATTRS
+static chtype
+my_termattrs(void)
+{
+    static int first = TRUE;
+    static chtype result = 0;
+
+    if (first) {
+#if !HAVE_TIGETSTR
+	char buffer[4096];
+	char parsed[4096];
+	char *area_pointer = parsed;
+
+	tgetent(buffer, getenv("TERM"));
+#endif
+
+	if (TIGETSTR("smso", "so"))
+	    result |= A_STANDOUT;
+	if (TIGETSTR("smul", "us"))
+	    result |= A_UNDERLINE;
+	if (TIGETSTR("rev", "mr"))
+	    result |= A_REVERSE;
+	if (TIGETSTR("blink", "mb"))
+	    result |= A_BLINK;
+	if (TIGETSTR("dim", "mh"))
+	    result |= A_DIM;
+	if (TIGETSTR("bold", "md"))
+	    result |= A_BOLD;
+	if (TIGETSTR("smacs", "ac"))
+	    result |= A_ALTCHARSET;
+
+	first = FALSE;
+    }
+    return result;
+}
+#define termattrs() my_termattrs()
+#endif
+
+#define MAX_ATTRSTRING 31
+#define LEN_ATTRSTRING 26
+
+static char attr_test_string[MAX_ATTRSTRING + 1];
+
+static void
+attr_legend(WINDOW *helpwin)
+{
+    int row = 1;
+    int col = 1;
+
+    mvwprintw(helpwin, row++, col,
+	      "ESC to exit.");
+    mvwprintw(helpwin, row++, col,
+	      "^L repaints.");
+    ++row;
+    mvwprintw(helpwin, row++, col,
+	      "Modify the test strings:");
+    mvwprintw(helpwin, row++, col,
+	      "  A digit sets gaps on each side of displayed attributes");
+    mvwprintw(helpwin, row++, col,
+	      "  </> shifts the text left/right. ");
+    ++row;
+    mvwprintw(helpwin, row++, col,
+	      "Toggles:");
+    if (use_colors) {
+	mvwprintw(helpwin, row++, col,
+		  "  f/F/b/F toggle foreground/background background color");
+	mvwprintw(helpwin, row++, col,
+		  "  t/T     toggle text/background color attribute");
+    }
+    mvwprintw(helpwin, row++, col,
+	      "  a/A     toggle ACS (alternate character set) mapping");
+    mvwprintw(helpwin, row++, col,
+	      "  v/V     toggle video attribute to combine with each line");
+}
+
+static void
+show_color_attr(int fg, int bg, int tx)
+{
+    if (use_colors) {
+	printw("  Colors (fg %d, bg %d", fg, bg);
+	if (tx >= 0)
+	    printw(", text %d", tx);
+	printw("),");
+    }
+}
+
+static bool
+cycle_color_attr(int ch, short *fg, short *bg, short *tx)
+{
+    bool error = FALSE;
+
+    if (use_colors) {
+	switch (ch) {
+	case 'f':
+	    *fg = (short) (*fg + 1);
+	    break;
+	case 'F':
+	    *fg = (short) (*fg - 1);
+	    break;
+	case 'b':
+	    *bg = (short) (*bg + 1);
+	    break;
+	case 'B':
+	    *bg = (short) (*bg - 1);
+	    break;
+	case 't':
+	    *tx = (short) (*tx + 1);
+	    break;
+	case 'T':
+	    *tx = (short) (*tx - 1);
+	    break;
+	default:
+	    beep();
+	    error = TRUE;
+	    break;
+	}
+	if (*fg >= COLORS)
+	    *fg = (short) min_colors;
+	if (*fg < min_colors)
+	    *fg = (short) (COLORS - 1);
+	if (*bg >= COLORS)
+	    *bg = (short) min_colors;
+	if (*bg < min_colors)
+	    *bg = (short) (COLORS - 1);
+	if (*tx >= COLORS)
+	    *tx = -1;
+	if (*tx < -1)
+	    *tx = (short) (COLORS - 1);
+    } else {
+	beep();
+	error = TRUE;
+    }
+    return error;
+}
+
+static void
+adjust_attr_string(int adjust)
+{
+    int first = ((int) UChar(attr_test_string[0])) + adjust;
+    int last = first + LEN_ATTRSTRING;
+
+    if (first >= ' ' && last <= '~') {	/* 32..126 */
+	int j, k;
+	for (j = 0, k = first; j < MAX_ATTRSTRING && k <= last; ++j, ++k) {
+	    attr_test_string[j] = (char) k;
+	    if (((k + 1 - first) % 5) == 0) {
+		if (++j >= MAX_ATTRSTRING)
+		    break;
+		attr_test_string[j] = ' ';
+	    }
+	}
+	while (j < MAX_ATTRSTRING)
+	    attr_test_string[j++] = ' ';
+	attr_test_string[j] = '\0';
+    } else {
+	beep();
+    }
+}
+
+static void
+init_attr_string(void)
+{
+    attr_test_string[0] = 'a';
+    adjust_attr_string(0);
+}
+
+static int
+show_attr(int row, int skip, bool arrow, chtype attr, const char *name)
+{
+    int ncv = get_ncv();
+    chtype test = attr & (chtype) (~A_ALTCHARSET);
+
+    if (arrow)
+	mvprintw(row, 5, "-->");
+    mvprintw(row, 8, "%s mode:", name);
+    mvprintw(row, 24, "|");
+    if (skip)
+	printw("%*s", skip, " ");
+    /*
+     * Just for testing, write text using the alternate character set one
+     * character at a time (to pass its rendition directly), and use the
+     * string operation for the other attributes.
+     */
+    if (attr & A_ALTCHARSET) {
+	const char *s;
+	chtype ch;
+
+	for (s = attr_test_string; *s != '\0'; ++s) {
+	    ch = UChar(*s);
+	    addch(ch | attr);
+	}
+    } else {
+	attrset(attr);
+	addstr(attr_test_string);
+	attroff(attr);
+    }
+    if (skip)
+	printw("%*s", skip, " ");
+    printw("|");
+    if (test != A_NORMAL) {
+	if (!(termattrs() & test)) {
+	    printw(" (N/A)");
+	} else {
+	    if (ncv > 0 && (getbkgd(stdscr) & A_COLOR)) {
+		static const chtype table[] =
+		{
+		    A_STANDOUT,
+		    A_UNDERLINE,
+		    A_REVERSE,
+		    A_BLINK,
+		    A_DIM,
+		    A_BOLD,
+#ifdef A_INVIS
+		    A_INVIS,
+#endif
+		    A_PROTECT,
+		    A_ALTCHARSET
+		};
+		unsigned n;
+		bool found = FALSE;
+		for (n = 0; n < SIZEOF(table); n++) {
+		    if ((table[n] & attr) != 0
+			&& ((1 << n) & ncv) != 0) {
+			found = TRUE;
+			break;
+		    }
+		}
+		if (found)
+		    printw(" (NCV)");
+	    }
+	    if ((termattrs() & test) != test)
+		printw(" (Part)");
+	}
+    }
+    return row + 2;
+}
+/* *INDENT-OFF* */
+static const struct {
+    chtype			attr;
+    NCURSES_CONST char *	name;
+} attrs_to_test[] = {
+    { A_STANDOUT,	"STANDOUT" },
+    { A_REVERSE,	"REVERSE" },
+    { A_BOLD,		"BOLD" },
+    { A_UNDERLINE,	"UNDERLINE" },
+    { A_DIM,		"DIM" },
+    { A_BLINK,		"BLINK" },
+    { A_PROTECT,	"PROTECT" },
+#ifdef A_INVIS
+    { A_INVIS,		"INVISIBLE" },
+#endif
+    { A_NORMAL,		"NORMAL" },
+};
+/* *INDENT-ON* */
+
+static bool
+attr_getc(int *skip, short *fg, short *bg, short *tx, int *ac, unsigned *kc)
+{
+    bool result = TRUE;
+    bool error = FALSE;
+    WINDOW *helpwin;
+
+    do {
+	int ch = Getchar();
+
+	error = FALSE;
+	if (ch < 256 && isdigit(ch)) {
+	    *skip = (ch - '0');
+	} else {
+	    switch (ch) {
+	    case CTRL('L'):
+		Repaint();
+		break;
+	    case '?':
+		if ((helpwin = newwin(LINES - 1, COLS - 2, 0, 0)) != 0) {
+		    box(helpwin, 0, 0);
+		    attr_legend(helpwin);
+		    wGetchar(helpwin);
+		    delwin(helpwin);
+		}
+		break;
+	    case 'a':
+		*ac = 0;
+		break;
+	    case 'A':
+		*ac = A_ALTCHARSET;
+		break;
+	    case 'v':
+		if (*kc == 0)
+		    *kc = SIZEOF(attrs_to_test) - 1;
+		else
+		    *kc -= 1;
+		break;
+	    case 'V':
+		*kc += 1;
+		if (*kc >= SIZEOF(attrs_to_test))
+		    *kc = 0;
+		break;
+	    case '<':
+		adjust_attr_string(-1);
+		break;
+	    case '>':
+		adjust_attr_string(1);
+		break;
+	    case case_QUIT:
+		result = FALSE;
+		break;
+	    default:
+		error = cycle_color_attr(ch, fg, bg, tx);
+		break;
+	    }
+	}
+    } while (error);
+    return result;
+}
+
+static void
+attr_test(void)
+/* test text attributes */
+{
+    int n;
+    int skip = get_xmc();
+    short fg = COLOR_BLACK;	/* color pair 0 is special */
+    short bg = COLOR_BLACK;
+    short tx = -1;
+    int ac = 0;
+    unsigned j, k;
+
+    if (skip < 0)
+	skip = 0;
+
+    n = skip;			/* make it easy */
+    k = SIZEOF(attrs_to_test) - 1;
+    init_attr_string();
+
+    do {
+	int row = 2;
+	chtype normal = A_NORMAL | BLANK;
+	chtype extras = (chtype) ac;
+
+	if (use_colors) {
+	    short pair = (short) (fg != COLOR_BLACK || bg != COLOR_BLACK);
+	    if (pair != 0) {
+		pair = 1;
+		if (init_pair(pair, fg, bg) == ERR) {
+		    beep();
+		} else {
+		    normal |= COLOR_PAIR(pair);
+		}
+	    }
+	    if (tx >= 0) {
+		pair = 2;
+		if (init_pair(pair, tx, bg) == ERR) {
+		    beep();
+		} else {
+		    extras |= COLOR_PAIR(pair);
+		}
+	    }
+	}
+	bkgd(normal);
+	bkgdset(normal);
+	erase();
+
+	box(stdscr, 0, 0);
+	mvaddstr(0, 20, "Character attribute test display");
+
+	for (j = 0; j < SIZEOF(attrs_to_test); ++j) {
+	    bool arrow = (j == k);
+	    row = show_attr(row, n, arrow,
+			    extras |
+			    attrs_to_test[j].attr |
+			    attrs_to_test[k].attr,
+			    attrs_to_test[j].name);
+	}
+
+	mvprintw(row, 8,
+		 "This terminal does %shave the magic-cookie glitch",
+		 get_xmc() > -1 ? "" : "not ");
+	mvprintw(row + 1, 8, "Enter '?' for help.");
+	show_color_attr(fg, bg, tx);
+	printw("  ACS (%d)", ac != 0);
+
+	refresh();
+    } while (attr_getc(&n, &fg, &bg, &tx, &ac, &k));
+
+    bkgdset(A_NORMAL | BLANK);
+    erase();
+    endwin();
+}
+
+#if USE_WIDEC_SUPPORT
+static wchar_t wide_attr_test_string[MAX_ATTRSTRING + 1];
+
+static void
+wide_adjust_attr_string(int adjust)
+{
+    int first = ((int) UChar(wide_attr_test_string[0])) + adjust;
+    int last = first + LEN_ATTRSTRING;
+
+    if (first >= ' ' && last <= '~') {	/* 32..126 */
+	int j, k;
+	for (j = 0, k = first; j < MAX_ATTRSTRING && k <= last; ++j, ++k) {
+	    wide_attr_test_string[j] = k;
+	    if (((k + 1 - first) % 5) == 0) {
+		if (++j >= MAX_ATTRSTRING)
+		    break;
+		wide_attr_test_string[j] = ' ';
+	    }
+	}
+	while (j < MAX_ATTRSTRING)
+	    wide_attr_test_string[j++] = ' ';
+	wide_attr_test_string[j] = '\0';
+    } else {
+	beep();
+    }
+}
+
+static void
+wide_init_attr_string(void)
+{
+    wide_attr_test_string[0] = 'a';
+    wide_adjust_attr_string(0);
+}
+
+static void
+set_wide_background(short pair)
+{
+    cchar_t normal;
+    wchar_t blank[2];
+
+    blank[0] = ' ';
+    blank[1] = 0;
+    setcchar(&normal, blank, A_NORMAL, pair, 0);
+    bkgrnd(&normal);
+    bkgrndset(&normal);
+}
+
+static attr_t
+get_wide_background(void)
+{
+    attr_t result = A_NORMAL;
+    attr_t attr;
+    cchar_t ch;
+    short pair;
+    wchar_t wch[10];
+
+    if (getbkgrnd(&ch) != ERR) {
+	if (getcchar(&ch, wch, &attr, &pair, 0) != ERR) {
+	    result = attr;
+	}
+    }
+    return result;
+}
+
+static int
+wide_show_attr(int row, int skip, bool arrow, chtype attr, short pair, const char *name)
+{
+    int ncv = get_ncv();
+    chtype test = attr & ~WA_ALTCHARSET;
+
+    if (arrow)
+	mvprintw(row, 5, "-->");
+    mvprintw(row, 8, "%s mode:", name);
+    mvprintw(row, 24, "|");
+    if (skip)
+	printw("%*s", skip, " ");
+
+    /*
+     * Just for testing, write text using the alternate character set one
+     * character at a time (to pass its rendition directly), and use the
+     * string operation for the other attributes.
+     */
+    if (attr & WA_ALTCHARSET) {
+	const wchar_t *s;
+	cchar_t ch;
+
+	for (s = wide_attr_test_string; *s != L'\0'; ++s) {
+	    wchar_t fill[2];
+	    fill[0] = *s;
+	    fill[1] = L'\0';
+	    setcchar(&ch, fill, attr, pair, 0);
+	    add_wch(&ch);
+	}
+    } else {
+	attr_t old_attr;
+	short old_pair;
+
+	attr_get(&old_attr, &old_pair, 0);
+	attr_set(attr, pair, 0);
+	addwstr(wide_attr_test_string);
+	attr_set(old_attr, old_pair, 0);
+    }
+    if (skip)
+	printw("%*s", skip, " ");
+    printw("|");
+    if (test != A_NORMAL) {
+	if (!(term_attrs() & test)) {
+	    printw(" (N/A)");
+	} else {
+	    if (ncv > 0 && (get_wide_background() & A_COLOR)) {
+		static const attr_t table[] =
+		{
+		    WA_STANDOUT,
+		    WA_UNDERLINE,
+		    WA_REVERSE,
+		    WA_BLINK,
+		    WA_DIM,
+		    WA_BOLD,
+		    WA_INVIS,
+		    WA_PROTECT,
+		    WA_ALTCHARSET
+		};
+		unsigned n;
+		bool found = FALSE;
+		for (n = 0; n < SIZEOF(table); n++) {
+		    if ((table[n] & attr) != 0
+			&& ((1 << n) & ncv) != 0) {
+			found = TRUE;
+			break;
+		    }
+		}
+		if (found)
+		    printw(" (NCV)");
+	    }
+	    if ((term_attrs() & test) != test)
+		printw(" (Part)");
+	}
+    }
+    return row + 2;
+}
+
+static bool
+wide_attr_getc(int *skip, short *fg, short *bg, short *tx, int *ac, unsigned *kc)
+{
+    bool result = TRUE;
+    bool error = FALSE;
+    WINDOW *helpwin;
+
+    do {
+	int ch = Getchar();
+
+	error = FALSE;
+	if (ch < 256 && isdigit(ch)) {
+	    *skip = (ch - '0');
+	} else {
+	    switch (ch) {
+	    case CTRL('L'):
+		Repaint();
+		break;
+	    case '?':
+		if ((helpwin = newwin(LINES - 1, COLS - 2, 0, 0)) != 0) {
+		    box_set(helpwin, 0, 0);
+		    attr_legend(helpwin);
+		    wGetchar(helpwin);
+		    delwin(helpwin);
+		}
+		break;
+	    case 'a':
+		*ac = 0;
+		break;
+	    case 'A':
+		*ac = A_ALTCHARSET;
+		break;
+	    case 'v':
+		if (*kc == 0)
+		    *kc = SIZEOF(attrs_to_test) - 1;
+		else
+		    *kc -= 1;
+		break;
+	    case 'V':
+		*kc += 1;
+		if (*kc >= SIZEOF(attrs_to_test))
+		    *kc = 0;
+		break;
+	    case '<':
+		wide_adjust_attr_string(-1);
+		break;
+	    case '>':
+		wide_adjust_attr_string(1);
+		break;
+	    case case_QUIT:
+		result = FALSE;
+		break;
+	    default:
+		error = cycle_color_attr(ch, fg, bg, tx);
+		break;
+	    }
+	}
+    } while (error);
+    return result;
+}
+
+static void
+wide_attr_test(void)
+/* test text attributes using wide-character calls */
+{
+    int n;
+    int skip = get_xmc();
+    short fg = COLOR_BLACK;	/* color pair 0 is special */
+    short bg = COLOR_BLACK;
+    short tx = -1;
+    int ac = 0;
+    unsigned j, k;
+
+    if (skip < 0)
+	skip = 0;
+
+    n = skip;			/* make it easy */
+    k = SIZEOF(attrs_to_test) - 1;
+    wide_init_attr_string();
+
+    do {
+	int row = 2;
+	short pair = 0;
+	short extras = 0;
+
+	if (use_colors) {
+	    pair = (short) (fg != COLOR_BLACK || bg != COLOR_BLACK);
+	    if (pair != 0) {
+		pair = 1;
+		if (init_pair(pair, fg, bg) == ERR) {
+		    beep();
+		}
+	    }
+	    extras = pair;
+	    if (tx >= 0) {
+		extras = 2;
+		if (init_pair(extras, tx, bg) == ERR) {
+		    beep();
+		}
+	    }
+	}
+	set_wide_background(pair);
+	erase();
+
+	box_set(stdscr, 0, 0);
+	mvaddstr(0, 20, "Character attribute test display");
+
+	for (j = 0; j < SIZEOF(attrs_to_test); ++j) {
+	    row = wide_show_attr(row, n, j == k,
+				 ac |
+				 attrs_to_test[j].attr |
+				 attrs_to_test[k].attr,
+				 extras,
+				 attrs_to_test[j].name);
+	}
+
+	mvprintw(row, 8,
+		 "This terminal does %shave the magic-cookie glitch",
+		 get_xmc() > -1 ? "" : "not ");
+	mvprintw(row + 1, 8, "Enter '?' for help.");
+	show_color_attr(fg, bg, tx);
+	printw("  ACS (%d)", ac != 0);
+
+	refresh();
+    } while (wide_attr_getc(&n, &fg, &bg, &tx, &ac, &k));
+
+    set_wide_background(0);
+    erase();
+    endwin();
+}
+#endif
+
+/****************************************************************************
+ *
+ * Color support tests
+ *
+ ****************************************************************************/
+
+static NCURSES_CONST char *the_color_names[] =
+{
+    "black",
+    "red",
+    "green",
+    "yellow",
+    "blue",
+    "magenta",
+    "cyan",
+    "white",
+    "BLACK",
+    "RED",
+    "GREEN",
+    "YELLOW",
+    "BLUE",
+    "MAGENTA",
+    "CYAN",
+    "WHITE"
+};
+
+static void
+show_color_name(int y, int x, int color, bool wide)
+{
+    if (move(y, x) != ERR) {
+	char temp[80];
+	int width = 8;
+
+	if (wide) {
+	    sprintf(temp, "%02d", color);
+	    width = 4;
+	} else if (color >= 8) {
+	    sprintf(temp, "[%02d]", color);
+	} else {
+	    strcpy(temp, the_color_names[color]);
+	}
+	printw("%-*.*s", width, width, temp);
+    }
+}
+
+static void
+color_legend(WINDOW *helpwin, bool wide)
+{
+    int row = 1;
+    int col = 1;
+
+    mvwprintw(helpwin, row++, col,
+	      "ESC to exit.");
+    ++row;
+    mvwprintw(helpwin, row++, col,
+	      "Use up/down arrow to scroll through the display if it is");
+    mvwprintw(helpwin, row++, col,
+	      "longer than one screen. Control/N and Control/P can be used");
+    mvwprintw(helpwin, row++, col,
+	      "in place of up/down arrow.  Use pageup/pagedown to scroll a");
+    mvwprintw(helpwin, row++, col,
+	      "full screen; control/B and control/F can be used here.");
+    ++row;
+    mvwprintw(helpwin, row++, col,
+	      "Toggles:");
+    mvwprintw(helpwin, row++, col,
+	      "  a/A     toggle altcharset off/on");
+    mvwprintw(helpwin, row++, col,
+	      "  b/B     toggle bold off/on");
+    mvwprintw(helpwin, row++, col,
+	      "  n/N     toggle text/number on/off");
+    mvwprintw(helpwin, row++, col,
+	      "  w/W     toggle width between 8/16 colors");
+#if USE_WIDEC_SUPPORT
+    if (wide) {
+	mvwprintw(helpwin, row++, col,
+		  "Wide characters:");
+	mvwprintw(helpwin, row++, col,
+		  "  x/X     toggle text between ASCII and wide-character");
+    }
+#else
+    (void) wide;
+#endif
+}
+
+#define set_color_test(name, value) if (name != value) { name = value; base_row = 0; }
+
+/* generate a color test pattern */
+static void
+color_test(void)
+{
+    short i;
+    int top = 0, width;
+    int base_row = 0;
+    int grid_top = top + 3;
+    int page_size = (LINES - grid_top);
+    int pairs_max = PAIR_NUMBER(A_COLOR) + 1;
+    int row_limit;
+    int per_row;
+    char numbered[80];
+    const char *hello;
+    bool done = FALSE;
+    bool opt_acsc = FALSE;
+    bool opt_bold = FALSE;
+    bool opt_wide = FALSE;
+    bool opt_nums = FALSE;
+    WINDOW *helpwin;
+
+    if (pairs_max > COLOR_PAIRS)
+	pairs_max = COLOR_PAIRS;
+
+    while (!done) {
+	int shown = 0;
+
+	/* this assumes an 80-column line */
+	if (opt_wide) {
+	    width = 4;
+	    hello = "Test";
+	    per_row = (COLORS > 8) ? 16 : 8;
+	} else {
+	    width = 8;
+	    hello = "Hello";
+	    per_row = 8;
+	}
+
+	row_limit = (pairs_max + per_row - 1) / per_row;
+
+	move(0, 0);
+	(void) printw("There are %d color pairs and %d colors\n",
+		      pairs_max, COLORS);
+
+	clrtobot();
+	(void) mvprintw(top + 1, 0,
+			"%dx%d matrix of foreground/background colors, bold *%s*\n",
+			row_limit,
+			per_row,
+			opt_bold ? "on" : "off");
+
+	/* show color names/numbers across the top */
+	for (i = 0; i < per_row; i++)
+	    show_color_name(top + 2, (i + 1) * width, i, opt_wide);
+
+	/* show a grid of colors, with color names/ numbers on the left */
+	for (i = (short) (base_row * per_row); i < pairs_max; i++) {
+	    int row = grid_top + (i / per_row) - base_row;
+	    int col = (i % per_row + 1) * width;
+	    short pair = i;
+
+	    if (row >= 0 && move(row, col) != ERR) {
+		short fg = (short) (i % COLORS);
+		short bg = (short) (i / COLORS);
+
+		init_pair(pair, fg, bg);
+		attron((attr_t) COLOR_PAIR(pair));
+		if (opt_acsc)
+		    attron((attr_t) A_ALTCHARSET);
+		if (opt_bold)
+		    attron((attr_t) A_BOLD);
+
+		if (opt_nums) {
+		    sprintf(numbered, "{%02X}", i);
+		    hello = numbered;
+		}
+		printw("%-*.*s", width, width, hello);
+		attrset(A_NORMAL);
+
+		if ((i % per_row) == 0 && (i % COLORS) == 0) {
+		    show_color_name(row, 0, i / COLORS, opt_wide);
+		}
+		++shown;
+	    } else if (shown) {
+		break;
+	    }
+	}
+
+	switch (wGetchar(stdscr)) {
+	case 'a':
+	    opt_acsc = FALSE;
+	    break;
+	case 'A':
+	    opt_acsc = TRUE;
+	    break;
+	case 'b':
+	    opt_bold = FALSE;
+	    break;
+	case 'B':
+	    opt_bold = TRUE;
+	    break;
+	case 'n':
+	    opt_nums = FALSE;
+	    break;
+	case 'N':
+	    opt_nums = TRUE;
+	    break;
+	case case_QUIT:
+	    done = TRUE;
+	    continue;
+	case 'w':
+	    set_color_test(opt_wide, FALSE);
+	    break;
+	case 'W':
+	    set_color_test(opt_wide, TRUE);
+	    break;
+	case CTRL('p'):
+	case KEY_UP:
+	    if (base_row <= 0) {
+		beep();
+	    } else {
+		base_row -= 1;
+	    }
+	    break;
+	case CTRL('n'):
+	case KEY_DOWN:
+	    if (base_row + page_size >= row_limit) {
+		beep();
+	    } else {
+		base_row += 1;
+	    }
+	    break;
+	case CTRL('b'):
+	case KEY_PREVIOUS:
+	case KEY_PPAGE:
+	    if (base_row <= 0) {
+		beep();
+	    } else {
+		base_row -= (page_size - 1);
+		if (base_row < 0)
+		    base_row = 0;
+	    }
+	    break;
+	case CTRL('f'):
+	case KEY_NEXT:
+	case KEY_NPAGE:
+	    if (base_row + page_size >= row_limit) {
+		beep();
+	    } else {
+		base_row += page_size - 1;
+		if (base_row + page_size >= row_limit) {
+		    base_row = row_limit - page_size - 1;
+		}
+	    }
+	    break;
+	case '?':
+	    if ((helpwin = newwin(LINES - 1, COLS - 2, 0, 0)) != 0) {
+		box(helpwin, 0, 0);
+		color_legend(helpwin, FALSE);
+		wGetchar(helpwin);
+		delwin(helpwin);
+	    }
+	    break;
+	default:
+	    beep();
+	    continue;
+	}
+    }
+
+    erase();
+    endwin();
+}
+
+#if USE_WIDEC_SUPPORT
+/* generate a color test pattern */
+static void
+wide_color_test(void)
+{
+    int c;
+    int i;
+    int top = 0, width;
+    int base_row = 0;
+    int grid_top = top + 3;
+    int page_size = (LINES - grid_top);
+    int pairs_max = COLOR_PAIRS;
+    int row_limit;
+    int per_row;
+    char numbered[80];
+    const char *hello;
+    bool done = FALSE;
+    bool opt_acsc = FALSE;
+    bool opt_bold = FALSE;
+    bool opt_wide = FALSE;
+    bool opt_nums = FALSE;
+    bool opt_xchr = FALSE;
+    wchar_t buffer[10];
+    WINDOW *helpwin;
+
+    while (!done) {
+	int shown = 0;
+
+	/* this assumes an 80-column line */
+	if (opt_wide) {
+	    width = 4;
+	    hello = "Test";
+	    per_row = (COLORS > 8) ? 16 : 8;
+	} else {
+	    width = 8;
+	    hello = "Hello";
+	    per_row = 8;
+	}
+	if (opt_xchr) {
+	    make_fullwidth_text(buffer, hello);
+	    width *= 2;
+	    per_row /= 2;
+	} else {
+	    make_narrow_text(buffer, hello);
+	}
+
+	row_limit = (pairs_max + per_row - 1) / per_row;
+
+	move(0, 0);
+	(void) printw("There are %d color pairs and %d colors\n",
+		      pairs_max, COLORS);
+
+	clrtobot();
+	(void) mvprintw(top + 1, 0,
+			"%dx%d matrix of foreground/background colors, bold *%s*\n",
+			row_limit,
+			per_row,
+			opt_bold ? "on" : "off");
+
+	/* show color names/numbers across the top */
+	for (i = 0; i < per_row; i++)
+	    show_color_name(top + 2, (i + 1) * width, i, opt_wide);
+
+	/* show a grid of colors, with color names/ numbers on the left */
+	for (i = (base_row * per_row); i < pairs_max; i++) {
+	    int row = grid_top + (i / per_row) - base_row;
+	    int col = (i % per_row + 1) * width;
+	    short pair = (short) i;
+
+	    if (row >= 0 && move(row, col) != ERR) {
+		init_pair(pair, (short) (i % COLORS), (short) (i / COLORS));
+		color_set(pair, NULL);
+		if (opt_acsc)
+		    attr_on((attr_t) A_ALTCHARSET, NULL);
+		if (opt_bold)
+		    attr_on((attr_t) A_BOLD, NULL);
+
+		if (opt_nums) {
+		    sprintf(numbered, "{%02X}", i);
+		    if (opt_xchr) {
+			make_fullwidth_text(buffer, numbered);
+		    } else {
+			make_narrow_text(buffer, numbered);
+		    }
+		}
+		addnwstr(buffer, width);
+		attr_set(A_NORMAL, 0, NULL);
+
+		if ((i % per_row) == 0 && (i % COLORS) == 0) {
+		    show_color_name(row, 0, i / COLORS, opt_wide);
+		}
+		++shown;
+	    } else if (shown) {
+		break;
+	    }
+	}
+
+	switch (c = wGetchar(stdscr)) {
+	case 'a':
+	    opt_acsc = FALSE;
+	    break;
+	case 'A':
+	    opt_acsc = TRUE;
+	    break;
+	case 'b':
+	    opt_bold = FALSE;
+	    break;
+	case 'B':
+	    opt_bold = TRUE;
+	    break;
+	case 'n':
+	    opt_nums = FALSE;
+	    break;
+	case 'N':
+	    opt_nums = TRUE;
+	    break;
+	case case_QUIT:
+	    done = TRUE;
+	    continue;
+	case 'w':
+	    set_color_test(opt_wide, FALSE);
+	    break;
+	case 'W':
+	    set_color_test(opt_wide, TRUE);
+	    break;
+	case 'x':
+	    opt_xchr = FALSE;
+	    break;
+	case 'X':
+	    opt_xchr = TRUE;
+	    break;
+	case CTRL('p'):
+	case KEY_UP:
+	    if (base_row <= 0) {
+		beep();
+	    } else {
+		base_row -= 1;
+	    }
+	    break;
+	case CTRL('n'):
+	case KEY_DOWN:
+	    if (base_row + page_size >= row_limit) {
+		beep();
+	    } else {
+		base_row += 1;
+	    }
+	    break;
+	case CTRL('b'):
+	case KEY_PREVIOUS:
+	case KEY_PPAGE:
+	    if (base_row <= 0) {
+		beep();
+	    } else {
+		base_row -= (page_size - 1);
+		if (base_row < 0)
+		    base_row = 0;
+	    }
+	    break;
+	case CTRL('f'):
+	case KEY_NEXT:
+	case KEY_NPAGE:
+	    if (base_row + page_size >= row_limit) {
+		beep();
+	    } else {
+		base_row += page_size - 1;
+		if (base_row + page_size >= row_limit) {
+		    base_row = row_limit - page_size - 1;
+		}
+	    }
+	    break;
+	case '?':
+	    if ((helpwin = newwin(LINES - 1, COLS - 2, 0, 0)) != 0) {
+		box(helpwin, 0, 0);
+		color_legend(helpwin, TRUE);
+		wGetchar(helpwin);
+		delwin(helpwin);
+	    }
+	    break;
+	default:
+	    beep();
+	    continue;
+	}
+    }
+
+    erase();
+    endwin();
+}
+#endif /* USE_WIDEC_SUPPORT */
+
+static void
+change_color(short current, int field, int value, int usebase)
+{
+    short red, green, blue;
+
+    color_content(current, &red, &green, &blue);
+
+    switch (field) {
+    case 0:
+	red = (short) (usebase ? (red + value) : value);
+	break;
+    case 1:
+	green = (short) (usebase ? (green + value) : value);
+	break;
+    case 2:
+	blue = (short) (usebase ? (blue + value) : value);
+	break;
+    }
+
+    if (init_color(current, red, green, blue) == ERR)
+	beep();
+}
+
+static void
+init_all_colors(void)
+{
+    short c;
+
+    for (c = 0; c < COLORS; ++c)
+	init_color(c,
+		   all_colors[c].red,
+		   all_colors[c].green,
+		   all_colors[c].blue);
+}
+
+#define scaled_rgb(n) ((255 * (n)) / 1000)
+
+static void
+color_edit(void)
+/* display the color test pattern, without trying to edit colors */
+{
+    int i;
+    int current = 0;
+    int this_c = 0, value = 0, field = 0;
+    int last_c;
+    int top_color = 0;
+    int page_size = (LINES - 6);
+
+    init_all_colors();
+    refresh();
+
+    for (i = 0; i < max_colors; i++)
+	init_pair((short) i, (short) COLOR_WHITE, (short) i);
+
+    mvprintw(LINES - 2, 0, "Number: %d", value);
+
+    do {
+	short red, green, blue;
+
+	attron(A_BOLD);
+	mvaddstr(0, 20, "Color RGB Value Editing");
+	attroff(A_BOLD);
+
+	for (i = (short) top_color;
+	     (i - top_color < page_size)
+	     && (i < max_colors); i++) {
+	    char numeric[80];
+
+	    sprintf(numeric, "[%d]", i);
+	    mvprintw(2 + i - top_color, 0, "%c %-8s:",
+		     (i == current ? '>' : ' '),
+		     (i < (int) SIZEOF(the_color_names)
+		      ? the_color_names[i] : numeric));
+	    attrset(COLOR_PAIR(i));
+	    addstr("        ");
+	    attrset(A_NORMAL);
+
+	    color_content((short) i, &red, &green, &blue);
+	    addstr("   R = ");
+	    if (current == i && field == 0)
+		attron(A_STANDOUT);
+	    printw("%04d", red);
+	    if (current == i && field == 0)
+		attrset(A_NORMAL);
+	    addstr(", G = ");
+	    if (current == i && field == 1)
+		attron(A_STANDOUT);
+	    printw("%04d", green);
+	    if (current == i && field == 1)
+		attrset(A_NORMAL);
+	    addstr(", B = ");
+	    if (current == i && field == 2)
+		attron(A_STANDOUT);
+	    printw("%04d", blue);
+	    if (current == i && field == 2)
+		attrset(A_NORMAL);
+	    attrset(A_NORMAL);
+	    printw(" ( %3d %3d %3d )",
+		   scaled_rgb(red),
+		   scaled_rgb(green),
+		   scaled_rgb(blue));
+	}
+
+	mvaddstr(LINES - 3, 0,
+		 "Use up/down to select a color, left/right to change fields.");
+	mvaddstr(LINES - 2, 0,
+		 "Modify field by typing nnn=, nnn-, or nnn+.  ? for help.");
+
+	move(2 + current - top_color, 0);
+
+	last_c = this_c;
+	this_c = Getchar();
+	if (this_c < 256 && isdigit(this_c) && !isdigit(last_c))
+	    value = 0;
+
+	switch (this_c) {
+	case CTRL('b'):
+	case KEY_PPAGE:
+	    if (current > 0)
+		current -= (page_size - 1);
+	    else
+		beep();
+	    break;
+
+	case CTRL('f'):
+	case KEY_NPAGE:
+	    if (current < (max_colors - 1))
+		current += (page_size - 1);
+	    else
+		beep();
+	    break;
+
+	case CTRL('p'):
+	case KEY_UP:
+	    current = (current == 0 ? (max_colors - 1) : current - 1);
+	    break;
+
+	case CTRL('n'):
+	case KEY_DOWN:
+	    current = (current == (max_colors - 1) ? 0 : current + 1);
+	    break;
+
+	case KEY_RIGHT:
+	    field = (field == 2 ? 0 : field + 1);
+	    break;
+
+	case KEY_LEFT:
+	    field = (field == 0 ? 2 : field - 1);
+	    break;
+
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	    value = value * 10 + (this_c - '0');
+	    break;
+
+	case '+':
+	    change_color((short) current, field, value, 1);
+	    break;
+
+	case '-':
+	    change_color((short) current, field, -value, 1);
+	    break;
+
+	case '=':
+	    change_color((short) current, field, value, 0);
+	    break;
+
+	case '?':
+	    erase();
+	    P("                      RGB Value Editing Help");
+	    P("");
+	    P("You are in the RGB value editor.  Use the arrow keys to select one of");
+	    P("the fields in one of the RGB triples of the current colors; the one");
+	    P("currently selected will be reverse-video highlighted.");
+	    P("");
+	    P("To change a field, enter the digits of the new value; they are echoed");
+	    P("as entered.  Finish by typing `='.  The change will take effect instantly.");
+	    P("To increment or decrement a value, use the same procedure, but finish");
+	    P("with a `+' or `-'.");
+	    P("");
+	    P("Press 'm' to invoke the top-level menu with the current color settings.");
+	    P("To quit, do ESC");
+
+	    Pause();
+	    erase();
+	    break;
+
+	case 'm':
+	    endwin();
+	    main_menu(FALSE);
+	    refresh();
+	    break;
+
+	case case_QUIT:
+	    break;
+
+	default:
+	    beep();
+	    break;
+	}
+
+	if (current < 0)
+	    current = 0;
+	if (current >= max_colors)
+	    current = max_colors - 1;
+	if (current < top_color)
+	    top_color = current;
+	if (current - top_color >= page_size)
+	    top_color = current - (page_size - 1);
+
+	mvprintw(LINES - 1, 0, "Number: %d", value);
+	clrtoeol();
+    } while
+	(!isQuit(this_c));
+
+    erase();
+
+    /*
+     * ncurses does not reset each color individually when calling endwin().
+     */
+    init_all_colors();
+
+    endwin();
+}
+
+/****************************************************************************
+ *
+ * Soft-key label test
+ *
+ ****************************************************************************/
+
+#if USE_SOFTKEYS
+
+#define SLK_HELP 17
+#define SLK_WORK (SLK_HELP + 3)
+
+static void
+slk_help(void)
+{
+    static const char *table[] =
+    {
+	"Available commands are:"
+	,""
+	,"^L         -- repaint this message and activate soft keys"
+	,"a/d        -- activate/disable soft keys"
+	,"c          -- set centered format for labels"
+	,"l          -- set left-justified format for labels"
+	,"r          -- set right-justified format for labels"
+	,"[12345678] -- set label; labels are numbered 1 through 8"
+	,"e          -- erase stdscr (should not erase labels)"
+	,"s          -- test scrolling of shortened screen"
+#if HAVE_SLK_COLOR
+	,"F/B        -- cycle through foreground/background colors"
+#endif
+	,"ESC        -- return to main menu"
+	,""
+	,"Note: if activating the soft keys causes your terminal to scroll up"
+	,"one line, your terminal auto-scrolls when anything is written to the"
+	,"last screen position.  The ncurses code does not yet handle this"
+	,"gracefully."
+    };
+    unsigned j;
+
+    move(2, 0);
+    for (j = 0; j < SIZEOF(table); ++j) {
+	P(table[j]);
+    }
+    refresh();
+}
+
+#if HAVE_SLK_COLOR
+static void
+call_slk_color(short fg, short bg)
+{
+    init_pair(1, bg, fg);
+    slk_color(1);
+    mvprintw(SLK_WORK, 0, "Colors %d/%d\n", fg, bg);
+    clrtoeol();
+    refresh();
+}
+#endif
+
+static void
+slk_test(void)
+/* exercise the soft keys */
+{
+    int c, fmt = 1;
+    char buf[9];
+    char *s;
+#if HAVE_SLK_COLOR
+    short fg = COLOR_BLACK;
+    short bg = COLOR_WHITE;
+#endif
+
+    c = CTRL('l');
+#if HAVE_SLK_COLOR
+    if (use_colors) {
+	call_slk_color(fg, bg);
+    }
+#endif
+
+    do {
+	move(0, 0);
+	switch (c) {
+	case CTRL('l'):
+	    erase();
+	    attron(A_BOLD);
+	    mvaddstr(0, 20, "Soft Key Exerciser");
+	    attroff(A_BOLD);
+
+	    slk_help();
+	    /* fall through */
+
+	case 'a':
+	    slk_restore();
+	    break;
+
+	case 'e':
+	    wclear(stdscr);
+	    break;
+
+	case 's':
+	    mvprintw(SLK_WORK, 0, "Press Q to stop the scrolling-test: ");
+	    while ((c = Getchar()) != 'Q' && (c != ERR))
+		addch((chtype) c);
+	    break;
+
+	case 'd':
+	    slk_clear();
+	    break;
+
+	case 'l':
+	    fmt = 0;
+	    break;
+
+	case 'c':
+	    fmt = 1;
+	    break;
+
+	case 'r':
+	    fmt = 2;
+	    break;
+
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	    (void) mvaddstr(SLK_WORK, 0, "Please enter the label value: ");
+	    strcpy(buf, "");
+	    if ((s = slk_label(c - '0')) != 0) {
+		strncpy(buf, s, 8);
+	    }
+	    wGetstring(stdscr, buf, 8);
+	    slk_set((c - '0'), buf, fmt);
+	    slk_refresh();
+	    move(SLK_WORK, 0);
+	    clrtobot();
+	    break;
+
+	case case_QUIT:
+	    goto done;
+
+#if HAVE_SLK_COLOR
+	case 'F':
+	    if (use_colors) {
+		fg = (short) ((fg + 1) % COLORS);
+		call_slk_color(fg, bg);
+	    }
+	    break;
+	case 'B':
+	    if (use_colors) {
+		bg = (short) ((bg + 1) % COLORS);
+		call_slk_color(fg, bg);
+	    }
+	    break;
+#endif
+#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
+	case KEY_RESIZE:
+	    wnoutrefresh(stdscr);
+	    break;
+#endif
+
+	default:
+	    beep();
+	}
+    } while (!isQuit(c = Getchar()));
+
+  done:
+    slk_clear();
+    erase();
+    endwin();
+}
+
+#if USE_WIDEC_SUPPORT
+#define SLKLEN 8
+static void
+wide_slk_test(void)
+/* exercise the soft keys */
+{
+    int c, fmt = 1;
+    wchar_t buf[SLKLEN + 1];
+    char *s;
+    short fg = COLOR_BLACK;
+    short bg = COLOR_WHITE;
+
+    c = CTRL('l');
+    if (use_colors) {
+	call_slk_color(fg, bg);
+    }
+    do {
+	move(0, 0);
+	switch (c) {
+	case CTRL('l'):
+	    erase();
+	    attr_on(WA_BOLD, NULL);
+	    mvaddstr(0, 20, "Soft Key Exerciser");
+	    attr_off(WA_BOLD, NULL);
+
+	    slk_help();
+	    /* fall through */
+
+	case 'a':
+	    slk_restore();
+	    break;
+
+	case 'e':
+	    wclear(stdscr);
+	    break;
+
+	case 's':
+	    mvprintw(SLK_WORK, 0, "Press Q to stop the scrolling-test: ");
+	    while ((c = Getchar()) != 'Q' && (c != ERR))
+		addch((chtype) c);
+	    break;
+
+	case 'd':
+	    slk_clear();
+	    break;
+
+	case 'l':
+	    fmt = 0;
+	    break;
+
+	case 'c':
+	    fmt = 1;
+	    break;
+
+	case 'r':
+	    fmt = 2;
+	    break;
+
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	    (void) mvaddstr(SLK_WORK, 0, "Please enter the label value: ");
+	    *buf = 0;
+	    if ((s = slk_label(c - '0')) != 0) {
+		char *temp = strdup(s);
+		size_t used = strlen(temp);
+		size_t want = SLKLEN;
+		size_t test;
+#ifndef state_unused
+		mbstate_t state;
+#endif
+
+		buf[0] = L'\0';
+		while (want > 0 && used != 0) {
+		    const char *base = s;
+		    reset_mbytes(state);
+		    test = count_mbytes(base, 0, &state);
+		    if (test == (size_t) -1) {
+			temp[--used] = 0;
+		    } else if (test > want) {
+			temp[--used] = 0;
+		    } else {
+			reset_mbytes(state);
+			trans_mbytes(buf, base, want, &state);
+			break;
+		    }
+		}
+		free(temp);
+	    }
+	    wGet_wstring(stdscr, buf, SLKLEN);
+	    slk_wset((c - '0'), buf, fmt);
+	    slk_refresh();
+	    move(SLK_WORK, 0);
+	    clrtobot();
+	    break;
+
+	case case_QUIT:
+	    goto done;
+
+	case 'F':
+	    if (use_colors) {
+		fg = (short) ((fg + 1) % COLORS);
+		call_slk_color(fg, bg);
+	    }
+	    break;
+	case 'B':
+	    if (use_colors) {
+		bg = (short) ((bg + 1) % COLORS);
+		call_slk_color(fg, bg);
+	    }
+	    break;
+#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
+	case KEY_RESIZE:
+	    wnoutrefresh(stdscr);
+	    break;
+#endif
+	default:
+	    beep();
+	}
+    } while (!isQuit(c = Getchar()));
+
+  done:
+    slk_clear();
+    erase();
+    endwin();
+}
+#endif
+#endif /* SLK_INIT */
+
+/****************************************************************************
+ *
+ * Alternate character-set stuff
+ *
+ ****************************************************************************/
+/* *INDENT-OFF* */
+static struct {
+    chtype attr;
+    const char *name;
+} attrs_to_cycle[] = {
+    { A_NORMAL,		"normal" },
+    { A_BOLD,		"bold" },
+    { A_REVERSE,	"reverse" },
+    { A_UNDERLINE,	"underline" },
+};
+/* *INDENT-ON* */
+
+static bool
+cycle_attr(int ch, unsigned *at_code, chtype *attr)
+{
+    bool result = TRUE;
+
+    switch (ch) {
+    case 'v':
+	if ((*at_code += 1) >= SIZEOF(attrs_to_cycle))
+	    *at_code = 0;
+	break;
+    case 'V':
+	if (*at_code == 1)
+	    *at_code = SIZEOF(attrs_to_cycle) - 1;
+	else
+	    *at_code -= 1;
+	break;
+    default:
+	result = FALSE;
+	break;
+    }
+    if (result)
+	*attr = attrs_to_cycle[*at_code].attr;
+    return result;
+}
+
+static bool
+cycle_colors(int ch, int *fg, int *bg, short *pair)
+{
+    bool result = FALSE;
+
+    if (use_colors) {
+	result = TRUE;
+	switch (ch) {
+	case 'F':
+	    if ((*fg -= 1) < 0)
+		*fg = COLORS - 1;
+	    break;
+	case 'f':
+	    if ((*fg += 1) >= COLORS)
+		*fg = 0;
+	    break;
+	case 'B':
+	    if ((*bg -= 1) < 0)
+		*bg = COLORS - 1;
+	    break;
+	case 'b':
+	    if ((*bg += 1) >= COLORS)
+		*bg = 0;
+	    break;
+	default:
+	    result = FALSE;
+	    break;
+	}
+	if (result) {
+	    *pair = (short) (*fg != COLOR_BLACK || *bg != COLOR_BLACK);
+	    if (*pair != 0) {
+		*pair = 1;
+		if (init_pair(*pair, (short) *fg, (short) *bg) == ERR) {
+		    result = FALSE;
+		}
+	    }
+	}
+    }
+    return result;
+}
+
+/* ISO 6429:  codes 0x80 to 0x9f may be control characters that cause the
+ * terminal to perform functions.  The remaining codes can be graphic.
+ */
+static void
+show_upper_chars(unsigned first, int repeat, attr_t attr, short pair)
+{
+    bool C1 = (first == 128);
+    unsigned code;
+    unsigned last = first + 31;
+    int reply;
+
+    erase();
+    attron(A_BOLD);
+    mvprintw(0, 20, "Display of %s Character Codes %d to %d",
+	     C1 ? "C1" : "GR", first, last);
+    attroff(A_BOLD);
+    refresh();
+
+    for (code = first; code <= last; code++) {
+	int count = repeat;
+	int row = 2 + ((int) (code - first) % 16);
+	int col = ((int) (code - first) / 16) * COLS / 2;
+	char tmp[80];
+	sprintf(tmp, "%3u (0x%x)", code, code);
+	mvprintw(row, col, "%*s: ", COLS / 4, tmp);
+
+	do {
+	    if (C1)
+		nodelay(stdscr, TRUE);
+	    echochar(code | attr | COLOR_PAIR(pair));
+	    if (C1) {
+		/* (yes, this _is_ crude) */
+		while ((reply = Getchar()) != ERR) {
+		    addch(UChar(reply));
+		    napms(10);
+		}
+		nodelay(stdscr, FALSE);
+	    }
+	} while (--count > 0);
+    }
+}
+
+#define PC_COLS 4
+
+static void
+show_pc_chars(int repeat, attr_t attr, short pair)
+{
+    unsigned code;
+
+    erase();
+    attron(A_BOLD);
+    mvprintw(0, 20, "Display of PC Character Codes");
+    attroff(A_BOLD);
+    refresh();
+
+    for (code = 0; code < 16; ++code) {
+	mvprintw(2, (int) code * PC_COLS + 8, "%X", code);
+    }
+    for (code = 0; code < 256; code++) {
+	int count = repeat;
+	int row = 3 + (int) (code / 16) + (code >= 128);
+	int col = 8 + (int) (code % 16) * PC_COLS;
+	if ((code % 16) == 0)
+	    mvprintw(row, 0, "0x%02x:", code);
+	move(row, col);
+	do {
+	    switch (code) {
+	    case '\n':
+	    case '\r':
+	    case '\b':
+	    case '\f':
+	    case '\033':
+	    case 0x9b:
+		/*
+		 * Skip the ones that do not work.
+		 */
+		break;
+	    default:
+		addch(code | A_ALTCHARSET | attr | COLOR_PAIR(pair));
+		break;
+	    }
+	} while (--count > 0);
+    }
+}
+
+static void
+show_box_chars(int repeat, attr_t attr, short pair)
+{
+    (void) repeat;
+    attr |= COLOR_PAIR(pair);
+
+    erase();
+    attron(A_BOLD);
+    mvaddstr(0, 20, "Display of the ACS Line-Drawing Set");
+    attroff(A_BOLD);
+    refresh();
+    box(stdscr, 0, 0);
+    /* *INDENT-OFF* */
+    mvhline(LINES / 2, 0,        ACS_HLINE | attr, COLS);
+    mvvline(0,         COLS / 2, ACS_VLINE | attr, LINES);
+    mvaddch(0,         COLS / 2, ACS_TTEE | attr);
+    mvaddch(LINES / 2, COLS / 2, ACS_PLUS | attr);
+    mvaddch(LINES - 1, COLS / 2, ACS_BTEE | attr);
+    mvaddch(LINES / 2, 0,        ACS_LTEE | attr);
+    mvaddch(LINES / 2, COLS - 1, ACS_RTEE | attr);
+    /* *INDENT-ON* */
+
+}
+
+static int
+show_1_acs(int n, int repeat, const char *name, chtype code)
+{
+    const int height = 16;
+    int row = 2 + (n % height);
+    int col = (n / height) * COLS / 2;
+
+    mvprintw(row, col, "%*s : ", COLS / 4, name);
+    do {
+	addch(code);
+    } while (--repeat > 0);
+    return n + 1;
+}
+
+static void
+show_acs_chars(int repeat, attr_t attr, short pair)
+/* display the ACS character set */
+{
+    int n;
+
+#define BOTH(name) #name, (name | attr | COLOR_PAIR(pair))
+
+    erase();
+    attron(A_BOLD);
+    mvaddstr(0, 20, "Display of the ACS Character Set");
+    attroff(A_BOLD);
+    refresh();
+
+    n = show_1_acs(0, repeat, BOTH(ACS_ULCORNER));
+    n = show_1_acs(n, repeat, BOTH(ACS_URCORNER));
+    n = show_1_acs(n, repeat, BOTH(ACS_LLCORNER));
+    n = show_1_acs(n, repeat, BOTH(ACS_LRCORNER));
+
+    n = show_1_acs(n, repeat, BOTH(ACS_LTEE));
+    n = show_1_acs(n, repeat, BOTH(ACS_RTEE));
+    n = show_1_acs(n, repeat, BOTH(ACS_TTEE));
+    n = show_1_acs(n, repeat, BOTH(ACS_BTEE));
+
+    n = show_1_acs(n, repeat, BOTH(ACS_HLINE));
+    n = show_1_acs(n, repeat, BOTH(ACS_VLINE));
+
+    /*
+     * HPUX's ACS definitions are broken here.  Just give up.
+     */
+#if !(defined(__hpux) && !defined(NCURSES_VERSION))
+    n = show_1_acs(n, repeat, BOTH(ACS_LARROW));
+    n = show_1_acs(n, repeat, BOTH(ACS_RARROW));
+    n = show_1_acs(n, repeat, BOTH(ACS_UARROW));
+    n = show_1_acs(n, repeat, BOTH(ACS_DARROW));
+
+    n = show_1_acs(n, repeat, BOTH(ACS_BLOCK));
+    n = show_1_acs(n, repeat, BOTH(ACS_BOARD));
+    n = show_1_acs(n, repeat, BOTH(ACS_LANTERN));
+    n = show_1_acs(n, repeat, BOTH(ACS_BULLET));
+    n = show_1_acs(n, repeat, BOTH(ACS_CKBOARD));
+    n = show_1_acs(n, repeat, BOTH(ACS_DEGREE));
+    n = show_1_acs(n, repeat, BOTH(ACS_DIAMOND));
+    n = show_1_acs(n, repeat, BOTH(ACS_PLMINUS));
+    n = show_1_acs(n, repeat, BOTH(ACS_PLUS));
+
+    n = show_1_acs(n, repeat, BOTH(ACS_GEQUAL));
+    n = show_1_acs(n, repeat, BOTH(ACS_NEQUAL));
+    n = show_1_acs(n, repeat, BOTH(ACS_LEQUAL));
+
+    n = show_1_acs(n, repeat, BOTH(ACS_STERLING));
+    n = show_1_acs(n, repeat, BOTH(ACS_PI));
+    n = show_1_acs(n, repeat, BOTH(ACS_S1));
+    n = show_1_acs(n, repeat, BOTH(ACS_S3));
+    n = show_1_acs(n, repeat, BOTH(ACS_S7));
+    n = show_1_acs(n, repeat, BOTH(ACS_S9));
+#endif
+}
+
+static void
+acs_display(void)
+{
+    int c = 'a';
+    char *term = getenv("TERM");
+    const char *pch_kludge = ((term != 0 && strstr(term, "linux"))
+			      ? "p=PC, "
+			      : "");
+    chtype attr = A_NORMAL;
+    int digit = 0;
+    int repeat = 1;
+    int fg = COLOR_BLACK;
+    int bg = COLOR_BLACK;
+    unsigned at_code = 0;
+    short pair = 0;
+    void (*last_show_acs) (int, attr_t, short) = 0;
+
+    do {
+	switch (c) {
+	case CTRL('L'):
+	    Repaint();
+	    break;
+	case 'a':
+	    ToggleAcs(last_show_acs, show_acs_chars);
+	    break;
+	case 'p':
+	    if (*pch_kludge)
+		ToggleAcs(last_show_acs, show_pc_chars);
+	    else
+		beep();
+	    break;
+	case 'x':
+	    ToggleAcs(last_show_acs, show_box_chars);
+	    break;
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	    digit = (c - '0');
+	    last_show_acs = 0;
+	    break;
+	case '-':
+	    if (digit > 0) {
+		--digit;
+		last_show_acs = 0;
+	    } else {
+		beep();
+	    }
+	    break;
+	case '+':
+	    if (digit < 3) {
+		++digit;
+		last_show_acs = 0;
+	    } else {
+		beep();
+	    }
+	    break;
+	case '>':
+	    if (repeat < (COLS / 4))
+		++repeat;
+	    break;
+	case '<':
+	    if (repeat > 1)
+		--repeat;
+	    break;
+	default:
+	    if (cycle_attr(c, &at_code, &attr)
+		|| cycle_colors(c, &fg, &bg, &pair)) {
+		break;
+	    } else {
+		beep();
+	    }
+	    break;
+	}
+	if (last_show_acs != 0)
+	    last_show_acs(repeat, attr, pair);
+	else
+	    show_upper_chars((unsigned) (digit * 32 + 128), repeat, attr, pair);
+
+	mvprintw(LINES - 3, 0,
+		 "Note: ANSI terminals may not display C1 characters.");
+	mvprintw(LINES - 2, 0,
+		 "Select: a=ACS, x=box, %s0=C1, 1-3,+/- non-ASCII, </> repeat, ESC=quit",
+		 pch_kludge);
+	if (use_colors) {
+	    mvprintw(LINES - 1, 0,
+		     "v/V, f/F, b/B cycle through video attributes (%s) and color %d/%d.",
+		     attrs_to_cycle[at_code].name,
+		     fg, bg);
+	} else {
+	    mvprintw(LINES - 1, 0,
+		     "v/V cycles through video attributes (%s).",
+		     attrs_to_cycle[at_code].name);
+	}
+	refresh();
+    } while (!isQuit(c = Getchar()));
+
+    Pause();
+    erase();
+    endwin();
+}
+
+#if USE_WIDEC_SUPPORT
+static cchar_t *
+merge_wide_attr(cchar_t *dst, const cchar_t *src, attr_t attr, short pair)
+{
+    int count = getcchar(src, NULL, NULL, NULL, 0);
+    wchar_t *wch = 0;
+    attr_t ignore_attr;
+    short ignore_pair;
+
+    *dst = *src;
+    if (count > 0) {
+	if ((wch = typeMalloc(wchar_t, (unsigned) count + 1)) != 0) {
+	    if (getcchar(src, wch, &ignore_attr, &ignore_pair, 0) != ERR) {
+		attr |= (ignore_attr & A_ALTCHARSET);
+		setcchar(dst, wch, attr, pair, 0);
+	    }
+	    free(wch);
+	}
+    }
+    return dst;
+}
+
+static void
+show_upper_widechars(int first, int repeat, int space, attr_t attr, short pair)
+{
+    cchar_t temp;
+    wchar_t code;
+    int last = first + 31;
+
+    erase();
+    attron(A_BOLD);
+    mvprintw(0, 20, "Display of Character Codes %d to %d", first, last);
+    attroff(A_BOLD);
+
+    for (code = first; (int) code <= last; code++) {
+	int row = 2 + ((code - first) % 16);
+	int col = ((code - first) / 16) * COLS / 2;
+	wchar_t codes[10];
+	char tmp[80];
+	int count = repeat;
+	int y, x;
+
+	memset(&codes, 0, sizeof(codes));
+	codes[0] = code;
+	sprintf(tmp, "%3ld (0x%lx)", (long) code, (long) code);
+	mvprintw(row, col, "%*s: ", COLS / 4, tmp);
+	setcchar(&temp, codes, attr, pair, 0);
+	do {
+	    /*
+	     * Give non-spacing characters something to combine with.  If we
+	     * don't, they'll bunch up in a heap on the space after the ":".
+	     * Mark them with reverse-video to make them simpler to find on
+	     * the display.
+	     */
+	    if (wcwidth(code) == 0)
+		addch(space | A_REVERSE);
+	    /*
+	     * This could use add_wch(), but is done for comparison with the
+	     * normal 'f' test (and to make a test-case for echo_wchar()).
+	     * The screen will flicker because the erase() at the top of the
+	     * function is met by the builtin refresh() in echo_wchar().
+	     */
+	    echo_wchar(&temp);
+	    /*
+	     * The repeat-count may make text wrap - avoid that.
+	     */
+	    getyx(stdscr, y, x);
+	    if (x >= col + (COLS / 2) - 2)
+		break;
+	} while (--count > 0);
+    }
+}
+
+static int
+show_1_wacs(int n, int repeat, const char *name, const cchar_t *code)
+{
+    const int height = 16;
+    int row = 2 + (n % height);
+    int col = (n / height) * COLS / 2;
+
+    mvprintw(row, col, "%*s : ", COLS / 4, name);
+    while (repeat-- >= 0) {
+	add_wch(code);
+    }
+    return n + 1;
+}
+
+#define MERGE_ATTR(wch) merge_wide_attr(&temp, wch, attr, pair)
+
+static void
+show_wacs_chars(int repeat, attr_t attr, short pair)
+/* display the wide-ACS character set */
+{
+    cchar_t temp;
+
+    int n;
+
+/*#define BOTH2(name) #name, &(name) */
+#define BOTH2(name) #name, MERGE_ATTR(name)
+
+    erase();
+    attron(A_BOLD);
+    mvaddstr(0, 20, "Display of the Wide-ACS Character Set");
+    attroff(A_BOLD);
+    refresh();
+
+    n = show_1_wacs(0, repeat, BOTH2(WACS_ULCORNER));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_URCORNER));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_LLCORNER));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_LRCORNER));
+
+    n = show_1_wacs(n, repeat, BOTH2(WACS_LTEE));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_RTEE));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_TTEE));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_BTEE));
+
+    n = show_1_wacs(n, repeat, BOTH2(WACS_HLINE));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_VLINE));
+
+    n = show_1_wacs(n, repeat, BOTH2(WACS_LARROW));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_RARROW));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_UARROW));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_DARROW));
+
+    n = show_1_wacs(n, repeat, BOTH2(WACS_BLOCK));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_BOARD));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_LANTERN));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_BULLET));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_CKBOARD));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_DEGREE));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_DIAMOND));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_PLMINUS));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_PLUS));
+
+#ifdef CURSES_WACS_ARRAY
+    n = show_1_wacs(n, repeat, BOTH2(WACS_GEQUAL));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_NEQUAL));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_LEQUAL));
+
+    n = show_1_wacs(n, repeat, BOTH2(WACS_STERLING));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_PI));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_S1));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_S3));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_S7));
+    n = show_1_wacs(n, repeat, BOTH2(WACS_S9));
+#endif
+}
+
+#undef MERGE_ATTR
+
+#define MERGE_ATTR(wch) merge_wide_attr(&temp, wch, attr, pair)
+
+static void
+show_wbox_chars(int repeat, attr_t attr, short pair)
+{
+    cchar_t temp;
+
+    (void) repeat;
+    erase();
+    attron(A_BOLD);
+    mvaddstr(0, 20, "Display of the Wide-ACS Line-Drawing Set");
+    attroff(A_BOLD);
+    refresh();
+
+    attr_set(attr, pair, 0);
+    box_set(stdscr, 0, 0);
+    attr_set(A_NORMAL, 0, 0);
+    /* *INDENT-OFF* */
+    mvhline_set(LINES / 2, 0,        MERGE_ATTR(WACS_HLINE), COLS);
+    mvvline_set(0,         COLS / 2, MERGE_ATTR(WACS_VLINE), LINES);
+    mvadd_wch(0,           COLS / 2, MERGE_ATTR(WACS_TTEE));
+    mvadd_wch(LINES / 2,   COLS / 2, MERGE_ATTR(WACS_PLUS));
+    mvadd_wch(LINES - 1,   COLS / 2, MERGE_ATTR(WACS_BTEE));
+    mvadd_wch(LINES / 2,   0,        MERGE_ATTR(WACS_LTEE));
+    mvadd_wch(LINES / 2,   COLS - 1, MERGE_ATTR(WACS_RTEE));
+    /* *INDENT-ON* */
+
+}
+
+#undef MERGE_ATTR
+
+static int
+show_2_wacs(int n, const char *name, const char *code, attr_t attr, short pair)
+{
+    const int height = 16;
+    int row = 2 + (n % height);
+    int col = (n / height) * COLS / 2;
+    char temp[80];
+
+    mvprintw(row, col, "%*s : ", COLS / 4, name);
+    attr_set(attr, pair, 0);
+    addstr(strcpy(temp, code));
+    attr_set(A_NORMAL, 0, 0);
+    return n + 1;
+}
+
+#define SHOW_UTF8(n, name, code) show_2_wacs(n, name, code, attr, pair)
+
+static void
+show_utf8_chars(int repeat, attr_t attr, short pair)
+{
+    int n;
+
+    (void) repeat;
+    erase();
+    attron(A_BOLD);
+    mvaddstr(0, 20, "Display of the Wide-ACS Character Set");
+    attroff(A_BOLD);
+    refresh();
+    /* *INDENT-OFF* */
+    n = SHOW_UTF8(0, "WACS_ULCORNER",	"\342\224\214");
+    n = SHOW_UTF8(n, "WACS_URCORNER",	"\342\224\220");
+    n = SHOW_UTF8(n, "WACS_LLCORNER",	"\342\224\224");
+    n = SHOW_UTF8(n, "WACS_LRCORNER",	"\342\224\230");
+
+    n = SHOW_UTF8(n, "WACS_LTEE",	"\342\224\234");
+    n = SHOW_UTF8(n, "WACS_RTEE",	"\342\224\244");
+    n = SHOW_UTF8(n, "WACS_TTEE",	"\342\224\254");
+    n = SHOW_UTF8(n, "WACS_BTEE",	"\342\224\264");
+
+    n = SHOW_UTF8(n, "WACS_HLINE",	"\342\224\200");
+    n = SHOW_UTF8(n, "WACS_VLINE",	"\342\224\202");
+
+    n = SHOW_UTF8(n, "WACS_LARROW",	"\342\206\220");
+    n = SHOW_UTF8(n, "WACS_RARROW",	"\342\206\222");
+    n = SHOW_UTF8(n, "WACS_UARROW",	"\342\206\221");
+    n = SHOW_UTF8(n, "WACS_DARROW",	"\342\206\223");
+
+    n = SHOW_UTF8(n, "WACS_BLOCK",	"\342\226\256");
+    n = SHOW_UTF8(n, "WACS_BOARD",	"\342\226\222");
+    n = SHOW_UTF8(n, "WACS_LANTERN",	"\342\230\203");
+    n = SHOW_UTF8(n, "WACS_BULLET",	"\302\267");
+    n = SHOW_UTF8(n, "WACS_CKBOARD",	"\342\226\222");
+    n = SHOW_UTF8(n, "WACS_DEGREE",	"\302\260");
+    n = SHOW_UTF8(n, "WACS_DIAMOND",	"\342\227\206");
+    n = SHOW_UTF8(n, "WACS_PLMINUS",	"\302\261");
+    n = SHOW_UTF8(n, "WACS_PLUS",	"\342\224\274");
+    n = SHOW_UTF8(n, "WACS_GEQUAL",	"\342\211\245");
+    n = SHOW_UTF8(n, "WACS_NEQUAL",	"\342\211\240");
+    n = SHOW_UTF8(n, "WACS_LEQUAL",	"\342\211\244");
+
+    n = SHOW_UTF8(n, "WACS_STERLING",	"\302\243");
+    n = SHOW_UTF8(n, "WACS_PI",		"\317\200");
+    n = SHOW_UTF8(n, "WACS_S1",		"\342\216\272");
+    n = SHOW_UTF8(n, "WACS_S3",		"\342\216\273");
+    n = SHOW_UTF8(n, "WACS_S7",		"\342\216\274");
+    n = SHOW_UTF8(n, "WACS_S9",		"\342\216\275");
+    /* *INDENT-ON* */
+
+}
+
+/* display the wide-ACS character set */
+static void
+wide_acs_display(void)
+{
+    int c = 'a';
+    int digit = 0;
+    int repeat = 1;
+    int space = ' ';
+    chtype attr = A_NORMAL;
+    int fg = COLOR_BLACK;
+    int bg = COLOR_BLACK;
+    unsigned at_code = 0;
+    short pair = 0;
+    void (*last_show_wacs) (int, attr_t, short) = 0;
+
+    do {
+	switch (c) {
+	case CTRL('L'):
+	    Repaint();
+	    break;
+	case 'a':
+	    ToggleAcs(last_show_wacs, show_wacs_chars);
+	    break;
+	case 'x':
+	    ToggleAcs(last_show_wacs, show_wbox_chars);
+	    break;
+	case 'u':
+	    ToggleAcs(last_show_wacs, show_utf8_chars);
+	    break;
+	default:
+	    if (c < 256 && isdigit(c)) {
+		digit = (c - '0');
+		last_show_wacs = 0;
+	    } else if (c == '+') {
+		++digit;
+		last_show_wacs = 0;
+	    } else if (c == '-' && digit > 0) {
+		--digit;
+		last_show_wacs = 0;
+	    } else if (c == '>' && repeat < (COLS / 4)) {
+		++repeat;
+	    } else if (c == '<' && repeat > 1) {
+		--repeat;
+	    } else if (c == '_') {
+		space = (space == ' ') ? '_' : ' ';
+		last_show_wacs = 0;
+	    } else if (cycle_attr(c, &at_code, &attr)
+		       || cycle_colors(c, &fg, &bg, &pair)) {
+		if (last_show_wacs != 0)
+		    break;
+	    } else {
+		beep();
+		break;
+	    }
+	    break;
+	}
+	if (last_show_wacs != 0)
+	    last_show_wacs(repeat, attr, pair);
+	else
+	    show_upper_widechars(digit * 32 + 128, repeat, space, attr, pair);
+
+	mvprintw(LINES - 3, 0,
+		 "Select: a WACS, x box, u UTF-8, 0-9,+/- non-ASCII, </> repeat, ESC=quit");
+	if (use_colors) {
+	    mvprintw(LINES - 2, 0,
+		     "v/V, f/F, b/B cycle through video attributes (%s) and color %d/%d.",
+		     attrs_to_cycle[at_code].name,
+		     fg, bg);
+	} else {
+	    mvprintw(LINES - 2, 0,
+		     "v/V cycles through video attributes (%s).",
+		     attrs_to_cycle[at_code].name);
+	}
+	refresh();
+    } while (!isQuit(c = Getchar()));
+
+    Pause();
+    erase();
+    endwin();
+}
+
+#endif
+
+/*
+ * Graphic-rendition test (adapted from vttest)
+ */
+static void
+test_sgr_attributes(void)
+{
+    int pass;
+
+    for (pass = 0; pass < 2; pass++) {
+	chtype normal = ((pass == 0 ? A_NORMAL : A_REVERSE)) | BLANK;
+
+	/* Use non-default colors if possible to exercise bce a little */
+	if (use_colors) {
+	    init_pair(1, COLOR_WHITE, COLOR_BLUE);
+	    normal |= COLOR_PAIR(1);
+	}
+	bkgdset(normal);
+	erase();
+	mvprintw(1, 20, "Graphic rendition test pattern:");
+
+	mvprintw(4, 1, "vanilla");
+
+#define set_sgr(mask) bkgdset((normal^(mask)));
+	set_sgr(A_BOLD);
+	mvprintw(4, 40, "bold");
+
+	set_sgr(A_UNDERLINE);
+	mvprintw(6, 6, "underline");
+
+	set_sgr(A_BOLD | A_UNDERLINE);
+	mvprintw(6, 45, "bold underline");
+
+	set_sgr(A_BLINK);
+	mvprintw(8, 1, "blink");
+
+	set_sgr(A_BLINK | A_BOLD);
+	mvprintw(8, 40, "bold blink");
+
+	set_sgr(A_UNDERLINE | A_BLINK);
+	mvprintw(10, 6, "underline blink");
+
+	set_sgr(A_BOLD | A_UNDERLINE | A_BLINK);
+	mvprintw(10, 45, "bold underline blink");
+
+	set_sgr(A_REVERSE);
+	mvprintw(12, 1, "negative");
+
+	set_sgr(A_BOLD | A_REVERSE);
+	mvprintw(12, 40, "bold negative");
+
+	set_sgr(A_UNDERLINE | A_REVERSE);
+	mvprintw(14, 6, "underline negative");
+
+	set_sgr(A_BOLD | A_UNDERLINE | A_REVERSE);
+	mvprintw(14, 45, "bold underline negative");
+
+	set_sgr(A_BLINK | A_REVERSE);
+	mvprintw(16, 1, "blink negative");
+
+	set_sgr(A_BOLD | A_BLINK | A_REVERSE);
+	mvprintw(16, 40, "bold blink negative");
+
+	set_sgr(A_UNDERLINE | A_BLINK | A_REVERSE);
+	mvprintw(18, 6, "underline blink negative");
+
+	set_sgr(A_BOLD | A_UNDERLINE | A_BLINK | A_REVERSE);
+	mvprintw(18, 45, "bold underline blink negative");
+
+	bkgdset(normal);
+	mvprintw(LINES - 2, 1, "%s background. ", pass == 0 ? "Dark" :
+		 "Light");
+	clrtoeol();
+	Pause();
+    }
+
+    bkgdset(A_NORMAL | BLANK);
+    erase();
+    endwin();
+}
+
+/****************************************************************************
+ *
+ * Windows and scrolling tester.
+ *
+ ****************************************************************************/
+
+#define BOTLINES	4	/* number of line stolen from screen bottom */
+
+typedef struct {
+    int y, x;
+} pair;
+
+#define FRAME struct frame
+FRAME
+{
+    FRAME *next, *last;
+    bool do_scroll;
+    bool do_keypad;
+    WINDOW *wind;
+};
+
+#if defined(NCURSES_VERSION)
+#if (NCURSES_VERSION_PATCH < 20070331) && NCURSES_EXT_FUNCS
+#define is_keypad(win)   (win)->_use_keypad
+#define is_scrollok(win) (win)->_scroll
+#elif !defined(is_keypad)
+#define is_keypad(win)   FALSE
+#define is_scrollok(win) FALSE
+#endif
+#else
+#define is_keypad(win)   FALSE
+#define is_scrollok(win) FALSE
+#endif
+
+static WINDOW *
+frame_win(FRAME * curp)
+{
+    return (curp != 0) ? curp->wind : stdscr;
+}
+
+/* We need to know if these flags are actually set, so don't look in FRAME.
+ * These names are known to work with SVr4 curses as well as ncurses.  The
+ * _use_keypad name does not work with Solaris 8.
+ */
+static bool
+HaveKeypad(FRAME * curp)
+{
+    WINDOW *win = frame_win(curp);
+    (void) win;
+    return is_keypad(win);
+}
+
+static bool
+HaveScroll(FRAME * curp)
+{
+    WINDOW *win = frame_win(curp);
+    (void) win;
+    return is_scrollok(win);
+}
+
+static void
+newwin_legend(FRAME * curp)
+{
+    static const struct {
+	const char *msg;
+	int code;
+    } legend[] = {
+	{
+	    "^C = create window", 0
+	},
+	{
+	    "^N = next window", 0
+	},
+	{
+	    "^P = previous window", 0
+	},
+	{
+	    "^F = scroll forward", 0
+	},
+	{
+	    "^B = scroll backward", 0
+	},
+	{
+	    "^K = keypad(%s)", 1
+	},
+	{
+	    "^S = scrollok(%s)", 2
+	},
+	{
+	    "^W = save window to file", 0
+	},
+	{
+	    "^R = restore window", 0
+	},
+#if HAVE_WRESIZE
+	{
+	    "^X = resize", 0
+	},
+#endif
+	{
+	    "^Q%s = exit", 3
+	}
+    };
+    size_t n;
+    int x;
+    bool do_keypad = HaveKeypad(curp);
+    bool do_scroll = HaveScroll(curp);
+    char buf[BUFSIZ];
+
+    move(LINES - 4, 0);
+    for (n = 0; n < SIZEOF(legend); n++) {
+	switch (legend[n].code) {
+	default:
+	    strcpy(buf, legend[n].msg);
+	    break;
+	case 1:
+	    sprintf(buf, legend[n].msg, do_keypad ? "yes" : "no");
+	    break;
+	case 2:
+	    sprintf(buf, legend[n].msg, do_scroll ? "yes" : "no");
+	    break;
+	case 3:
+	    sprintf(buf, legend[n].msg, do_keypad ? "/ESC" : "");
+	    break;
+	}
+	x = getcurx(stdscr);
+	addstr((COLS < (x + 3 + (int) strlen(buf))) ? "\n" : (n ? ", " : ""));
+	addstr(buf);
+    }
+    clrtoeol();
+}
+
+static void
+transient(FRAME * curp, NCURSES_CONST char *msg)
+{
+    newwin_legend(curp);
+    if (msg) {
+	mvaddstr(LINES - 1, 0, msg);
+	refresh();
+	napms(1000);
+    }
+
+    move(LINES - 1, 0);
+    printw("%s characters are echoed, window should %sscroll.",
+	   HaveKeypad(curp) ? "Non-arrow" : "All other",
+	   HaveScroll(curp) ? "" : "not ");
+    clrtoeol();
+}
+
+static void
+newwin_report(FRAME * curp)
+/* report on the cursor's current position, then restore it */
+{
+    WINDOW *win = frame_win(curp);
+    int y, x;
+
+    if (win != stdscr)
+	transient(curp, (char *) 0);
+    getyx(win, y, x);
+    move(LINES - 1, COLS - 17);
+    printw("Y = %2d X = %2d", y, x);
+    if (win != stdscr)
+	refresh();
+    else
+	wmove(win, y, x);
+}
+
+static pair *
+selectcell(int uli, int ulj, int lri, int lrj)
+/* arrows keys move cursor, return location at current on non-arrow key */
+{
+    static pair res;		/* result cell */
+    int si = lri - uli + 1;	/* depth of the select area */
+    int sj = lrj - ulj + 1;	/* width of the select area */
+    int i = 0, j = 0;		/* offsets into the select area */
+
+    res.y = uli;
+    res.x = ulj;
+    for (;;) {
+	move(uli + i, ulj + j);
+	newwin_report((FRAME *) 0);
+
+	switch (Getchar()) {
+	case KEY_UP:
+	    i += si - 1;
+	    break;
+	case KEY_DOWN:
+	    i++;
+	    break;
+	case KEY_LEFT:
+	    j += sj - 1;
+	    break;
+	case KEY_RIGHT:
+	    j++;
+	    break;
+	case case_QUIT:
+	    return ((pair *) 0);
+#ifdef NCURSES_MOUSE_VERSION
+	case KEY_MOUSE:
+	    {
+		MEVENT event;
+
+		getmouse(&event);
+		if (event.y > uli && event.x > ulj) {
+		    i = event.y - uli;
+		    j = event.x - ulj;
+		} else {
+		    beep();
+		    break;
+		}
+	    }
+	    /* FALLTHRU */
+#endif
+	default:
+	    res.y = uli + i;
+	    res.x = ulj + j;
+	    return (&res);
+	}
+	i %= si;
+	j %= sj;
+    }
+}
+
+static void
+outerbox(pair ul, pair lr, bool onoff)
+/* draw or erase a box *outside* the given pair of corners */
+{
+    mvaddch(ul.y - 1, lr.x - 1, onoff ? ACS_ULCORNER : ' ');
+    mvaddch(ul.y - 1, lr.x + 1, onoff ? ACS_URCORNER : ' ');
+    mvaddch(lr.y + 1, lr.x + 1, onoff ? ACS_LRCORNER : ' ');
+    mvaddch(lr.y + 1, ul.x - 1, onoff ? ACS_LLCORNER : ' ');
+    move(ul.y - 1, ul.x);
+    hline(onoff ? ACS_HLINE : ' ', lr.x - ul.x + 1);
+    move(ul.y, ul.x - 1);
+    vline(onoff ? ACS_VLINE : ' ', lr.y - ul.y + 1);
+    move(lr.y + 1, ul.x);
+    hline(onoff ? ACS_HLINE : ' ', lr.x - ul.x + 1);
+    move(ul.y, lr.x + 1);
+    vline(onoff ? ACS_VLINE : ' ', lr.y - ul.y + 1);
+}
+
+static WINDOW *
+getwindow(void)
+/* Ask user for a window definition */
+{
+    WINDOW *rwindow;
+    pair ul, lr, *tmp;
+
+    move(0, 0);
+    clrtoeol();
+    addstr("Use arrows to move cursor, anything else to mark corner 1");
+    refresh();
+    if ((tmp = selectcell(2, 1, LINES - BOTLINES - 2, COLS - 2)) == (pair *) 0)
+	return ((WINDOW *) 0);
+    memcpy(&ul, tmp, sizeof(pair));
+    mvaddch(ul.y - 1, ul.x - 1, ACS_ULCORNER);
+    move(0, 0);
+    clrtoeol();
+    addstr("Use arrows to move cursor, anything else to mark corner 2");
+    refresh();
+    if ((tmp = selectcell(ul.y, ul.x, LINES - BOTLINES - 2, COLS - 2)) ==
+	(pair *) 0)
+	return ((WINDOW *) 0);
+    memcpy(&lr, tmp, sizeof(pair));
+
+    rwindow = subwin(stdscr, lr.y - ul.y + 1, lr.x - ul.x + 1, ul.y, ul.x);
+
+    outerbox(ul, lr, TRUE);
+    refresh();
+
+    wrefresh(rwindow);
+
+    move(0, 0);
+    clrtoeol();
+    return (rwindow);
+}
+
+static void
+newwin_move(FRAME * curp, int dy, int dx)
+{
+    WINDOW *win = frame_win(curp);
+    int cur_y, cur_x;
+    int max_y, max_x;
+
+    getyx(win, cur_y, cur_x);
+    getmaxyx(win, max_y, max_x);
+    if ((cur_x += dx) < 0)
+	cur_x = 0;
+    else if (cur_x >= max_x)
+	cur_x = max_x - 1;
+    if ((cur_y += dy) < 0)
+	cur_y = 0;
+    else if (cur_y >= max_y)
+	cur_y = max_y - 1;
+    wmove(win, cur_y, cur_x);
+}
+
+static FRAME *
+delete_framed(FRAME * fp, bool showit)
+{
+    FRAME *np = 0;
+
+    if (fp != 0) {
+	fp->last->next = fp->next;
+	fp->next->last = fp->last;
+
+	if (showit) {
+	    werase(fp->wind);
+	    wrefresh(fp->wind);
+	}
+	delwin(fp->wind);
+
+	np = (fp == fp->next) ? 0 : fp->next;
+	free(fp);
+    }
+    return np;
+}
+
+static void
+acs_and_scroll(void)
+/* Demonstrate windows */
+{
+    int c;
+    FRAME *current = (FRAME *) 0, *neww;
+    WINDOW *usescr = stdscr;
+#if HAVE_PUTWIN && HAVE_GETWIN
+    FILE *fp;
+#endif
+
+#define DUMPFILE	"screendump"
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(BUTTON1_CLICKED, (mmask_t *) 0);
+#endif
+    c = CTRL('C');
+    raw();
+    do {
+	transient((FRAME *) 0, (char *) 0);
+	switch (c) {
+	case CTRL('C'):
+	    if ((neww = typeCalloc(FRAME, 1)) == 0) {
+		goto breakout;
+	    }
+	    if ((neww->wind = getwindow()) == (WINDOW *) 0) {
+		free(neww);
+		goto breakout;
+	    }
+
+	    if (current == 0) {	/* First element,  */
+		neww->next = neww;	/*   so point it at itself */
+		neww->last = neww;
+	    } else {
+		neww->next = current->next;
+		neww->last = current;
+		neww->last->next = neww;
+		neww->next->last = neww;
+	    }
+	    current = neww;
+	    /* SVr4 curses sets the keypad on all newly-created windows to
+	     * false.  Someone reported that PDCurses makes new windows inherit
+	     * this flag.  Remove the following 'keypad()' call to test this
+	     */
+	    keypad(current->wind, TRUE);
+	    current->do_keypad = HaveKeypad(current);
+	    current->do_scroll = HaveScroll(current);
+	    break;
+
+	case CTRL('N'):	/* go to next window */
+	    if (current)
+		current = current->next;
+	    break;
+
+	case CTRL('P'):	/* go to previous window */
+	    if (current)
+		current = current->last;
+	    break;
+
+	case CTRL('F'):	/* scroll current window forward */
+	    if (current)
+		wscrl(frame_win(current), 1);
+	    break;
+
+	case CTRL('B'):	/* scroll current window backwards */
+	    if (current)
+		wscrl(frame_win(current), -1);
+	    break;
+
+	case CTRL('K'):	/* toggle keypad mode for current */
+	    if (current) {
+		current->do_keypad = !current->do_keypad;
+		keypad(current->wind, current->do_keypad);
+	    }
+	    break;
+
+	case CTRL('S'):
+	    if (current) {
+		current->do_scroll = !current->do_scroll;
+		scrollok(current->wind, current->do_scroll);
+	    }
+	    break;
+
+#if HAVE_PUTWIN && HAVE_GETWIN
+	case CTRL('W'):	/* save and delete window */
+	    if ((current != 0) && (current == current->next)) {
+		transient(current, "Will not save/delete ONLY window");
+		break;
+	    } else if ((fp = fopen(DUMPFILE, "w")) == (FILE *) 0) {
+		transient(current, "Can't open screen dump file");
+	    } else {
+		(void) putwin(frame_win(current), fp);
+		(void) fclose(fp);
+
+		current = delete_framed(current, TRUE);
+	    }
+	    break;
+
+	case CTRL('R'):	/* restore window */
+	    if ((fp = fopen(DUMPFILE, "r")) == (FILE *) 0) {
+		transient(current, "Can't open screen dump file");
+	    } else {
+		if ((neww = typeCalloc(FRAME, 1)) != 0) {
+
+		    neww->next = current ? current->next : 0;
+		    neww->last = current;
+		    neww->last->next = neww;
+		    neww->next->last = neww;
+
+		    neww->wind = getwin(fp);
+
+		    wrefresh(neww->wind);
+		}
+		(void) fclose(fp);
+	    }
+	    break;
+#endif
+
+#if HAVE_WRESIZE
+	case CTRL('X'):	/* resize window */
+	    if (current) {
+		pair *tmp, ul, lr;
+		int i, mx, my;
+
+		move(0, 0);
+		clrtoeol();
+		addstr("Use arrows to move cursor, anything else to mark new corner");
+		refresh();
+
+		getbegyx(current->wind, ul.y, ul.x);
+
+		tmp = selectcell(ul.y, ul.x, LINES - BOTLINES - 2, COLS - 2);
+		if (tmp == (pair *) 0) {
+		    beep();
+		    break;
+		}
+
+		getmaxyx(current->wind, lr.y, lr.x);
+		lr.y += (ul.y - 1);
+		lr.x += (ul.x - 1);
+		outerbox(ul, lr, FALSE);
+		wnoutrefresh(stdscr);
+
+		/* strictly cosmetic hack for the test */
+		getmaxyx(current->wind, my, mx);
+		if (my > tmp->y - ul.y) {
+		    getyx(current->wind, lr.y, lr.x);
+		    wmove(current->wind, tmp->y - ul.y + 1, 0);
+		    wclrtobot(current->wind);
+		    wmove(current->wind, lr.y, lr.x);
+		}
+		if (mx > tmp->x - ul.x)
+		    for (i = 0; i < my; i++) {
+			wmove(current->wind, i, tmp->x - ul.x + 1);
+			wclrtoeol(current->wind);
+		    }
+		wnoutrefresh(current->wind);
+
+		memcpy(&lr, tmp, sizeof(pair));
+		(void) wresize(current->wind, lr.y - ul.y + 0, lr.x - ul.x + 0);
+
+		getbegyx(current->wind, ul.y, ul.x);
+		getmaxyx(current->wind, lr.y, lr.x);
+		lr.y += (ul.y - 1);
+		lr.x += (ul.x - 1);
+		outerbox(ul, lr, TRUE);
+		wnoutrefresh(stdscr);
+
+		wnoutrefresh(current->wind);
+		move(0, 0);
+		clrtoeol();
+		doupdate();
+	    }
+	    break;
+#endif /* HAVE_WRESIZE */
+
+	case KEY_F(10):	/* undocumented --- use this to test area clears */
+	    selectcell(0, 0, LINES - 1, COLS - 1);
+	    clrtobot();
+	    refresh();
+	    break;
+
+	case KEY_UP:
+	    newwin_move(current, -1, 0);
+	    break;
+	case KEY_DOWN:
+	    newwin_move(current, 1, 0);
+	    break;
+	case KEY_LEFT:
+	    newwin_move(current, 0, -1);
+	    break;
+	case KEY_RIGHT:
+	    newwin_move(current, 0, 1);
+	    break;
+
+	case KEY_BACKSPACE:
+	    /* FALLTHROUGH */
+	case KEY_DC:
+	    {
+		int y, x;
+		getyx(frame_win(current), y, x);
+		if (--x < 0) {
+		    if (--y < 0)
+			break;
+		    x = getmaxx(frame_win(current)) - 1;
+		}
+		mvwdelch(frame_win(current), y, x);
+	    }
+	    break;
+
+	case '\r':
+	    c = '\n';
+	    /* FALLTHROUGH */
+
+	default:
+	    if (current)
+		waddch(current->wind, (chtype) c);
+	    else
+		beep();
+	    break;
+	}
+	newwin_report(current);
+	usescr = frame_win(current);
+	wrefresh(usescr);
+    } while
+	(!isQuit(c = wGetchar(usescr))
+	 && (c != ERR));
+
+  breakout:
+    while (current != 0)
+	current = delete_framed(current, FALSE);
+
+    scrollok(stdscr, TRUE);	/* reset to driver's default */
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(0, (mmask_t *) 0);
+#endif
+    noraw();
+    erase();
+    endwin();
+}
+
+/****************************************************************************
+ *
+ * Panels tester
+ *
+ ****************************************************************************/
+
+#if USE_LIBPANEL
+static int nap_msec = 1;
+
+static NCURSES_CONST char *mod[] =
+{
+    "test ",
+    "TEST ",
+    "(**) ",
+    "*()* ",
+    "<--> ",
+    "LAST "
+};
+
+/*+-------------------------------------------------------------------------
+	wait_a_while(msec)
+--------------------------------------------------------------------------*/
+static void
+wait_a_while(int msec GCC_UNUSED)
+{
+#if HAVE_NAPMS
+    if (nap_msec == 1)
+	wGetchar(stdscr);
+    else
+	napms(nap_msec);
+#else
+    if (nap_msec == 1)
+	wGetchar(stdscr);
+    else if (msec > 1000)
+	sleep((unsigned) msec / 1000);
+    else
+	sleep(1);
+#endif
+}				/* end of wait_a_while */
+
+/*+-------------------------------------------------------------------------
+	saywhat(text)
+--------------------------------------------------------------------------*/
+static void
+saywhat(NCURSES_CONST char *text)
+{
+    wmove(stdscr, LINES - 1, 0);
+    wclrtoeol(stdscr);
+    if (text != 0 && *text != '\0') {
+	waddstr(stdscr, text);
+	waddstr(stdscr, "; ");
+    }
+    waddstr(stdscr, "press any key to continue");
+}				/* end of saywhat */
+
+/*+-------------------------------------------------------------------------
+	mkpanel(rows,cols,tly,tlx) - alloc a win and panel and associate them
+--------------------------------------------------------------------------*/
+static PANEL *
+mkpanel(short color, int rows, int cols, int tly, int tlx)
+{
+    WINDOW *win;
+    PANEL *pan = 0;
+
+    if ((win = newwin(rows, cols, tly, tlx)) != 0) {
+	if ((pan = new_panel(win)) == 0) {
+	    delwin(win);
+	} else if (use_colors) {
+	    short fg = (short) ((color == COLOR_BLUE) ? COLOR_WHITE : COLOR_BLACK);
+	    short bg = color;
+
+	    init_pair(color, fg, bg);
+	    wbkgdset(win, (chtype) (COLOR_PAIR(color) | ' '));
+	} else {
+	    wbkgdset(win, A_BOLD | ' ');
+	}
+    }
+    return pan;
+}				/* end of mkpanel */
+
+/*+-------------------------------------------------------------------------
+	rmpanel(pan)
+--------------------------------------------------------------------------*/
+static void
+rmpanel(PANEL * pan)
+{
+    WINDOW *win = panel_window(pan);
+    del_panel(pan);
+    delwin(win);
+}				/* end of rmpanel */
+
+/*+-------------------------------------------------------------------------
+	pflush()
+--------------------------------------------------------------------------*/
+static void
+pflush(void)
+{
+    update_panels();
+    doupdate();
+}				/* end of pflush */
+
+/*+-------------------------------------------------------------------------
+	fill_panel(win)
+--------------------------------------------------------------------------*/
+static void
+init_panel(void)
+{
+    register int y, x;
+
+    for (y = 0; y < LINES - 1; y++) {
+	for (x = 0; x < COLS; x++)
+	    wprintw(stdscr, "%d", (y + x) % 10);
+    }
+}
+
+static void
+fill_panel(PANEL * pan)
+{
+    WINDOW *win = panel_window(pan);
+    const char *userptr = (const char *) panel_userptr(pan);
+    int num = (userptr && *userptr) ? userptr[1] : '?';
+    int y, x;
+
+    wmove(win, 1, 1);
+    wprintw(win, "-pan%c-", num);
+    wclrtoeol(win);
+    box(win, 0, 0);
+    for (y = 2; y < getmaxy(win) - 1; y++) {
+	for (x = 1; x < getmaxx(win) - 1; x++) {
+	    wmove(win, y, x);
+	    waddch(win, UChar(num));
+	}
+    }
+}
+
+#if USE_WIDEC_SUPPORT
+static void
+init_wide_panel(void)
+{
+    int digit;
+    cchar_t temp[10];
+
+    for (digit = 0; digit < 10; ++digit)
+	make_fullwidth_digit(&temp[digit], digit);
+
+    do {
+	int y, x;
+	getyx(stdscr, y, x);
+	digit = (y + x / 2) % 10;
+    } while (add_wch(&temp[digit]) != ERR);
+}
+
+static void
+fill_wide_panel(PANEL * pan)
+{
+    WINDOW *win = panel_window(pan);
+    const char *userptr = (const char *) panel_userptr(pan);
+    int num = (userptr && *userptr) ? userptr[1] : '?';
+    int y, x;
+
+    wmove(win, 1, 1);
+    wprintw(win, "-pan%c-", num);
+    wclrtoeol(win);
+    box(win, 0, 0);
+    for (y = 2; y < getmaxy(win) - 1; y++) {
+	for (x = 1; x < getmaxx(win) - 1; x++) {
+	    wmove(win, y, x);
+	    waddch(win, UChar(num));
+	}
+    }
+}
+#endif
+
+#define MAX_PANELS 5
+
+static void
+canned_panel(PANEL * px[MAX_PANELS + 1], NCURSES_CONST char *cmd)
+{
+    int which = cmd[1] - '0';
+
+    saywhat(cmd);
+    switch (*cmd) {
+    case 'h':
+	hide_panel(px[which]);
+	break;
+    case 's':
+	show_panel(px[which]);
+	break;
+    case 't':
+	top_panel(px[which]);
+	break;
+    case 'b':
+	bottom_panel(px[which]);
+	break;
+    case 'd':
+	rmpanel(px[which]);
+	break;
+    }
+    pflush();
+    wait_a_while(nap_msec);
+}
+
+static void
+demo_panels(void (*InitPanel) (void), void (*FillPanel) (PANEL *))
+{
+    int count;
+    int itmp;
+    PANEL *px[MAX_PANELS + 1];
+
+    scrollok(stdscr, FALSE);	/* we don't want stdscr to scroll! */
+    refresh();
+
+    InitPanel();
+    for (count = 0; count < 5; count++) {
+	px[1] = mkpanel(COLOR_RED,
+			LINES / 2 - 2,
+			COLS / 8 + 1,
+			0,
+			0);
+	set_panel_userptr(px[1], (NCURSES_CONST void *) "p1");
+
+	px[2] = mkpanel(COLOR_GREEN,
+			LINES / 2 + 1,
+			COLS / 7,
+			LINES / 4,
+			COLS / 10);
+	set_panel_userptr(px[2], (NCURSES_CONST void *) "p2");
+
+	px[3] = mkpanel(COLOR_YELLOW,
+			LINES / 4,
+			COLS / 10,
+			LINES / 2,
+			COLS / 9);
+	set_panel_userptr(px[3], (NCURSES_CONST void *) "p3");
+
+	px[4] = mkpanel(COLOR_BLUE,
+			LINES / 2 - 2,
+			COLS / 8,
+			LINES / 2 - 2,
+			COLS / 3);
+	set_panel_userptr(px[4], (NCURSES_CONST void *) "p4");
+
+	px[5] = mkpanel(COLOR_MAGENTA,
+			LINES / 2 - 2,
+			COLS / 8,
+			LINES / 2,
+			COLS / 2 - 2);
+	set_panel_userptr(px[5], (NCURSES_CONST void *) "p5");
+
+	FillPanel(px[1]);
+	FillPanel(px[2]);
+	FillPanel(px[3]);
+	FillPanel(px[4]);
+	FillPanel(px[5]);
+
+	hide_panel(px[4]);
+	hide_panel(px[5]);
+	pflush();
+	saywhat("");
+	wait_a_while(nap_msec);
+
+	saywhat("h3 s1 s2 s4 s5");
+	move_panel(px[1], 0, 0);
+	hide_panel(px[3]);
+	show_panel(px[1]);
+	show_panel(px[2]);
+	show_panel(px[4]);
+	show_panel(px[5]);
+	pflush();
+	wait_a_while(nap_msec);
+
+	canned_panel(px, "s1");
+	canned_panel(px, "s2");
+
+	saywhat("m2");
+	move_panel(px[2], LINES / 3 + 1, COLS / 8);
+	pflush();
+	wait_a_while(nap_msec);
+
+	canned_panel(px, "s3");
+
+	saywhat("m3");
+	move_panel(px[3], LINES / 4 + 1, COLS / 15);
+	pflush();
+	wait_a_while(nap_msec);
+
+	canned_panel(px, "b3");
+	canned_panel(px, "s4");
+	canned_panel(px, "s5");
+	canned_panel(px, "t3");
+	canned_panel(px, "t1");
+	canned_panel(px, "t2");
+	canned_panel(px, "t3");
+	canned_panel(px, "t4");
+
+	for (itmp = 0; itmp < 6; itmp++) {
+	    WINDOW *w4 = panel_window(px[4]);
+	    WINDOW *w5 = panel_window(px[5]);
+
+	    saywhat("m4");
+	    wmove(w4, LINES / 8, 1);
+	    waddstr(w4, mod[itmp]);
+	    move_panel(px[4], LINES / 6, itmp * (COLS / 8));
+	    wmove(w5, LINES / 6, 1);
+	    waddstr(w5, mod[itmp]);
+	    pflush();
+	    wait_a_while(nap_msec);
+
+	    saywhat("m5");
+	    wmove(w4, LINES / 6, 1);
+	    waddstr(w4, mod[itmp]);
+	    move_panel(px[5], LINES / 3 - 1, (itmp * 10) + 6);
+	    wmove(w5, LINES / 8, 1);
+	    waddstr(w5, mod[itmp]);
+	    pflush();
+	    wait_a_while(nap_msec);
+	}
+
+	saywhat("m4");
+	move_panel(px[4], LINES / 6, itmp * (COLS / 8));
+	pflush();
+	wait_a_while(nap_msec);
+
+	canned_panel(px, "t5");
+	canned_panel(px, "t2");
+	canned_panel(px, "t1");
+	canned_panel(px, "d2");
+	canned_panel(px, "h3");
+	canned_panel(px, "d1");
+	canned_panel(px, "d4");
+	canned_panel(px, "d5");
+	canned_panel(px, "d3");
+
+	wait_a_while(nap_msec);
+	if (nap_msec == 1)
+	    break;
+	nap_msec = 100L;
+    }
+
+    erase();
+    endwin();
+}
+#endif /* USE_LIBPANEL */
+
+/****************************************************************************
+ *
+ * Pad tester
+ *
+ ****************************************************************************/
+
+#define GRIDSIZE	3
+
+static bool pending_pan = FALSE;
+static bool show_panner_legend = TRUE;
+
+static int
+panner_legend(int line)
+{
+    static const char *const legend[] =
+    {
+	"Use arrow keys (or U,D,L,R) to pan, ESC to quit, ! to shell-out.",
+	"Use +,- (or j,k) to grow/shrink the panner vertically.",
+	"Use <,> (or h,l) to grow/shrink the panner horizontally.",
+	"Number repeats.  Toggle legend:? filler:a timer:t scrollmark:s."
+    };
+    int n = ((int) SIZEOF(legend) - (LINES - line));
+    if (line < LINES && (n >= 0)) {
+	move(line, 0);
+	if (show_panner_legend)
+	    printw("%s", legend[n]);
+	clrtoeol();
+	return show_panner_legend;
+    }
+    return FALSE;
+}
+
+static void
+panner_h_cleanup(int from_y, int from_x, int to_x)
+{
+    if (!panner_legend(from_y))
+	do_h_line(from_y, from_x, ' ', to_x);
+}
+
+static void
+panner_v_cleanup(int from_y, int from_x, int to_y)
+{
+    if (!panner_legend(from_y))
+	do_v_line(from_y, from_x, ' ', to_y);
+}
+
+static void
+fill_pad(WINDOW *panpad, bool pan_lines)
+{
+    int y, x;
+    unsigned gridcount = 0;
+
+    wmove(panpad, 0, 0);
+    for (y = 0; y < getmaxy(panpad); y++) {
+	for (x = 0; x < getmaxx(panpad); x++) {
+	    if (y % GRIDSIZE == 0 && x % GRIDSIZE == 0) {
+		if (y == 0 && x == 0)
+		    waddch(panpad, pan_lines ? ACS_ULCORNER : '+');
+		else if (y == 0)
+		    waddch(panpad, pan_lines ? ACS_TTEE : '+');
+		else if (y == 0 || x == 0)
+		    waddch(panpad, pan_lines ? ACS_LTEE : '+');
+		else
+		    waddch(panpad, (chtype) ((pan_lines ? 'a' : 'A') +
+					     (int) (gridcount++ % 26)));
+	    } else if (y % GRIDSIZE == 0)
+		waddch(panpad, pan_lines ? ACS_HLINE : '-');
+	    else if (x % GRIDSIZE == 0)
+		waddch(panpad, pan_lines ? ACS_VLINE : '|');
+	    else
+		waddch(panpad, ' ');
+	}
+    }
+}
+
+static void
+panner(WINDOW *pad,
+       int top_x, int top_y, int porty, int portx,
+       int (*pgetc) (WINDOW *))
+{
+#if HAVE_GETTIMEOFDAY
+    struct timeval before, after;
+    bool timing = TRUE;
+#endif
+    bool pan_lines = FALSE;
+    bool scrollers = TRUE;
+    int basex = 0;
+    int basey = 0;
+    int pxmax, pymax, lowend, highend, c;
+
+    getmaxyx(pad, pymax, pxmax);
+    scrollok(stdscr, FALSE);	/* we don't want stdscr to scroll! */
+
+    c = KEY_REFRESH;
+    do {
+#ifdef NCURSES_VERSION
+	/*
+	 * During shell-out, the user may have resized the window.  Adjust
+	 * the port size of the pad to accommodate this.  Ncurses automatically
+	 * resizes all of the normal windows to fit on the new screen.
+	 */
+	if (top_x > COLS)
+	    top_x = COLS;
+	if (portx > COLS)
+	    portx = COLS;
+	if (top_y > LINES)
+	    top_y = LINES;
+	if (porty > LINES)
+	    porty = LINES;
+#endif
+	switch (c) {
+	case KEY_REFRESH:
+	    erase();
+
+	    /* FALLTHRU */
+	case '?':
+	    if (c == '?')
+		show_panner_legend = !show_panner_legend;
+	    panner_legend(LINES - 4);
+	    panner_legend(LINES - 3);
+	    panner_legend(LINES - 2);
+	    panner_legend(LINES - 1);
+	    break;
+	case 'a':
+	    pan_lines = !pan_lines;
+	    fill_pad(pad, pan_lines);
+	    pending_pan = FALSE;
+	    break;
+
+#if HAVE_GETTIMEOFDAY
+	case 't':
+	    timing = !timing;
+	    if (!timing)
+		panner_legend(LINES - 1);
+	    break;
+#endif
+	case 's':
+	    scrollers = !scrollers;
+	    break;
+
+	    /* Move the top-left corner of the pad, keeping the bottom-right
+	     * corner fixed.
+	     */
+	case 'h':		/* increase-columns: move left edge to left */
+	    if (top_x <= 0)
+		beep();
+	    else {
+		panner_v_cleanup(top_y, top_x, porty);
+		top_x--;
+	    }
+	    break;
+
+	case 'j':		/* decrease-lines: move top-edge down */
+	    if (top_y >= porty)
+		beep();
+	    else {
+		panner_h_cleanup(top_y - 1, top_x - (top_x > 0), portx);
+		top_y++;
+	    }
+	    break;
+
+	case 'k':		/* increase-lines: move top-edge up */
+	    if (top_y <= 0)
+		beep();
+	    else {
+		top_y--;
+		panner_h_cleanup(top_y, top_x, portx);
+	    }
+	    break;
+
+	case 'l':		/* decrease-columns: move left-edge to right */
+	    if (top_x >= portx)
+		beep();
+	    else {
+		panner_v_cleanup(top_y - (top_y > 0), top_x - 1, porty);
+		top_x++;
+	    }
+	    break;
+
+	    /* Move the bottom-right corner of the pad, keeping the top-left
+	     * corner fixed.
+	     */
+	case KEY_IC:		/* increase-columns: move right-edge to right */
+	    if (portx >= pxmax || portx >= COLS)
+		beep();
+	    else {
+		panner_v_cleanup(top_y - (top_y > 0), portx - 1, porty);
+		++portx;
+	    }
+	    break;
+
+	case KEY_IL:		/* increase-lines: move bottom-edge down */
+	    if (porty >= pymax || porty >= LINES)
+		beep();
+	    else {
+		panner_h_cleanup(porty - 1, top_x - (top_x > 0), portx);
+		++porty;
+	    }
+	    break;
+
+	case KEY_DC:		/* decrease-columns: move bottom edge up */
+	    if (portx <= top_x)
+		beep();
+	    else {
+		portx--;
+		panner_v_cleanup(top_y - (top_y > 0), portx, porty);
+	    }
+	    break;
+
+	case KEY_DL:		/* decrease-lines */
+	    if (porty <= top_y)
+		beep();
+	    else {
+		porty--;
+		panner_h_cleanup(porty, top_x - (top_x > 0), portx);
+	    }
+	    break;
+
+	case KEY_LEFT:		/* pan leftwards */
+	    if (basex > 0)
+		basex--;
+	    else
+		beep();
+	    break;
+
+	case KEY_RIGHT:	/* pan rightwards */
+	    if (basex + portx - (pymax > porty) < pxmax)
+		basex++;
+	    else
+		beep();
+	    break;
+
+	case KEY_UP:		/* pan upwards */
+	    if (basey > 0)
+		basey--;
+	    else
+		beep();
+	    break;
+
+	case KEY_DOWN:		/* pan downwards */
+	    if (basey + porty - (pxmax > portx) < pymax)
+		basey++;
+	    else
+		beep();
+	    break;
+
+	case 'H':
+	case KEY_HOME:
+	case KEY_FIND:
+	    basey = 0;
+	    break;
+
+	case 'E':
+	case KEY_END:
+	case KEY_SELECT:
+	    basey = pymax - porty;
+	    if (basey < 0)
+		basey = 0;
+	    break;
+
+	default:
+	    beep();
+	    break;
+	}
+
+	mvaddch(top_y - 1, top_x - 1, ACS_ULCORNER);
+	do_v_line(top_y, top_x - 1, ACS_VLINE, porty);
+	do_h_line(top_y - 1, top_x, ACS_HLINE, portx);
+
+	if (scrollers && (pxmax > portx - 1)) {
+	    int length = (portx - top_x - 1);
+	    float ratio = ((float) length) / ((float) pxmax);
+
+	    lowend = (int) ((float) top_x + ((float) basex * ratio));
+	    highend = (int) ((float) top_x + ((float) (basex + length) * ratio));
+
+	    do_h_line(porty - 1, top_x, ACS_HLINE, lowend);
+	    if (highend < portx) {
+		attron(A_REVERSE);
+		do_h_line(porty - 1, lowend, ' ', highend + 1);
+		attroff(A_REVERSE);
+		do_h_line(porty - 1, highend + 1, ACS_HLINE, portx);
+	    }
+	} else
+	    do_h_line(porty - 1, top_x, ACS_HLINE, portx);
+
+	if (scrollers && (pymax > porty - 1)) {
+	    int length = (porty - top_y - 1);
+	    float ratio = ((float) length) / ((float) pymax);
+
+	    lowend = (int) ((float) top_y + ((float) basey * ratio));
+	    highend = (int) ((float) top_y + ((float) (basey + length) * ratio));
+
+	    do_v_line(top_y, portx - 1, ACS_VLINE, lowend);
+	    if (highend < porty) {
+		attron(A_REVERSE);
+		do_v_line(lowend, portx - 1, ' ', highend + 1);
+		attroff(A_REVERSE);
+		do_v_line(highend + 1, portx - 1, ACS_VLINE, porty);
+	    }
+	} else
+	    do_v_line(top_y, portx - 1, ACS_VLINE, porty);
+
+	mvaddch(top_y - 1, portx - 1, ACS_URCORNER);
+	mvaddch(porty - 1, top_x - 1, ACS_LLCORNER);
+	mvaddch(porty - 1, portx - 1, ACS_LRCORNER);
+
+	if (!pending_pan) {
+#if HAVE_GETTIMEOFDAY
+	    gettimeofday(&before, 0);
+#endif
+	    wnoutrefresh(stdscr);
+
+	    pnoutrefresh(pad,
+			 basey, basex,
+			 top_y, top_x,
+			 porty - (pxmax > portx) - 1,
+			 portx - (pymax > porty) - 1);
+
+	    doupdate();
+#if HAVE_GETTIMEOFDAY
+	    if (timing) {
+		double elapsed;
+		gettimeofday(&after, 0);
+		elapsed = (after.tv_sec + after.tv_usec / 1.0e6)
+		    - (before.tv_sec + before.tv_usec / 1.0e6);
+		move(LINES - 1, COLS - 12);
+		printw("Secs: %2.03f", elapsed);
+		refresh();
+	    }
+#endif
+	}
+
+    } while
+	((c = pgetc(pad)) != KEY_EXIT);
+
+    scrollok(stdscr, TRUE);	/* reset to driver's default */
+}
+
+static int
+padgetch(WINDOW *win)
+{
+    static int count;
+    static int last;
+    int c;
+
+    if ((pending_pan = (count > 0)) != FALSE) {
+	count--;
+	pending_pan = (count != 0);
+    } else {
+	for (;;) {
+	    switch (c = wGetchar(win)) {
+	    case '!':
+		ShellOut(FALSE);
+		/* FALLTHRU */
+	    case CTRL('r'):
+		endwin();
+		refresh();
+		c = KEY_REFRESH;
+		break;
+	    case CTRL('l'):
+		c = KEY_REFRESH;
+		break;
+	    case 'U':
+		c = KEY_UP;
+		break;
+	    case 'D':
+		c = KEY_DOWN;
+		break;
+	    case 'R':
+		c = KEY_RIGHT;
+		break;
+	    case 'L':
+		c = KEY_LEFT;
+		break;
+	    case '+':
+		c = KEY_IL;
+		break;
+	    case '-':
+		c = KEY_DL;
+		break;
+	    case '>':
+		c = KEY_IC;
+		break;
+	    case '<':
+		c = KEY_DC;
+		break;
+	    case ERR:		/* FALLTHRU */
+	    case case_QUIT:
+		count = 0;
+		c = KEY_EXIT;
+		break;
+	    default:
+		if (c >= '0' && c <= '9') {
+		    count = count * 10 + (c - '0');
+		    continue;
+		}
+		break;
+	    }
+	    last = c;
+	    break;
+	}
+	if (count > 0)
+	    count--;
+    }
+    return (last);
+}
+
+#define PAD_HIGH 200
+#define PAD_WIDE 200
+
+static void
+demo_pad(void)
+/* Demonstrate pads. */
+{
+    WINDOW *panpad = newpad(PAD_HIGH, PAD_WIDE);
+
+    if (panpad == 0) {
+	Cannot("cannot create requested pad");
+	return;
+    }
+
+    fill_pad(panpad, FALSE);
+
+    panner_legend(LINES - 4);
+    panner_legend(LINES - 3);
+    panner_legend(LINES - 2);
+    panner_legend(LINES - 1);
+
+    keypad(panpad, TRUE);
+
+    /* Make the pad (initially) narrow enough that a trace file won't wrap.
+     * We'll still be able to widen it during a test, since that's required
+     * for testing boundaries.
+     */
+    panner(panpad, 2, 2, LINES - 5, COLS - 15, padgetch);
+
+    delwin(panpad);
+    endwin();
+    erase();
+}
+
+/****************************************************************************
+ *
+ * Tests from John Burnell's PDCurses tester
+ *
+ ****************************************************************************/
+
+static void
+Continue(WINDOW *win)
+{
+    noecho();
+    wmove(win, 10, 1);
+    mvwaddstr(win, 10, 1, " Press any key to continue");
+    wrefresh(win);
+    wGetchar(win);
+}
+
+static void
+flushinp_test(WINDOW *win)
+/* Input test, adapted from John Burnell's PDCurses tester */
+{
+    int w, h, bx, by, sw, sh, i;
+
+    WINDOW *subWin;
+    wclear(win);
+
+    getmaxyx(win, h, w);
+    getbegyx(win, by, bx);
+    sw = w / 3;
+    sh = h / 3;
+    if ((subWin = subwin(win, sh, sw, by + h - sh - 2, bx + w - sw - 2)) == 0)
+	return;
+
+#ifdef A_COLOR
+    if (use_colors) {
+	init_pair(2, COLOR_CYAN, COLOR_BLUE);
+	wbkgd(subWin, COLOR_PAIR(2) | ' ');
+    }
+#endif
+    wattrset(subWin, A_BOLD);
+    box(subWin, ACS_VLINE, ACS_HLINE);
+    mvwaddstr(subWin, 2, 1, "This is a subwindow");
+    wrefresh(win);
+
+    /*
+     * This used to set 'nocbreak()'.  However, Alexander Lukyanov says that
+     * it only happened to "work" on SVr4 because that implementation does not
+     * emulate nocbreak+noecho mode, whereas ncurses does.  To get the desired
+     * test behavior, we're using 'cbreak()', which will allow a single
+     * character to return without needing a newline. - T.Dickey 1997/10/11.
+     */
+    cbreak();
+    mvwaddstr(win, 0, 1, "This is a test of the flushinp() call.");
+
+    mvwaddstr(win, 2, 1, "Type random keys for 5 seconds.");
+    mvwaddstr(win, 3, 1,
+	      "These should be discarded (not echoed) after the subwindow goes away.");
+    wrefresh(win);
+
+    for (i = 0; i < 5; i++) {
+	mvwprintw(subWin, 1, 1, "Time = %d", i);
+	wrefresh(subWin);
+	napms(1000);
+	flushinp();
+    }
+
+    delwin(subWin);
+    werase(win);
+    flash();
+    wrefresh(win);
+    napms(1000);
+
+    mvwaddstr(win, 2, 1,
+	      "If you were still typing when the window timer expired,");
+    mvwaddstr(win, 3, 1,
+	      "or else you typed nothing at all while it was running,");
+    mvwaddstr(win, 4, 1,
+	      "test was invalid.  You'll see garbage or nothing at all. ");
+    mvwaddstr(win, 6, 1, "Press a key");
+    wmove(win, 9, 10);
+    wrefresh(win);
+    echo();
+    wGetchar(win);
+    flushinp();
+    mvwaddstr(win, 12, 0,
+	      "If you see any key other than what you typed, flushinp() is broken.");
+    Continue(win);
+
+    wmove(win, 9, 10);
+    wdelch(win);
+    wrefresh(win);
+    wmove(win, 12, 0);
+    clrtoeol();
+    waddstr(win,
+	    "What you typed should now have been deleted; if not, wdelch() failed.");
+    Continue(win);
+
+    cbreak();
+}
+
+/****************************************************************************
+ *
+ * Menu test
+ *
+ ****************************************************************************/
+
+#if USE_LIBMENU
+
+#define MENU_Y	8
+#define MENU_X	8
+
+static int
+menu_virtualize(int c)
+{
+    if (c == '\n' || c == KEY_EXIT)
+	return (MAX_COMMAND + 1);
+    else if (c == 'u')
+	return (REQ_SCR_ULINE);
+    else if (c == 'd')
+	return (REQ_SCR_DLINE);
+    else if (c == 'b' || c == KEY_NPAGE)
+	return (REQ_SCR_UPAGE);
+    else if (c == 'f' || c == KEY_PPAGE)
+	return (REQ_SCR_DPAGE);
+    else if (c == 'n' || c == KEY_DOWN)
+	return (REQ_NEXT_ITEM);
+    else if (c == 'p' || c == KEY_UP)
+	return (REQ_PREV_ITEM);
+    else if (c == ' ')
+	return (REQ_TOGGLE_ITEM);
+    else {
+	if (c != KEY_MOUSE)
+	    beep();
+	return (c);
+    }
+}
+
+static CONST_MENUS char *animals[] =
+{
+    "Lions",
+    "Tigers",
+    "Bears",
+    "(Oh my!)",
+    "Newts",
+    "Platypi",
+    "Lemurs",
+    "(Oh really?!)",
+    "Leopards",
+    "Panthers",
+    "Pumas",
+    "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
+    "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs, Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
+    (char *) 0
+};
+
+static void
+menu_test(void)
+{
+    MENU *m;
+    ITEM *items[SIZEOF(animals)];
+    ITEM **ip = items;
+    CONST_MENUS char **ap;
+    int mrows, mcols, c;
+    WINDOW *menuwin;
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
+#endif
+    mvaddstr(0, 0, "This is the menu test:");
+    mvaddstr(2, 0, "  Use up and down arrow to move the select bar.");
+    mvaddstr(3, 0, "  'n' and 'p' act like arrows.");
+    mvaddstr(4, 0,
+	     "  'b' and 'f' scroll up/down (page), 'u' and 'd' (line).");
+    mvaddstr(5, 0, "  Press return to exit.");
+    refresh();
+
+    for (ap = animals; *ap; ap++) {
+	if ((*ip = new_item(*ap, "")) != 0)
+	    ++ip;
+    }
+    *ip = (ITEM *) 0;
+
+    m = new_menu(items);
+
+    set_menu_format(m, (SIZEOF(animals) + 1) / 2, 1);
+    scale_menu(m, &mrows, &mcols);
+
+    menuwin = newwin(mrows + 2, mcols + 2, MENU_Y, MENU_X);
+    set_menu_win(m, menuwin);
+    keypad(menuwin, TRUE);
+    box(menuwin, 0, 0);
+
+    set_menu_sub(m, derwin(menuwin, mrows, mcols, 1, 1));
+
+    post_menu(m);
+
+    while ((c = menu_driver(m, menu_virtualize(wGetchar(menuwin)))) != E_UNKNOWN_COMMAND) {
+	if (c == E_NOT_POSTED)
+	    break;
+	if (c == E_REQUEST_DENIED)
+	    beep();
+	continue;
+    }
+
+    (void) mvprintw(LINES - 2, 0,
+		    "You chose: %s\n", item_name(current_item(m)));
+    (void) addstr("Press any key to continue...");
+    wGetchar(stdscr);
+
+    unpost_menu(m);
+    delwin(menuwin);
+
+    free_menu(m);
+    for (ip = items; *ip; ip++)
+	free_item(*ip);
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(0, (mmask_t *) 0);
+#endif
+}
+
+#ifdef TRACE
+#define T_TBL(name) { #name, name }
+static struct {
+    const char *name;
+    unsigned mask;
+} t_tbl[] = {
+
+    T_TBL(TRACE_DISABLE),
+	T_TBL(TRACE_TIMES),
+	T_TBL(TRACE_TPUTS),
+	T_TBL(TRACE_UPDATE),
+	T_TBL(TRACE_MOVE),
+	T_TBL(TRACE_CHARPUT),
+	T_TBL(TRACE_ORDINARY),
+	T_TBL(TRACE_CALLS),
+	T_TBL(TRACE_VIRTPUT),
+	T_TBL(TRACE_IEVENT),
+	T_TBL(TRACE_BITS),
+	T_TBL(TRACE_ICALLS),
+	T_TBL(TRACE_CCALLS),
+	T_TBL(TRACE_DATABASE),
+	T_TBL(TRACE_ATTRS),
+	T_TBL(TRACE_MAXIMUM),
+    {
+	(char *) 0, 0
+    }
+};
+
+static char *
+tracetrace(unsigned tlevel)
+{
+    static char *buf;
+    int n;
+
+    if (buf == 0) {
+	size_t need = 12;
+	for (n = 0; t_tbl[n].name != 0; n++)
+	    need += strlen(t_tbl[n].name) + 2;
+	buf = typeMalloc(char, need);
+    }
+    sprintf(buf, "0x%02x = {", tlevel);
+    if (tlevel == 0) {
+	sprintf(buf + strlen(buf), "%s, ", t_tbl[0].name);
+    } else {
+	for (n = 1; t_tbl[n].name != 0; n++)
+	    if ((tlevel & t_tbl[n].mask) == t_tbl[n].mask) {
+		strcat(buf, t_tbl[n].name);
+		strcat(buf, ", ");
+	    }
+    }
+    if (buf[strlen(buf) - 2] == ',')
+	buf[strlen(buf) - 2] = '\0';
+    return (strcat(buf, "}"));
+}
+
+/* fake a dynamically reconfigurable menu using the 0th entry to deselect
+ * the others
+ */
+static int
+run_trace_menu(MENU * m)
+{
+    ITEM **items;
+    ITEM *i, **p;
+
+    for (;;) {
+	bool changed = FALSE;
+	switch (menu_driver(m, menu_virtualize(wGetchar(menu_win(m))))) {
+	case E_UNKNOWN_COMMAND:
+	    return FALSE;
+	default:
+	    items = menu_items(m);
+	    i = current_item(m);
+	    if (i == items[0]) {
+		if (item_value(i)) {
+		    for (p = items + 1; *p != 0; p++)
+			if (item_value(*p)) {
+			    set_item_value(*p, FALSE);
+			    changed = TRUE;
+			}
+		}
+	    } else {
+		for (p = items + 1; *p != 0; p++)
+		    if (item_value(*p)) {
+			set_item_value(items[0], FALSE);
+			changed = TRUE;
+			break;
+		    }
+	    }
+	    if (!changed)
+		return TRUE;
+	}
+    }
+}
+
+static void
+trace_set(void)
+/* interactively set the trace level */
+{
+    MENU *m;
+    ITEM *items[SIZEOF(t_tbl)];
+    ITEM **ip = items;
+    int mrows, mcols;
+    unsigned newtrace;
+    int n;
+    WINDOW *menuwin;
+
+    mvaddstr(0, 0, "Interactively set trace level:");
+    mvaddstr(2, 0, "  Press space bar to toggle a selection.");
+    mvaddstr(3, 0, "  Use up and down arrow to move the select bar.");
+    mvaddstr(4, 0, "  Press return to set the trace level.");
+    mvprintw(6, 0, "(Current trace level is %s)", tracetrace(_nc_tracing));
+
+    refresh();
+
+    for (n = 0; t_tbl[n].name != 0; n++) {
+	if ((*ip = new_item(t_tbl[n].name, "")) != 0) {
+	    ++ip;
+	}
+    }
+    *ip = (ITEM *) 0;
+
+    m = new_menu(items);
+
+    set_menu_format(m, 0, 2);
+    scale_menu(m, &mrows, &mcols);
+
+    menu_opts_off(m, O_ONEVALUE);
+    menuwin = newwin(mrows + 2, mcols + 2, MENU_Y, MENU_X);
+    set_menu_win(m, menuwin);
+    keypad(menuwin, TRUE);
+    box(menuwin, 0, 0);
+
+    set_menu_sub(m, derwin(menuwin, mrows, mcols, 1, 1));
+
+    post_menu(m);
+
+    for (ip = menu_items(m); *ip; ip++) {
+	unsigned mask = t_tbl[item_index(*ip)].mask;
+	if (mask == 0)
+	    set_item_value(*ip, _nc_tracing == 0);
+	else if ((mask & _nc_tracing) == mask)
+	    set_item_value(*ip, TRUE);
+    }
+
+    while (run_trace_menu(m))
+	continue;
+
+    newtrace = 0;
+    for (ip = menu_items(m); *ip; ip++)
+	if (item_value(*ip))
+	    newtrace |= t_tbl[item_index(*ip)].mask;
+    trace(newtrace);
+    Trace(("trace level interactively set to %s", tracetrace(_nc_tracing)));
+
+    (void) mvprintw(LINES - 2, 0,
+		    "Trace level is %s\n", tracetrace(_nc_tracing));
+    (void) addstr("Press any key to continue...");
+    wGetchar(stdscr);
+
+    unpost_menu(m);
+    delwin(menuwin);
+
+    free_menu(m);
+    for (ip = items; *ip; ip++)
+	free_item(*ip);
+}
+#endif /* TRACE */
+#endif /* USE_LIBMENU */
+
+/****************************************************************************
+ *
+ * Forms test
+ *
+ ****************************************************************************/
+#if USE_LIBFORM
+static FIELD *
+make_label(int frow, int fcol, NCURSES_CONST char *label)
+{
+    FIELD *f = new_field(1, (int) strlen(label), frow, fcol, 0, 0);
+
+    if (f) {
+	set_field_buffer(f, 0, label);
+	set_field_opts(f, (int) (field_opts(f) & ~O_ACTIVE));
+    }
+    return (f);
+}
+
+static FIELD *
+make_field(int frow, int fcol, int rows, int cols, bool secure)
+{
+    FIELD *f = new_field(rows, cols, frow, fcol, 0, secure ? 1 : 0);
+
+    if (f) {
+	set_field_back(f, A_UNDERLINE);
+	set_field_userptr(f, (void *) 0);
+    }
+    return (f);
+}
+
+static void
+display_form(FORM * f)
+{
+    WINDOW *w;
+    int rows, cols;
+
+    scale_form(f, &rows, &cols);
+
+    if ((w = newwin(rows + 2, cols + 4, 0, 0)) != (WINDOW *) 0) {
+	set_form_win(f, w);
+	set_form_sub(f, derwin(w, rows, cols, 1, 2));
+	box(w, 0, 0);
+	keypad(w, TRUE);
+    }
+
+    if (post_form(f) != E_OK)
+	wrefresh(w);
+}
+
+static void
+erase_form(FORM * f)
+{
+    WINDOW *w = form_win(f);
+    WINDOW *s = form_sub(f);
+
+    unpost_form(f);
+    werase(w);
+    wrefresh(w);
+    delwin(s);
+    delwin(w);
+}
+
+static int
+edit_secure(FIELD * me, int c)
+{
+    int rows, cols, frow, fcol, nrow, nbuf;
+
+    if (field_info(me, &rows, &cols, &frow, &fcol, &nrow, &nbuf) == E_OK
+	&& nbuf > 0) {
+	char *source = field_buffer(me, 1);
+	char temp[80];
+	long len;
+
+	strcpy(temp, source ? source : "");
+	len = (long) (char *) field_userptr(me);
+	if (c <= KEY_MAX) {
+	    if (isgraph(c) && (len + 1) < (int) sizeof(temp)) {
+		temp[len++] = (char) c;
+		temp[len] = 0;
+		set_field_buffer(me, 1, temp);
+		c = '*';
+	    } else {
+		c = 0;
+	    }
+	} else {
+	    switch (c) {
+	    case REQ_BEG_FIELD:
+	    case REQ_CLR_EOF:
+	    case REQ_CLR_EOL:
+	    case REQ_DEL_LINE:
+	    case REQ_DEL_WORD:
+	    case REQ_DOWN_CHAR:
+	    case REQ_END_FIELD:
+	    case REQ_INS_CHAR:
+	    case REQ_INS_LINE:
+	    case REQ_LEFT_CHAR:
+	    case REQ_NEW_LINE:
+	    case REQ_NEXT_WORD:
+	    case REQ_PREV_WORD:
+	    case REQ_RIGHT_CHAR:
+	    case REQ_UP_CHAR:
+		c = 0;		/* we don't want to do inline editing */
+		break;
+	    case REQ_CLR_FIELD:
+		if (len) {
+		    temp[0] = 0;
+		    set_field_buffer(me, 1, temp);
+		}
+		break;
+	    case REQ_DEL_CHAR:
+	    case REQ_DEL_PREV:
+		if (len) {
+		    temp[--len] = 0;
+		    set_field_buffer(me, 1, temp);
+		}
+		break;
+	    }
+	}
+	set_field_userptr(me, (void *) len);
+    }
+    return c;
+}
+
+static int
+form_virtualize(FORM * f, WINDOW *w)
+{
+    /* *INDENT-OFF* */
+    static const struct {
+	int code;
+	int result;
+    } lookup[] = {
+	{ CTRL('A'),	REQ_NEXT_CHOICE },
+	{ CTRL('B'),	REQ_PREV_WORD },
+	{ CTRL('C'),	REQ_CLR_EOL },
+	{ CTRL('D'),	REQ_DOWN_FIELD },
+	{ CTRL('E'),	REQ_END_FIELD },
+	{ CTRL('F'),	REQ_NEXT_PAGE },
+	{ CTRL('G'),	REQ_DEL_WORD },
+	{ CTRL('H'),	REQ_DEL_PREV },
+	{ CTRL('I'),	REQ_INS_CHAR },
+	{ CTRL('K'),	REQ_CLR_EOF },
+	{ CTRL('L'),	REQ_LEFT_FIELD },
+	{ CTRL('M'),	REQ_NEW_LINE },
+	{ CTRL('N'),	REQ_NEXT_FIELD },
+	{ CTRL('O'),	REQ_INS_LINE },
+	{ CTRL('P'),	REQ_PREV_FIELD },
+	{ CTRL('R'),	REQ_RIGHT_FIELD },
+	{ CTRL('S'),	REQ_BEG_FIELD },
+	{ CTRL('U'),	REQ_UP_FIELD },
+	{ CTRL('V'),	REQ_DEL_CHAR },
+	{ CTRL('W'),	REQ_NEXT_WORD },
+	{ CTRL('X'),	REQ_CLR_FIELD },
+	{ CTRL('Y'),	REQ_DEL_LINE },
+	{ CTRL('Z'),	REQ_PREV_CHOICE },
+	{ ESCAPE,	MAX_FORM_COMMAND + 1 },
+	{ KEY_BACKSPACE, REQ_DEL_PREV },
+	{ KEY_DOWN,	REQ_DOWN_CHAR },
+	{ KEY_END,	REQ_LAST_FIELD },
+	{ KEY_HOME,	REQ_FIRST_FIELD },
+	{ KEY_LEFT,	REQ_LEFT_CHAR },
+	{ KEY_LL,	REQ_LAST_FIELD },
+	{ KEY_NEXT,	REQ_NEXT_FIELD },
+	{ KEY_NPAGE,	REQ_NEXT_PAGE },
+	{ KEY_PPAGE,	REQ_PREV_PAGE },
+	{ KEY_PREVIOUS, REQ_PREV_FIELD },
+	{ KEY_RIGHT,	REQ_RIGHT_CHAR },
+	{ KEY_UP,	REQ_UP_CHAR },
+	{ QUIT,		MAX_FORM_COMMAND + 1 }
+    };
+    /* *INDENT-ON* */
+
+    static int mode = REQ_INS_MODE;
+    int c = wGetchar(w);
+    unsigned n;
+    FIELD *me = current_field(f);
+    bool current = TRUE;
+
+    if (c == CTRL(']')) {
+	if (mode == REQ_INS_MODE) {
+	    mode = REQ_OVL_MODE;
+	} else {
+	    mode = REQ_INS_MODE;
+	}
+	c = mode;
+    } else {
+	for (n = 0; n < SIZEOF(lookup); n++) {
+	    if (lookup[n].code == c) {
+		c = lookup[n].result;
+		break;
+	    }
+	}
+    }
+    mvprintw(0, COLS - 6, "(%s)", mode == REQ_INS_MODE ? "INS" : "OVL");
+
+    /*
+     * Force the field that the user is typing into to be in reverse video,
+     * while the other fields are shown underlined.
+     */
+    switch (c) {
+    case REQ_BEG_FIELD:
+    case REQ_CLR_EOF:
+    case REQ_CLR_EOL:
+    case REQ_CLR_FIELD:
+    case REQ_DEL_CHAR:
+    case REQ_DEL_LINE:
+    case REQ_DEL_PREV:
+    case REQ_DEL_WORD:
+    case REQ_END_FIELD:
+    case REQ_INS_CHAR:
+    case REQ_INS_LINE:
+    case REQ_LEFT_CHAR:
+    case REQ_LEFT_FIELD:
+    case REQ_NEXT_WORD:
+    case REQ_RIGHT_CHAR:
+	current = TRUE;
+	break;
+    default:
+	current = (c < KEY_MAX);
+	break;
+    }
+    if (current) {
+	c = edit_secure(me, c);
+	set_field_back(me, A_REVERSE);
+    } else {
+	c = edit_secure(me, c);
+	set_field_back(me, A_UNDERLINE);
+    }
+    return c;
+}
+
+static int
+my_form_driver(FORM * form, int c)
+{
+    if (c == (MAX_FORM_COMMAND + 1)
+	&& form_driver(form, REQ_VALIDATION) == E_OK)
+	return (TRUE);
+    else {
+	beep();
+	return (FALSE);
+    }
+}
+
+#ifdef NCURSES_VERSION
+#define FIELDCHECK_CB(func) bool func(FIELD * fld, const void * data GCC_UNUSED)
+#define CHAR_CHECK_CB(func) bool func(int ch, const void *data GCC_UNUSED)
+#else
+#define FIELDCHECK_CB(func) int func(FIELD * fld, char * data GCC_UNUSED)
+#define CHAR_CHECK_CB(func) int func(int ch, char *data GCC_UNUSED)
+#endif
+
+/*
+ * Allow a middle initial, optionally with a '.' to end it.
+ */
+static
+FIELDCHECK_CB(mi_field_check)
+{
+    char *s = field_buffer(fld, 0);
+    int state = 0;
+    int n;
+
+    for (n = 0; s[n] != '\0'; ++n) {
+	switch (state) {
+	case 0:
+	    if (s[n] == '.') {
+		if (n != 1)
+		    return FALSE;
+		state = 2;
+	    } else if (isspace(UChar(s[n]))) {
+		state = 2;
+	    }
+	    break;
+	case 2:
+	    if (!isspace(UChar(s[n])))
+		return FALSE;
+	    break;
+	}
+    }
+
+    /* force the form to display a leading capital */
+    if (islower(UChar(s[0]))) {
+	s[0] = (char) toupper(UChar(s[0]));
+	set_field_buffer(fld, 0, s);
+    }
+    return TRUE;
+}
+
+static
+CHAR_CHECK_CB(mi_char_check)
+{
+    return ((isalpha(ch) || ch == '.') ? TRUE : FALSE);
+}
+
+/*
+ * Passwords should be at least 6 characters.
+ */
+static
+FIELDCHECK_CB(pw_field_check)
+{
+    char *s = field_buffer(fld, 0);
+    int n;
+
+    for (n = 0; s[n] != '\0'; ++n) {
+	if (isspace(UChar(s[n]))) {
+	    if (n < 6)
+		return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+static
+CHAR_CHECK_CB(pw_char_check)
+{
+    return (isgraph(ch) ? TRUE : FALSE);
+}
+
+static void
+demo_forms(void)
+{
+    WINDOW *w;
+    FORM *form;
+    FIELD *f[12], *secure;
+    FIELDTYPE *fty_middle = new_fieldtype(mi_field_check, mi_char_check);
+    FIELDTYPE *fty_passwd = new_fieldtype(pw_field_check, pw_char_check);
+    int finished = 0, c;
+    unsigned n = 0;
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
+#endif
+
+    move(18, 0);
+    addstr("Defined edit/traversal keys:   ^Q/ESC- exit form\n");
+    addstr("^N   -- go to next field       ^P  -- go to previous field\n");
+    addstr("Home -- go to first field      End -- go to last field\n");
+    addstr("^L   -- go to field to left    ^R  -- go to field to right\n");
+    addstr("^U   -- move upward to field   ^D  -- move downward to field\n");
+    addstr("^W   -- go to next word        ^B  -- go to previous word\n");
+    addstr("^S   -- go to start of field   ^E  -- go to end of field\n");
+    addstr("^H   -- delete previous char   ^Y  -- delete line\n");
+    addstr("^G   -- delete current word    ^C  -- clear to end of line\n");
+    addstr("^K   -- clear to end of field  ^X  -- clear field\n");
+    addstr("Arrow keys move within a field as you would expect. ^] toggles overlay mode.");
+
+    mvaddstr(4, 57, "Forms Entry Test");
+
+    refresh();
+
+    /* describe the form */
+    memset(f, 0, sizeof(f));
+    f[n++] = make_label(0, 15, "Sample Form");
+
+    f[n++] = make_label(2, 0, "Last Name");
+    f[n++] = make_field(3, 0, 1, 18, FALSE);
+    set_field_type(f[n - 1], TYPE_ALPHA, 1);
+
+    f[n++] = make_label(2, 20, "First Name");
+    f[n++] = make_field(3, 20, 1, 12, FALSE);
+    set_field_type(f[n - 1], TYPE_ALPHA, 1);
+
+    f[n++] = make_label(2, 34, "Middle Name");
+    f[n++] = make_field(3, 34, 1, 12, FALSE);
+    set_field_type(f[n - 1], fty_middle);
+
+    f[n++] = make_label(5, 0, "Comments");
+    f[n++] = make_field(6, 0, 4, 46, FALSE);
+
+    f[n++] = make_label(5, 20, "Password:");
+    secure =
+	f[n++] = make_field(5, 30, 1, 9, TRUE);
+    set_field_type(f[n - 1], fty_passwd);
+    f[n++] = (FIELD *) 0;
+
+    if ((form = new_form(f)) != 0) {
+
+	display_form(form);
+
+	w = form_win(form);
+	raw();
+	nonl();			/* lets us read ^M's */
+	while (!finished) {
+	    switch (form_driver(form, c = form_virtualize(form, w))) {
+	    case E_OK:
+		mvaddstr(5, 57, field_buffer(secure, 1));
+		clrtoeol();
+		refresh();
+		break;
+	    case E_UNKNOWN_COMMAND:
+		finished = my_form_driver(form, c);
+		break;
+	    default:
+		beep();
+		break;
+	    }
+	}
+
+	erase_form(form);
+
+	free_form(form);
+    }
+    for (c = 0; f[c] != 0; c++)
+	free_field(f[c]);
+    free_fieldtype(fty_middle);
+    free_fieldtype(fty_passwd);
+    noraw();
+    nl();
+
+#ifdef NCURSES_MOUSE_VERSION
+    mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
+#endif
+}
+#endif /* USE_LIBFORM */
+
+/****************************************************************************
+ *
+ * Overlap test
+ *
+ ****************************************************************************/
+
+static void
+fillwin(WINDOW *win, char ch)
+{
+    int y, x;
+    int y1, x1;
+
+    getmaxyx(win, y1, x1);
+    for (y = 0; y < y1; y++) {
+	wmove(win, y, 0);
+	for (x = 0; x < x1; x++)
+	    waddch(win, UChar(ch));
+    }
+}
+
+static void
+crosswin(WINDOW *win, char ch)
+{
+    int y, x;
+    int y1, x1;
+
+    getmaxyx(win, y1, x1);
+    for (y = 0; y < y1; y++) {
+	for (x = 0; x < x1; x++)
+	    if (((x > (x1 - 1) / 3) && (x <= (2 * (x1 - 1)) / 3))
+		|| (((y > (y1 - 1) / 3) && (y <= (2 * (y1 - 1)) / 3)))) {
+		wmove(win, y, x);
+		waddch(win, UChar(ch));
+	    }
+    }
+}
+
+#define OVERLAP_FLAVORS 5
+
+static void
+overlap_helpitem(int state, int item, char *message)
+{
+    int row = (item / 2);
+    int col = ((item % 2) ? COLS / 2 : 0);
+
+    move(LINES - 6 + row, col);
+    printw("%c%c = %s", state == row ? '>' : ' ', 'a' + item, message);
+    clrtoeol();
+}
+
+static void
+overlap_test_1_attr(WINDOW *win, int flavor, int col)
+{
+    short cpair = (short) (1 + (flavor * 2) + col);
+
+    switch (flavor) {
+    case 0:
+	wattrset(win, A_NORMAL);
+	break;
+    case 1:
+	wattrset(win, A_BOLD);
+	break;
+    case 2:
+	init_pair(cpair, COLOR_BLUE, COLOR_WHITE);
+	wattrset(win, COLOR_PAIR(cpair) | A_NORMAL);
+	break;
+    case 3:
+	init_pair(cpair, COLOR_WHITE, COLOR_BLUE);
+	wattrset(win, COLOR_PAIR(cpair) | A_BOLD);
+	break;
+    }
+}
+
+static void
+overlap_test_2_attr(WINDOW *win, int flavor, int col)
+{
+    short cpair = (short) (9 + (flavor * 2) + col);
+
+    switch (flavor) {
+    case 0:
+	/* no effect */
+	break;
+    case 1:
+	/* no effect */
+	break;
+    case 2:
+	init_pair(cpair, COLOR_RED, COLOR_GREEN);
+	wbkgdset(win, ' ' | A_BLINK | COLOR_PAIR(cpair));
+	break;
+    case 3:
+	wbkgdset(win, ' ' | A_NORMAL);
+	break;
+    }
+}
+
+static int
+overlap_help(int state, int flavors[OVERLAP_FLAVORS])
+{
+    int row;
+    int col;
+    int item;
+    const char *ths, *tht;
+    char msg[80];
+
+    if (state < 0)
+	state += OVERLAP_FLAVORS;
+    state = state % OVERLAP_FLAVORS;
+    assert(state >= 0 && state < OVERLAP_FLAVORS);
+
+    for (item = 0; item < (2 * OVERLAP_FLAVORS); ++item) {
+	row = item / 2;
+	col = item % 2;
+	ths = col ? "B" : "A";
+	tht = col ? "A" : "B";
+
+	switch (row) {
+	case 0:
+	    flavors[row] = 0;
+	    sprintf(msg, "refresh %s, then %s, then doupdate.", ths, tht);
+	    break;
+	case 1:
+	    if (use_colors) {
+		flavors[row] %= 4;
+	    } else {
+		flavors[row] %= 2;
+	    }
+	    overlap_test_1_attr(stdscr, flavors[row], col);
+	    sprintf(msg, "fill window %s with letter %s.", ths, ths);
+	    break;
+	case 2:
+	    if (use_colors) {
+		flavors[row] %= 4;
+	    } else {
+		flavors[row] %= 2;
+	    }
+	    switch (flavors[row]) {
+	    case 0:
+		sprintf(msg, "cross pattern in window %s.", ths);
+		break;
+	    case 1:
+		sprintf(msg, "draw box in window %s.", ths);
+		break;
+	    case 2:
+		sprintf(msg, "set background of window %s.", ths);
+		break;
+	    case 3:
+		sprintf(msg, "reset background of window %s.", ths);
+		break;
+	    }
+	    break;
+	case 3:
+	    flavors[row] = 0;
+	    sprintf(msg, "clear window %s.", ths);
+	    break;
+	case 4:
+	    flavors[row] %= 4;
+	    switch (flavors[row]) {
+	    case 0:
+		sprintf(msg, "overwrite %s onto %s.", ths, tht);
+		break;
+	    case 1:
+		sprintf(msg, "copywin(FALSE) %s onto %s.", ths, tht);
+		break;
+	    case 2:
+		sprintf(msg, "copywin(TRUE) %s onto %s.", ths, tht);
+		break;
+	    case 3:
+		sprintf(msg, "overlay %s onto %s.", ths, tht);
+		break;
+	    }
+	    break;
+	}
+	overlap_helpitem(state, item, msg);
+	wattrset(stdscr, A_NORMAL);
+	wbkgdset(stdscr, ' ' | A_NORMAL);
+    }
+    move(LINES - 1, 0);
+    printw("^Q/ESC = terminate test.  Up/down/space select test variations (%d %d).",
+	   state, flavors[state]);
+
+    return state;
+}
+
+static void
+overlap_test_0(WINDOW *a, WINDOW *b)
+{
+    touchwin(a);
+    touchwin(b);
+    wnoutrefresh(a);
+    wnoutrefresh(b);
+    doupdate();
+}
+
+static void
+overlap_test_1(int flavor, int col, WINDOW *a, char fill)
+{
+    overlap_test_1_attr(a, flavor, col);
+    fillwin(a, fill);
+    wattrset(a, A_NORMAL);
+}
+
+static void
+overlap_test_2(int flavor, int col, WINDOW *a, char fill)
+{
+    overlap_test_2_attr(a, flavor, col);
+    switch (flavor) {
+    case 0:
+	crosswin(a, fill);
+	break;
+    case 1:
+	box(a, 0, 0);
+	break;
+    case 2:
+	/* done in overlap_test_2_attr */
+	break;
+    case 3:
+	/* done in overlap_test_2_attr */
+	break;
+    }
+}
+
+static void
+overlap_test_3(WINDOW *a)
+{
+    wclear(a);
+    wmove(a, 0, 0);
+}
+
+static void
+overlap_test_4(int flavor, WINDOW *a, WINDOW *b)
+{
+    switch (flavor) {
+    case 0:
+	overwrite(a, b);
+	break;
+    case 1:
+	copywin(a, b, 0, 0, 0, 0, getmaxy(b), getmaxx(b), FALSE);
+	break;
+    case 2:
+	copywin(a, b, 0, 0, 0, 0, getmaxy(b), getmaxx(b), TRUE);
+	break;
+    case 3:
+	overlay(a, b);
+	break;
+    }
+}
+
+/* test effects of overlapping windows */
+static void
+overlap_test(void)
+{
+    int ch;
+    int state, flavor[OVERLAP_FLAVORS];
+
+    WINDOW *win1 = newwin(9, 20, 3, 3);
+    WINDOW *win2 = newwin(9, 20, 9, 16);
+
+    curs_set(0);
+    raw();
+    refresh();
+    move(0, 0);
+    printw("This test shows the behavior of wnoutrefresh() with respect to\n");
+    printw("the shared region of two overlapping windows A and B.  The cross\n");
+    printw("pattern in each window does not overlap the other.\n");
+
+    memset(flavor, 0, sizeof(flavor));
+    state = overlap_help(0, flavor);
+
+    while (!isQuit(ch = Getchar()))
+	switch (ch) {
+	case 'a':		/* refresh window A first, then B */
+	    overlap_test_0(win1, win2);
+	    break;
+
+	case 'b':		/* refresh window B first, then A */
+	    overlap_test_0(win2, win1);
+	    break;
+
+	case 'c':		/* fill window A so it's visible */
+	    overlap_test_1(flavor[1], 0, win1, 'A');
+	    break;
+
+	case 'd':		/* fill window B so it's visible */
+	    overlap_test_1(flavor[1], 1, win2, 'B');
+	    break;
+
+	case 'e':		/* cross test pattern in window A */
+	    overlap_test_2(flavor[2], 0, win1, 'A');
+	    break;
+
+	case 'f':		/* cross test pattern in window A */
+	    overlap_test_2(flavor[2], 1, win2, 'B');
+	    break;
+
+	case 'g':		/* clear window A */
+	    overlap_test_3(win1);
+	    break;
+
+	case 'h':		/* clear window B */
+	    overlap_test_3(win2);
+	    break;
+
+	case 'i':		/* overwrite A onto B */
+	    overlap_test_4(flavor[4], win1, win2);
+	    break;
+
+	case 'j':		/* overwrite B onto A */
+	    overlap_test_4(flavor[4], win2, win1);
+	    break;
+
+	case CTRL('n'):
+	case KEY_DOWN:
+	    state = overlap_help(state + 1, flavor);
+	    break;
+
+	case CTRL('p'):
+	case KEY_UP:
+	    state = overlap_help(state - 1, flavor);
+	    break;
+
+	case ' ':
+	    flavor[state] += 1;
+	    state = overlap_help(state, flavor);
+	    break;
+
+	case '?':
+	    state = overlap_help(state, flavor);
+	    break;
+
+	default:
+	    beep();
+	    break;
+	}
+
+    delwin(win2);
+    delwin(win1);
+    erase();
+    curs_set(1);
+    endwin();
+}
+
+/****************************************************************************
+ *
+ * Main sequence
+ *
+ ****************************************************************************/
+
+static bool
+do_single_test(const char c)
+/* perform a single specified test */
+{
+    switch (c) {
+    case 'a':
+	getch_test();
+	break;
+
+#if USE_WIDEC_SUPPORT
+    case 'A':
+	get_wch_test();
+	break;
+#endif
+
+    case 'b':
+	attr_test();
+	break;
+
+#if USE_WIDEC_SUPPORT
+    case 'B':
+	wide_attr_test();
+	break;
+#endif
+
+    case 'c':
+	if (!use_colors)
+	    Cannot("does not support color.");
+	else
+	    color_test();
+	break;
+
+#if USE_WIDEC_SUPPORT
+    case 'C':
+	if (!use_colors)
+	    Cannot("does not support color.");
+	else
+	    wide_color_test();
+	break;
+#endif
+
+    case 'd':
+	if (!use_colors)
+	    Cannot("does not support color.");
+	else if (!can_change_color())
+	    Cannot("has hardwired color values.");
+	else
+	    color_edit();
+	break;
+
+#if USE_SOFTKEYS
+    case 'e':
+	slk_test();
+	break;
+#endif
+
+#if USE_WIDEC_SUPPORT
+    case 'E':
+	wide_slk_test();
+	break;
+#endif
+    case 'f':
+	acs_display();
+	break;
+
+#if USE_WIDEC_SUPPORT
+    case 'F':
+	wide_acs_display();
+	break;
+#endif
+
+#if USE_LIBPANEL
+    case 'o':
+	demo_panels(init_panel, fill_panel);
+	break;
+#endif
+
+#if USE_WIDEC_SUPPORT && USE_LIBPANEL
+    case 'O':
+	demo_panels(init_wide_panel, fill_wide_panel);
+	break;
+#endif
+
+    case 'g':
+	acs_and_scroll();
+	break;
+
+    case 'i':
+	flushinp_test(stdscr);
+	break;
+
+    case 'k':
+	test_sgr_attributes();
+	break;
+
+#if USE_LIBMENU
+    case 'm':
+	menu_test();
+	break;
+#endif
+
+    case 'p':
+	demo_pad();
+	break;
+
+#if USE_LIBFORM
+    case 'r':
+	demo_forms();
+	break;
+#endif
+
+    case 's':
+	overlap_test();
+	break;
+
+#if USE_LIBMENU && defined(TRACE)
+    case 't':
+	trace_set();
+	break;
+#endif
+
+    case '?':
+	break;
+
+    default:
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void
+usage(void)
+{
+    static const char *const tbl[] =
+    {
+	"Usage: ncurses [options]"
+	,""
+	,"Options:"
+#ifdef NCURSES_VERSION
+	,"  -a f,b   set default-colors (assumed white-on-black)"
+	,"  -d       use default-colors if terminal supports them"
+#endif
+#if USE_SOFTKEYS
+	,"  -e fmt   specify format for soft-keys test (e)"
+#endif
+#if HAVE_RIPOFFLINE
+	,"  -f       rip-off footer line (can repeat)"
+	,"  -h       rip-off header line (can repeat)"
+#endif
+	,"  -m       do not use colors"
+	,"  -p file  rgb values to use in 'd' rather than ncurses's builtin"
+#if USE_LIBPANEL
+	,"  -s msec  specify nominal time for panel-demo (default: 1, to hold)"
+#endif
+#ifdef TRACE
+	,"  -t mask  specify default trace-level (may toggle with ^T)"
+#endif
+    };
+    size_t n;
+    for (n = 0; n < SIZEOF(tbl); n++)
+	fprintf(stderr, "%s\n", tbl[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+static void
+set_terminal_modes(void)
+{
+    noraw();
+    cbreak();
+    noecho();
+    scrollok(stdscr, TRUE);
+    idlok(stdscr, TRUE);
+    keypad(stdscr, TRUE);
+}
+
+#ifdef SIGUSR1
+static RETSIGTYPE
+announce_sig(int sig)
+{
+    (void) fprintf(stderr, "Handled signal %d\r\n", sig);
+}
+#endif
+
+#if HAVE_RIPOFFLINE
+static int
+rip_footer(WINDOW *win, int cols)
+{
+    wbkgd(win, A_REVERSE);
+    werase(win);
+    wmove(win, 0, 0);
+    wprintw(win, "footer: window %p, %d columns", win, cols);
+    wnoutrefresh(win);
+    return OK;
+}
+
+static int
+rip_header(WINDOW *win, int cols)
+{
+    wbkgd(win, A_REVERSE);
+    werase(win);
+    wmove(win, 0, 0);
+    wprintw(win, "header: window %p, %d columns", win, cols);
+    wnoutrefresh(win);
+    return OK;
+}
+#endif /* HAVE_RIPOFFLINE */
+
+static void
+main_menu(bool top)
+{
+    char command;
+
+    do {
+	(void) puts("This is the ncurses main menu");
+	(void) puts("a = keyboard and mouse input test");
+#if USE_WIDEC_SUPPORT
+	(void) puts("A = wide-character keyboard and mouse input test");
+#endif
+	(void) puts("b = character attribute test");
+#if USE_WIDEC_SUPPORT
+	(void) puts("B = wide-character attribute test");
+#endif
+	(void) puts("c = color test pattern");
+#if USE_WIDEC_SUPPORT
+	(void) puts("C = color test pattern using wide-character calls");
+#endif
+	if (top)
+	    (void) puts("d = edit RGB color values");
+#if USE_SOFTKEYS
+	(void) puts("e = exercise soft keys");
+#if USE_WIDEC_SUPPORT
+	(void) puts("E = exercise soft keys using wide-characters");
+#endif
+#endif
+	(void) puts("f = display ACS characters");
+#if USE_WIDEC_SUPPORT
+	(void) puts("F = display Wide-ACS characters");
+#endif
+	(void) puts("g = display windows and scrolling");
+	(void) puts("i = test of flushinp()");
+	(void) puts("k = display character attributes");
+#if USE_LIBMENU
+	(void) puts("m = menu code test");
+#endif
+#if USE_LIBPANEL
+	(void) puts("o = exercise panels library");
+#if USE_WIDEC_SUPPORT
+	(void) puts("O = exercise panels with wide-characters");
+#endif
+#endif
+	(void) puts("p = exercise pad features");
+	(void) puts("q = quit");
+#if USE_LIBFORM
+	(void) puts("r = exercise forms code");
+#endif
+	(void) puts("s = overlapping-refresh test");
+#if USE_LIBMENU && defined(TRACE)
+	(void) puts("t = set trace level");
+#endif
+	(void) puts("? = repeat this command summary");
+
+	(void) fputs("> ", stdout);
+	(void) fflush(stdout);	/* necessary under SVr4 curses */
+
+	/*
+	 * This used to be an 'fgets()' call.  However (on Linux, at least)
+	 * mixing stream I/O and 'read()' (used in the library) causes the
+	 * input stream to be flushed when switching between the two.
+	 */
+	command = 0;
+	for (;;) {
+	    char ch = '\0';
+	    if (read(fileno(stdin), &ch, 1) <= 0) {
+		if (command == 0)
+		    command = 'q';
+		break;
+	    } else if (command == 0 && !isspace(UChar(ch))) {
+		command = ch;
+	    } else if (ch == '\n' || ch == '\r') {
+		if ((command == 'd') && !top) {
+		    (void) fputs("Do not nest test-d\n", stdout);
+		    command = 0;
+		}
+		if (command != 0)
+		    break;
+		(void) fputs("> ", stdout);
+		(void) fflush(stdout);
+	    }
+	}
+
+	if (do_single_test(command)) {
+	    /*
+	     * This may be overkill; it's intended to reset everything back
+	     * to the initial terminal modes so that tests don't get in
+	     * each other's way.
+	     */
+	    flushinp();
+	    set_terminal_modes();
+	    reset_prog_mode();
+	    clear();
+	    refresh();
+	    endwin();
+	    if (command == '?') {
+		(void) puts("This is the ncurses capability tester.");
+		(void)
+		    puts("You may select a test from the main menu by typing the");
+		(void)
+		    puts("key letter of the choice (the letter to left of the =)");
+		(void)
+		    puts("at the > prompt.  Type `q' to exit.");
+	    }
+	    continue;
+	}
+    } while
+	(command != 'q');
+}
+
+/*+-------------------------------------------------------------------------
+	main(argc,argv)
+--------------------------------------------------------------------------*/
+
+#define okCOLOR(n) ((n) >= 0 && (n) < max_colors)
+#define okRGB(n)   ((n) >= 0 && (n) <= 1000)
+
+int
+main(int argc, char *argv[])
+{
+    int c;
+    int my_e_param = 1;
+#ifdef NCURSES_VERSION
+    int default_fg = COLOR_WHITE;
+    int default_bg = COLOR_BLACK;
+    bool assumed_colors = FALSE;
+    bool default_colors = FALSE;
+#endif
+    char *palette_file = 0;
+    bool monochrome = FALSE;
+
+    setlocale(LC_ALL, "");
+
+    while ((c = getopt(argc, argv, "a:de:fhmp:s:t:")) != -1) {
+	switch (c) {
+#ifdef NCURSES_VERSION
+	case 'a':
+	    assumed_colors = TRUE;
+	    sscanf(optarg, "%d,%d", &default_fg, &default_bg);
+	    break;
+	case 'd':
+	    default_colors = TRUE;
+	    break;
+#endif
+	case 'e':
+	    my_e_param = atoi(optarg);
+#ifdef NCURSES_VERSION
+	    if (my_e_param > 3)	/* allow extended layouts */
+		usage();
+#else
+	    if (my_e_param > 1)
+		usage();
+#endif
+	    break;
+#if HAVE_RIPOFFLINE
+	case 'f':
+	    ripoffline(-1, rip_footer);
+	    break;
+	case 'h':
+	    ripoffline(1, rip_header);
+	    break;
+#endif /* HAVE_RIPOFFLINE */
+	case 'm':
+	    monochrome = TRUE;
+	    break;
+	case 'p':
+	    palette_file = optarg;
+	    break;
+#if USE_LIBPANEL
+	case 's':
+	    nap_msec = atol(optarg);
+	    break;
+#endif
+#ifdef TRACE
+	case 't':
+	    save_trace = (unsigned) strtol(optarg, 0, 0);
+	    break;
+#endif
+	default:
+	    usage();
+	}
+    }
+
+    /*
+     * If there's no menus (unlikely for ncurses!), then we'll have to set
+     * tracing on initially, just in case the user wants to test something that
+     * doesn't involve wGetchar.
+     */
+#ifdef TRACE
+    /* enable debugging */
+#if !USE_LIBMENU
+    trace(save_trace);
+#else
+    if (!isatty(fileno(stdin)))
+	trace(save_trace);
+#endif /* USE_LIBMENU */
+#endif /* TRACE */
+
+#if USE_SOFTKEYS
+    /* tell it we're going to play with soft keys */
+    slk_init(my_e_param);
+#endif
+
+#ifdef SIGUSR1
+    /* set up null signal catcher so we can see what interrupts to getch do */
+    signal(SIGUSR1, announce_sig);
+#endif
+
+    /* we must initialize the curses data structure only once */
+    initscr();
+    bkgdset(BLANK);
+
+    /* tests, in general, will want these modes */
+    use_colors = monochrome ? FALSE : has_colors();
+
+    if (use_colors) {
+	start_color();
+#ifdef NCURSES_VERSION_PATCH
+	max_colors = COLORS;	/* was > 16 ? 16 : COLORS */
+#if HAVE_USE_DEFAULT_COLORS
+	if (default_colors) {
+	    use_default_colors();
+	    min_colors = -1;
+	}
+#if NCURSES_VERSION_PATCH >= 20000708
+	else if (assumed_colors)
+	    assume_default_colors(default_fg, default_bg);
+#endif
+#endif
+#else /* normal SVr4 curses */
+	max_colors = COLORS;	/* was > 8 ? 8 : COLORS */
+#endif
+	max_pairs = COLOR_PAIRS;	/* was > 256 ? 256 : COLOR_PAIRS */
+
+	if (can_change_color()) {
+	    short cp;
+	    all_colors = typeMalloc(RGB_DATA, (unsigned) max_colors);
+	    for (cp = 0; cp < max_colors; ++cp) {
+		color_content(cp,
+			      &all_colors[cp].red,
+			      &all_colors[cp].green,
+			      &all_colors[cp].blue);
+	    }
+	    if (palette_file != 0) {
+		FILE *fp = fopen(palette_file, "r");
+		if (fp != 0) {
+		    char buffer[BUFSIZ];
+		    int red, green, blue;
+		    int scale = 1000;
+		    while (fgets(buffer, sizeof(buffer), fp) != 0) {
+			if (sscanf(buffer, "scale:%d", &c) == 1) {
+			    scale = c;
+			} else if (sscanf(buffer, "%d:%d %d %d",
+					  &c,
+					  &red,
+					  &green,
+					  &blue) == 4
+				   && okCOLOR(c)
+				   && okRGB(red)
+				   && okRGB(green)
+				   && okRGB(blue)) {
+			    all_colors[c].red = (short) ((red * 1000) / scale);
+			    all_colors[c].green = (short) ((green * 1000) / scale);
+			    all_colors[c].blue = (short) ((blue * 1000) / scale);
+			}
+		    }
+		    fclose(fp);
+		}
+	    }
+	}
+    }
+    set_terminal_modes();
+    def_prog_mode();
+
+    /*
+     * Return to terminal mode, so we're guaranteed of being able to
+     * select terminal commands even if the capabilities are wrong.
+     */
+    endwin();
+
+#if HAVE_CURSES_VERSION
+    (void) printf("Welcome to %s.  Press ? for help.\n", curses_version());
+#elif defined(NCURSES_VERSION_MAJOR) && defined(NCURSES_VERSION_MINOR) && defined(NCURSES_VERSION_PATCH)
+    (void) printf("Welcome to ncurses %d.%d.%d.  Press ? for help.\n",
+		  NCURSES_VERSION_MAJOR,
+		  NCURSES_VERSION_MINOR,
+		  NCURSES_VERSION_PATCH);
+#else
+    (void) puts("Welcome to ncurses.  Press ? for help.");
+#endif
+
+    main_menu(TRUE);
+
+    ExitProgram(EXIT_SUCCESS);
+}
+
+/* ncurses.c ends here */
diff --git a/test/ncurses_tst.hin b/test/ncurses_tst.hin
new file mode 100644
index 0000000..1d77cbd
--- /dev/null
+++ b/test/ncurses_tst.hin
@@ -0,0 +1,56 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/****************************************************************************
+ *  Author: Thomas E. Dickey <dickey@clark.net> 1998                        *
+ ****************************************************************************/
+/*
+ * $Id: ncurses_tst.hin,v 1.2 1998/02/11 12:14:05 tom Exp $
+ *
+ * This is a template-file used to generate the "ncurses_cfg.h" file.
+ *
+ * Rather than list every definition, the configuration script substitutes
+ * the definitions that it finds using 'sed'.  You need a patch (971222)
+ * to autoconf 2.12 to do this.
+ */
+#ifndef NC_CONFIG_H
+#define NC_CONFIG_H
+@DEFS@
+
+	/* The C compiler may not treat these properly but C++ has to */
+#ifdef __cplusplus
+#undef const
+#undef inline
+#else
+#if defined(lint) || defined(TRACE)
+#undef inline
+#define inline /* nothing */
+#endif
+#endif
+
+#endif /* NC_CONFIG_H */
diff --git a/test/newdemo.c b/test/newdemo.c
new file mode 100644
index 0000000..d43996b
--- /dev/null
+++ b/test/newdemo.c
@@ -0,0 +1,358 @@
+/*
+ *  newdemo.c	-	A demo program using PDCurses. The program illustrate
+ *  	 		the use of colours for text output.
+ *
+ * $Id: newdemo.c,v 1.31 2008/08/03 20:19:38 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <time.h>
+
+/*
+ *  The Australian map
+ */
+static CONST_MENUS char *AusMap[16] =
+{
+    "           A           A ",
+    "    N.T. AAAAA       AAAA ",
+    "     AAAAAAAAAAA  AAAAAAAA ",
+    "   AAAAAAAAAAAAAAAAAAAAAAAAA Qld.",
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
+    " AAAAAAAAAAAAAAAAAAAAAAAAAAAA ",
+    "   AAAAAAAAAAAAAAAAAAAAAAAAA N.S.W.",
+    "W.A. AAAAAAAAA      AAAAAA Vic.",
+    "       AAA   S.A.     AA",
+    "                       A  Tas.",
+    ""
+};
+
+/*
+ *  Funny messages
+ */
+#define NMESSAGES   6
+
+static NCURSES_CONST char *messages[] =
+{
+    "Hello from the Land Down Under",
+    "The Land of crocs. and a big Red Rock",
+    "Where the sunflower runs along the highways",
+    "the dusty red roads lead one to loneliness",
+    "Blue sky in the morning and",
+    "freezing nights and twinkling stars",
+    ""
+};
+
+/*
+ *  Trap interrupt
+ */
+static RETSIGTYPE
+trap(int sig GCC_UNUSED)
+{
+    endwin();
+    ExitProgram(EXIT_FAILURE);
+}
+
+/*
+ *  Wait for user
+ */
+static int
+WaitForUser(WINDOW *win)
+{
+    time_t t;
+    chtype key;
+
+    nodelay(win, TRUE);
+    t = time((time_t *) 0);
+    while (1) {
+	if ((int) (key = wgetch(win)) != ERR) {
+	    if (key == 'q' || key == 'Q')
+		return 1;
+	    else
+		return 0;
+	}
+	if (time((time_t *) 0) - t > 5)
+	    return 0;
+    }
+}
+
+static void
+set_colors(WINDOW *win, int pair, int foreground, int background)
+{
+    if (has_colors()) {
+	if (pair > COLOR_PAIRS)
+	    pair = COLOR_PAIRS;
+	init_pair(pair, foreground, background);
+	wattrset(win, COLOR_PAIR(pair));
+    }
+}
+
+static chtype
+use_colors(WINDOW *win, int pair, chtype attrs)
+{
+    if (has_colors()) {
+	if (pair > COLOR_PAIRS)
+	    pair = COLOR_PAIRS;
+	attrs |= COLOR_PAIR(pair);
+    }
+    wattrset(win, attrs);
+    return attrs;
+}
+
+/*
+ * Test sub windows
+ */
+static int
+SubWinTest(WINDOW *win)
+{
+    int w, h, sw, sh, bx, by;
+    WINDOW *swin1, *swin2, *swin3;
+
+    getmaxyx(win, h, w);
+    getbegyx(win, by, bx);
+    sw = w / 3;
+    sh = h / 3;
+    if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL)
+	return 1;
+    if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL)
+	return 1;
+    if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL)
+	return 1;
+
+    set_colors(swin1, 8, COLOR_RED, COLOR_BLUE);
+    werase(swin1);
+    mvwaddstr(swin1, 0, 3, "Sub-window 1");
+    wrefresh(swin1);
+
+    set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA);
+    werase(swin2);
+    mvwaddstr(swin2, 0, 3, "Sub-window 2");
+    wrefresh(swin2);
+
+    set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN);
+    werase(swin3);
+    mvwaddstr(swin3, 0, 3, "Sub-window 3");
+    wrefresh(swin3);
+
+    delwin(swin1);
+    delwin(swin2);
+    delwin(swin3);
+    WaitForUser(win);
+    return 0;
+}
+
+static int
+bounce(int n, int *dir, int len)
+{
+    if (*dir > 0)
+	++n;
+    else
+	--n;
+    if (n <= 1 || n >= len - 2)
+	*dir = *dir ? 0 : 1;
+    return n;
+}
+
+/*
+ *  Bouncing balls
+ */
+static int
+BouncingBalls(WINDOW *win)
+{
+    int w, h;
+    int x1, y1, xd1, yd1;
+    int x2, y2, xd2, yd2;
+    int x3, y3, xd3, yd3;
+
+    getmaxyx(win, h, w);
+
+    x1 = 2 + rand() % (w - 4);
+    y1 = 2 + rand() % (h - 4);
+    x2 = 2 + rand() % (w - 4);
+    y2 = 2 + rand() % (h - 4);
+    x3 = 2 + rand() % (w - 4);
+    y3 = 2 + rand() % (h - 4);
+
+    xd1 = 1;
+    yd1 = 1;
+    xd2 = 1;
+    yd2 = 0;
+    xd3 = 0;
+    yd3 = 1;
+
+    nodelay(win, TRUE);
+
+    while (wgetch(win) == ERR) {
+	x1 = bounce(x1, &xd1, w);
+	y1 = bounce(y1, &yd1, h);
+	x2 = bounce(x2, &xd2, w);
+	y2 = bounce(y2, &yd2, h);
+	x3 = bounce(x3, &xd3, w);
+	y3 = bounce(y3, &yd3, h);
+
+	set_colors(win, 11, COLOR_RED, COLOR_BLUE);
+	mvwaddch(win, y1, x1, 'O');
+
+	set_colors(win, 12, COLOR_BLUE, COLOR_RED);
+	mvwaddch(win, y2, x2, '*');
+
+	set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE);
+	mvwaddch(win, y3, x3, '@');
+
+	wmove(win, 0, 0);
+	wrefresh(win);
+	delay_output(100);
+    }
+    return 0;
+}
+
+/*
+ *  Main driver
+ */
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    WINDOW *win;
+    int w, x, y, i, j, k;
+    char buffer[200];
+    const char *message;
+    int width, height;
+    chtype save[80];
+    chtype c;
+
+    setlocale(LC_ALL, "");
+
+    CATCHALL(trap);
+
+    initscr();
+    if (has_colors())
+	start_color();
+    cbreak();
+    curs_set(0);
+    width = 48;
+    height = 14;		/* Create a drawing window */
+    win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
+    if (win == NULL) {
+	endwin();
+	ExitProgram(EXIT_FAILURE);
+    }
+
+    while (1) {
+	set_colors(win, 1, COLOR_WHITE, COLOR_BLUE);
+	werase(win);
+
+	set_colors(win, 2, COLOR_RED, COLOR_RED);
+	box(win, ACS_VLINE, ACS_HLINE);
+	wrefresh(win);
+	/* Do ramdom output of a character */
+	use_colors(win, 1, A_NORMAL);
+	c = 'a';
+	for (i = 0; i < 5000; ++i) {
+	    x = rand() % (width - 2) + 1;
+	    y = rand() % (height - 2) + 1;
+	    mvwaddch(win, y, x, c);
+	    wrefresh(win);
+	    nodelay(win, TRUE);
+	    if (wgetch(win) != ERR)
+		break;
+	    if (i == 2000) {
+		c = 'b';
+		set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW);
+	    }
+	}
+
+	SubWinTest(win);
+	/* Erase and draw green window */
+	set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN);
+	wbkgd(win, use_colors(win, 4, A_BOLD));
+	werase(win);
+	wrefresh(win);
+	/* Draw RED bounding box */
+	use_colors(win, 2, A_NORMAL);
+	box(win, ' ', ' ');
+	wrefresh(win);
+	/* Display Australia map */
+	use_colors(win, 4, A_BOLD);
+	i = 0;
+	while (*AusMap[i]) {
+	    mvwaddstr(win, i + 1, 8, AusMap[i]);
+	    wrefresh(win);
+	    delay_output(50);
+	    ++i;
+	}
+
+	set_colors(win, 5, COLOR_BLUE, COLOR_WHITE);
+	use_colors(win, 5, A_BLINK);
+	mvwaddstr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix");
+	wrefresh(win);
+
+	/* Draw running messages */
+	set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE);
+	message = messages[j = 0];
+	i = 1;
+	w = width - 2;
+	strcpy(buffer, message);
+	while (j < NMESSAGES) {
+	    while ((int) strlen(buffer) < w) {
+		strcat(buffer, " ... ");
+		strcat(buffer, messages[++j % NMESSAGES]);
+	    }
+
+	    if (i < w)
+		mvwaddnstr(win, height / 2, w - i, buffer, i);
+	    else
+		mvwaddnstr(win, height / 2, 1, buffer, w);
+
+	    wrefresh(win);
+	    nodelay(win, TRUE);
+	    if (wgetch(win) != ERR) {
+		flushinp();
+		break;
+	    }
+	    if (i++ >= w) {
+		for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ;
+	    }
+	    delay_output(100);
+	}
+
+	j = 0;
+	/*  Draw running As across in RED */
+	set_colors(win, 7, COLOR_RED, COLOR_GREEN);
+	memset(save, ' ', sizeof(save));
+	for (i = 2; i < width - 4; ++i) {
+	    k = mvwinch(win, 4, i);
+	    if (k == ERR)
+		break;
+	    save[j++] = c = k;
+	    c &= A_CHARTEXT;
+	    mvwaddch(win, 4, i, c);
+	}
+	wrefresh(win);
+
+	/* Put a message up wait for a key */
+	i = height - 2;
+	use_colors(win, 5, A_NORMAL);
+	mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit ");
+	wrefresh(win);
+
+	if (WaitForUser(win) == 1)
+	    break;
+
+	j = 0;			/* Restore the old line */
+	for (i = 2; i < width - 4; ++i)
+	    mvwaddch(win, 4, i, save[j++]);
+	wrefresh(win);
+
+	BouncingBalls(win);
+	/* Put a message up wait for a key */
+	i = height - 2;
+	use_colors(win, 5, A_NORMAL);
+	mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit ");
+	wrefresh(win);
+	if (WaitForUser(win) == 1)
+	    break;
+    }
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/programs b/test/programs
new file mode 100644
index 0000000..9949a4c
--- /dev/null
+++ b/test/programs
@@ -0,0 +1,86 @@
+# $Id: programs,v 1.14 2008/08/16 21:47:39 tom Exp $
+##############################################################################
+# Copyright (c) 2006-2007,2008 Free Software Foundation, Inc.                #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+#
+# Author: Thomas E. Dickey
+#
+# programs used for ncurses tests
+background	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	background
+blue		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	blue
+bs		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	bs
+cardfile	$(LDFLAGS_DEFAULT)	$(LOCAL_LIBS)	cardfile
+chgat		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	chgat
+color_set	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	color_set
+demo_altkeys	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	demo_altkeys
+demo_defkey	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	demo_defkey
+demo_forms	$(LDFLAGS_DEFAULT)	$(LOCAL_LIBS)	demo_forms edit_field
+demo_keyok	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	demo_keyok
+demo_menus	$(LDFLAGS_DEFAULT)	$(LOCAL_LIBS)	demo_menus
+demo_panels	$(LDFLAGS_DEFAULT)	$(LOCAL_LIBS)	demo_panels
+demo_termcap	$(LDFLAGS_TINFO)	$(LOCAL_LIBS)	demo_termcap
+ditto		$(LDFLAGS_THREADS)	$(LOCAL_LIBS)	ditto
+dots		$(LDFLAGS_TINFO)	$(LOCAL_LIBS)	dots
+dots_mvcur	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	dots_mvcur
+echochar	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	echochar
+filter		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	filter
+firework	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	firework
+firstlast	$(LDFLAGS_DEFAULT)	$(LOCAL_LIBS)	firstlast
+foldkeys	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	foldkeys
+gdc		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	gdc
+hanoi		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	hanoi
+hashtest	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	hashtest
+inch_wide	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	inch_wide
+inchs		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	inchs
+ins_wide	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	ins_wide
+inserts		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	inserts
+key_names	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	key_names
+keynames	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	keynames
+knight		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	knight
+lrtest		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	lrtest
+movewindow	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	movewindow
+ncurses		$(LDFLAGS_DEFAULT)	$(LOCAL_LIBS)	ncurses
+newdemo		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	newdemo
+railroad	$(LDFLAGS_TINFO)	$(LOCAL_LIBS)	railroad
+rain		$(LDFLAGS_THREADS)	$(LOCAL_LIBS)	rain
+redraw		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	redraw
+savescreen	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	savescreen
+tclock		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	tclock
+test_arrays	$(LDFLAGS_TINFO)	$(LOCAL_LIBS)	test_arrays
+test_get_wstr	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	test_get_wstr
+test_getstr	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	test_getstr
+test_instr	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	test_instr
+test_inwstr	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	test_inwstr
+test_opaque	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	test_opaque
+testaddch	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	testaddch
+testcurs	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	testcurs
+testscanw	$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	testscanw
+view		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	view
+worm		$(LDFLAGS_THREADS)	$(LOCAL_LIBS)	worm
+xmas		$(LDFLAGS_CURSES)	$(LOCAL_LIBS)	xmas
+
+# vile:makemode
diff --git a/test/railroad.c b/test/railroad.c
new file mode 100644
index 0000000..160823d
--- /dev/null
+++ b/test/railroad.c
@@ -0,0 +1,250 @@
+/****************************************************************************
+ * Copyright (c) 2000-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ * Author: Thomas E. Dickey - 2000
+ *
+ * $Id: railroad.c,v 1.16 2008/02/09 18:08:43 tom Exp $
+ *
+ * A simple demo of the termcap interface.
+ */
+#define USE_TINFO
+#include <test.priv.h>
+
+#if HAVE_TGETENT
+
+static char *wipeit;
+static char *moveit;
+static int length;
+static int height;
+
+static char *finisC;
+static char *finisS;
+static char *finisU;
+
+static char *startC;
+static char *startS;
+static char *startU;
+
+static char *backup;
+
+static bool interrupted = FALSE;
+
+static int
+outc(TPUTS_ARG c)
+{
+    if (interrupted) {
+	char tmp = c;
+	write(STDOUT_FILENO, &tmp, 1);
+    } else {
+	putc(c, stdout);
+    }
+    return 0;
+}
+
+static void
+PutChar(int ch)
+{
+    putchar(ch);
+    fflush(stdout);
+    napms(moveit ? 10 : 50);	/* not really termcap... */
+}
+
+static void
+Backup(void)
+{
+    tputs(backup != 0 ? backup : "\b", 1, outc);
+}
+
+static void
+ShowCursor(int flag)
+{
+    if (startC != 0 && finisC != 0) {
+	tputs(flag ? startC : finisC, 1, outc);
+    }
+}
+
+static void
+StandOut(int flag)
+{
+    if (startS != 0 && finisS != 0) {
+	tputs(flag ? startS : finisS, 1, outc);
+    }
+}
+
+static void
+Underline(int flag)
+{
+    if (startU != 0 && finisU != 0) {
+	tputs(flag ? startU : finisU, 1, outc);
+    }
+}
+
+static void
+ShowSign(char *string)
+{
+    char *base = string;
+    int ch, first, last;
+
+    if (moveit != 0) {
+	tputs(tgoto(moveit, 0, height - 1), 1, outc);
+	tputs(wipeit, 1, outc);
+    }
+
+    while (*string != 0) {
+	ch = *string;
+	if (ch != ' ') {
+	    if (moveit != 0) {
+		for (first = length - 2; first >= (string - base); first--) {
+		    if (first < length - 1) {
+			tputs(tgoto(moveit, first + 1, height - 1), 1, outc);
+			PutChar(' ');
+		    }
+		    tputs(tgoto(moveit, first, height - 1), 1, outc);
+		    PutChar(ch);
+		}
+	    } else {
+		last = ch;
+		if (isalpha(ch)) {
+		    first = isupper(ch) ? 'A' : 'a';
+		} else if (isdigit(ch)) {
+		    first = '0';
+		} else {
+		    first = ch;
+		}
+		if (first < last) {
+		    Underline(1);
+		    while (first < last) {
+			PutChar(first);
+			Backup();
+			first++;
+		    }
+		    Underline(0);
+		}
+	    }
+	    if (moveit != 0)
+		Backup();
+	}
+	StandOut(1);
+	PutChar(ch);
+	StandOut(0);
+	fflush(stdout);
+	string++;
+    }
+    if (moveit != 0)
+	tputs(wipeit, 1, outc);
+    putchar('\n');
+}
+
+static void
+cleanup(void)
+{
+    Underline(0);
+    StandOut(0);
+    ShowCursor(1);
+}
+
+static void
+onsig(int n GCC_UNUSED)
+{
+    interrupted = TRUE;
+    cleanup();
+    ExitProgram(EXIT_FAILURE);
+}
+
+static void
+railroad(char **args)
+{
+    NCURSES_CONST char *name = getenv("TERM");
+    char buffer[1024];
+    char area[1024], *ap = area;
+
+    if (name == 0)
+	name = "dumb";
+    if (tgetent(buffer, name) >= 0) {
+
+	wipeit = tgetstr("ce", &ap);
+	height = tgetnum("li");
+	length = tgetnum("co");
+	moveit = tgetstr("cm", &ap);
+
+	if (wipeit == 0
+	    || moveit == 0
+	    || height <= 0
+	    || length <= 0) {
+	    wipeit = 0;
+	    moveit = 0;
+	    height = 0;
+	    length = 0;
+	}
+
+	startS = tgetstr("so", &ap);
+	finisS = tgetstr("se", &ap);
+
+	startU = tgetstr("us", &ap);
+	finisU = tgetstr("ue", &ap);
+
+	backup = tgetstr("le", &ap);
+
+	startC = tgetstr("ve", &ap);
+	finisC = tgetstr("vi", &ap);
+
+	ShowCursor(0);
+
+	CATCHALL(onsig);
+
+	while (*args) {
+	    ShowSign(*args++);
+	}
+	ShowCursor(1);
+    }
+}
+
+int
+main(int argc, char *argv[])
+{
+    if (argc > 1) {
+	railroad(argv + 1);
+    } else {
+	static char world[] = "Hello World";
+	static char *hello[] =
+	{world, 0};
+	railroad(hello);
+    }
+    ExitProgram(EXIT_SUCCESS);
+}
+
+#else
+int
+main(int argc GCC_UNUSED,
+     char *argv[]GCC_UNUSED)
+{
+    printf("This program requires termcap\n");
+    exit(EXIT_FAILURE);
+}
+#endif
diff --git a/test/rain.c b/test/rain.c
new file mode 100644
index 0000000..f4a5e7f
--- /dev/null
+++ b/test/rain.c
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: rain.c,v 1.34 2008/05/24 23:34:34 tom Exp $
+ */
+#include <test.priv.h>
+
+/* rain 11/3/1980 EPS/CITHEP */
+
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
+
+WANT_USE_WINDOW();
+
+#define MAX_THREADS	10
+#define MAX_DROP	5
+
+struct DATA;
+
+typedef void (*DrawPart) (struct DATA *);
+
+typedef struct DATA {
+    int y, x;
+#ifdef USE_PTHREADS
+    DrawPart func;
+    int state;
+#endif
+} DATA;
+
+#ifdef USE_PTHREADS
+pthread_cond_t cond_next_drop;
+pthread_mutex_t mutex_next_drop;
+static int used_threads;
+
+typedef struct {
+    pthread_t myself;
+    long counter;
+} STATS;
+
+static STATS drop_threads[MAX_THREADS];
+#endif
+
+static void
+onsig(int n GCC_UNUSED)
+{
+    curs_set(1);
+    endwin();
+    ExitProgram(EXIT_FAILURE);
+}
+
+static float
+ranf(void)
+{
+    long r = (rand() & 077777);
+    return ((float) r / 32768.);
+}
+
+static int
+random_x(void)
+{
+    return (((float) (COLS - 4) * ranf()) + 2);
+}
+
+static int
+random_y(void)
+{
+    return (((float) (LINES - 4) * ranf()) + 2);
+}
+
+static int
+next_j(int j)
+{
+    if (j == 0)
+	j = MAX_DROP - 1;
+    else
+	--j;
+    if (has_colors()) {
+	int z = (int) (3 * ranf());
+	chtype color = COLOR_PAIR(z);
+	if (z)
+	    color |= A_BOLD;
+	attrset(color);
+    }
+    return j;
+}
+
+static void
+part1(DATA * drop)
+{
+    mvaddch(drop->y, drop->x, '.');
+}
+
+static void
+part2(DATA * drop)
+{
+    mvaddch(drop->y, drop->x, 'o');
+}
+
+static void
+part3(DATA * drop)
+{
+    mvaddch(drop->y, drop->x, 'O');
+}
+
+static void
+part4(DATA * drop)
+{
+    mvaddch(drop->y - 1, drop->x, '-');
+    mvaddstr(drop->y, drop->x - 1, "|.|");
+    mvaddch(drop->y + 1, drop->x, '-');
+}
+
+static void
+part5(DATA * drop)
+{
+    mvaddch(drop->y - 2, drop->x, '-');
+    mvaddstr(drop->y - 1, drop->x - 1, "/ \\");
+    mvaddstr(drop->y, drop->x - 2, "| O |");
+    mvaddstr(drop->y + 1, drop->x - 1, "\\ /");
+    mvaddch(drop->y + 2, drop->x, '-');
+}
+
+static void
+part6(DATA * drop)
+{
+    mvaddch(drop->y - 2, drop->x, ' ');
+    mvaddstr(drop->y - 1, drop->x - 1, "   ");
+    mvaddstr(drop->y, drop->x - 2, "     ");
+    mvaddstr(drop->y + 1, drop->x - 1, "   ");
+    mvaddch(drop->y + 2, drop->x, ' ');
+}
+
+#ifdef USE_PTHREADS
+static void
+napsome(void)
+{
+    napms(60);
+}
+
+/*
+ * This runs inside the use_window() mutex.
+ */
+static int
+really_draw(WINDOW *win, void *arg)
+{
+    DATA *data = (DATA *) arg;
+
+    (void) win;
+    next_j(data->state);
+    data->func(data);
+    refresh();
+    return OK;
+}
+
+static void
+draw_part(void (*func) (DATA *), int state, DATA * data)
+{
+    data->func = func;
+    data->state = state;
+    use_window(stdscr, really_draw, (void *) data);
+    napsome();
+}
+
+/*
+ * Tell the threads that one of them can start work on a new raindrop.
+ * They may all be busy if we're sending requests too rapidly.
+ */
+static int
+put_next_drop(void)
+{
+    pthread_cond_signal(&cond_next_drop);
+    pthread_mutex_unlock(&mutex_next_drop);
+
+    return 0;
+}
+
+/*
+ * Wait until we're assigned the task of drawing a new raindrop.
+ */
+static int
+get_next_drop(void)
+{
+    pthread_mutex_lock(&mutex_next_drop);
+    pthread_cond_wait(&cond_next_drop, &mutex_next_drop);
+
+    return TRUE;
+}
+
+static void *
+draw_drop(void *arg)
+{
+    DATA mydata;
+    int mystats;
+
+    /*
+     * Find myself in the list of threads so we can count the number of loops.
+     */
+    for (mystats = 0; mystats < MAX_THREADS; ++mystats) {
+	if (drop_threads[mystats].myself == pthread_self())
+	    break;
+    }
+
+    do {
+	if (mystats < MAX_THREADS)
+	    drop_threads[mystats].counter++;
+
+	/*
+	 * Make a copy of caller's data.  We're cheating for the cases after
+	 * the first loop since we still have a pointer into the main thread
+	 * to the data which it uses for setting up this thread (but it has
+	 * been modified to use different coordinates).
+	 */
+	mydata = *(DATA *) arg;
+
+	draw_part(part1, 0, &mydata);
+	draw_part(part2, 1, &mydata);
+	draw_part(part3, 2, &mydata);
+	draw_part(part4, 3, &mydata);
+	draw_part(part5, 4, &mydata);
+	draw_part(part6, 0, &mydata);
+    } while (get_next_drop());
+
+    return NULL;
+}
+
+/*
+ * The description of pthread_create() is misleading, since it implies that
+ * threads will exit cleanly after their function returns.
+ * 
+ * Since they do not (and the number of threads is limited by system
+ * resources), make a limited number of threads, and signal any that are
+ * waiting when we want a thread past that limit.
+ */
+static int
+start_drop(DATA * data)
+{
+    int rc;
+
+    if (!used_threads) {
+	/* mutex and condition for signalling thread */
+	pthread_mutex_init(&mutex_next_drop, NULL);
+	pthread_cond_init(&cond_next_drop, NULL);
+    }
+
+    if (used_threads < MAX_THREADS) {
+	rc = pthread_create(&(drop_threads[used_threads].myself),
+			    NULL,
+			    draw_drop,
+			    data);
+	++used_threads;
+    } else {
+	rc = put_next_drop();
+    }
+    return rc;
+}
+#endif
+
+static int
+get_input(void)
+{
+    return USING_WINDOW(stdscr, wgetch);
+}
+
+int
+main(int argc GCC_UNUSED,
+     char *argv[]GCC_UNUSED)
+{
+    bool done = FALSE;
+    DATA drop;
+#ifndef USE_PTHREADS
+    DATA last[MAX_DROP];
+#endif
+    int j = 0;
+
+    setlocale(LC_ALL, "");
+
+    CATCHALL(onsig);
+
+    initscr();
+    if (has_colors()) {
+	int bg = COLOR_BLACK;
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() == OK)
+	    bg = -1;
+#endif
+	init_pair(1, COLOR_BLUE, bg);
+	init_pair(2, COLOR_CYAN, bg);
+    }
+    nl();
+    noecho();
+    curs_set(0);
+    timeout(0);
+
+#ifndef USE_PTHREADS
+    for (j = MAX_DROP; --j >= 0;) {
+	last[j].x = random_x();
+	last[j].y = random_y();
+    }
+    j = 0;
+#endif
+
+    while (!done) {
+	drop.x = random_x();
+	drop.y = random_y();
+
+#ifdef USE_PTHREADS
+	if (start_drop(&drop) != 0) {
+	    beep();
+	}
+#else
+	/*
+	 * The non-threaded code draws parts of each drop on each loop.
+	 */
+	part1(&drop);
+
+	part2(&last[j]);
+
+	j = next_j(j);
+	part3(&last[j]);
+
+	j = next_j(j);
+	part4(&last[j]);
+
+	j = next_j(j);
+	part5(&last[j]);
+
+	j = next_j(j);
+	part6(&last[j]);
+
+	last[j] = drop;
+#endif
+
+	switch (get_input()) {
+	case ('q'):
+	case ('Q'):
+	    done = TRUE;
+	    break;
+	case 's':
+	    nodelay(stdscr, FALSE);
+	    break;
+	case ' ':
+	    nodelay(stdscr, TRUE);
+	    break;
+#ifdef KEY_RESIZE
+	case (KEY_RESIZE):
+	    break;
+#endif
+	}
+	napms(50);
+    }
+    curs_set(1);
+    endwin();
+#ifdef USE_PTHREADS
+    printf("Counts per thread:\n");
+    for (j = 0; j < MAX_THREADS; ++j)
+	printf("  %d:%ld\n", j, drop_threads[j].counter);
+#endif
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/redraw.c b/test/redraw.c
new file mode 100644
index 0000000..82e6378
--- /dev/null
+++ b/test/redraw.c
@@ -0,0 +1,169 @@
+/****************************************************************************
+ * Copyright (c) 2006,2007 Free Software Foundation, Inc.                   *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: redraw.c,v 1.4 2007/06/30 17:55:06 tom Exp $
+ *
+ * Demonstrate the redrawwin() and wredrawln() functions.
+ * Thomas Dickey - 2006/11/4
+ */
+
+#include <test.priv.h>
+
+static void
+trash(int beg_x, int max_x, int cur_x)
+{
+    int x;
+
+    for (x = cur_x; x > beg_x; --x) {
+	putchar('\b');
+    }
+    for (x = beg_x; x < max_x; ++x) {
+	if (x < cur_x)
+	    putchar('<');
+	else if (x == cur_x)
+	    putchar('=');
+	else if (x > cur_x)
+	    putchar('>');
+    }
+    for (x = max_x; x > cur_x; --x) {
+	putchar('\b');
+    }
+}
+
+static void
+test_redraw(WINDOW *win)
+{
+    WINDOW *win1;
+    WINDOW *win2;
+    bool done = FALSE;
+    int ch, y, x;
+    int max_y, max_x;
+    int beg_y, beg_x;
+
+    scrollok(win, TRUE);
+    keypad(win, TRUE);
+    getmaxyx(win, max_y, max_x);
+    getbegyx(win, beg_y, beg_x);
+    while (!done) {
+	ch = wgetch(win);
+	getyx(win, y, x);
+	switch (ch) {
+	case 'q':
+	    /* FALLTHRU */
+	case ESCAPE:
+	    done = TRUE;
+	    break;
+	case 'w':
+	    win1 = newwin(max_y, max_x,
+			  beg_y, beg_x);
+	    win2 = newwin(max_y - 2, max_x - 2,
+			  beg_y + 1, beg_x + 1);
+	    box(win1, 0, 0);
+	    wrefresh(win1);
+
+	    test_redraw(win2);
+
+	    delwin(win2);
+	    delwin(win1);
+
+	    touchwin(win);
+	    break;
+
+	case '!':
+	    /*
+	     * redrawwin() and wredrawln() do not take into account the
+	     * possibility that the cursor may have moved.  That makes them
+	     * cumbersome for using with a shell command.  So we simply
+	     * trash the current line of the window using backspace/overwrite.
+	     */
+	    trash(beg_x, max_x, x + beg_x);
+	    break;
+
+#ifdef NCURSES_VERSION
+	case '@':
+	    /*
+	     * For a shell command, we can work around the problem noted above
+	     * using mvcur().  It is ifdef'd for NCURSES, since X/Open does
+	     * not define the case where the old location is unknown. 
+	     */
+	    system("date");
+	    mvcur(-1, -1, y, x);
+	    break;
+#endif
+
+	case CTRL('W'):
+	    redrawwin(win);
+	    break;
+
+	case CTRL('L'):
+	    wredrawln(win, y, 1);
+	    break;
+
+	case KEY_UP:
+	    if (y > 0)
+		wmove(win, y - 1, x);
+	    break;
+
+	case KEY_DOWN:
+	    if (y < max_y)
+		wmove(win, y + 1, x);
+	    break;
+
+	case KEY_LEFT:
+	    if (x > 0)
+		wmove(win, y, x - 1);
+	    break;
+
+	case KEY_RIGHT:
+	    if (x < max_x)
+		wmove(win, y, x + 1);
+	    break;
+
+	default:
+	    if (ch > KEY_MIN) {
+		waddstr(win, keyname(ch));
+	    } else {
+		waddstr(win, unctrl(UChar(ch)));
+	    }
+	    break;
+	}
+	wnoutrefresh(win);
+	doupdate();
+    }
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    initscr();
+    raw();
+    noecho();
+    test_redraw(stdscr);
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/savescreen.c b/test/savescreen.c
new file mode 100644
index 0000000..09f328b
--- /dev/null
+++ b/test/savescreen.c
@@ -0,0 +1,316 @@
+/****************************************************************************
+ * Copyright (c) 2007 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: savescreen.c,v 1.10 2007/07/21 17:57:37 tom Exp $
+ *
+ * Demonstrate save/restore functions from the curses library.
+ * Thomas Dickey - 2007/7/14
+ */
+
+#include <test.priv.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+static bool use_init = FALSE;
+
+static void
+setup_next(void)
+{
+    curs_set(1);
+    reset_shell_mode();
+}
+
+static void
+cleanup(char *files[])
+{
+    int n;
+
+    for (n = 0; files[n] != 0; ++n) {
+	unlink(files[n]);
+    }
+}
+
+static int
+load_screen(char *filename)
+{
+    int result;
+
+    if (use_init) {
+	if ((result = scr_init(filename)) != ERR)
+	    result = scr_restore(filename);
+    } else {
+	result = scr_set(filename);
+    }
+    return result;
+}
+
+/*
+ * scr_restore() or scr_set() operates on curscr.  If we read a character using
+ * getch() that will refresh stdscr, wiping out the result.  To avoid that,
+ * copy the data back from curscr to stdscr.
+ */
+static void
+after_load(void)
+{
+    overwrite(curscr, stdscr);
+    doupdate();
+}
+
+static void
+show_what(int which, int last)
+{
+    int y, x;
+    time_t now = time((time_t *) 0);
+
+    getyx(stdscr, y, x);
+
+    move(0, 0);
+    printw("Saved %d of %d - %s", which, last + 1, ctime(&now));
+
+    move(y, x);
+
+    refresh();
+}
+
+static int
+get_command(int which, int last)
+{
+    int ch;
+
+    timeout(100);
+
+    do {
+	show_what(which, last);
+	ch = getch();
+    } while (ch == ERR);
+
+    return ch;
+}
+
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+	"Usage: savescreen [-r] files",
+	"",
+	"Options:",
+	" -i  use scr_init/scr_restore rather than scr_set",
+	" -r  replay the screen-dump files"
+    };
+    unsigned n;
+    for (n = 0; n < SIZEOF(msg); ++n) {
+	fprintf(stderr, "%s\n", msg[n]);
+    }
+    ExitProgram(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+    int ch;
+    int which = 0;
+    int last;
+    bool replaying = FALSE;
+    bool done = FALSE;
+    char **files;
+
+    while ((ch = getopt(argc, argv, "ir")) != -1) {
+	switch (ch) {
+	case 'i':
+	    use_init = TRUE;
+	    break;
+	case 'r':
+	    replaying = TRUE;
+	    break;
+	default:
+	    usage();
+	    break;
+	}
+    }
+
+    initscr();
+    cbreak();
+    noecho();
+    keypad(stdscr, TRUE);
+    curs_set(0);
+    if (has_colors()) {
+	start_color();
+	for (ch = 0; ch < COLOR_PAIRS; ++ch) {
+	    short pair = ch % COLOR_PAIRS;
+	    init_pair(pair, COLOR_WHITE, ch % COLORS);
+	}
+    }
+
+    files = argv + optind;
+    last = argc - optind - 1;
+    if (replaying) {
+
+	/*
+	 * Use the last file as the initial/current screen.
+	 */
+	if (last < 0) {
+	    endwin();
+	    printf("No screen-dumps given\n");
+	    ExitProgram(EXIT_FAILURE);
+	}
+
+	which = last;
+	if (load_screen(files[which]) == ERR) {
+	    endwin();
+	    printf("Cannot load screen-dump %s\n", files[which]);
+	    ExitProgram(EXIT_FAILURE);
+	}
+	after_load();
+
+	while (!done && (ch = getch()) != ERR) {
+	    switch (ch) {
+	    case 'n':
+		/*
+		 * If we got a "next" here, skip to the final screen before
+		 * moving to the next process.
+		 */
+		setup_next();
+		which = last;
+		done = TRUE;
+		break;
+	    case 'q':
+		endwin();
+		cleanup(files);
+		done = TRUE;
+		break;
+	    case KEY_BACKSPACE:
+	    case '\b':
+		if (--which < 0)
+		    which = last;
+		break;
+	    case ' ':
+		if (++which > last)
+		    which = 0;
+		break;
+	    default:
+		beep();
+		continue;
+	    }
+
+	    if (ch == 'q') {
+		;
+	    } else if (scr_restore(files[which]) == ERR) {
+		endwin();
+		printf("Cannot load screen-dump %s\n", files[which]);
+		cleanup(files);
+		ExitProgram(EXIT_FAILURE);
+	    } else {
+		wrefresh(curscr);
+	    }
+	}
+    } else {
+	int y;
+	int x;
+
+	move(2, 0);
+	printw("Use h,j,k,l or arrows to move around the screen\n");
+	printw("Press 'q' to quit, ' ' to dump a screen\n");
+	printw("When the last screen has been dumped, press 'n' to run the\n");
+	printw("screen-loader.  That allows only 'q', backspace and ' ' for\n");
+	printw("stepping through the dumped/restored screens.\n");
+	getyx(stdscr, y, x);
+
+	while (!done) {
+	    switch (ch = get_command(which, last)) {
+	    case 'n':
+		setup_next();
+		done = TRUE;
+		break;
+	    case 'q':
+		endwin();
+		cleanup(files);
+		done = TRUE;
+		break;
+	    case ' ':
+		if (files[which] != 0) {
+		    show_what(which + 1, last);
+		    if (scr_dump(files[which]) == ERR) {
+			endwin();
+			printf("Cannot write screen-dump %s\n", files[which]);
+			cleanup(files);
+			done = TRUE;
+			break;
+		    }
+		    ++which;
+		    if (has_colors()) {
+			short pair = which % COLOR_PAIRS;
+			bkgd(COLOR_PAIR(pair));
+		    }
+		} else {
+		    beep();
+		}
+		break;
+	    case KEY_LEFT:
+	    case 'h':
+		if (--x < 0)
+		    x = COLS - 1;
+		break;
+	    case KEY_DOWN:
+	    case 'j':
+		if (++y >= LINES)
+		    y = 1;
+		break;
+	    case KEY_UP:
+	    case 'k':
+		if (--y < 1)
+		    y = LINES - 1;
+		break;
+	    case KEY_RIGHT:
+	    case 'l':
+		if (++x >= COLS)
+		    x = 0;
+		break;
+	    }
+	    if (!done) {
+		time_t now = time((time_t *) 0);
+
+		move(0, 0);
+		addstr(ctime(&now));
+		move(y, x);
+		addch('#' | A_REVERSE);
+		move(y, x);
+	    }
+	}
+    }
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/savescreen.sh b/test/savescreen.sh
new file mode 100755
index 0000000..481d3ff
--- /dev/null
+++ b/test/savescreen.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+##############################################################################
+# Copyright (c) 2007 Free Software Foundation, Inc.                          #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+# $Id: savescreen.sh,v 1.3 2007/07/14 21:50:26 tom Exp $
+#
+# Use this script to exercise "savescreen".
+# It starts by generating a series of temporary-filenames, which are passed
+# to the test-program.  Loop as long as the first file named exists.
+PARAMS=
+NFILES=4
+PREFIX=savescreen-$$
+n=0
+BEGINS=$PREFIX-$n.tmp
+while test $n != $NFILES
+do
+	LATEST=$PREFIX-$n.tmp
+	PARAMS="$PARAMS $LATEST"
+	n=`expr $n + 1`
+done
+
+./savescreen $PARAMS
+if test -f $BEGINS
+then
+	while test -f $BEGINS
+	do
+		./savescreen -r $PARAMS
+	done
+else
+	echo "No screens were saved"
+fi
diff --git a/test/tclock.c b/test/tclock.c
new file mode 100644
index 0000000..394ee81
--- /dev/null
+++ b/test/tclock.c
@@ -0,0 +1,258 @@
+/* $Id: tclock.c,v 1.25 2005/04/16 16:39:27 tom Exp $ */
+
+#include <test.priv.h>
+
+#include <math.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+/*
+  tclock - analog/digital clock for curses.
+  If it gives you joy, then
+  (a) I'm glad
+  (b) you need to get out more :-)
+
+  This program is copyright Howard Jones, September 1994
+  (ha.jones@ic.ac.uk). It may be freely distributed as
+  long as this copyright message remains intact, and any
+  modifications are clearly marked as such. [In fact, if
+  you modify it, I wouldn't mind the modifications back,
+  especially if they add any nice features. A good one
+  would be a precalc table for the 60 hand positions, so
+  that the floating point stuff can be ditched. As I said,
+  it was a 20 hackup minute job.]
+
+  COMING SOON: tfishtank. Be the envy of your mac-owning
+  colleagues.
+*/
+
+/* To compile: cc -o tclock tclock.c -lcurses -lm */
+
+#ifndef PI
+#define PI 3.141592654
+#endif
+
+#define sign(_x) (_x<0?-1:1)
+
+#define ASPECT 2.2
+#define ROUND(value) ((int)((value) + 0.5))
+
+#define A2X(angle,radius) ROUND(ASPECT * radius * sin(angle))
+#define A2Y(angle,radius) ROUND(radius * cos(angle))
+
+/* Plot a point */
+static void
+plot(int x, int y, char col)
+{
+    mvaddch(y, x, (chtype) col);
+}
+
+/* Draw a diagonal(arbitrary) line using Bresenham's alogrithm. */
+static void
+dline(int pair, int from_x, int from_y, int x2, int y2, char ch)
+{
+    int dx, dy;
+    int ax, ay;
+    int sx, sy;
+    int x, y;
+    int d;
+
+    if (has_colors())
+	attrset(COLOR_PAIR(pair));
+
+    dx = x2 - from_x;
+    dy = y2 - from_y;
+
+    ax = abs(dx * 2);
+    ay = abs(dy * 2);
+
+    sx = sign(dx);
+    sy = sign(dy);
+
+    x = from_x;
+    y = from_y;
+
+    if (ax > ay) {
+	d = ay - (ax / 2);
+
+	while (1) {
+	    plot(x, y, ch);
+	    if (x == x2)
+		return;
+
+	    if (d >= 0) {
+		y += sy;
+		d -= ax;
+	    }
+	    x += sx;
+	    d += ay;
+	}
+    } else {
+	d = ax - (ay / 2);
+
+	while (1) {
+	    plot(x, y, ch);
+	    if (y == y2)
+		return;
+
+	    if (d >= 0) {
+		x += sx;
+		d -= ay;
+	    }
+	    y += sy;
+	    d += ax;
+	}
+    }
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    int i, cx, cy;
+    double cr, mradius, hradius, mangle, hangle;
+    double sangle, sradius, hours;
+    int hdx, hdy;
+    int mdx, mdy;
+    int sdx, sdy;
+    int ch;
+    int lastbeep = -1;
+    bool odd = FALSE;
+    time_t tim;
+    struct tm *t;
+    char szChar[10];
+    char *text;
+    int my_bg = COLOR_BLACK;
+#if HAVE_GETTIMEOFDAY
+    struct timeval current;
+    double fraction = 0.0;
+#endif
+
+    setlocale(LC_ALL, "");
+
+    initscr();
+    noecho();
+    cbreak();
+    nodelay(stdscr, TRUE);
+    curs_set(0);
+
+    if (has_colors()) {
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() == OK)
+	    my_bg = -1;
+#endif
+	init_pair(1, COLOR_RED, my_bg);
+	init_pair(2, COLOR_MAGENTA, my_bg);
+	init_pair(3, COLOR_GREEN, my_bg);
+	init_pair(4, COLOR_WHITE, COLOR_BLUE);
+    }
+#ifdef KEY_RESIZE
+    keypad(stdscr, TRUE);
+  restart:
+#endif
+    cx = (COLS - 1) / 2;	/* 39 */
+    cy = LINES / 2;		/* 12 */
+    if (cx / ASPECT < cy)
+	cr = cx / ASPECT;
+    else
+	cr = cy;
+    sradius = (5 * cr) / 6;	/* 10 */
+    mradius = (3 * cr) / 4;	/* 9 */
+    hradius = cr / 2;		/* 6 */
+
+    for (i = 0; i < 12; i++) {
+	sangle = (i + 1) * (2.0 * PI) / 12.0;
+	sdx = A2X(sangle, sradius);
+	sdy = A2Y(sangle, sradius);
+	sprintf(szChar, "%d", i + 1);
+
+	mvaddstr(cy - sdy, cx + sdx, szChar);
+    }
+
+    mvaddstr(0, 0, "ASCII Clock by Howard Jones (ha.jones@ic.ac.uk),1994");
+
+    sradius = (4 * sradius) / 5;
+    for (;;) {
+	napms(100);
+
+	tim = time(0);
+	t = localtime(&tim);
+
+	hours = (t->tm_hour + (t->tm_min / 60.0));
+	if (hours > 12.0)
+	    hours -= 12.0;
+
+	mangle = ((t->tm_min + (t->tm_sec / 60.0)) * (2 * PI) / 60.0);
+	mdx = A2X(mangle, mradius);
+	mdy = A2Y(mangle, mradius);
+
+	hangle = ((hours) * (2.0 * PI) / 12.0);
+	hdx = A2X(hangle, hradius);
+	hdy = A2Y(hangle, hradius);
+
+#if HAVE_GETTIMEOFDAY
+	gettimeofday(&current, 0);
+	fraction = (current.tv_usec / 1.0e6);
+#endif
+	sangle = ((t->tm_sec + fraction) * (2.0 * PI) / 60.0);
+	sdx = A2X(sangle, sradius);
+	sdy = A2Y(sangle, sradius);
+
+	dline(3, cx, cy, cx + mdx, cy - mdy, '#');
+
+	attrset(A_REVERSE);
+	dline(2, cx, cy, cx + hdx, cy - hdy, '.');
+	attroff(A_REVERSE);
+
+	if (has_colors())
+	    attrset(COLOR_PAIR(1));
+
+	dline(1, cx, cy, cx + sdx, cy - sdy, 'O');
+
+	if (has_colors())
+	    attrset(COLOR_PAIR(0));
+
+	text = ctime(&tim);
+	mvprintw(2, 0, "%.*s", (int) (strlen(text) - 1), text);
+	refresh();
+	if ((t->tm_sec % 5) == 0
+	    && t->tm_sec != lastbeep) {
+	    lastbeep = t->tm_sec;
+	    if (has_colors()) {
+		odd = !odd;
+		bkgd((chtype) (odd ? COLOR_PAIR(4) : COLOR_PAIR(0)));
+	    }
+	    beep();
+	}
+
+	if ((ch = getch()) != ERR) {
+#ifdef KEY_RESIZE
+	    if (ch == KEY_RESIZE) {
+		flash();
+		erase();
+		wrefresh(curscr);
+		goto restart;
+	    }
+#endif
+	    break;
+	}
+
+	dline(0, cx, cy, cx + hdx, cy - hdy, ' ');
+	dline(0, cx, cy, cx + mdx, cy - mdy, ' ');
+	dline(0, cx, cy, cx + sdx, cy - sdy, ' ');
+
+    }
+
+    curs_set(1);
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/test.priv.h b/test/test.priv.h
new file mode 100644
index 0000000..7c1f39f
--- /dev/null
+++ b/test/test.priv.h
@@ -0,0 +1,577 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/****************************************************************************
+ *  Author: Thomas E. Dickey                    1996-on                     *
+ ****************************************************************************/
+/* $Id: test.priv.h,v 1.79 2008/10/04 21:53:41 tom Exp $ */
+
+#ifndef __TEST_PRIV_H
+#define __TEST_PRIV_H 1
+
+#include <ncurses_cfg.h>
+
+/*
+ * Fix ifdef's that look for the form/menu/panel libraries, if we are building
+ * with wide-character ncurses.
+ */
+#ifdef  HAVE_LIBFORMW
+#define HAVE_LIBFORMW 1
+#endif
+
+#ifdef  HAVE_LIBMENUW
+#define HAVE_LIBMENUW 1
+#endif
+
+#ifdef  HAVE_LIBPANELW
+#define HAVE_LIBPANELW 1
+#endif
+
+/*
+ * Fallback definitions to accommodate broken compilers.
+ */
+#ifndef HAVE_CURSES_VERSION
+#define HAVE_CURSES_VERSION 0
+#endif
+
+#ifndef HAVE_CHGAT
+#define HAVE_CHGAT 0
+#endif
+
+#ifndef HAVE_COLOR_SET
+#define HAVE_COLOR_SET 0
+#endif
+
+#ifndef HAVE_FILTER
+#define HAVE_FILTER 0
+#endif
+
+#ifndef HAVE_FORM_H
+#define HAVE_FORM_H 0
+#endif
+
+#ifndef HAVE_GETBEGX
+#define HAVE_GETBEGX 0
+#endif
+
+#ifndef HAVE_GETCURX
+#define HAVE_GETCURX 0
+#endif
+
+#ifndef HAVE_GETMAXX
+#define HAVE_GETMAXX 0
+#endif
+
+#ifndef HAVE_GETOPT_H
+#define HAVE_GETOPT_H 0
+#endif
+
+#ifndef HAVE_GETPARX
+#define HAVE_GETPARX 0
+#endif
+
+#ifndef HAVE_GETWIN
+#define HAVE_GETWIN 0
+#endif
+
+#ifndef HAVE_LIBFORM
+#define HAVE_LIBFORM 0
+#endif
+
+#ifndef HAVE_LIBMENU
+#define HAVE_LIBMENU 0
+#endif
+
+#ifndef HAVE_LIBPANEL
+#define HAVE_LIBPANEL 0
+#endif
+
+#ifndef HAVE_LOCALE_H
+#define HAVE_LOCALE_H 0
+#endif
+
+#ifndef HAVE_MENU_H
+#define HAVE_MENU_H 0
+#endif
+
+#ifndef HAVE_MVVLINE
+#define HAVE_MVVLINE 0
+#endif
+
+#ifndef HAVE_MVWVLINE
+#define HAVE_MVWVLINE 0
+#endif
+
+#ifndef HAVE_NAPMS
+#define HAVE_NAPMS 1
+#endif
+
+#ifndef HAVE_NC_ALLOC_H
+#define HAVE_NC_ALLOC_H 0
+#endif
+
+#ifndef HAVE_PANEL_H
+#define HAVE_PANEL_H 0
+#endif
+
+#ifndef HAVE_PUTWIN
+#define HAVE_PUTWIN 0
+#endif
+
+#ifndef HAVE_RESIZE_TERM
+#define HAVE_RESIZE_TERM 0
+#endif
+
+#ifndef HAVE_RIPOFFLINE
+#define HAVE_RIPOFFLINE 0
+#endif
+
+#ifndef HAVE_SETUPTERM
+#define HAVE_SETUPTERM 0
+#endif
+
+#ifndef HAVE_SLK_COLOR
+#define HAVE_SLK_COLOR 0
+#endif
+
+#ifndef HAVE_SLK_INIT
+#define HAVE_SLK_INIT 0
+#endif
+
+#ifndef HAVE_TERMATTRS
+#define HAVE_TERMATTRS 0
+#endif
+
+#ifndef HAVE_TERMNAME
+#define HAVE_TERMNAME 0
+#endif
+
+#ifndef HAVE_TGETENT
+#define HAVE_TGETENT 0
+#endif
+
+#ifndef HAVE_TIGETNUM
+#define HAVE_TIGETNUM 0
+#endif
+
+#ifndef HAVE_TYPEAHEAD
+#define HAVE_TYPEAHEAD 0
+#endif
+
+#ifndef HAVE_TIGETSTR
+#define HAVE_TIGETSTR 0
+#endif
+
+#ifndef HAVE_WINSSTR
+#define HAVE_WINSSTR 0
+#endif
+
+#ifndef HAVE_USE_DEFAULT_COLORS
+#define HAVE_USE_DEFAULT_COLORS 0
+#endif
+
+#ifndef HAVE_WRESIZE
+#define HAVE_WRESIZE 0
+#endif
+
+#ifndef NCURSES_EXT_FUNCS
+#define NCURSES_EXT_FUNCS 0
+#endif
+
+#ifndef NEED_PTEM_H
+#define NEED_PTEM_H 0
+#endif
+
+#ifndef NO_LEAKS
+#define NO_LEAKS 0
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <signal.h>	/* include before curses.h to work around glibc bug */
+
+#if defined(HAVE_XCURSES)
+#include <xcurses.h>
+#elif defined(HAVE_NCURSESW_NCURSES_H)
+#include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#include <ncurses/curses.h>
+#else
+#include <curses.h>
+#endif
+
+#if defined(HAVE_XCURSES)
+/* no other headers */
+#undef  HAVE_SETUPTERM		/* nonfunctional */
+#define HAVE_SETUPTERM 0
+#undef  HAVE_TGETENT		/* nonfunctional */
+#define HAVE_TGETENT 0
+#undef  HAVE_TIGETSTR		/* nonfunctional */
+#define HAVE_TIGETSTR 0
+#elif defined(HAVE_NCURSESW_TERM_H)
+#include <ncursesw/term.h>
+#elif defined(HAVE_NCURSES_TERM_H)
+#include <ncurses/term.h>
+#elif defined(HAVE_TERM_H)
+#include <term.h>
+#endif
+
+/*
+ * Not all curses.h implementations include unctrl.h,
+ * Solaris 10 xpg4 for example.
+ */
+#if defined(NCURSES_VERSION) || defined(_XOPEN_CURSES)
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#include <ncursesw/unctrl.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#include <ncurses/unctrl.h>
+#else
+#include <unctrl.h>
+#endif
+#endif
+
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#else
+/* 'getopt()' may be prototyped in <stdlib.h>, but declaring its variables
+ * doesn't hurt.
+ */
+extern char *optarg;
+extern int optind;
+#endif /* HAVE_GETOPT_H */
+
+#if HAVE_LOCALE_H
+#include <locale.h>
+#else
+#define setlocale(name,string) /* nothing */
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+
+#ifndef GCC_NORETURN
+#define GCC_NORETURN /* nothing */
+#endif
+#ifndef GCC_PRINTFLIKE
+#define GCC_PRINTFLIKE(a,b) /* nothing */
+#endif
+#ifndef GCC_UNUSED
+#define GCC_UNUSED /* nothing */
+#endif
+
+#ifndef HAVE_GETNSTR
+#define getnstr(s,n) getstr(s)
+#endif
+
+#ifndef USE_SOFTKEYS
+#if HAVE_SLK_INIT
+#define USE_SOFTKEYS 1
+#else
+#define USE_SOFTKEYS 0
+#endif
+#endif
+
+#ifndef USE_WIDEC_SUPPORT
+#if defined(_XOPEN_SOURCE_EXTENDED) && defined(WACS_ULCORNER)
+#define USE_WIDEC_SUPPORT 1
+#else
+#define USE_WIDEC_SUPPORT 0
+#endif
+#endif
+
+#if HAVE_PANEL_H && HAVE_LIBPANEL
+#define USE_LIBPANEL 1
+#else
+#define USE_LIBPANEL 0
+#endif
+
+#if HAVE_MENU_H && HAVE_LIBMENU
+#define USE_LIBMENU 1
+#else
+#define USE_LIBMENU 0
+#endif
+
+#if HAVE_FORM_H && HAVE_LIBFORM
+#define USE_LIBFORM 1
+#else
+#define USE_LIBFORM 0
+#endif
+
+#ifndef HAVE_TYPE_ATTR_T
+#if !USE_WIDEC_SUPPORT && !defined(attr_t)
+#define attr_t chtype
+#endif
+#endif
+
+#undef NCURSES_CH_T
+#if !USE_WIDEC_SUPPORT
+#define NCURSES_CH_T chtype
+#else
+#define NCURSES_CH_T cchar_t
+#endif
+
+#ifndef NCURSES_OPAQUE
+#define NCURSES_OPAQUE 0
+#endif
+
+#ifndef CCHARW_MAX
+#define CCHARW_MAX 5
+#endif
+
+#undef CTRL
+#define CTRL(x)	((x) & 0x1f)
+
+#define QUIT		CTRL('Q')
+#define ESCAPE		CTRL('[')
+
+#ifndef KEY_MIN
+#define KEY_MIN 256	/* not defined in Solaris 8 */
+#endif
+
+/*
+ * Workaround for HPUX
+ */
+#if defined(__hpux) && !defined(NCURSES_VERSION)
+#define getbegx(w) __getbegx(w)
+#define getbegy(w) __getbegy(w)
+#define getcurx(w) __getcurx(w)
+#define getcury(w) __getcury(w)
+#define getmaxx(w) __getmaxx(w)
+#define getmaxy(w) __getmaxy(w)
+#define getparx(w) __getparx(w)
+#define getpary(w) __getpary(w)
+#endif
+
+/*
+ * These usually are implemented as macros, but may be functions.
+ */
+#if !defined(getcurx) && !HAVE_GETCURX
+#define getcurx(win)            ((win)?(win)->_curx:ERR)
+#define getcury(win)            ((win)?(win)->_cury:ERR)
+#endif
+
+#if !defined(getbegx) && !HAVE_GETBEGX
+#define getbegx(win)            ((win)?(win)->_begx:ERR)
+#define getbegy(win)            ((win)?(win)->_begy:ERR)
+#endif
+
+#if !defined(getmaxx) && !HAVE_GETMAXX
+#define getmaxx(win)            ((win)?((win)->_maxx + 1):ERR)
+#define getmaxy(win)            ((win)?((win)->_maxy + 1):ERR)
+#endif
+
+/*
+ * Solaris 10 xpg4:
+#define	__m_getparx(w)		((w)->_parent == (WINDOW *) 0 ? -1 \
+				: (w)->_begx - (w)->_parent->_begx)
+ */
+#if !defined(getparx) && !HAVE_GETPARX
+#ifdef __m_getparx
+#define getparx(win)            __m_getparx(win)
+#define getpary(win)            __m_getpary(win)
+#else
+#define getparx(win)            ((win)?((win)->_parx + 1):ERR)
+#define getpary(win)            ((win)?((win)->_pary + 1):ERR)
+#endif
+#endif
+
+#if !defined(mvwvline) && !HAVE_MVWVLINE
+#define mvwvline(w,y,x,ch,n)    (move(y,x) == ERR ? ERR : wvline(w,ch,n))
+#define mvwhline(w,y,x,ch,n)    (move(y,x) == ERR ? ERR : whline(w,ch,n))
+#endif
+
+#if !defined(mvvline) && !HAVE_MVVLINE
+#define mvvline(y,x,ch,n)       (move(y,x) == ERR ? ERR : vline(ch,n))
+#define mvhline(y,x,ch,n)       (move(y,x) == ERR ? ERR : hline(ch,n))
+#endif
+
+/*
+ * Try to accommodate curses implementations that have no terminfo support.
+ */
+#if HAVE_TIGETNUM
+#define TIGETNUM(ti,tc) tigetnum(ti)
+#else
+#define TIGETNUM(ti,tc) tgetnum(tc)
+#endif
+
+#if HAVE_TIGETSTR
+#define TIGETSTR(ti,tc) tigetstr(ti)
+#else
+#define TIGETSTR(ti,tc) tgetstr(tc,&area_pointer)
+#endif
+
+/* ncurses implements tparm() with varargs, X/Open with a fixed-parameter list
+ * (which is incompatible with legacy usage, doesn't solve any problems).
+ */
+#define tparm3(a,b,c) tparm(a,b,c,0,0,0,0,0,0,0)
+#define tparm2(a,b)   tparm(a,b,0,0,0,0,0,0,0,0)
+
+#define UChar(c)    ((unsigned char)(c))
+
+#define SIZEOF(table)	(sizeof(table)/sizeof(table[0]))
+
+#if defined(NCURSES_VERSION) && HAVE_NC_ALLOC_H
+#include <nc_alloc.h>
+#if HAVE_NC_FREEALL && defined(USE_TINFO)
+#undef ExitProgram
+#define ExitProgram(code) _nc_free_tinfo(code)
+#endif
+#else
+#define typeMalloc(type,n) (type *) malloc((n) * sizeof(type))
+#define typeCalloc(type,elts) (type *) calloc((elts), sizeof(type))
+#define typeRealloc(type,n,p) (type *) realloc(p, (n) * sizeof(type))
+#endif
+
+#ifndef ExitProgram
+#define ExitProgram(code) exit(code)
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+/* Use this to quiet gcc's -Wwrite-strings warnings, but accommodate SVr4
+ * curses which doesn't have const parameters declared (so far) in the places
+ * that XSI shows.
+ */
+#ifndef NCURSES_CONST
+#define NCURSES_CONST /* nothing */
+#endif
+
+/* out-of-band values for representing absent capabilities */
+#define ABSENT_BOOLEAN		((signed char)-1)	/* 255 */
+#define ABSENT_NUMERIC		(-1)
+#define ABSENT_STRING		(char *)0
+
+/* out-of-band values for representing cancels */
+#define CANCELLED_BOOLEAN	((signed char)-2)	/* 254 */
+#define CANCELLED_NUMERIC	(-2)
+#define CANCELLED_STRING	(char *)(-1)
+
+#define VALID_BOOLEAN(s) ((unsigned char)(s) <= 1) /* reject "-1" */
+#define VALID_NUMERIC(s) ((s) >= 0)
+#define VALID_STRING(s)  ((s) != CANCELLED_STRING && (s) != ABSENT_STRING)
+
+#define VT_ACSC "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~"
+
+#define CATCHALL(handler) { \
+		int nsig; \
+		for (nsig = SIGHUP; nsig < SIGTERM; ++nsig) \
+		    if (nsig != SIGKILL) \
+			signal(nsig, handler); \
+	    }
+
+/*
+ * Workaround for clean(er) compile with Solaris's legacy curses.
+ * The same would be needed for HPUX 10.20
+ */
+#ifndef TPUTS_ARG
+#if defined(sun) && !defined(_XOPEN_CURSES) && !defined(NCURSES_VERSION_PATCH)
+#define TPUTS_ARG char
+extern char *tgoto(char *, int, int);	/* available, but not prototyped */
+#else
+#define TPUTS_ARG int
+#endif
+#endif
+
+/*
+ * Workarounds for Solaris's X/Open curses
+ */
+#if defined(sun) && defined(_XOPEN_CURSES) && !defined(NCURSES_VERSION_PATCH)
+#if !defined(KEY_MIN) && defined(__KEY_MIN)
+#define KEY_MIN __KEY_MIN
+#endif
+#if !defined(KEY_MAX) && defined(__KEY_MIN)
+#define KEY_MAX __KEY_MAX
+#endif
+#endif
+
+/*
+ * ncurses uses const in some places where X/Open does (or did) not allow.
+ */
+#ifdef NCURSES_VERSION
+#define CONST_MENUS const
+#else
+#define CONST_MENUS /* nothing */
+#endif
+
+#ifndef HAVE_USE_WINDOW
+#if !defined(NCURSES_VERSION_PATCH) || (NCURSES_VERSION_PATCH < 20070915) || !NCURSES_EXT_FUNCS
+#define HAVE_USE_WINDOW 0
+#else
+#define HAVE_USE_WINDOW 1
+#endif
+#endif
+
+/*
+ * Simplify setting up demo of threading with these macros.
+ */
+
+#if !HAVE_USE_WINDOW
+typedef int (*NCURSES_WINDOW_CB)(WINDOW *, void *);
+typedef int (*NCURSES_SCREEN_CB)(SCREEN *, void *);
+#endif
+
+#if HAVE_USE_WINDOW
+#define USING_WINDOW(w,func) use_window(w, (NCURSES_WINDOW_CB) func, w)
+#define USING_WINDOW2(w,func,data) use_window(w, (NCURSES_WINDOW_CB) func, data)
+#define WANT_USE_WINDOW() extern void _nc_want_use_window(void)
+#else
+#define USING_WINDOW(w,func) func(w)
+#define USING_WINDOW2(w,func,data) func(w,data)
+#define WANT_USE_WINDOW() extern void _nc_want_use_window(void)
+#endif
+
+#if HAVE_USE_WINDOW
+#define USING_SCREEN(s,func,data) use_screen(s, (NCURSES_SCREEN_CB) func, data)
+#define WANT_USE_SCREEN() extern void _nc_want_use_screen(void)
+#else
+#define USING_SCREEN(s,func,data) func(s,data)
+#define WANT_USE_SCREEN() extern void _nc_want_use_screen(void)
+#endif
+
+#ifdef TRACE
+#define Trace(p) _tracef p
+#define USE_TRACE 1
+#else
+#define Trace(p)		/* nothing */
+#define USE_TRACE 0
+#endif
+
+#define init_mb(state)	memset(&state, 0, sizeof(state))
+
+#endif /* __TEST_PRIV_H */
diff --git a/test/test_arrays.c b/test/test_arrays.c
new file mode 100644
index 0000000..ff6a10b
--- /dev/null
+++ b/test/test_arrays.c
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * Copyright (c) 2007,2008 Free Software Foundation, Inc.                   *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: test_arrays.c,v 1.3 2008/02/09 18:09:43 tom Exp $
+ *
+ * Author: Thomas E Dickey
+ *
+ * Demonstrate the public arrays from the terminfo library.
+
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolnames[];
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolcodes[];
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolfnames[];
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numnames[];
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numcodes[];
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numfnames[];
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strnames[];
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strcodes[];
+extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strfnames[];
+
+ */
+
+#define USE_TINFO
+#include <test.priv.h>
+
+#if defined(NCURSES_VERSION) || !defined(_XOPEN_CURSES)
+
+#define DUMP(name) dump_array(#name, name)
+
+static void
+dump_array(const char *name, NCURSES_CONST char *const *list)
+{
+    int n;
+
+    printf("%s:\n", name);
+    for (n = 0; list[n] != 0; ++n) {
+	printf("%5d:%s\n", n, list[n]);
+    }
+}
+
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    DUMP(boolnames);
+    DUMP(boolcodes);
+    DUMP(boolfnames);
+
+    DUMP(numnames);
+    DUMP(numcodes);
+    DUMP(numfnames);
+
+    DUMP(strnames);
+    DUMP(strcodes);
+    DUMP(strfnames);
+
+    ExitProgram(EXIT_SUCCESS);
+}
+
+#else
+int
+main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
+{
+    printf("This program requires the terminfo arrays\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/test_get_wstr.c b/test/test_get_wstr.c
new file mode 100644
index 0000000..7ae3730
--- /dev/null
+++ b/test/test_get_wstr.c
@@ -0,0 +1,361 @@
+/****************************************************************************
+ * Copyright (c) 2007 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: test_get_wstr.c,v 1.5 2007/08/11 17:01:43 tom Exp $
+ *
+ * Author: Thomas E Dickey
+ *
+ * Demonstrate the get_wstr functions from the curses library.
+
+       int get_wstr(wint_t *wstr);
+       int getn_wstr(wint_t *wstr, int n);
+       int wget_wstr(WINDOW *win, wint_t *wstr);
+       int wgetn_wstr(WINDOW *win, wint_t *wstr, int n);
+       int mvget_wstr(int y, int x, wint_t *wstr);
+       int mvgetn_wstr(int y, int x, wint_t *wstr, int n);
+       int mvwget_wstr(WINDOW *win, int y, int x, wint_t *wstr);
+       int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n);
+ */
+
+#include <test.priv.h>
+
+#if USE_WIDEC_SUPPORT
+
+#define BASE_Y 6
+#define MAX_COLS 1024
+
+typedef enum {
+    eGetStr = 0,
+    eGetNStr,
+    eMvGetStr,
+    eMvGetNStr,
+    eMaxFlavor
+} Flavors;
+
+static bool
+Quit(int ch)
+{
+    return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
+}
+
+static int
+Remainder(WINDOW *txtwin)
+{
+    int result = getmaxx(txtwin) - getcurx(txtwin);
+    return (result > 0) ? result : 0;
+}
+
+/*
+ * Show a highlighted line in the place where input will happen.
+ */
+static void
+ShowPrompt(WINDOW *txtwin, int limit)
+{
+    wchgat(txtwin, limit, A_REVERSE, 0, NULL);
+    wnoutrefresh(txtwin);
+}
+
+static void
+MovePrompt(WINDOW *txtwin, int limit, int y, int x)
+{
+    wchgat(txtwin, Remainder(txtwin), A_NORMAL, 0, NULL);
+    wmove(txtwin, y, x);
+    ShowPrompt(txtwin, limit);
+}
+
+static int
+ShowFlavor(WINDOW *strwin, WINDOW *txtwin, int flavor, int limit)
+{
+    const char *name = "?";
+    bool limited = FALSE;
+    bool wins = (txtwin != stdscr);
+    int result;
+
+    switch (flavor) {
+    case eGetStr:
+	name = wins ? "wget_wstr" : "get_wstr";
+	break;
+    case eGetNStr:
+	limited = TRUE;
+	name = wins ? "wgetn_wstr" : "getn_wstr";
+	break;
+    case eMvGetStr:
+	name = wins ? "mvwget_wstr" : "mvget_wstr";
+	break;
+    case eMvGetNStr:
+	limited = TRUE;
+	name = wins ? "mvwgetn_wstr" : "mvgetn_wstr";
+	break;
+    case eMaxFlavor:
+	break;
+    }
+
+    wmove(strwin, 0, 0);
+    werase(strwin);
+
+    if (limited) {
+	wprintw(strwin, "%s(%d):", name, limit);
+    } else {
+	wprintw(strwin, "%s:", name);
+    }
+    result = limited ? limit : Remainder(txtwin);
+    ShowPrompt(txtwin, result);
+
+    wnoutrefresh(strwin);
+    return result;
+}
+
+static int
+test_get_wstr(int level, char **argv, WINDOW *strwin)
+{
+    WINDOW *txtbox = 0;
+    WINDOW *txtwin = 0;
+    FILE *fp;
+    int ch;
+    int rc;
+    int txt_x = 0, txt_y = 0;
+    int base_y;
+    int flavor = 0;
+    int limit = getmaxx(strwin) - 5;
+    int actual;
+    wint_t buffer[MAX_COLS];
+
+    if (argv[level] == 0) {
+	beep();
+	return FALSE;
+    }
+
+    if (level > 1) {
+	txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
+	box(txtbox, 0, 0);
+	wnoutrefresh(txtbox);
+
+	txtwin = derwin(txtbox,
+			getmaxy(txtbox) - 2,
+			getmaxx(txtbox) - 2,
+			1, 1);
+	base_y = 0;
+    } else {
+	txtwin = stdscr;
+	base_y = BASE_Y;
+    }
+
+    keypad(txtwin, TRUE);	/* enable keyboard mapping */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    txt_y = base_y;
+    txt_x = 0;
+    wmove(txtwin, txt_y, txt_x);
+
+    if ((fp = fopen(argv[level], "r")) != 0) {
+	while ((ch = fgetc(fp)) != EOF) {
+	    if (waddch(txtwin, UChar(ch)) != OK) {
+		break;
+	    }
+	}
+	fclose(fp);
+    } else {
+	wprintw(txtwin, "Cannot open:\n%s", argv[1]);
+    }
+
+    wmove(txtwin, txt_y, txt_x);
+    actual = ShowFlavor(strwin, txtwin, flavor, limit);
+    while (!Quit(ch = mvwgetch(txtwin, txt_y, txt_x))) {
+	switch (ch) {
+	case KEY_DOWN:
+	case 'j':
+	    if (txt_y < getmaxy(txtwin) - 1) {
+		MovePrompt(txtwin, actual, ++txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_UP:
+	case 'k':
+	    if (txt_y > base_y) {
+		MovePrompt(txtwin, actual, --txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_LEFT:
+	case 'h':
+	    if (txt_x > 0) {
+		MovePrompt(txtwin, actual, txt_y, --txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_RIGHT:
+	case 'l':
+	    if (txt_x < getmaxx(txtwin) - 1) {
+		MovePrompt(txtwin, actual, txt_y, ++txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+
+	case 'w':
+	    test_get_wstr(level + 1, argv, strwin);
+	    if (txtbox != 0) {
+		touchwin(txtbox);
+		wnoutrefresh(txtbox);
+	    } else {
+		touchwin(txtwin);
+		wnoutrefresh(txtwin);
+	    }
+	    break;
+
+	case '-':
+	    if (limit > 0) {
+		actual = ShowFlavor(strwin, txtwin, flavor, --limit);
+		MovePrompt(txtwin, actual, txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+
+	case '+':
+	    actual = ShowFlavor(strwin, txtwin, flavor, ++limit);
+	    MovePrompt(txtwin, actual, txt_y, txt_x);
+	    break;
+
+	case '<':
+	    if (flavor > 0) {
+		actual = ShowFlavor(strwin, txtwin, --flavor, limit);
+		MovePrompt(txtwin, actual, txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+
+	case '>':
+	    if (flavor + 1 < eMaxFlavor) {
+		actual = ShowFlavor(strwin, txtwin, ++flavor, limit);
+		MovePrompt(txtwin, actual, txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+
+	case ':':
+	    actual = ShowFlavor(strwin, txtwin, flavor, limit);
+	    *buffer = '\0';
+	    rc = ERR;
+	    echo();
+	    wattrset(txtwin, A_REVERSE);
+	    switch (flavor) {
+	    case eGetStr:
+		if (txtwin != stdscr) {
+		    wmove(txtwin, txt_y, txt_x);
+		    rc = wget_wstr(txtwin, buffer);
+		} else {
+		    move(txt_y, txt_x);
+		    rc = get_wstr(buffer);
+		}
+		break;
+	    case eGetNStr:
+		if (txtwin != stdscr) {
+		    wmove(txtwin, txt_y, txt_x);
+		    rc = wgetn_wstr(txtwin, buffer, limit);
+		} else {
+		    move(txt_y, txt_x);
+		    rc = getn_wstr(buffer, limit);
+		}
+		break;
+	    case eMvGetStr:
+		if (txtwin != stdscr) {
+		    rc = mvwget_wstr(txtwin, txt_y, txt_x, buffer);
+		} else {
+		    rc = mvget_wstr(txt_y, txt_x, buffer);
+		}
+		break;
+	    case eMvGetNStr:
+		if (txtwin != stdscr) {
+		    rc = mvwgetn_wstr(txtwin, txt_y, txt_x, buffer, limit);
+		} else {
+		    rc = mvgetn_wstr(txt_y, txt_x, buffer, limit);
+		}
+		break;
+	    case eMaxFlavor:
+		break;
+	    }
+	    noecho();
+	    wattrset(txtwin, A_NORMAL);
+	    wprintw(strwin, "%d", rc);
+	    waddwstr(strwin, (wchar_t *) buffer);
+	    wnoutrefresh(strwin);
+	    break;
+	default:
+	    beep();
+	    break;
+	}
+	doupdate();
+    }
+    if (level > 1) {
+	delwin(txtwin);
+	delwin(txtbox);
+    }
+    return TRUE;
+}
+
+int
+main(int argc, char *argv[])
+{
+    WINDOW *chrbox;
+    WINDOW *strwin;
+
+    setlocale(LC_ALL, "");
+
+    if (argc < 2) {
+	fprintf(stderr, "usage: %s file\n", argv[0]);
+	return EXIT_FAILURE;
+    }
+
+    initscr();
+
+    chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
+    box(chrbox, 0, 0);
+    wnoutrefresh(chrbox);
+
+    strwin = derwin(chrbox, 4, COLS - 2, 1, 1);
+
+    test_get_wstr(1, argv, strwin);
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the wide-ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/test_getstr.c b/test/test_getstr.c
new file mode 100644
index 0000000..25dbecf
--- /dev/null
+++ b/test/test_getstr.c
@@ -0,0 +1,363 @@
+/****************************************************************************
+ * Copyright (c) 2007,2008 Free Software Foundation, Inc.                   *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: test_getstr.c,v 1.8 2008/02/09 18:09:35 tom Exp $
+ *
+ * Author: Thomas E Dickey
+ *
+ * Demonstrate the getstr functions from the curses library.
+
+       int getstr(char *str);
+       int getnstr(char *str, int n);
+       int wgetstr(WINDOW *win, char *str);
+       int wgetnstr(WINDOW *win, char *str, int n);
+       int mvgetstr(int y, int x, char *str);
+       int mvwgetstr(WINDOW *win, int y, int x, char *str);
+       int mvgetnstr(int y, int x, char *str, int n);
+       int mvwgetnstr(WINDOW *, int y, int x, char *str, int n);
+ */
+
+#include <test.priv.h>
+
+#if HAVE_CHGAT
+/* Solaris SVr4 curses lacks wchgat, mvgetnstr, mvwgetnstr */
+
+#define BASE_Y 6
+#define MAX_COLS 1024
+
+typedef enum {
+    eGetStr = 0,
+    eGetNStr,
+    eMvGetStr,
+    eMvGetNStr,
+    eMaxFlavor
+} Flavors;
+
+static bool
+Quit(int ch)
+{
+    return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
+}
+
+static int
+Remainder(WINDOW *txtwin)
+{
+    int result = getmaxx(txtwin) - getcurx(txtwin);
+    return (result > 0) ? result : 0;
+}
+
+/*
+ * Show a highlighted line in the place where input will happen.
+ */
+static void
+ShowPrompt(WINDOW *txtwin, int limit)
+{
+    wchgat(txtwin, limit, A_REVERSE, 0, NULL);
+    wnoutrefresh(txtwin);
+}
+
+static void
+MovePrompt(WINDOW *txtwin, int limit, int y, int x)
+{
+    wchgat(txtwin, Remainder(txtwin), A_NORMAL, 0, NULL);
+    wmove(txtwin, y, x);
+    ShowPrompt(txtwin, limit);
+}
+
+static int
+ShowFlavor(WINDOW *strwin, WINDOW *txtwin, int flavor, int limit)
+{
+    const char *name = "?";
+    bool limited = FALSE;
+    bool wins = (txtwin != stdscr);
+    int result;
+
+    switch (flavor) {
+    case eGetStr:
+	name = wins ? "wgetstr" : "getstr";
+	break;
+    case eGetNStr:
+	limited = TRUE;
+	name = wins ? "wgetnstr" : "getnstr";
+	break;
+    case eMvGetStr:
+	name = wins ? "mvwgetstr" : "mvgetstr";
+	break;
+    case eMvGetNStr:
+	limited = TRUE;
+	name = wins ? "mvwgetnstr" : "mvgetnstr";
+	break;
+    case eMaxFlavor:
+	break;
+    }
+
+    wmove(strwin, 0, 0);
+    werase(strwin);
+
+    if (limited) {
+	wprintw(strwin, "%s(%d):", name, limit);
+    } else {
+	wprintw(strwin, "%s:", name);
+    }
+    result = limited ? limit : Remainder(txtwin);
+    ShowPrompt(txtwin, result);
+
+    wnoutrefresh(strwin);
+    return result;
+}
+
+static int
+test_getstr(int level, char **argv, WINDOW *strwin)
+{
+    WINDOW *txtbox = 0;
+    WINDOW *txtwin = 0;
+    FILE *fp;
+    int ch;
+    int rc;
+    int txt_x = 0, txt_y = 0;
+    int base_y;
+    int flavor = 0;
+    int limit = getmaxx(strwin) - 5;
+    int actual;
+
+    char buffer[MAX_COLS];
+
+    if (argv[level] == 0) {
+	beep();
+	return FALSE;
+    }
+
+    if (level > 1) {
+	txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
+	box(txtbox, 0, 0);
+	wnoutrefresh(txtbox);
+
+	txtwin = derwin(txtbox,
+			getmaxy(txtbox) - 2,
+			getmaxx(txtbox) - 2,
+			1, 1);
+	base_y = 0;
+    } else {
+	txtwin = stdscr;
+	base_y = BASE_Y;
+    }
+
+    keypad(txtwin, TRUE);	/* enable keyboard mapping */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    txt_y = base_y;
+    txt_x = 0;
+    wmove(txtwin, txt_y, txt_x);
+
+    if ((fp = fopen(argv[level], "r")) != 0) {
+	while ((ch = fgetc(fp)) != EOF) {
+	    if (waddch(txtwin, UChar(ch)) != OK) {
+		break;
+	    }
+	}
+	fclose(fp);
+    } else {
+	wprintw(txtwin, "Cannot open:\n%s", argv[1]);
+    }
+
+    wmove(txtwin, txt_y, txt_x);
+    actual = ShowFlavor(strwin, txtwin, flavor, limit);
+    while (!Quit(ch = mvwgetch(txtwin, txt_y, txt_x))) {
+	switch (ch) {
+	case KEY_DOWN:
+	case 'j':
+	    if (txt_y < getmaxy(txtwin) - 1) {
+		MovePrompt(txtwin, actual, ++txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_UP:
+	case 'k':
+	    if (txt_y > base_y) {
+		MovePrompt(txtwin, actual, --txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_LEFT:
+	case 'h':
+	    if (txt_x > 0) {
+		MovePrompt(txtwin, actual, txt_y, --txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+	case KEY_RIGHT:
+	case 'l':
+	    if (txt_x < getmaxx(txtwin) - 1) {
+		MovePrompt(txtwin, actual, txt_y, ++txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+
+	case 'w':
+	    test_getstr(level + 1, argv, strwin);
+	    if (txtbox != 0) {
+		touchwin(txtbox);
+		wnoutrefresh(txtbox);
+	    } else {
+		touchwin(txtwin);
+		wnoutrefresh(txtwin);
+	    }
+	    break;
+
+	case '-':
+	    if (limit > 0) {
+		actual = ShowFlavor(strwin, txtwin, flavor, --limit);
+		MovePrompt(txtwin, actual, txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+
+	case '+':
+	    actual = ShowFlavor(strwin, txtwin, flavor, ++limit);
+	    MovePrompt(txtwin, actual, txt_y, txt_x);
+	    break;
+
+	case '<':
+	    if (flavor > 0) {
+		actual = ShowFlavor(strwin, txtwin, --flavor, limit);
+		MovePrompt(txtwin, actual, txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+
+	case '>':
+	    if (flavor + 1 < eMaxFlavor) {
+		actual = ShowFlavor(strwin, txtwin, ++flavor, limit);
+		MovePrompt(txtwin, actual, txt_y, txt_x);
+	    } else {
+		beep();
+	    }
+	    break;
+
+	case ':':
+	    actual = ShowFlavor(strwin, txtwin, flavor, limit);
+	    *buffer = '\0';
+	    rc = ERR;
+	    echo();
+	    wattrset(txtwin, A_REVERSE);
+	    switch (flavor) {
+	    case eGetStr:
+		if (txtwin != stdscr) {
+		    wmove(txtwin, txt_y, txt_x);
+		    rc = wgetstr(txtwin, buffer);
+		} else {
+		    move(txt_y, txt_x);
+		    rc = getstr(buffer);
+		}
+		break;
+	    case eGetNStr:
+		if (txtwin != stdscr) {
+		    wmove(txtwin, txt_y, txt_x);
+		    rc = wgetnstr(txtwin, buffer, limit);
+		} else {
+		    move(txt_y, txt_x);
+		    rc = getnstr(buffer, limit);
+		}
+		break;
+	    case eMvGetStr:
+		if (txtwin != stdscr) {
+		    rc = mvwgetstr(txtwin, txt_y, txt_x, buffer);
+		} else {
+		    rc = mvgetstr(txt_y, txt_x, buffer);
+		}
+		break;
+	    case eMvGetNStr:
+		if (txtwin != stdscr) {
+		    rc = mvwgetnstr(txtwin, txt_y, txt_x, buffer, limit);
+		} else {
+		    rc = mvgetnstr(txt_y, txt_x, buffer, limit);
+		}
+		break;
+	    case eMaxFlavor:
+		break;
+	    }
+	    noecho();
+	    wattrset(txtwin, A_NORMAL);
+	    wprintw(strwin, "%d:%s", rc, buffer);
+	    wnoutrefresh(strwin);
+	    break;
+	default:
+	    beep();
+	    break;
+	}
+	doupdate();
+    }
+    if (level > 1) {
+	delwin(txtwin);
+	delwin(txtbox);
+    }
+    return TRUE;
+}
+
+int
+main(int argc, char *argv[])
+{
+    WINDOW *chrbox;
+    WINDOW *strwin;
+
+    setlocale(LC_ALL, "");
+
+    if (argc < 2) {
+	fprintf(stderr, "usage: %s file\n", argv[0]);
+	return EXIT_FAILURE;
+    }
+
+    initscr();
+
+    chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
+    box(chrbox, 0, 0);
+    wnoutrefresh(chrbox);
+
+    strwin = derwin(chrbox, 4, COLS - 2, 1, 1);
+
+    test_getstr(1, argv, strwin);
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+
+#else
+int
+main(void)
+{
+    printf("This program requires the curses chgat function\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/test_instr.c b/test/test_instr.c
new file mode 100644
index 0000000..b24f772
--- /dev/null
+++ b/test/test_instr.c
@@ -0,0 +1,260 @@
+/****************************************************************************
+ * Copyright (c) 2007 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: test_instr.c,v 1.4 2007/07/21 19:38:04 tom Exp $
+ *
+ * Author: Thomas E Dickey
+ *
+ * Demonstrate the instr functions from the curses library.
+
+       int instr(char *str);
+       int innstr(char *str, int n);
+       int winstr(WINDOW *win, char *str);
+       int winnstr(WINDOW *win, char *str, int n);
+       int mvinstr(int y, int x, char *str);
+       int mvinnstr(int y, int x, char *str, int n);
+       int mvwinstr(WINDOW *win, int y, int x, char *str);
+       int mvwinnstr(WINDOW *win, int y, int x, char *str, int n);
+ */
+
+#include <test.priv.h>
+
+#define BASE_Y 6
+#define MAX_COLS 1024
+
+static bool
+Quit(int ch)
+{
+    return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
+}
+
+static void
+show_1st(WINDOW *win, int line, char *buffer)
+{
+    mvwaddstr(win, line, 5, buffer);
+}
+
+static void
+showmore(WINDOW *win, int line, char *buffer)
+{
+    wmove(win, line, 0);
+    wclrtoeol(win);
+    show_1st(win, line, buffer);
+}
+
+static int
+test_inchs(int level, char **argv, WINDOW *chrwin, WINDOW *strwin)
+{
+    WINDOW *txtbox = 0;
+    WINDOW *txtwin = 0;
+    FILE *fp;
+    int ch;
+    int txt_x = 0, txt_y = 0;
+    int base_y;
+    int limit = getmaxx(strwin) - 5;
+
+    char buffer[MAX_COLS];
+
+    if (argv[level] == 0) {
+	beep();
+	return FALSE;
+    }
+
+    if (level > 1) {
+	txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
+	box(txtbox, 0, 0);
+	wnoutrefresh(txtbox);
+
+	txtwin = derwin(txtbox,
+			getmaxy(txtbox) - 2,
+			getmaxx(txtbox) - 2,
+			1, 1);
+	base_y = 0;
+    } else {
+	txtwin = stdscr;
+	base_y = BASE_Y;
+    }
+
+    keypad(txtwin, TRUE);	/* enable keyboard mapping */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    txt_y = base_y;
+    txt_x = 0;
+    wmove(txtwin, txt_y, txt_x);
+
+    if ((fp = fopen(argv[level], "r")) != 0) {
+	while ((ch = fgetc(fp)) != EOF) {
+	    if (waddch(txtwin, UChar(ch)) != OK) {
+		break;
+	    }
+	}
+	fclose(fp);
+    } else {
+	wprintw(txtwin, "Cannot open:\n%s", argv[1]);
+    }
+
+    while (!Quit(ch = mvwgetch(txtwin, txt_y, txt_x))) {
+	switch (ch) {
+	case KEY_DOWN:
+	case 'j':
+	    if (txt_y < getmaxy(txtwin) - 1)
+		txt_y++;
+	    else
+		beep();
+	    break;
+	case KEY_UP:
+	case 'k':
+	    if (txt_y > base_y)
+		txt_y--;
+	    else
+		beep();
+	    break;
+	case KEY_LEFT:
+	case 'h':
+	    if (txt_x > 0)
+		txt_x--;
+	    else
+		beep();
+	    break;
+	case KEY_RIGHT:
+	case 'l':
+	    if (txt_x < getmaxx(txtwin) - 1)
+		txt_x++;
+	    else
+		beep();
+	    break;
+	case 'w':
+	    test_inchs(level + 1, argv, chrwin, strwin);
+	    if (txtbox != 0) {
+		touchwin(txtbox);
+		wnoutrefresh(txtbox);
+	    } else {
+		touchwin(txtwin);
+		wnoutrefresh(txtwin);
+	    }
+	    break;
+	case '-':
+	    if (limit > 0) {
+		--limit;
+	    } else {
+		beep();
+	    }
+	    break;
+	case '+':
+	    ++limit;
+	    break;
+	default:
+	    beep();
+	    break;
+	}
+
+	mvwprintw(chrwin, 0, 0, "line:");
+	wclrtoeol(chrwin);
+
+	if (txtwin != stdscr) {
+	    wmove(txtwin, txt_y, txt_x);
+
+	    if (winstr(txtwin, buffer) != ERR) {
+		show_1st(chrwin, 0, buffer);
+	    }
+	    if (mvwinstr(txtwin, txt_y, txt_x, buffer) != ERR) {
+		showmore(chrwin, 1, buffer);
+	    }
+	} else {
+	    move(txt_y, txt_x);
+
+	    if (instr(buffer) != ERR) {
+		show_1st(chrwin, 0, buffer);
+	    }
+	    if (mvinstr(txt_y, txt_x, buffer) != ERR) {
+		showmore(chrwin, 1, buffer);
+	    }
+	}
+	wnoutrefresh(chrwin);
+
+	mvwprintw(strwin, 0, 0, "%4d:", limit);
+	wclrtobot(strwin);
+
+	if (txtwin != stdscr) {
+	    wmove(txtwin, txt_y, txt_x);
+	    if (winnstr(txtwin, buffer, limit) != ERR) {
+		show_1st(strwin, 0, buffer);
+	    }
+
+	    if (mvwinnstr(txtwin, txt_y, txt_x, buffer, limit) != ERR) {
+		showmore(strwin, 1, buffer);
+	    }
+	} else {
+	    move(txt_y, txt_x);
+	    if (innstr(buffer, limit) != ERR) {
+		show_1st(strwin, 0, buffer);
+	    }
+
+	    if (mvinnstr(txt_y, txt_x, buffer, limit) != ERR) {
+		showmore(strwin, 1, buffer);
+	    }
+	}
+
+	wnoutrefresh(strwin);
+    }
+    if (level > 1) {
+	delwin(txtwin);
+	delwin(txtbox);
+    }
+    return TRUE;
+}
+
+int
+main(int argc, char *argv[])
+{
+    WINDOW *chrbox;
+    WINDOW *chrwin;
+    WINDOW *strwin;
+
+    setlocale(LC_ALL, "");
+
+    if (argc < 2) {
+	fprintf(stderr, "usage: %s file\n", argv[0]);
+	return EXIT_FAILURE;
+    }
+
+    initscr();
+
+    chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
+    box(chrbox, 0, 0);
+    wnoutrefresh(chrbox);
+
+    chrwin = derwin(chrbox, 2, COLS - 2, 1, 1);
+    strwin = derwin(chrbox, 2, COLS - 2, 3, 1);
+
+    test_inchs(1, argv, chrwin, strwin);
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/test_inwstr.c b/test/test_inwstr.c
new file mode 100644
index 0000000..fe2b645
--- /dev/null
+++ b/test/test_inwstr.c
@@ -0,0 +1,269 @@
+/****************************************************************************
+ * Copyright (c) 2007 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: test_inwstr.c,v 1.3 2007/07/21 22:47:42 tom Exp $
+ *
+ * Author: Thomas E Dickey
+ *
+ * Demonstrate the inwstr functions from the curses library.
+
+       int inwstr(wchar_t *str);
+       int innwstr(wchar_t *str, int n);
+       int winwstr(WINDOW *win, wchar_t *str);
+       int winnwstr(WINDOW *win, wchar_t *str, int n);
+       int mvinwstr(int y, int x, wchar_t *str);
+       int mvinnwstr(int y, int x, wchar_t *str, int n);
+       int mvwinwstr(WINDOW *win, int y, int x, wchar_t *str);
+       int mvwinnwstr(WINDOW *win, int y, int x, wchar_t *str, int n);
+ */
+
+#include <test.priv.h>
+
+#if USE_WIDEC_SUPPORT
+
+#define BASE_Y 6
+#define MAX_COLS 1024
+
+static bool
+Quit(int ch)
+{
+    return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
+}
+
+static void
+show_1st(WINDOW *win, int line, wchar_t *buffer)
+{
+    mvwaddwstr(win, line, 5, buffer);
+}
+
+static void
+showmore(WINDOW *win, int line, wchar_t *buffer)
+{
+    wmove(win, line, 0);
+    wclrtoeol(win);
+    show_1st(win, line, buffer);
+}
+
+static int
+test_inchs(int level, char **argv, WINDOW *chrwin, WINDOW *strwin)
+{
+    WINDOW *txtbox = 0;
+    WINDOW *txtwin = 0;
+    FILE *fp;
+    int ch;
+    int txt_x = 0, txt_y = 0;
+    int base_y;
+    int limit = getmaxx(strwin) - 5;
+    wchar_t buffer[MAX_COLS];
+
+    if (argv[level] == 0) {
+	beep();
+	return FALSE;
+    }
+
+    if (level > 1) {
+	txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
+	box(txtbox, 0, 0);
+	wnoutrefresh(txtbox);
+
+	txtwin = derwin(txtbox,
+			getmaxy(txtbox) - 2,
+			getmaxx(txtbox) - 2,
+			1, 1);
+	base_y = 0;
+    } else {
+	txtwin = stdscr;
+	base_y = BASE_Y;
+    }
+
+    keypad(txtwin, TRUE);	/* enable keyboard mapping */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    txt_y = base_y;
+    txt_x = 0;
+    wmove(txtwin, txt_y, txt_x);
+
+    if ((fp = fopen(argv[level], "r")) != 0) {
+	while ((ch = fgetc(fp)) != EOF) {
+	    if (waddch(txtwin, UChar(ch)) != OK) {
+		break;
+	    }
+	}
+	fclose(fp);
+    } else {
+	wprintw(txtwin, "Cannot open:\n%s", argv[1]);
+    }
+
+    while (!Quit(ch = mvwgetch(txtwin, txt_y, txt_x))) {
+	switch (ch) {
+	case KEY_DOWN:
+	case 'j':
+	    if (txt_y < getmaxy(txtwin) - 1)
+		txt_y++;
+	    else
+		beep();
+	    break;
+	case KEY_UP:
+	case 'k':
+	    if (txt_y > base_y)
+		txt_y--;
+	    else
+		beep();
+	    break;
+	case KEY_LEFT:
+	case 'h':
+	    if (txt_x > 0)
+		txt_x--;
+	    else
+		beep();
+	    break;
+	case KEY_RIGHT:
+	case 'l':
+	    if (txt_x < getmaxx(txtwin) - 1)
+		txt_x++;
+	    else
+		beep();
+	    break;
+	case 'w':
+	    test_inchs(level + 1, argv, chrwin, strwin);
+	    if (txtbox != 0) {
+		touchwin(txtbox);
+		wnoutrefresh(txtbox);
+	    } else {
+		touchwin(txtwin);
+		wnoutrefresh(txtwin);
+	    }
+	    break;
+	case '-':
+	    if (limit > 0) {
+		--limit;
+	    } else {
+		beep();
+	    }
+	    break;
+	case '+':
+	    ++limit;
+	    break;
+	default:
+	    beep();
+	    break;
+	}
+
+	mvwprintw(chrwin, 0, 0, "line:");
+	wclrtoeol(chrwin);
+
+	if (txtwin != stdscr) {
+	    wmove(txtwin, txt_y, txt_x);
+
+	    if (winwstr(txtwin, buffer) != ERR) {
+		show_1st(chrwin, 0, buffer);
+	    }
+	    if (mvwinwstr(txtwin, txt_y, txt_x, buffer) != ERR) {
+		showmore(chrwin, 1, buffer);
+	    }
+	} else {
+	    move(txt_y, txt_x);
+
+	    if (inwstr(buffer) != ERR) {
+		show_1st(chrwin, 0, buffer);
+	    }
+	    if (mvinwstr(txt_y, txt_x, buffer) != ERR) {
+		showmore(chrwin, 1, buffer);
+	    }
+	}
+	wnoutrefresh(chrwin);
+
+	mvwprintw(strwin, 0, 0, "%4d:", limit);
+	wclrtobot(strwin);
+
+	if (txtwin != stdscr) {
+	    wmove(txtwin, txt_y, txt_x);
+	    if (winnwstr(txtwin, buffer, limit) != ERR) {
+		show_1st(strwin, 0, buffer);
+	    }
+
+	    if (mvwinnwstr(txtwin, txt_y, txt_x, buffer, limit) != ERR) {
+		showmore(strwin, 1, buffer);
+	    }
+	} else {
+	    move(txt_y, txt_x);
+	    if (innwstr(buffer, limit) != ERR) {
+		show_1st(strwin, 0, buffer);
+	    }
+
+	    if (mvinnwstr(txt_y, txt_x, buffer, limit) != ERR) {
+		showmore(strwin, 1, buffer);
+	    }
+	}
+
+	wnoutrefresh(strwin);
+    }
+    if (level > 1) {
+	delwin(txtwin);
+	delwin(txtbox);
+    }
+    return TRUE;
+}
+
+int
+main(int argc, char *argv[])
+{
+    WINDOW *chrbox;
+    WINDOW *chrwin;
+    WINDOW *strwin;
+
+    setlocale(LC_ALL, "");
+
+    if (argc < 2) {
+	fprintf(stderr, "usage: %s file\n", argv[0]);
+	return EXIT_FAILURE;
+    }
+
+    initscr();
+
+    chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
+    box(chrbox, 0, 0);
+    wnoutrefresh(chrbox);
+
+    chrwin = derwin(chrbox, 2, COLS - 2, 1, 1);
+    strwin = derwin(chrbox, 2, COLS - 2, 3, 1);
+
+    test_inchs(1, argv, chrwin, strwin);
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the wide-ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/test_opaque.c b/test/test_opaque.c
new file mode 100644
index 0000000..f1ab78c
--- /dev/null
+++ b/test/test_opaque.c
@@ -0,0 +1,471 @@
+/****************************************************************************
+ * Copyright (c) 2007,2008 Free Software Foundation, Inc.                   *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * $Id: test_opaque.c,v 1.7 2008/07/05 23:18:40 tom Exp $
+ *
+ * Author: Thomas E Dickey
+ *
+ * Demonstrate the opaque functions from the curses library.
+
+       WINDOW * wgetparent (const WINDOW *);
+       bool is_cleared(const WINDOW *win);
+       bool is_idcok(const WINDOW *win);
+       bool is_idlok(const WINDOW *win);
+       bool is_immedok(const WINDOW *win);
+       bool is_keypad(const WINDOW *win);
+       bool is_leaveok(const WINDOW *win);
+       bool is_nodelay(const WINDOW *win);
+       bool is_notimeout(const WINDOW *win);
+       bool is_scrollok(const WINDOW *win);
+       bool is_syncok(const WINDOW *win);
+       int wgetscrreg (const WINDOW *, int *, int *);
+ */
+
+#include <test.priv.h>
+
+#define BASE_Y 6
+#define MAX_COLS 1024
+
+#if defined(NCURSES_VERSION_PATCH) && (NCURSES_VERSION_PATCH >= 20080119) && NCURSES_EXT_FUNCS
+
+static bool
+Quit(int ch)
+{
+    return (ch == 'q' || ch == QUIT || ch == ESCAPE);
+}
+
+typedef bool(*BoolOpaque) (WINDOW *, int);
+
+static bool
+test_opaque_cleared(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	if (mode)
+	    wclear(win);
+    }
+    return is_cleared(win);
+}
+
+static bool
+test_opaque_idcok(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	idcok(win, mode);
+    }
+    return is_idcok(win);
+}
+
+static bool
+test_opaque_idlok(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	idlok(win, mode);
+    }
+    return is_idlok(win);
+}
+
+static bool
+test_opaque_immedok(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	immedok(win, mode);
+    }
+    return is_immedok(win);
+}
+
+static bool
+test_opaque_keypad(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	keypad(win, mode);
+    }
+    return is_keypad(win);
+}
+
+static bool
+test_opaque_leaveok(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	leaveok(win, mode);
+    }
+    return is_leaveok(win);
+}
+
+static bool
+test_opaque_nodelay(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	nodelay(win, mode);
+    }
+    return is_nodelay(win);
+}
+
+static bool
+test_opaque_notimeout(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	notimeout(win, mode);
+    }
+    return is_notimeout(win);
+}
+
+static bool
+test_opaque_scrollok(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	scrollok(win, mode);
+    }
+    return is_scrollok(win);
+}
+
+static bool
+test_opaque_syncok(WINDOW *win, int mode)
+{
+    if (mode >= 0) {
+	syncok(win, mode);
+    }
+    return is_syncok(win);
+}
+
+static int
+status_y(WINDOW *stswin, int cell)
+{
+    return (cell % getmaxy(stswin));
+}
+
+static int
+status_x(WINDOW *stswin, int cell)
+{
+    return (15 * (cell / getmaxy(stswin)));
+}
+
+static void
+to_keyword(WINDOW *stswin, int cell)
+{
+    wmove(stswin, status_y(stswin, cell), status_x(stswin, cell));
+}
+
+static void
+to_result(WINDOW *stswin, int cell, bool before)
+{
+    int y = status_y(stswin, cell);
+    int x = status_x(stswin, cell) + 11;
+    if (!before)
+	++x;
+    wmove(stswin, y, x);
+}
+
+static void
+show_keyword(WINDOW *stswin, int cell, int active, const char *name)
+{
+    to_keyword(stswin, cell);
+    if (active == cell)
+	wstandout(stswin);
+    wprintw(stswin, "%s:", name);
+    if (active == cell)
+	wstandend(stswin);
+}
+/* *INDENT-OFF* */
+static struct {
+    const char *name;
+    BoolOpaque func;
+} bool_funcs[] = {
+    { "cleared",   test_opaque_cleared },
+    { "idcok",     test_opaque_idcok },
+    { "idlok",     test_opaque_idlok },
+    { "immedok",   test_opaque_immedok },
+    { "keypad",    test_opaque_keypad },
+    { "leaveok",   test_opaque_leaveok },
+    { "nodelay",   test_opaque_nodelay },
+    { "notimeout", test_opaque_notimeout },
+    { "scrollok",  test_opaque_scrollok },
+    { "syncok",    test_opaque_syncok }
+};
+/* *INDENT-ON* */
+
+/*
+ * Display and/or allow update for the properties accessed in the opaque
+ * window.  Some may change state after refreshing the window, so we
+ * distinguish between them using the 'before' parameter.
+ */
+static int
+show_opaque(WINDOW *stswin, WINDOW *txtwin, bool before, int active)
+{
+    int n;
+    int top, bottom;
+
+    if (before) {
+	werase(stswin);
+    }
+    for (n = 0; n < (int) SIZEOF(bool_funcs); ++n) {
+	show_keyword(stswin, n, active, bool_funcs[n].name);
+
+	to_result(stswin, n, before);
+	wprintw(stswin, "%c", bool_funcs[n].func(txtwin, -1) ? 'T' : 'F');
+    }
+
+    show_keyword(stswin, n, active, "wgetparent");
+    to_result(stswin, n, TRUE);
+    wprintw(stswin, "%p", wgetparent(txtwin));
+
+    ++n;
+    show_keyword(stswin, n, active, "wgetscrreg");
+    to_result(stswin, n, TRUE);
+    if (wgetscrreg(txtwin, &top, &bottom) == OK)
+	wprintw(stswin, "%d,%d", top, bottom);
+
+    wnoutrefresh(stswin);
+    return active;
+}
+
+static int
+test_opaque(int level, char **argv, WINDOW *stswin)
+{
+    WINDOW *txtbox = 0;
+    WINDOW *txtwin = 0;
+    FILE *fp;
+    int ch;
+    int txt_x = 0, txt_y = 0;
+    int base_y;
+    bool in_status = FALSE;
+    int active = 0;
+
+    if (argv[level] == 0) {
+	beep();
+	return FALSE;
+    }
+
+    if (level > 1) {
+	txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
+	box(txtbox, 0, 0);
+	wnoutrefresh(txtbox);
+
+	txtwin = derwin(txtbox,
+			getmaxy(txtbox) - 2,
+			getmaxx(txtbox) - 2,
+			1, 1);
+	base_y = 0;
+    } else {
+	txtwin = stdscr;
+	base_y = BASE_Y;
+    }
+
+    keypad(txtwin, TRUE);	/* enable keyboard mapping */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    txt_y = base_y;
+    txt_x = 0;
+    wmove(txtwin, txt_y, txt_x);
+
+    if ((fp = fopen(argv[level], "r")) != 0) {
+	while ((ch = fgetc(fp)) != EOF) {
+	    if (waddch(txtwin, UChar(ch)) != OK) {
+		break;
+	    }
+	}
+	fclose(fp);
+    } else {
+	wprintw(txtwin, "Cannot open:\n%s", argv[1]);
+    }
+
+    for (;;) {
+	if (in_status) {
+	    to_keyword(stswin, active);
+
+	    ch = wgetch(stswin);
+	    show_opaque(stswin, txtwin, TRUE, active);
+	    if (Quit(ch))
+		break;
+
+	    switch (ch) {
+	    case '\t':
+		in_status = FALSE;
+		break;
+	    case KEY_DOWN:
+	    case 'j':
+		if (active < (int) SIZEOF(bool_funcs) - 1)
+		    active++;
+		else
+		    beep();
+		break;
+	    case KEY_UP:
+	    case 'k':
+		if (active > 0)
+		    active--;
+		else
+		    beep();
+		break;
+	    case ' ':
+		bool_funcs[active].func(txtwin,
+					!bool_funcs[active].func(txtwin, -1));
+		break;
+	    default:
+		beep();
+		break;
+	    }
+	    show_opaque(stswin, txtwin, FALSE, in_status ? active : -1);
+	} else {
+	    ch = mvwgetch(txtwin, txt_y, txt_x);
+	    show_opaque(stswin, txtwin, TRUE, -1);
+	    if (Quit(ch))
+		break;
+
+	    switch (ch) {
+	    case '\t':
+		in_status = TRUE;
+		break;
+	    case KEY_DOWN:
+	    case 'j':
+		if (txt_y < getmaxy(txtwin) - 1)
+		    txt_y++;
+		else
+		    beep();
+		break;
+	    case KEY_UP:
+	    case 'k':
+		if (txt_y > base_y)
+		    txt_y--;
+		else
+		    beep();
+		break;
+	    case KEY_LEFT:
+	    case 'h':
+		if (txt_x > 0)
+		    txt_x--;
+		else
+		    beep();
+		break;
+	    case KEY_RIGHT:
+	    case 'l':
+		if (txt_x < getmaxx(txtwin) - 1)
+		    txt_x++;
+		else
+		    beep();
+		break;
+	    case 'w':
+		test_opaque(level + 1, argv, stswin);
+		if (txtbox != 0) {
+		    touchwin(txtbox);
+		    wnoutrefresh(txtbox);
+		} else {
+		    touchwin(txtwin);
+		    wnoutrefresh(txtwin);
+		}
+		break;
+	    default:
+		beep();
+		napms(100);
+		break;
+	    }
+
+	    show_opaque(stswin, txtwin, FALSE, -1);
+	}
+    }
+    if (level > 1) {
+	delwin(txtwin);
+	delwin(txtbox);
+    }
+    return TRUE;
+}
+
+static void
+test_set_escdelay(void)
+{
+    set_escdelay((100 + ESCDELAY) / 2);
+}
+
+static void
+test_set_tabsize(void)
+{
+    int y0, x0;
+    int y, x;
+    int save_tabsize = TABSIZE;
+
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+
+    for (y = 0; y < LINES; ++y) {
+	set_tabsize(y + 1);
+	if (move(y, 0) == ERR)
+	    break;
+	for (x = 0; x < COLS;) {
+	    addch('\t');
+	    if (addch('*') == ERR) {
+		break;
+	    }
+	    getyx(stdscr, y0, x0);
+	    if (y0 != y || x0 == x) {
+		break;
+	    }
+	}
+    }
+    getch();
+    erase();
+
+    set_tabsize(save_tabsize);
+}
+
+int
+main(int argc, char *argv[])
+{
+    WINDOW *stsbox;
+    WINDOW *stswin;
+
+    setlocale(LC_ALL, "");
+
+    if (argc < 2) {
+	fprintf(stderr, "usage: %s file\n", argv[0]);
+	return EXIT_FAILURE;
+    }
+
+    initscr();
+
+    test_set_escdelay();
+    test_set_tabsize();
+
+    stsbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
+    box(stsbox, 0, 0);
+    wnoutrefresh(stsbox);
+
+    stswin = derwin(stsbox, BASE_Y - 2, COLS - 2, 1, 1);
+    keypad(stswin, TRUE);
+
+    test_opaque(1, argv, stswin);
+
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
+#else
+int
+main(void)
+{
+    printf("This program requires the ncurses library\n");
+    ExitProgram(EXIT_FAILURE);
+}
+#endif
diff --git a/test/testaddch.c b/test/testaddch.c
new file mode 100644
index 0000000..c1651c6
--- /dev/null
+++ b/test/testaddch.c
@@ -0,0 +1,88 @@
+/****************************************************************************
+ * Copyright (c) 1998-2002,2006 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * This is an example written by Alexander V. Lukyanov <lav@yars.free.net>,
+ * to demonstrate an inconsistency between ncurses and SVr4 curses.
+ *
+ * $Id: testaddch.c,v 1.6 2006/04/01 19:08:03 tom Exp $
+ */
+#include <test.priv.h>
+
+static void
+attr_addstr(const char *s, chtype a)
+{
+    while (*s)
+	addch(((unsigned char) (*s++)) | a);
+}
+
+int
+main(
+	int argc GCC_UNUSED,
+	char *argv[]GCC_UNUSED)
+{
+    unsigned i;
+    chtype back, set, attr;
+
+    setlocale(LC_ALL, "");
+
+    initscr();
+    start_color();
+    init_pair(1, COLOR_WHITE, COLOR_BLUE);
+    init_pair(2, COLOR_WHITE, COLOR_RED);
+    init_pair(3, COLOR_BLACK, COLOR_MAGENTA);
+    init_pair(4, COLOR_BLACK, COLOR_GREEN);
+    init_pair(5, COLOR_BLACK, COLOR_CYAN);
+    init_pair(6, COLOR_BLACK, COLOR_YELLOW);
+    init_pair(7, COLOR_BLACK, COLOR_WHITE);
+
+    for (i = 0; i < 8; i++) {
+	back = (i & 1) ? A_BOLD | 'B' : ' ';
+	set = (i & 2) ? A_REVERSE : 0;
+	attr = (i & 4) ? COLOR_PAIR(4) : 0;
+
+	bkgdset(back);
+	attrset(set);
+
+	attr_addstr("Test string with spaces ->   <-\n", attr);
+    }
+    addch('\n');
+    for (i = 0; i < 8; i++) {
+	back = (i & 1) ? A_BOLD | 'B' | COLOR_PAIR(1) : ' ';
+	set = (i & 2) ? A_REVERSE | COLOR_PAIR(2) : 0;
+	attr = (i & 4) ? COLOR_PAIR(4) : 0;
+
+	bkgdset(back);
+	attrset(set);
+
+	attr_addstr("Test string with spaces ->   <-\n", attr);
+    }
+
+    getch();
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/testcurs.c b/test/testcurs.c
new file mode 100644
index 0000000..6a2e53f
--- /dev/null
+++ b/test/testcurs.c
@@ -0,0 +1,738 @@
+/*
+ *
+ * This is a test program for the PDCurses screen package for IBM PC type
+ * machines.
+ *
+ * This program was written by John Burnell (johnb@kea.am.dsir.govt.nz)
+ *  wrs(5/28/93) -- modified to be consistent (perform identically) with either
+ *                  PDCurses or under Unix System V, R4
+ *
+ * $Id: testcurs.c,v 1.39 2008/08/03 17:58:09 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#if defined(XCURSES)
+char *XCursesProgramName = "testcurs";
+#endif
+
+static int initTest(WINDOW **);
+static void display_menu(int, int);
+static void inputTest(WINDOW *);
+static void introTest(WINDOW *);
+static void outputTest(WINDOW *);
+static void padTest(WINDOW *);
+static void scrollTest(WINDOW *);
+#if defined(PDCURSES) && !defined(XCURSES)
+static void resizeTest(WINDOW *);
+#endif
+
+struct commands {
+    NCURSES_CONST char *text;
+    void (*function) (WINDOW *);
+};
+typedef struct commands COMMAND;
+
+static const COMMAND command[] =
+{
+    {"General Test", introTest},
+    {"Pad Test", padTest},
+#if defined(PDCURSES) && !defined(XCURSES)
+    {"Resize Test", resizeTest},
+#endif
+    {"Scroll Test", scrollTest},
+    {"Input Test", inputTest},
+    {"Output Test", outputTest}
+};
+#define MAX_OPTIONS (int) SIZEOF(command)
+
+#if !HAVE_STRDUP
+#define strdup my_strdup
+static char *
+strdup(char *s)
+{
+    char *p = typeMalloc(char, strlen(s) + 1);
+    if (p)
+	strcpy(p, s);
+    return (p);
+}
+#endif /* not HAVE_STRDUP */
+
+static int width, height;
+
+int
+main(
+	int argc GCC_UNUSED,
+	char *argv[]GCC_UNUSED)
+{
+    WINDOW *win;
+    int key;
+    int old_option = (-1);
+    int new_option = 0;
+    bool quit = FALSE;
+    int n;
+
+    setlocale(LC_ALL, "");
+
+#ifdef PDCDEBUG
+    PDC_debug("testcurs started\n");
+#endif
+    if (!initTest(&win))
+	ExitProgram(EXIT_FAILURE);
+
+    erase();
+    display_menu(old_option, new_option);
+    for (;;) {
+#ifdef A_COLOR
+	if (has_colors()) {
+	    init_pair(1, COLOR_WHITE, COLOR_BLUE);
+	    wbkgd(win, COLOR_PAIR(1));
+	} else
+	    wbkgd(win, A_REVERSE);
+#else
+	wbkgd(win, A_REVERSE);
+#endif
+	werase(win);
+
+	noecho();
+	keypad(stdscr, TRUE);
+	raw();
+	key = getch();
+	if (key < KEY_MIN && key > 0 && isalpha(key)) {
+	    if (islower(key))
+		key = toupper(key);
+	    for (n = 0; n < MAX_OPTIONS; ++n) {
+		if (key == command[n].text[0]) {
+		    display_menu(old_option, new_option = n);
+		    key = ' ';
+		    break;
+		}
+	    }
+	}
+	switch (key) {
+	case 10:
+	case 13:
+	case KEY_ENTER:
+	    erase();
+	    refresh();
+	    (*command[new_option].function) (win);
+	    erase();
+	    display_menu(old_option, new_option);
+	    break;
+	case KEY_UP:
+	    new_option = ((new_option == 0)
+			  ? new_option
+			  : new_option - 1);
+	    display_menu(old_option, new_option);
+	    break;
+	case KEY_DOWN:
+	    new_option = ((new_option == (MAX_OPTIONS - 1))
+			  ? new_option
+			  : new_option + 1);
+	    display_menu(old_option, new_option);
+	    break;
+	case 'Q':
+	case 'q':
+	    quit = TRUE;
+	    break;
+	default:
+	    beep();
+	    break;
+	case ' ':
+	    break;
+	}
+	if (quit == TRUE)
+	    break;
+    }
+
+    delwin(win);
+
+    endwin();
+#ifdef XCURSES
+    XCursesExit();
+#endif
+    ExitProgram(EXIT_SUCCESS);
+}
+
+static void
+Continue(WINDOW *win)
+{
+    int y1 = getmaxy(win);
+    int x1 = getmaxx(win);
+    int y0 = y1 < 10 ? y1 : 10;
+    int x0 = 1;
+    chtype save;
+
+    save = mvwinch(win, y0, x1 - 1);
+
+    mvwaddstr(win, y0, x0, " Press any key to continue");
+    wclrtoeol(win);
+    getyx(win, y0, x0);
+
+    mvwaddch(win, y0, x1 - 1, save);
+
+    wmove(win, y0, x0);
+    raw();
+    wgetch(win);
+}
+
+static int
+initTest(WINDOW **win)
+{
+#ifdef PDCDEBUG
+    PDC_debug("initTest called\n");
+#endif
+#ifdef TRACE
+    trace(TRACE_MAXIMUM);
+#endif
+    initscr();
+#ifdef PDCDEBUG
+    PDC_debug("after initscr()\n");
+#endif
+#ifdef A_COLOR
+    if (has_colors())
+	start_color();
+#endif
+    width = 60;
+    height = 13;		/* Create a drawing window */
+    *win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
+    if (*win == NULL) {
+	endwin();
+	return 0;
+    }
+    return 1;
+}
+
+static void
+introTest(WINDOW *win)
+{
+    wmove(win, height / 2 - 5, width / 2);
+    wvline(win, ACS_VLINE, 10);
+    wmove(win, height / 2, width / 2 - 10);
+    whline(win, ACS_HLINE, 20);
+    Continue(win);
+
+    beep();
+    werase(win);
+
+    box(win, ACS_VLINE, ACS_HLINE);
+    wrefresh(win);
+    cbreak();
+    mvwaddstr(win, 1, 1,
+	      "You should have rectangle in the middle of the screen");
+    mvwaddstr(win, 2, 1, "You should have heard a beep");
+    Continue(win);
+    return;
+}
+
+static void
+scrollTest(WINDOW *win)
+{
+    int i;
+    int half;
+    int OldY;
+    NCURSES_CONST char *Message = "The window will now scroll slowly";
+
+    wclear(win);
+    OldY = getmaxy(win);
+    half = OldY / 2;
+    mvwprintw(win, OldY - 2, 1, Message);
+    wrefresh(win);
+    scrollok(win, TRUE);
+    for (i = 1; i <= OldY; i++) {
+	napms(600);
+	scroll(win);
+	wrefresh(win);
+    }
+
+    werase(win);
+    for (i = 1; i < OldY; i++) {
+	mvwprintw(win, i, 1, "Line %d", i);
+    }
+    mvwprintw(win, OldY - 2, 1, "The top of the window will scroll");
+    wmove(win, 1, 1);
+    wsetscrreg(win, 0, half - 1);
+    box(win, ACS_VLINE, ACS_HLINE);
+    wrefresh(win);
+    for (i = 1; i <= half; i++) {
+	napms(600);
+	scroll(win);
+	box(win, ACS_VLINE, ACS_HLINE);
+	wrefresh(win);
+    }
+
+    werase(win);
+    for (i = 1; i < OldY; i++) {
+	mvwprintw(win, i, 1, "Line %d", i);
+    }
+    mvwprintw(win, 1, 1, "The bottom of the window will scroll");
+    wmove(win, OldY - 2, 1);
+    wsetscrreg(win, half, --OldY);
+    box(win, ACS_VLINE, ACS_HLINE);
+    wrefresh(win);
+    for (i = half; i <= OldY; i++) {
+	napms(600);
+	wscrl(win, -1);
+	box(win, ACS_VLINE, ACS_HLINE);
+	wrefresh(win);
+    }
+    wsetscrreg(win, 0, OldY);
+}
+
+static void
+inputTest(WINDOW *win)
+{
+    int answered;
+    int repeat;
+    int w, h, bx, by, sw, sh, i, c, num;
+    char buffer[80];
+    WINDOW *subWin;
+    wclear(win);
+
+    getmaxyx(win, h, w);
+    getbegyx(win, by, bx);
+    sw = w / 3;
+    sh = h / 3;
+    if ((subWin = subwin(win, sh, sw, by + h - sh - 2, bx + w - sw - 2)) == NULL)
+	return;
+
+#ifdef A_COLOR
+    if (has_colors()) {
+	init_pair(2, COLOR_WHITE, COLOR_RED);
+	wbkgd(subWin, COLOR_PAIR(2) | A_BOLD);
+    } else
+	wbkgd(subWin, A_BOLD);
+#else
+    wbkgd(subWin, A_BOLD);
+#endif
+    box(subWin, ACS_VLINE, ACS_HLINE);
+    wrefresh(win);
+
+    nocbreak();
+    mvwaddstr(win, 2, 1, "Press some keys for 5 seconds");
+    mvwaddstr(win, 1, 1, "Pressing ^C should do nothing");
+    wrefresh(win);
+
+    werase(subWin);
+    box(subWin, ACS_VLINE, ACS_HLINE);
+    for (i = 0; i < 5; i++) {
+	mvwprintw(subWin, 1, 1, "Time = %d", i);
+	wrefresh(subWin);
+	napms(1000);
+	flushinp();
+    }
+
+    delwin(subWin);
+    werase(win);
+    flash();
+    wrefresh(win);
+    napms(500);
+
+    mvwaddstr(win, 2, 1, "Press a key, followed by ENTER");
+    wmove(win, 9, 10);
+    wrefresh(win);
+    echo();
+    noraw();
+    wgetch(win);
+    flushinp();
+
+    wmove(win, 9, 10);
+    wdelch(win);
+    mvwaddstr(win, 4, 1, "The character should now have been deleted");
+    Continue(win);
+
+    wclear(win);
+    mvwaddstr(win, 1, 1, "Press keys (or mouse buttons) to show their names");
+    mvwaddstr(win, 2, 1, "Press spacebar to finish");
+    wrefresh(win);
+
+    keypad(win, TRUE);
+    raw();
+    noecho();
+
+#if HAVE_TYPEAHEAD
+    typeahead(-1);
+#endif
+
+#if defined(PDCURSES)
+    mouse_set(ALL_MOUSE_EVENTS);
+#endif
+
+    for (;;) {
+	wmove(win, 3, 5);
+	c = wgetch(win);
+	wclrtobot(win);
+	if (c >= KEY_MIN)
+	    wprintw(win, "Key Pressed: %s", keyname(c));
+	else if (isprint(c))
+	    wprintw(win, "Key Pressed: %c", c);
+	else
+	    wprintw(win, "Key Pressed: %s", unctrl(UChar(c)));
+#if defined(PDCURSES)
+	if (c == KEY_MOUSE) {
+	    int button = 0;
+	    request_mouse_pos();
+	    if (BUTTON_CHANGED(1))
+		button = 1;
+	    else if (BUTTON_CHANGED(2))
+		button = 2;
+	    else if (BUTTON_CHANGED(3))
+		button = 3;
+	    else
+		button = 0;
+	    wmove(win, 4, 18);
+	    wprintw(win, "Button %d: ", button);
+	    if (MOUSE_MOVED)
+		wprintw(win, "moved: ");
+	    else if ((BUTTON_STATUS(button) & BUTTON_ACTION_MASK) == BUTTON_PRESSED)
+		wprintw(win, "pressed: ");
+	    else if ((BUTTON_STATUS(button) & BUTTON_ACTION_MASK) == BUTTON_DOUBLE_CLICKED)
+		wprintw(win, "double: ");
+	    else
+		wprintw(win, "released: ");
+	    wprintw(win, " Position: Y: %d X: %d", MOUSE_Y_POS, MOUSE_X_POS);
+	}
+#endif
+	wrefresh(win);
+	if (c == ' ')
+	    break;
+    }
+#if 0
+    nodelay(win, TRUE);
+    wgetch(win);
+    nodelay(win, FALSE);
+#endif
+#if defined(PDCURSES)
+    mouse_set(0L);
+#endif
+    refresh();
+
+    repeat = 0;
+    do {
+	static const char *fmt[] =
+	{
+	    "%d %10s",
+	    "%d %[a-zA-Z]s",
+	    "%d %[][a-zA-Z]s",
+	    "%d %[^0-9]"
+	};
+	const char *format = fmt[repeat % SIZEOF(fmt)];
+
+	wclear(win);
+	mvwaddstr(win, 3, 2, "The window should have moved");
+	mvwaddstr(win, 4, 2,
+		  "This text should have appeared without you pressing a key");
+	mvwprintw(win, 6, 2,
+		  "Scanning with format \"%s\"", format);
+	mvwin(win, 2 + 2 * (repeat % 4), 1 + 2 * (repeat % 4));
+	erase();
+	refresh();
+	wrefresh(win);
+	echo();
+	noraw();
+	num = 0;
+	*buffer = 0;
+	answered = mvwscanw(win, 7, 6, strdup(format), &num, buffer);
+	mvwprintw(win, 8, 6,
+		  "String: %s Number: %d (%d values read)",
+		  buffer, num, answered);
+	Continue(win);
+	++repeat;
+    } while (answered > 0);
+}
+
+static void
+outputTest(WINDOW *win)
+{
+    WINDOW *win1;
+    char Buffer[80];
+    chtype ch;
+    int by, bx;
+
+#if !HAVE_TIGETSTR
+#if HAVE_TGETENT
+    char tc_buffer[4096];
+    char tc_parsed[4096];
+    char *area_pointer = tc_parsed;
+    tgetent(tc_buffer, getenv("TERM"));
+#else
+#define tgetstr(a,b) 0
+#endif
+#endif /* !HAVE_TIGETSTR */
+
+    nl();
+    wclear(win);
+    mvwaddstr(win, 1, 1,
+	      "You should now have a screen in the upper left corner, and this text should have wrapped");
+    mvwin(win, 2, 1);
+    waddstr(win, "\nThis text should be down\n");
+    waddstr(win, "and broken into two here ^");
+    Continue(win);
+
+    wclear(win);
+    wattron(win, A_BOLD);
+    mvwaddstr(win, 1, 1, "A new window will appear with this text in it");
+    mvwaddstr(win, 8, 1, "Press any key to continue");
+    wrefresh(win);
+    wgetch(win);
+
+    getbegyx(win, by, bx);
+
+    if (LINES < 24 || COLS < 75) {
+	mvwaddstr(win, 5, 1,
+		  "Some tests have been skipped as they require a");
+	mvwaddstr(win, 6, 1, "display of at least 24 LINES by 75 COLUMNS");
+	Continue(win);
+    } else {
+	win1 = newwin(10, 50, 14, 25);
+	if (win1 == NULL) {
+	    endwin();
+	    return;
+	}
+#ifdef A_COLOR
+	if (has_colors()) {
+	    init_pair(3, COLOR_BLUE, COLOR_WHITE);
+	    wbkgd(win1, COLOR_PAIR(3));
+	} else
+	    wbkgd(win1, A_NORMAL);
+#else
+	wbkgd(win1, A_NORMAL);
+#endif
+	wclear(win1);
+	mvwaddstr(win1, 5, 1,
+		  "This text should appear; using overlay option");
+	copywin(win, win1, 0, 0, 0, 0, 9, 49, TRUE);
+
+#if defined(PDCURSES) && !defined(XCURSES)
+	box(win1, 0xb3, 0xc4);
+#else
+	box(win1, ACS_VLINE, ACS_HLINE);
+#endif
+	wmove(win1, 8, 26);
+	wrefresh(win1);
+	wgetch(win1);
+
+	wclear(win1);
+	wattron(win1, A_BLINK);
+	mvwaddstr(win1, 4, 1,
+		  "This blinking text should appear in only the second window");
+	wattroff(win1, A_BLINK);
+	mvwin(win1, by, bx);
+	overlay(win, win1);
+	mvwin(win1, 14, 25);
+	wmove(win1, 8, 26);
+	wrefresh(win1);
+	wgetch(win1);
+	delwin(win1);
+    }
+
+    clear();
+    wclear(win);
+    wrefresh(win);
+    mvwaddstr(win, 6, 2, "This line shouldn't appear");
+    mvwaddstr(win, 4, 2, "Only half of the next line is visible");
+    mvwaddstr(win, 5, 2, "Only half of the next line is visible");
+    wmove(win, 6, 1);
+    wclrtobot(win);
+    wmove(win, 5, 20);
+    wclrtoeol(win);
+    mvwaddstr(win, 8, 2, "This line also shouldn't appear");
+    wmove(win, 8, 1);
+    wdeleteln(win);
+    Continue(win);
+
+    wmove(win, 5, 9);
+    ch = winch(win);
+
+    wclear(win);
+    wmove(win, 6, 2);
+    waddstr(win, "The next char should be l:  ");
+    winsch(win, ch);
+    Continue(win);
+
+#if HAVE_WINSSTR
+    mvwinsstr(win, 6, 2, "A1B2C3D4E5");
+    Continue(win);
+#endif
+
+    wmove(win, 5, 1);
+    winsertln(win);
+    mvwaddstr(win, 5, 2, "The lines below should have moved down");
+    Continue(win);
+
+    wclear(win);
+    wmove(win, 2, 2);
+    wprintw(win, "This is a formatted string in a window: %d %s\n", 42,
+	    "is it");
+    mvwaddstr(win, 10, 1, "Enter a string: ");
+    wrefresh(win);
+    noraw();
+    echo();
+    *Buffer = 0;
+    wscanw(win, "%s", Buffer);
+
+    printw("This is a formatted string in stdscr: %d %s\n", 42, "is it");
+    mvaddstr(10, 1, "Enter a string: ");
+    *Buffer = 0;
+    scanw("%s", Buffer);
+
+    if (TIGETSTR("cvvis", "vs") != 0) {
+	wclear(win);
+	curs_set(2);
+	mvwaddstr(win, 1, 1, "The cursor should appear as a block (visible)");
+	Continue(win);
+    }
+
+    if (TIGETSTR("civis", "vi") != 0) {
+	wclear(win);
+	curs_set(0);
+	mvwaddstr(win, 1, 1,
+		  "The cursor should have disappeared (invisible)");
+	Continue(win);
+    }
+
+    if (TIGETSTR("cnorm", "ve") != 0) {
+	wclear(win);
+	curs_set(1);
+	mvwaddstr(win, 1, 1, "The cursor should be an underline (normal)");
+	Continue(win);
+    }
+#ifdef A_COLOR
+    if (has_colors()) {
+	wclear(win);
+	mvwaddstr(win, 1, 1, "Colors should change after you press a key");
+	Continue(win);
+	init_pair(1, COLOR_RED, COLOR_WHITE);
+	wrefresh(win);
+    }
+#endif
+
+    werase(win);
+
+#if HAVE_TERMNAME
+    mvwaddstr(win, 1, 1, "Information About Your Terminal");
+    mvwaddstr(win, 3, 1, termname());
+    mvwaddstr(win, 4, 1, longname());
+    if (termattrs() & A_BLINK)
+	mvwaddstr(win, 5, 1, "This terminal supports blinking.");
+    else
+	mvwaddstr(win, 5, 1, "This terminal does NOT support blinking.");
+#endif
+
+    mvwaddnstr(win, 7, 5, "Have a nice day!ok", 16);
+    wrefresh(win);
+
+    mvwinnstr(win, 7, 5, Buffer, 18);
+    mvaddstr(LINES - 2, 10, Buffer);
+    refresh();
+    Continue(win);
+}
+
+#if defined(PDCURSES) && !defined(XCURSES)
+static void
+resizeTest(WINDOW *dummy GCC_UNUSED)
+{
+    WINDOW *win1;
+
+    savetty();
+
+    clear();
+    refresh();
+#  if defined(OS2)
+    resize_term(50, 120);
+#  else
+    resize_term(50, 80);
+#  endif
+
+    win1 = newwin(10, 50, 14, 25);
+    if (win1 == NULL) {
+	endwin();
+	return;
+    }
+#ifdef A_COLOR
+    if (has_colors()) {
+	init_pair(3, COLOR_BLUE, COLOR_WHITE);
+	wattrset(win1, COLOR_PAIR(3));
+    }
+#endif
+    wclear(win1);
+
+    mvwaddstr(win1, 1, 1, "The screen may now have 50 lines");
+    Continue(win1);
+
+    wclear(win1);
+    resetty();
+
+    mvwaddstr(win1, 1, 1, "The screen should now be reset");
+    Continue(win1);
+
+    delwin(win1);
+
+    clear();
+    refresh();
+
+}
+#endif
+
+static void
+padTest(WINDOW *dummy GCC_UNUSED)
+{
+    WINDOW *pad, *spad;
+
+    if ((pad = newpad(50, 100)) != 0) {
+	wattron(pad, A_REVERSE);
+	mvwaddstr(pad, 5, 2, "This is a new pad");
+	wattrset(pad, A_NORMAL);
+	mvwaddstr(pad, 8, 0,
+		  "The end of this line should be truncated here:except  now");
+	mvwaddstr(pad, 11, 1, "This line should not appear.It will now");
+	wmove(pad, 10, 1);
+	wclrtoeol(pad);
+	mvwaddstr(pad, 10, 1, " Press any key to continue");
+	prefresh(pad, 0, 0, 0, 0, 10, 45);
+	keypad(pad, TRUE);
+	raw();
+	wgetch(pad);
+
+	spad = subpad(pad, 12, 25, 6, 52);
+	mvwaddstr(spad, 2, 2, "This is a new subpad");
+	box(spad, 0, 0);
+	prefresh(pad, 0, 0, 0, 0, 15, 75);
+	keypad(pad, TRUE);
+	raw();
+	wgetch(pad);
+
+	mvwaddstr(pad, 35, 2, "This is displayed at line 35 in the pad");
+	mvwaddstr(pad, 40, 1, " Press any key to continue");
+	prefresh(pad, 30, 0, 0, 0, 10, 45);
+	keypad(pad, TRUE);
+	raw();
+	wgetch(pad);
+
+	delwin(pad);
+    }
+}
+
+static void
+display_menu(int old_option, int new_option)
+{
+    int i;
+
+    assert((new_option >= 0) && (new_option < MAX_OPTIONS));
+
+    attrset(A_NORMAL);
+    mvaddstr(3, 20, "PDCurses Test Program");
+
+    for (i = 0; i < (int) MAX_OPTIONS; i++)
+	mvaddstr(5 + i, 25, command[i].text);
+
+    if ((old_option >= 0) && (old_option < MAX_OPTIONS))
+	mvaddstr(5 + old_option, 25, command[old_option].text);
+
+    attrset(A_REVERSE);
+    mvaddstr(5 + new_option, 25, command[new_option].text);
+    attrset(A_NORMAL);
+    mvaddstr(13, 3,
+	     "Use Up and Down Arrows to select - Enter to run - Q to quit");
+    refresh();
+}
diff --git a/test/testscanw.c b/test/testscanw.c
new file mode 100644
index 0000000..79589c2
--- /dev/null
+++ b/test/testscanw.c
@@ -0,0 +1,67 @@
+/****************************************************************************
+ * Copyright (c) 1998-2002,2006 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/* gleaned from a web-search, shows a bug combining scanw and implicit scroll.
+ * Date:  1997/03/17
+ * From:  bayern@morpheus.cis.yale.edu
+ *
+ * $Id: testscanw.c,v 1.11 2006/04/01 19:08:03 tom Exp $
+ */
+#include <test.priv.h>
+
+int
+main(int argc, char *argv[])
+{
+    long badanswer = 1;
+    long *response = &badanswer;
+
+    setlocale(LC_ALL, "");
+
+    initscr();
+    scrollok(stdscr, TRUE);
+    idlok(stdscr, TRUE);
+    echo();
+
+#if 0
+    trace(TRACE_UPDATE | TRACE_CALLS);
+#endif
+    while (argc > 1) {
+	if (isdigit(UChar(*argv[1])))
+	    move(atoi(argv[1]), 0);
+	else if (!strcmp(argv[1], "-k"))
+	    keypad(stdscr, TRUE);
+	argc--, argv++;
+    }
+
+    while (badanswer) {
+	printw("Enter a number (0 to quit):\n");
+	printw("--> ");
+	scanw("%20ld", response);	/* yes, it's a pointer */
+    }
+    endwin();
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/tracemunch b/test/tracemunch
new file mode 100755
index 0000000..1ea6f4b
--- /dev/null
+++ b/test/tracemunch
@@ -0,0 +1,161 @@
+#!/usr/bin/perl -w
+# $Id: tracemunch,v 1.6 2005/03/12 21:48:23 tom Exp $
+##############################################################################
+# Copyright (c) 1998-2002,2005 Free Software Foundation, Inc.                #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+# tracemunch -- compactify ncurses trace logs
+#
+# The error logs produced by ncurses with tracing enabled can be very tedious
+# to wade through.  This script helps by compacting runs of log lines that
+# can be conveniently expressed as higher-level operations.
+use strict;
+
+our $putattr="PutAttrChar\\({{ '(.)' = 0[0-7]+ }}\\) at \\(([0-9]+), ([0-9]+)\\)";
+our $waddnstr="waddnstr\\(0x([0-9a-f]+),\"([^\"]+)\",[0-9]+\\) called {A_NORMAL}";
+
+our $win_nums=0;
+our $curscr="";
+our $newscr="";
+our $stdscr="";
+our @win_addr;
+
+sub transaddr
+{
+    my $n;
+    my $arg = $_[0];
+
+    $arg =~ s/$curscr/curscr/g if ($curscr);
+    $arg =~ s/$newscr/newscr/g if ($newscr);
+    $arg =~ s/$stdscr/stdscr/g if ($stdscr);
+    for $n (0..$#win_addr) {
+	$arg =~ s/$win_addr[$n]/window$n/g if $win_addr[$n];
+    }
+
+    return $arg;
+}
+
+while (<STDIN>)
+{
+	my $addr;
+	my $n;
+	my $awaiting;
+
+CLASSIFY: {
+	# Transform window pointer addresses so it's easier to compare logs
+	$awaiting = "curscr" if ($_ =~ /creating curscr/);
+	$awaiting = "newscr" if ($_ =~ /creating newscr/);
+	$awaiting = "stdscr" if ($_ =~ /creating stdscr/);
+	if ($_ =~ /^create :window 0x([0-9a-f]+)/) {
+	    $addr = "0x$1";
+	    if ($awaiting eq "curscr") {
+		$curscr = $addr;
+	    } elsif ($awaiting eq "newscr") {
+		$newscr = $addr;
+	    } elsif ($awaiting eq "stdscr") {
+		$stdscr = $addr;
+	    } else {
+		$win_addr[$win_nums] = $addr;
+		$win_nums = $win_nums + 1;
+	    }
+	    $awaiting = "";
+	} elsif ($_ =~ /^\.\.\.deleted win=0x([0-9a-f]+)/) {
+	    $addr = "0x$1";
+	    $_ = &transaddr($_);
+	    if ($addr eq $curscr) {
+		$curscr = "";
+	    } elsif ($addr eq $newscr) {
+		$newscr = "";
+	    } elsif ($addr eq $stdscr) {
+		$stdscr = "";
+	    } else {
+		for $n (0..$#win_addr) {
+		    if ($win_addr[$n] eq $addr) {
+			$win_addr[$n] = "";
+		    }
+		}
+	    }
+	}
+
+	# Compactify runs of PutAttrChar calls (TR_CHARPUT)
+	if ($_ =~ /$putattr/)
+	{
+		my $putattr_chars = $1;
+		my $starty = $2;
+		my $startx = $3;
+		while (<STDIN>)
+		{
+			if ($_ =~ /$putattr/) {
+				$putattr_chars .= $1;
+			} else {
+				last;
+			}
+		}
+		print "RUN of PutAttrChar()s: \"$putattr_chars\" from ${starty}, ${startx}\n";
+		redo CLASSIFY;
+	}
+
+	# Compactify runs of waddnstr calls (TR_CALLS)
+	if ($_ =~ /$waddnstr/)
+	{
+		my $waddnstr_chars = $2;
+		my $winaddr = $1;
+		while (<STDIN>)
+		{
+			if ($_ =~ /$waddnstr/ && $1 eq $winaddr) {
+				$waddnstr_chars .= $2;
+			} else {
+				last;
+			}
+		}
+		my $winaddstr = &transaddr($winaddr);
+		print "RUN of waddnstr()s: $winaddr, \"$waddnstr_chars\"\n";
+		redo CLASSIFY;
+	}
+
+	# More transformations can go here
+
+	# Repeated runs of anything
+	my $anyline = &transaddr($_);
+	my $repeatcount = 1;
+	while (<STDIN>) {
+	    if (&transaddr($_) eq $anyline) {
+		$repeatcount++;
+	    } else {
+		last;
+	    }
+	}
+	if ($repeatcount > 1) {
+		print "${repeatcount} REPEATS OF $anyline";
+	} else {
+		print $anyline
+	}
+	redo CLASSIFY if $_;
+
+	} # :CLASSIFY
+}
+
+# tracemunch ends here
diff --git a/test/view.c b/test/view.c
new file mode 100644
index 0000000..9f2d72f
--- /dev/null
+++ b/test/view.c
@@ -0,0 +1,573 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+ * view.c -- a silly little viewer program
+ *
+ * written by Eric S. Raymond <esr@snark.thyrsus.com> December 1994
+ * to test the scrolling code in ncurses.
+ *
+ * modified by Thomas Dickey <dickey@clark.net> July 1995 to demonstrate
+ * the use of 'resizeterm()', and May 2000 to illustrate wide-character
+ * handling.
+ *
+ * Takes a filename argument.  It's a simple file-viewer with various
+ * scroll-up and scroll-down commands.
+ *
+ * n	-- scroll one line forward
+ * p	-- scroll one line back
+ *
+ * Either command accepts a numeric prefix interpreted as a repeat count.
+ * Thus, typing `5n' should scroll forward 5 lines in the file.
+ *
+ * The way you can tell this is working OK is that, in the trace file,
+ * there should be one scroll operation plus a small number of line
+ * updates, as opposed to a whole-page update.  This means the physical
+ * scroll operation worked, and the refresh() code only had to do a
+ * partial repaint.
+ *
+ * $Id: view.c,v 1.69 2008/09/06 22:10:50 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <time.h>
+
+#undef CTRL			/* conflict on AIX 5.2 with <sys/ioctl.h> */
+
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#else
+# include <sgtty.h>
+#endif
+
+#if !defined(sun) || !HAVE_TERMIOS_H
+# if HAVE_SYS_IOCTL_H
+#  include <sys/ioctl.h>
+# endif
+#endif
+
+#define my_pair 1
+
+/* This is needed to compile 'struct winsize' */
+#if NEED_PTEM_H
+#include <sys/stream.h>
+#include <sys/ptem.h>
+#endif
+
+#if USE_WIDEC_SUPPORT
+#if HAVE_MBTOWC && HAVE_MBLEN
+#define reset_mbytes(state) mblen(NULL, 0), mbtowc(NULL, NULL, 0)
+#define count_mbytes(buffer,length,state) mblen(buffer,length)
+#define check_mbytes(wch,buffer,length,state) \
+	(int) mbtowc(&wch, buffer, length)
+#define state_unused
+#elif HAVE_MBRTOWC && HAVE_MBRLEN
+#define reset_mbytes(state) init_mb(state)
+#define count_mbytes(buffer,length,state) mbrlen(buffer,length,&state)
+#define check_mbytes(wch,buffer,length,state) \
+	(int) mbrtowc(&wch, buffer, length, &state)
+#else
+make an error
+#endif
+#endif				/* USE_WIDEC_SUPPORT */
+
+static RETSIGTYPE finish(int sig) GCC_NORETURN;
+static void show_all(const char *tag);
+
+#if defined(SIGWINCH) && defined(TIOCGWINSZ) && HAVE_RESIZE_TERM
+#define CAN_RESIZE 1
+#else
+#define CAN_RESIZE 0
+#endif
+
+#if CAN_RESIZE
+static RETSIGTYPE adjust(int sig);
+static int interrupted;
+#endif
+
+static bool waiting = FALSE;
+static int shift = 0;
+static bool try_color = FALSE;
+
+static char *fname;
+static NCURSES_CH_T **vec_lines;
+static NCURSES_CH_T **lptr;
+static int num_lines;
+
+static void
+usage(void)
+{
+    static const char *msg[] =
+    {
+	"Usage: view [options] file"
+	,""
+	,"Options:"
+	," -c       use color if terminal supports it"
+	," -i       ignore INT, QUIT, TERM signals"
+	," -n NUM   specify maximum number of lines (default 1000)"
+#if defined(KEY_RESIZE)
+	," -r       use old-style sigwinch handler rather than KEY_RESIZE"
+#endif
+#ifdef TRACE
+	," -t       trace screen updates"
+	," -T NUM   specify trace mask"
+#endif
+    };
+    size_t n;
+    for (n = 0; n < SIZEOF(msg); n++)
+	fprintf(stderr, "%s\n", msg[n]);
+    ExitProgram(EXIT_FAILURE);
+}
+
+static int
+ch_len(NCURSES_CH_T * src)
+{
+    int result = 0;
+#if USE_WIDEC_SUPPORT
+#endif
+
+#if USE_WIDEC_SUPPORT
+    while (getcchar(src++, NULL, NULL, NULL, NULL) > 0)
+	result++;
+#else
+    while (*src++)
+	result++;
+#endif
+    return result;
+}
+
+/*
+ * Allocate a string into an array of chtype's.  If UTF-8 mode is
+ * active, translate the string accordingly.
+ */
+static NCURSES_CH_T *
+ch_dup(char *src)
+{
+    unsigned len = strlen(src);
+    NCURSES_CH_T *dst = typeMalloc(NCURSES_CH_T, len + 1);
+    unsigned j, k;
+#if USE_WIDEC_SUPPORT
+    wchar_t wstr[CCHARW_MAX + 1];
+    wchar_t wch;
+    int l = 0;
+    size_t rc;
+    int width;
+#ifndef state_unused
+    mbstate_t state;
+#endif
+#endif /* USE_WIDEC_SUPPORT */
+
+#if USE_WIDEC_SUPPORT
+    reset_mbytes(state);
+#endif
+    for (j = k = 0; j < len; j++) {
+#if USE_WIDEC_SUPPORT
+	rc = check_mbytes(wch, src + j, len - j, state);
+	if (rc == (size_t) -1 || rc == (size_t) -2)
+	    break;
+	j += rc - 1;
+	if ((width = wcwidth(wch)) < 0)
+	    break;
+	if ((width > 0 && l > 0) || l == CCHARW_MAX) {
+	    wstr[l] = L'\0';
+	    l = 0;
+	    if (setcchar(dst + k, wstr, 0, 0, NULL) != OK)
+		break;
+	    ++k;
+	}
+	if (width == 0 && l == 0)
+	    wstr[l++] = L' ';
+	wstr[l++] = wch;
+#else
+	dst[k++] = src[j];
+#endif
+    }
+#if USE_WIDEC_SUPPORT
+    if (l > 0) {
+	wstr[l] = L'\0';
+	if (setcchar(dst + k, wstr, 0, 0, NULL) == OK)
+	    ++k;
+    }
+    wstr[0] = L'\0';
+    setcchar(dst + k, wstr, 0, 0, NULL);
+#else
+    dst[k] = 0;
+#endif
+    return dst;
+}
+
+int
+main(int argc, char *argv[])
+{
+    int MAXLINES = 1000;
+    FILE *fp;
+    char buf[BUFSIZ];
+    int i;
+    int my_delay = 0;
+    NCURSES_CH_T **olptr;
+    int value = 0;
+    bool done = FALSE;
+    bool got_number = FALSE;
+#if CAN_RESIZE
+    bool nonposix_resize = FALSE;
+#endif
+    const char *my_label = "Input";
+
+    setlocale(LC_ALL, "");
+
+#ifndef NCURSES_VERSION
+    /*
+     * We know ncurses will catch SIGINT if we don't establish our own handler.
+     * Other versions of curses may/may not catch it.
+     */
+    (void) signal(SIGINT, finish);	/* arrange interrupts to terminate */
+#endif
+
+    while ((i = getopt(argc, argv, "cin:rtT:")) != -1) {
+	switch (i) {
+	case 'c':
+	    try_color = TRUE;
+	    break;
+	case 'i':
+	    CATCHALL(SIG_IGN);
+	    break;
+	case 'n':
+	    if ((MAXLINES = atoi(optarg)) < 1 ||
+		(MAXLINES + 2) <= 1)
+		usage();
+	    break;
+#if CAN_RESIZE
+	case 'r':
+	    nonposix_resize = TRUE;
+	    break;
+#endif
+#ifdef TRACE
+	case 'T':
+	    trace((unsigned) atoi(optarg));
+	    break;
+	case 't':
+	    trace(TRACE_CALLS);
+	    break;
+#endif
+	default:
+	    usage();
+	}
+    }
+    if (optind + 1 != argc)
+	usage();
+
+    if ((vec_lines = typeMalloc(NCURSES_CH_T *, MAXLINES + 2)) == 0)
+	usage();
+
+    fname = argv[optind];
+    if ((fp = fopen(fname, "r")) == 0) {
+	perror(fname);
+	ExitProgram(EXIT_FAILURE);
+    }
+#if CAN_RESIZE
+    if (nonposix_resize)
+	(void) signal(SIGWINCH, adjust);	/* arrange interrupts to resize */
+#endif
+
+    /* slurp the file */
+    for (lptr = &vec_lines[0]; (lptr - vec_lines) < MAXLINES; lptr++) {
+	char temp[BUFSIZ], *s, *d;
+	int col;
+
+	if (fgets(buf, sizeof(buf), fp) == 0)
+	    break;
+
+	/* convert tabs so that shift will work properly */
+	for (s = buf, d = temp, col = 0; (*d = *s) != '\0'; s++) {
+	    if (*d == '\n') {
+		*d = '\0';
+		break;
+	    } else if (*d == '\t') {
+		col = (col | 7) + 1;
+		while ((d - temp) != col)
+		    *d++ = ' ';
+	    } else
+#if USE_WIDEC_SUPPORT
+		col++, d++;
+#else
+	    if (isprint(UChar(*d))) {
+		col++;
+		d++;
+	    } else {
+		sprintf(d, "\\%03o", UChar(*s));
+		d += strlen(d);
+		col = (d - temp);
+	    }
+#endif
+	}
+	*lptr = ch_dup(temp);
+    }
+    (void) fclose(fp);
+    num_lines = lptr - vec_lines;
+
+    (void) initscr();		/* initialize the curses library */
+    keypad(stdscr, TRUE);	/* enable keyboard mapping */
+    (void) nonl();		/* tell curses not to do NL->CR/NL on output */
+    (void) cbreak();		/* take input chars one at a time, no wait for \n */
+    (void) noecho();		/* don't echo input */
+    nodelay(stdscr, TRUE);
+    idlok(stdscr, TRUE);	/* allow use of insert/delete line */
+
+    if (try_color) {
+	if (has_colors()) {
+	    start_color();
+	    init_pair(my_pair, COLOR_WHITE, COLOR_BLUE);
+	    bkgd(COLOR_PAIR(my_pair));
+	} else {
+	    try_color = FALSE;
+	}
+    }
+
+    lptr = vec_lines;
+    while (!done) {
+	int n, c;
+
+	if (!got_number)
+	    show_all(my_label);
+
+	n = 0;
+	for (;;) {
+#if CAN_RESIZE
+	    if (interrupted) {
+		adjust(0);
+		my_label = "interrupt";
+	    }
+#endif
+	    waiting = TRUE;
+	    c = getch();
+	    waiting = FALSE;
+	    if ((c < 127) && isdigit(c)) {
+		if (!got_number) {
+		    mvprintw(0, 0, "Count: ");
+		    clrtoeol();
+		}
+		addch(UChar(c));
+		value = 10 * value + (c - '0');
+		got_number = TRUE;
+	    } else
+		break;
+	}
+	if (got_number && value) {
+	    n = value;
+	} else {
+	    n = 1;
+	}
+
+	if (c != ERR)
+	    my_label = keyname(c);
+	switch (c) {
+	case KEY_DOWN:
+	case 'n':
+	    olptr = lptr;
+	    for (i = 0; i < n; i++)
+		if ((lptr - vec_lines) < (num_lines - LINES + 1))
+		    lptr++;
+		else
+		    break;
+	    scrl(lptr - olptr);
+	    break;
+
+	case KEY_UP:
+	case 'p':
+	    olptr = lptr;
+	    for (i = 0; i < n; i++)
+		if (lptr > vec_lines)
+		    lptr--;
+		else
+		    break;
+	    scrl(lptr - olptr);
+	    break;
+
+	case 'h':
+	case KEY_HOME:
+	    lptr = vec_lines;
+	    break;
+
+	case 'e':
+	case KEY_END:
+	    if (num_lines > LINES)
+		lptr = vec_lines + num_lines - LINES + 1;
+	    else
+		lptr = vec_lines;
+	    break;
+
+	case 'r':
+	case KEY_RIGHT:
+	    shift += n;
+	    break;
+
+	case 'l':
+	case KEY_LEFT:
+	    shift -= n;
+	    if (shift < 0) {
+		shift = 0;
+		beep();
+	    }
+	    break;
+
+	case 'q':
+	    done = TRUE;
+	    break;
+
+#ifdef KEY_RESIZE
+	case KEY_RESIZE:	/* ignore this; ncurses will repaint */
+	    break;
+#endif
+	case 's':
+	    if (got_number) {
+		halfdelay(my_delay = n);
+	    } else {
+		nodelay(stdscr, FALSE);
+		my_delay = -1;
+	    }
+	    break;
+	case ' ':
+	    nodelay(stdscr, TRUE);
+	    my_delay = 0;
+	    break;
+	case ERR:
+	    if (!my_delay)
+		napms(50);
+	    break;
+	default:
+	    beep();
+	    break;
+	}
+	if (c >= KEY_MIN || (c > 0 && !isdigit(c))) {
+	    got_number = FALSE;
+	    value = 0;
+	}
+    }
+
+    finish(0);			/* we're done */
+}
+
+static RETSIGTYPE
+finish(int sig)
+{
+    endwin();
+#if NO_LEAKS
+    if (vec_lines != 0) {
+	int n;
+	for (n = 0; n < num_lines; ++n) {
+	    free(vec_lines[n]);
+	}
+	free(vec_lines);
+    }
+#endif
+    ExitProgram(sig != 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+#if CAN_RESIZE
+/*
+ * This uses functions that are "unsafe", but it seems to work on SunOS and
+ * Linux.  Usually:  the "unsafe" refers to the functions that POSIX lists
+ * which may be called from a signal handler.  Those do not include buffered
+ * I/O, which is used for instance in wrefresh().  To be really portable, you
+ * should use the KEY_RESIZE return (which relies on ncurses' sigwinch
+ * handler).
+ *
+ * The 'wrefresh(curscr)' is needed to force the refresh to start from the top
+ * of the screen -- some xterms mangle the bitmap while resizing.
+ */
+static RETSIGTYPE
+adjust(int sig)
+{
+    if (waiting || sig == 0) {
+	struct winsize size;
+
+	if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
+	    resize_term(size.ws_row, size.ws_col);
+	    wrefresh(curscr);	/* Linux needs this */
+	    show_all(sig ? "SIGWINCH" : "interrupt");
+	}
+	interrupted = FALSE;
+    } else {
+	interrupted = TRUE;
+    }
+    (void) signal(SIGWINCH, adjust);	/* some systems need this */
+}
+#endif /* CAN_RESIZE */
+
+static void
+show_all(const char *tag)
+{
+    int i;
+    char temp[BUFSIZ];
+    NCURSES_CH_T *s;
+    time_t this_time;
+
+#if CAN_RESIZE
+    sprintf(temp, "%.20s (%3dx%3d) col %d ", tag, LINES, COLS, shift);
+    i = strlen(temp);
+    if ((i + 7) < (int) sizeof(temp))
+	sprintf(temp + i, "view %.*s", (int) (sizeof(temp) - 7 - i), fname);
+#else
+    (void) tag;
+    sprintf(temp, "view %.*s", (int) sizeof(temp) - 7, fname);
+#endif
+    move(0, 0);
+    printw("%.*s", COLS, temp);
+    clrtoeol();
+    this_time = time((time_t *) 0);
+    strcpy(temp, ctime(&this_time));
+    if ((i = strlen(temp)) != 0) {
+	temp[--i] = 0;
+	if (move(0, COLS - i - 2) != ERR)
+	    printw("  %s", temp);
+    }
+
+    scrollok(stdscr, FALSE);	/* prevent screen from moving */
+    for (i = 1; i < LINES; i++) {
+	move(i, 0);
+	printw("%3ld:", (long) (lptr + i - vec_lines));
+	clrtoeol();
+	if ((s = lptr[i - 1]) != 0) {
+	    int len = ch_len(s);
+	    if (len > shift) {
+#if USE_WIDEC_SUPPORT
+		add_wchstr(s + shift);
+#else
+		addchstr(s + shift);
+#endif
+	    }
+#if defined(NCURSES_VERSION) || defined(HAVE_WCHGAT)
+	    if (try_color)
+		wchgat(stdscr, -1, A_NORMAL, my_pair, NULL);
+#endif
+	}
+    }
+    setscrreg(1, LINES - 1);
+    scrollok(stdscr, TRUE);
+    refresh();
+}
diff --git a/test/widechars-utf8.txt b/test/widechars-utf8.txt
new file mode 100644
index 0000000..43ecd0f
--- /dev/null
+++ b/test/widechars-utf8.txt
@@ -0,0 +1,7 @@
+APPLE     -- It's an APPLE.
+DOG         -- No, that's not my DOG.
+ORANGE   -- Yeah, that's JUICY.
+CHICKEN -- Normally not a PET.
+CAT         -- No, never put a DOG and a CAT together!
+FISH       -- Cats like FISH.
+LEMON     -- You KNOW how it TASTES.
diff --git a/test/worm.c b/test/worm.c
new file mode 100644
index 0000000..2029b34
--- /dev/null
+++ b/test/worm.c
@@ -0,0 +1,608 @@
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+/*
+
+	 @@@        @@@    @@@@@@@@@@     @@@@@@@@@@@    @@@@@@@@@@@@
+	 @@@        @@@   @@@@@@@@@@@@    @@@@@@@@@@@@   @@@@@@@@@@@@@
+	 @@@        @@@  @@@@      @@@@   @@@@           @@@@ @@@  @@@@
+	 @@@   @@   @@@  @@@        @@@   @@@            @@@  @@@   @@@
+	 @@@  @@@@  @@@  @@@        @@@   @@@            @@@  @@@   @@@
+	 @@@@ @@@@ @@@@  @@@        @@@   @@@            @@@  @@@   @@@
+	  @@@@@@@@@@@@   @@@@      @@@@   @@@            @@@  @@@   @@@
+	   @@@@  @@@@     @@@@@@@@@@@@    @@@            @@@  @@@   @@@
+	    @@    @@       @@@@@@@@@@     @@@            @@@  @@@   @@@
+
+				 Eric P. Scott
+			  Caltech High Energy Physics
+				 October, 1980
+
+		Hacks to turn this into a test frame for cursor movement:
+			Eric S. Raymond <esr@snark.thyrsus.com>
+				January, 1995
+
+		July 1995 (esr): worms is now in living color! :-)
+
+Options:
+	-f			fill screen with copies of 'WORM' at start.
+	-l <n>			set worm length
+	-n <n>			set number of worms
+	-t			make worms leave droppings
+	-T <start> <end>	set trace interval
+	-S			set single-stepping during trace interval
+	-N			suppress cursor-movement optimization
+
+  This program makes a good torture-test for the ncurses cursor-optimization
+  code.  You can use -T to set the worm move interval over which movement
+  traces will be dumped.  The program stops and waits for one character of
+  input at the beginning and end of the interval.
+
+  $Id: worm.c,v 1.58 2008/10/04 21:54:09 tom Exp $
+*/
+
+#include <test.priv.h>
+
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
+
+WANT_USE_WINDOW();
+
+#define MAX_WORMS	40
+#define MAX_LENGTH	1024
+
+static chtype flavor[] =
+{
+    'O', '*', '#', '$', '%', '0', '@',
+};
+static const short xinc[] =
+{
+    1, 1, 1, 0, -1, -1, -1, 0
+}, yinc[] =
+{
+    -1, 0, 1, 1, 1, 0, -1, -1
+};
+
+typedef struct worm {
+    int orientation;
+    int head;
+    short *xpos;
+    short *ypos;
+    chtype attrs;
+#ifdef USE_PTHREADS
+    pthread_t thread;
+#endif
+} WORM;
+
+static unsigned long sequence = 0;
+static bool quitting = FALSE;
+
+static WORM worm[MAX_WORMS];
+static short **refs;
+static int last_x, last_y;
+
+static const char *field;
+static int length = 16, number = 3;
+static chtype trail = ' ';
+
+static unsigned pending;
+#ifdef TRACE
+static int generation, trace_start, trace_end;
+#endif /* TRACE */
+/* *INDENT-OFF* */
+static const struct options {
+    int nopts;
+    int opts[3];
+} normal[8]={
+    { 3, { 7, 0, 1 } },
+    { 3, { 0, 1, 2 } },
+    { 3, { 1, 2, 3 } },
+    { 3, { 2, 3, 4 } },
+    { 3, { 3, 4, 5 } },
+    { 3, { 4, 5, 6 } },
+    { 3, { 5, 6, 7 } },
+    { 3, { 6, 7, 0 } }
+}, upper[8]={
+    { 1, { 1, 0, 0 } },
+    { 2, { 1, 2, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 2, { 4, 5, 0 } },
+    { 1, { 5, 0, 0 } },
+    { 2, { 1, 5, 0 } }
+}, left[8]={
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 2, { 2, 3, 0 } },
+    { 1, { 3, 0, 0 } },
+    { 2, { 3, 7, 0 } },
+    { 1, { 7, 0, 0 } },
+    { 2, { 7, 0, 0 } }
+}, right[8]={
+    { 1, { 7, 0, 0 } },
+    { 2, { 3, 7, 0 } },
+    { 1, { 3, 0, 0 } },
+    { 2, { 3, 4, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 2, { 6, 7, 0 } }
+}, lower[8]={
+    { 0, { 0, 0, 0 } },
+    { 2, { 0, 1, 0 } },
+    { 1, { 1, 0, 0 } },
+    { 2, { 1, 5, 0 } },
+    { 1, { 5, 0, 0 } },
+    { 2, { 5, 6, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } }
+}, upleft[8]={
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 1, { 3, 0, 0 } },
+    { 2, { 1, 3, 0 } },
+    { 1, { 1, 0, 0 } }
+}, upright[8]={
+    { 2, { 3, 5, 0 } },
+    { 1, { 3, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 1, { 5, 0, 0 } }
+}, lowleft[8]={
+    { 3, { 7, 0, 1 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 1, { 1, 0, 0 } },
+    { 2, { 1, 7, 0 } },
+    { 1, { 7, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } }
+}, lowright[8]={
+    { 0, { 0, 0, 0 } },
+    { 1, { 7, 0, 0 } },
+    { 2, { 5, 7, 0 } },
+    { 1, { 5, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } },
+    { 0, { 0, 0, 0 } }
+};
+/* *INDENT-ON* */
+
+static void
+cleanup(void)
+{
+    USING_WINDOW(stdscr, wrefresh);
+    curs_set(1);
+    endwin();
+}
+
+static RETSIGTYPE
+onsig(int sig GCC_UNUSED)
+{
+    cleanup();
+    ExitProgram(EXIT_FAILURE);
+}
+
+static float
+ranf(void)
+{
+    long r = (rand() & 077777);
+    return ((float) r / 32768.);
+}
+
+static int
+draw_worm(WINDOW *win, void *data)
+{
+    WORM *w = (WORM *) data;
+    const struct options *op;
+    unsigned mask = ~(1 << (w - worm));
+    chtype attrs = w->attrs | ((mask & pending) ? A_REVERSE : 0);
+
+    int x;
+    int y;
+    int h;
+
+    bool done = FALSE;
+
+    if ((x = w->xpos[h = w->head]) < 0) {
+	wmove(win, y = w->ypos[h] = last_y, x = w->xpos[h] = 0);
+	waddch(win, attrs);
+	refs[y][x]++;
+    } else {
+	y = w->ypos[h];
+    }
+
+    if (x > last_x)
+	x = last_x;
+    if (y > last_y)
+	y = last_y;
+
+    if (++h == length)
+	h = 0;
+
+    if (w->xpos[w->head = h] >= 0) {
+	int x1, y1;
+	x1 = w->xpos[h];
+	y1 = w->ypos[h];
+	if (y1 < LINES
+	    && x1 < COLS
+	    && --refs[y1][x1] == 0) {
+	    wmove(win, y1, x1);
+	    waddch(win, trail);
+	}
+    }
+
+    op = &(x == 0
+	   ? (y == 0
+	      ? upleft
+	      : (y == last_y
+		 ? lowleft
+		 : left))
+	   : (x == last_x
+	      ? (y == 0
+		 ? upright
+		 : (y == last_y
+		    ? lowright
+		    : right))
+	      : (y == 0
+		 ? upper
+		 : (y == last_y
+		    ? lower
+		    : normal))))[w->orientation];
+
+    switch (op->nopts) {
+    case 0:
+	done = TRUE;
+	break;
+    case 1:
+	w->orientation = op->opts[0];
+	break;
+    default:
+	w->orientation = op->opts[(int) (ranf() * (float) op->nopts)];
+	break;
+    }
+
+    if (!done) {
+	x += xinc[w->orientation];
+	y += yinc[w->orientation];
+	wmove(win, y, x);
+
+	if (y < 0)
+	    y = 0;
+	waddch(win, attrs);
+
+	w->ypos[h] = y;
+	w->xpos[h] = x;
+	refs[y][x]++;
+    }
+
+    return done;
+}
+
+#ifdef USE_PTHREADS
+static bool
+quit_worm(int bitnum)
+{
+    pending |= (1 << bitnum);
+    napms(10);			/* let the other thread(s) have a chance */
+    pending &= ~(1 << bitnum);
+    return quitting;
+}
+
+static void *
+start_worm(void *arg)
+{
+    unsigned long compare = 0;
+    Trace(("start_worm"));
+    while (!quit_worm(((struct worm *) arg) - worm)) {
+	while (compare < sequence) {
+	    ++compare;
+	    use_window(stdscr, draw_worm, arg);
+	}
+    }
+    Trace(("...start_worm (done)"));
+    return NULL;
+}
+#endif
+
+static bool
+draw_all_worms(void)
+{
+    bool done = FALSE;
+    int n;
+    struct worm *w;
+
+#ifdef USE_PTHREADS
+    static bool first = TRUE;
+    if (first) {
+	first = FALSE;
+	for (n = 0, w = &worm[0]; n < number; n++, w++) {
+	    int rc;
+	    rc = pthread_create(&(w->thread), NULL, start_worm, w);
+	}
+    }
+#else
+    for (n = 0, w = &worm[0]; n < number; n++, w++) {
+	if (USING_WINDOW2(stdscr, draw_worm, w))
+	    done = TRUE;
+    }
+#endif
+    return done;
+}
+
+static int
+get_input(void)
+{
+    int ch;
+    ch = USING_WINDOW(stdscr, wgetch);
+    return ch;
+}
+
+#ifdef KEY_RESIZE
+static int
+update_refs(WINDOW *win)
+{
+    int x, y;
+
+    (void) win;
+    if (last_x != COLS - 1) {
+	for (y = 0; y <= last_y; y++) {
+	    refs[y] = typeRealloc(short, COLS, refs[y]);
+	    for (x = last_x + 1; x < COLS; x++)
+		refs[y][x] = 0;
+	}
+	last_x = COLS - 1;
+    }
+    if (last_y != LINES - 1) {
+	for (y = LINES; y <= last_y; y++)
+	    free(refs[y]);
+	refs = typeRealloc(short *, LINES, refs);
+	for (y = last_y + 1; y < LINES; y++) {
+	    refs[y] = typeMalloc(short, COLS);
+	    for (x = 0; x < COLS; x++)
+		refs[y][x] = 0;
+	}
+	last_y = LINES - 1;
+    }
+    return OK;
+}
+#endif
+
+int
+main(int argc, char *argv[])
+{
+    int x, y;
+    int n;
+    struct worm *w;
+    short *ip;
+    bool done = FALSE;
+
+    setlocale(LC_ALL, "");
+
+    for (x = 1; x < argc; x++) {
+	char *p;
+	p = argv[x];
+	if (*p == '-')
+	    p++;
+	switch (*p) {
+	case 'f':
+	    field = "WORM";
+	    break;
+	case 'l':
+	    if (++x == argc)
+		goto usage;
+	    if ((length = atoi(argv[x])) < 2 || length > MAX_LENGTH) {
+		fprintf(stderr, "%s: Invalid length\n", *argv);
+		ExitProgram(EXIT_FAILURE);
+	    }
+	    break;
+	case 'n':
+	    if (++x == argc)
+		goto usage;
+	    if ((number = atoi(argv[x])) < 1 || number > MAX_WORMS) {
+		fprintf(stderr, "%s: Invalid number of worms\n", *argv);
+		ExitProgram(EXIT_FAILURE);
+	    }
+	    break;
+	case 't':
+	    trail = '.';
+	    break;
+#ifdef TRACE
+	case 'T':
+	    trace_start = atoi(argv[++x]);
+	    trace_end = atoi(argv[++x]);
+	    break;
+	case 'N':
+	    _nc_optimize_enable ^= OPTIMIZE_ALL;	/* declared by ncurses */
+	    break;
+#endif /* TRACE */
+	default:
+	  usage:
+	    fprintf(stderr,
+		    "usage: %s [-field] [-length #] [-number #] [-trail]\n", *argv);
+	    ExitProgram(EXIT_FAILURE);
+	}
+    }
+
+    signal(SIGINT, onsig);
+    initscr();
+    noecho();
+    cbreak();
+    nonl();
+
+    curs_set(0);
+
+    last_y = LINES - 1;
+    last_x = COLS - 1;
+
+#ifdef A_COLOR
+    if (has_colors()) {
+	int bg = COLOR_BLACK;
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() == OK)
+	    bg = -1;
+#endif
+
+#define SET_COLOR(num, fg) \
+	    init_pair(num+1, fg, bg); \
+	    flavor[num] |= COLOR_PAIR(num+1) | A_BOLD
+
+	SET_COLOR(0, COLOR_GREEN);
+	SET_COLOR(1, COLOR_RED);
+	SET_COLOR(2, COLOR_CYAN);
+	SET_COLOR(3, COLOR_WHITE);
+	SET_COLOR(4, COLOR_MAGENTA);
+	SET_COLOR(5, COLOR_BLUE);
+	SET_COLOR(6, COLOR_YELLOW);
+    }
+#endif /* A_COLOR */
+
+    refs = typeMalloc(short *, LINES);
+    for (y = 0; y < LINES; y++) {
+	refs[y] = typeMalloc(short, COLS);
+	for (x = 0; x < COLS; x++) {
+	    refs[y][x] = 0;
+	}
+    }
+
+#ifdef BADCORNER
+    /* if addressing the lower right corner doesn't work in your curses */
+    refs[last_y][last_x] = 1;
+#endif /* BADCORNER */
+
+    for (n = number, w = &worm[0]; --n >= 0; w++) {
+	w->attrs = flavor[n % SIZEOF(flavor)];
+	w->orientation = 0;
+	w->head = 0;
+
+	if (!(ip = typeMalloc(short, (length + 1)))) {
+	    fprintf(stderr, "%s: out of memory\n", *argv);
+	    ExitProgram(EXIT_FAILURE);
+	}
+	w->xpos = ip;
+	for (x = length; --x >= 0;)
+	    *ip++ = -1;
+	if (!(ip = typeMalloc(short, (length + 1)))) {
+	    fprintf(stderr, "%s: out of memory\n", *argv);
+	    ExitProgram(EXIT_FAILURE);
+	}
+	w->ypos = ip;
+	for (y = length; --y >= 0;)
+	    *ip++ = -1;
+    }
+    if (field) {
+	const char *p;
+	p = field;
+	for (y = last_y; --y >= 0;) {
+	    for (x = COLS; --x >= 0;) {
+		addch((chtype) (*p++));
+		if (!*p)
+		    p = field;
+	    }
+	}
+    }
+    USING_WINDOW(stdscr, wrefresh);
+    nodelay(stdscr, TRUE);
+
+    while (!done) {
+	int ch;
+
+	++sequence;
+	if ((ch = get_input()) > 0) {
+#ifdef TRACE
+	    if (trace_start || trace_end) {
+		if (generation == trace_start) {
+		    trace(TRACE_CALLS);
+		    get_input();
+		} else if (generation == trace_end) {
+		    trace(0);
+		    get_input();
+		}
+
+		generation++;
+	    }
+#endif
+
+#ifdef KEY_RESIZE
+	    if (ch == KEY_RESIZE) {
+		USING_WINDOW(stdscr, update_refs);
+	    }
+#endif
+
+	    /*
+	     * Make it simple to put this into single-step mode, or resume
+	     * normal operation -T.Dickey
+	     */
+	    if (ch == 'q') {
+		quitting = TRUE;
+		done = TRUE;
+		continue;
+	    } else if (ch == 's') {
+		nodelay(stdscr, FALSE);
+	    } else if (ch == ' ') {
+		nodelay(stdscr, TRUE);
+	    }
+	}
+
+	done = draw_all_worms();
+	napms(10);
+	USING_WINDOW(stdscr, wrefresh);
+    }
+
+    Trace(("Cleanup"));
+    cleanup();
+#ifdef NO_LEAKS
+    for (y = 0; y < LINES; y++) {
+	free(refs[y]);
+    }
+    free(refs);
+    for (n = number, w = &worm[0]; --n >= 0; w++) {
+	free(w->xpos);
+	free(w->ypos);
+    }
+#endif
+#ifdef USE_PTHREADS
+    /*
+     * Do this just in case one of the threads did not really exit.
+     */
+    Trace(("join all threads"));
+    for (n = 0; n < number; n++) {
+	pthread_join(worm[n].thread, NULL);
+    }
+#endif
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/xmas.c b/test/xmas.c
new file mode 100644
index 0000000..b838bae
--- /dev/null
+++ b/test/xmas.c
@@ -0,0 +1,1162 @@
+/******************************************************************************/
+/* asciixmas                                                                  */
+/* December 1989             Larry Bartz           Indianapolis, IN           */
+/*                                                                            */
+/*                                                                            */
+/* I'm dreaming of an ascii character-based monochrome Christmas,             */
+/* Just like the one's I used to know!                                        */
+/* Via a full duplex communications channel,                                  */
+/* At 9600 bits per second,                                                   */
+/* Even though it's kinda slow.                                               */
+/*                                                                            */
+/* I'm dreaming of an ascii character-based monochrome Christmas,             */
+/* With ev'ry C program I write!                                              */
+/* May your screen be merry and bright!                                       */
+/* And may all your Christmases be amber or green,                            */
+/* (for reduced eyestrain and improved visibility)!                           */
+/*                                                                            */
+/*                                                                            */
+/*                                                                            */
+/*                                                                            */
+/*                                                                            */
+/* IMPLEMENTATION                                                             */
+/*                                                                            */
+/* Feel free to modify the defined string FROMWHO to reflect you, your        */
+/* organization, your site, whatever.                                         */
+/*                                                                            */
+/* This really looks a lot better if you can turn off your cursor before      */
+/* execution. I wanted to do that here but very few termcap entries or        */
+/* terminfo definitions have the appropriate string defined. If you know      */
+/* the string(s) for the terminal(s) you use or which your site supports,     */
+/* you could call asciixmas from within a shell in which you issue the        */
+/* string to the terminal. The cursor is distracting but it doesn't really    */
+/* ruin the show.                                                             */
+/*                                                                            */
+/* At our site, we invoke this for our users just after login and the         */
+/* determination of terminal type.                                            */
+/*                                                                            */
+/*                                                                            */
+/* PORTABILITY                                                                */
+/*                                                                            */
+/* I wrote this using only the very simplest curses functions so that it      */
+/* might be the most portable. I was personally able to test on five          */
+/* different cpu/UNIX combinations.                                           */
+/*                                                                            */
+/*                                                                            */
+/* COMPILE                                                                    */
+/*                                                                            */
+/* usually this:                                                              */
+/*                                                                            */
+/* cc -O asciixmas.c -lcurses -o asciixmas -s                                 */
+/*                                                                            */
+/*                                                                            */
+/* Zilog S8000 models 11, 21, 31, etc with ZEUS variant of SYSTEM III         */
+/* maybe other SYSTEM III also:                                               */
+/*                                                                            */
+/* cc asciixmas.c -lcurses -ltermlib -o asciixmas -s                          */
+/*                                                                            */
+/* as above with optional "peephole optimizer" installed:                     */
+/*                                                                            */
+/* cc -O asciixmas.c -lcurses -ltermlib -o asciixmas -s                       */
+/*                                                                            */
+/*                                                                            */
+/* Zilog S8000 models 32, 130 with WE32100 chip and SYS V, REL2               */
+/* maybe 3B2 also?                                                            */
+/*                                                                            */
+/* cc -f -O -K sd asciixmas.c -lcurses -o asciixmas -s                        */
+/*                                                                            */
+/*                                                                            */
+/* Pyramid, Sequent, any other "dual universe" types compile and execute      */
+/* under either universe. The compile line for the ucb universe (as you       */
+/* might expect) is the same as for SYS III UNIX:                             */
+/*                                                                            */
+/* cc -O asciixmas.c -lcurses -ltermlib -o asciixmas -s                       */
+/*                                                                            */
+/* The above compile will also hold true for other BSD systems. (I hope)      */
+/*                                                                            */
+/*                                                                            */
+/*                                                                            */
+/*                                                                            */
+/* For the Scrooges out there among you who don't want this thing to loop     */
+/* forever (or until the user hits a key), insert this into your compile      */
+/* line just after "cc" :                                                     */
+/*                                                                            */
+/* -DNOLOOP                                                                   */
+/*                                                                            */
+/* like so:                                                                   */
+/*                                                                            */
+/* cc -DNOLOOP -O asciixmas.c -lcurses -o asciixmas -s                        */
+/*                                                                            */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+
+/*
+ * $Id: xmas.c,v 1.24 2008/08/03 11:08:59 tom Exp $
+ */
+#include <test.priv.h>
+
+#define FROMWHO "Mark Hessling - (M.Hessling@gu.edu.au)"
+
+static int my_bg = COLOR_BLACK;
+static int y_pos, x_pos;
+
+static WINDOW *treescrn;
+static WINDOW *treescrn2;
+static WINDOW *treescrn3;
+static WINDOW *treescrn4;
+static WINDOW *treescrn5;
+static WINDOW *treescrn6;
+static WINDOW *treescrn7;
+static WINDOW *treescrn8;
+static WINDOW *dotdeer0;
+static WINDOW *stardeer0;
+static WINDOW *lildeer0;
+static WINDOW *lildeer1;
+static WINDOW *lildeer2;
+static WINDOW *lildeer3;
+static WINDOW *middeer0;
+static WINDOW *middeer1;
+static WINDOW *middeer2;
+static WINDOW *middeer3;
+static WINDOW *bigdeer0;
+static WINDOW *bigdeer1;
+static WINDOW *bigdeer2;
+static WINDOW *bigdeer3;
+static WINDOW *bigdeer4;
+static WINDOW *lookdeer0;
+static WINDOW *lookdeer1;
+static WINDOW *lookdeer2;
+static WINDOW *lookdeer3;
+static WINDOW *lookdeer4;
+static WINDOW *w_holiday;
+static WINDOW *w_del_msg;
+static bool *my_pairs;
+
+static int boxit(void);
+static int seas(void);
+static int greet(void);
+static int fromwho(void);
+static int tree(void);
+static int balls(void);
+static int star(void);
+static int strng1(void);
+static int strng2(void);
+static int strng3(void);
+static int strng4(void);
+static int strng5(void);
+static int reindeer(void);
+static int blinkit(void);
+
+static RETSIGTYPE done(int sig) GCC_NORETURN;
+
+static void
+set_color(WINDOW *win, chtype color)
+{
+    if (has_colors()) {
+	int n = (color + 1);
+	if (my_pairs == 0)
+	    my_pairs = typeCalloc(bool, COLORS + 1);
+	if (!my_pairs[n]) {
+	    init_pair(n, color, my_bg);
+	    my_pairs[n] = TRUE;
+	}
+	wattroff(win, A_COLOR);
+	wattron(win, COLOR_PAIR(n));
+    }
+}
+
+static void
+unset_color(WINDOW *win)
+{
+    if (has_colors())
+	wattrset(win, COLOR_PAIR(0));
+}
+
+static void
+look_out(int msecs)
+{
+    napms(msecs);
+    if (getch() != ERR) {
+	beep();
+	done(0);
+    }
+}
+
+int
+main(int argc GCC_UNUSED, char **argv GCC_UNUSED)
+{
+    int loopy;
+
+    setlocale(LC_ALL, "");
+
+    initscr();
+    noecho();
+    nonl();
+    refresh();
+
+    CATCHALL(done);
+
+    if (has_colors()) {
+	start_color();
+#if HAVE_USE_DEFAULT_COLORS
+	if (use_default_colors() == OK)
+	    my_bg = -1;
+#endif
+    }
+    curs_set(0);
+
+    if ((treescrn = newwin(16, 27, 3, 53)) == 0 ||
+	(treescrn2 = newwin(16, 27, 3, 53)) == 0 ||
+	(treescrn3 = newwin(16, 27, 3, 53)) == 0 ||
+	(treescrn4 = newwin(16, 27, 3, 53)) == 0 ||
+	(treescrn5 = newwin(16, 27, 3, 53)) == 0 ||
+	(treescrn6 = newwin(16, 27, 3, 53)) == 0 ||
+	(treescrn7 = newwin(16, 27, 3, 53)) == 0 ||
+	(treescrn8 = newwin(16, 27, 3, 53)) == 0 ||
+
+	(dotdeer0 = newwin(3, 71, 0, 8)) == 0 ||
+
+	(stardeer0 = newwin(4, 56, 0, 8)) == 0 ||
+
+	(lildeer0 = newwin(7, 53, 0, 8)) == 0 ||
+	(lildeer1 = newwin(2, 4, 0, 0)) == 0 ||
+	(lildeer2 = newwin(2, 4, 0, 0)) == 0 ||
+	(lildeer3 = newwin(2, 4, 0, 0)) == 0 ||
+
+	(middeer0 = newwin(15, 42, 0, 8)) == 0 ||
+	(middeer1 = newwin(3, 7, 0, 0)) == 0 ||
+	(middeer2 = newwin(3, 7, 0, 0)) == 0 ||
+	(middeer3 = newwin(3, 7, 0, 0)) == 0 ||
+
+	(bigdeer0 = newwin(10, 23, 0, 0)) == 0 ||
+	(bigdeer1 = newwin(10, 23, 0, 0)) == 0 ||
+	(bigdeer2 = newwin(10, 23, 0, 0)) == 0 ||
+	(bigdeer3 = newwin(10, 23, 0, 0)) == 0 ||
+	(bigdeer4 = newwin(10, 23, 0, 0)) == 0 ||
+
+	(lookdeer0 = newwin(10, 25, 0, 0)) == 0 ||
+	(lookdeer1 = newwin(10, 25, 0, 0)) == 0 ||
+	(lookdeer2 = newwin(10, 25, 0, 0)) == 0 ||
+	(lookdeer3 = newwin(10, 25, 0, 0)) == 0 ||
+	(lookdeer4 = newwin(10, 25, 0, 0)) == 0 ||
+
+	(w_holiday = newwin(1, 26, 3, 27)) == 0 ||
+
+	(w_del_msg = newwin(1, 19, 23, 60)) == 0) {
+	endwin();
+	fprintf(stderr, "Cannot create windows - screen too small\n");
+	ExitProgram(EXIT_FAILURE);
+    }
+
+    mvwaddstr(w_del_msg, 0, 0, "Hit any key to quit");
+
+    mvwaddstr(w_holiday, 0, 0, "H A P P Y  H O L I D A Y S");
+
+    /* set up the windows for our various reindeer */
+
+    /* lildeer1 */
+    mvwaddch(lildeer1, 0, 0, (chtype) 'V');
+    mvwaddch(lildeer1, 1, 0, (chtype) '@');
+    mvwaddch(lildeer1, 1, 1, (chtype) '<');
+    mvwaddch(lildeer1, 1, 2, (chtype) '>');
+    mvwaddch(lildeer1, 1, 3, (chtype) '~');
+
+    /* lildeer2 */
+    mvwaddch(lildeer2, 0, 0, (chtype) 'V');
+    mvwaddch(lildeer2, 1, 0, (chtype) '@');
+    mvwaddch(lildeer2, 1, 1, (chtype) '|');
+    mvwaddch(lildeer2, 1, 2, (chtype) '|');
+    mvwaddch(lildeer2, 1, 3, (chtype) '~');
+
+    /* lildeer3 */
+    mvwaddch(lildeer3, 0, 0, (chtype) 'V');
+    mvwaddch(lildeer3, 1, 0, (chtype) '@');
+    mvwaddch(lildeer3, 1, 1, (chtype) '>');
+    mvwaddch(lildeer3, 1, 2, (chtype) '<');
+    mvwaddch(lildeer2, 1, 3, (chtype) '~');
+
+    /* middeer1 */
+    mvwaddch(middeer1, 0, 2, (chtype) 'y');
+    mvwaddch(middeer1, 0, 3, (chtype) 'y');
+    mvwaddch(middeer1, 1, 2, (chtype) '0');
+    mvwaddch(middeer1, 1, 3, (chtype) '(');
+    mvwaddch(middeer1, 1, 4, (chtype) '=');
+    mvwaddch(middeer1, 1, 5, (chtype) ')');
+    mvwaddch(middeer1, 1, 6, (chtype) '~');
+    mvwaddch(middeer1, 2, 3, (chtype) '\\');
+    mvwaddch(middeer1, 2, 4, (chtype) '/');
+
+    /* middeer2 */
+    mvwaddch(middeer2, 0, 2, (chtype) 'y');
+    mvwaddch(middeer2, 0, 3, (chtype) 'y');
+    mvwaddch(middeer2, 1, 2, (chtype) '0');
+    mvwaddch(middeer2, 1, 3, (chtype) '(');
+    mvwaddch(middeer2, 1, 4, (chtype) '=');
+    mvwaddch(middeer2, 1, 5, (chtype) ')');
+    mvwaddch(middeer2, 1, 6, (chtype) '~');
+    mvwaddch(middeer2, 2, 3, (chtype) '|');
+    mvwaddch(middeer2, 2, 5, (chtype) '|');
+
+    /* middeer3 */
+    mvwaddch(middeer3, 0, 2, (chtype) 'y');
+    mvwaddch(middeer3, 0, 3, (chtype) 'y');
+    mvwaddch(middeer3, 1, 2, (chtype) '0');
+    mvwaddch(middeer3, 1, 3, (chtype) '(');
+    mvwaddch(middeer3, 1, 4, (chtype) '=');
+    mvwaddch(middeer3, 1, 5, (chtype) ')');
+    mvwaddch(middeer3, 1, 6, (chtype) '~');
+    mvwaddch(middeer3, 2, 2, (chtype) '/');
+    mvwaddch(middeer3, 2, 6, (chtype) '\\');
+
+    /* bigdeer1 */
+    mvwaddch(bigdeer1, 0, 17, (chtype) '\\');
+    mvwaddch(bigdeer1, 0, 18, (chtype) '/');
+    mvwaddch(bigdeer1, 0, 20, (chtype) '\\');
+    mvwaddch(bigdeer1, 0, 21, (chtype) '/');
+    mvwaddch(bigdeer1, 1, 18, (chtype) '\\');
+    mvwaddch(bigdeer1, 1, 20, (chtype) '/');
+    mvwaddch(bigdeer1, 2, 19, (chtype) '|');
+    mvwaddch(bigdeer1, 2, 20, (chtype) '_');
+    mvwaddch(bigdeer1, 3, 18, (chtype) '/');
+    mvwaddch(bigdeer1, 3, 19, (chtype) '^');
+    mvwaddch(bigdeer1, 3, 20, (chtype) '0');
+    mvwaddch(bigdeer1, 3, 21, (chtype) '\\');
+    mvwaddch(bigdeer1, 4, 17, (chtype) '/');
+    mvwaddch(bigdeer1, 4, 18, (chtype) '/');
+    mvwaddch(bigdeer1, 4, 19, (chtype) '\\');
+    mvwaddch(bigdeer1, 4, 22, (chtype) '\\');
+    mvwaddstr(bigdeer1, 5, 7, "^~~~~~~~~//  ~~U");
+    mvwaddstr(bigdeer1, 6, 7, "( \\_____( /");
+    mvwaddstr(bigdeer1, 7, 8, "( )    /");
+    mvwaddstr(bigdeer1, 8, 9, "\\\\   /");
+    mvwaddstr(bigdeer1, 9, 11, "\\>/>");
+
+    /* bigdeer2 */
+    mvwaddch(bigdeer2, 0, 17, (chtype) '\\');
+    mvwaddch(bigdeer2, 0, 18, (chtype) '/');
+    mvwaddch(bigdeer2, 0, 20, (chtype) '\\');
+    mvwaddch(bigdeer2, 0, 21, (chtype) '/');
+    mvwaddch(bigdeer2, 1, 18, (chtype) '\\');
+    mvwaddch(bigdeer2, 1, 20, (chtype) '/');
+    mvwaddch(bigdeer2, 2, 19, (chtype) '|');
+    mvwaddch(bigdeer2, 2, 20, (chtype) '_');
+    mvwaddch(bigdeer2, 3, 18, (chtype) '/');
+    mvwaddch(bigdeer2, 3, 19, (chtype) '^');
+    mvwaddch(bigdeer2, 3, 20, (chtype) '0');
+    mvwaddch(bigdeer2, 3, 21, (chtype) '\\');
+    mvwaddch(bigdeer2, 4, 17, (chtype) '/');
+    mvwaddch(bigdeer2, 4, 18, (chtype) '/');
+    mvwaddch(bigdeer2, 4, 19, (chtype) '\\');
+    mvwaddch(bigdeer2, 4, 22, (chtype) '\\');
+    mvwaddstr(bigdeer2, 5, 7, "^~~~~~~~~//  ~~U");
+    mvwaddstr(bigdeer2, 6, 7, "(( )____( /");
+    mvwaddstr(bigdeer2, 7, 7, "( /      |");
+    mvwaddstr(bigdeer2, 8, 8, "\\/      |");
+    mvwaddstr(bigdeer2, 9, 9, "|>     |>");
+
+    /* bigdeer3 */
+    mvwaddch(bigdeer3, 0, 17, (chtype) '\\');
+    mvwaddch(bigdeer3, 0, 18, (chtype) '/');
+    mvwaddch(bigdeer3, 0, 20, (chtype) '\\');
+    mvwaddch(bigdeer3, 0, 21, (chtype) '/');
+    mvwaddch(bigdeer3, 1, 18, (chtype) '\\');
+    mvwaddch(bigdeer3, 1, 20, (chtype) '/');
+    mvwaddch(bigdeer3, 2, 19, (chtype) '|');
+    mvwaddch(bigdeer3, 2, 20, (chtype) '_');
+    mvwaddch(bigdeer3, 3, 18, (chtype) '/');
+    mvwaddch(bigdeer3, 3, 19, (chtype) '^');
+    mvwaddch(bigdeer3, 3, 20, (chtype) '0');
+    mvwaddch(bigdeer3, 3, 21, (chtype) '\\');
+    mvwaddch(bigdeer3, 4, 17, (chtype) '/');
+    mvwaddch(bigdeer3, 4, 18, (chtype) '/');
+    mvwaddch(bigdeer3, 4, 19, (chtype) '\\');
+    mvwaddch(bigdeer3, 4, 22, (chtype) '\\');
+    mvwaddstr(bigdeer3, 5, 7, "^~~~~~~~~//  ~~U");
+    mvwaddstr(bigdeer3, 6, 6, "( ()_____( /");
+    mvwaddstr(bigdeer3, 7, 6, "/ /       /");
+    mvwaddstr(bigdeer3, 8, 5, "|/          \\");
+    mvwaddstr(bigdeer3, 9, 5, "/>           \\>");
+
+    /* bigdeer4 */
+    mvwaddch(bigdeer4, 0, 17, (chtype) '\\');
+    mvwaddch(bigdeer4, 0, 18, (chtype) '/');
+    mvwaddch(bigdeer4, 0, 20, (chtype) '\\');
+    mvwaddch(bigdeer4, 0, 21, (chtype) '/');
+    mvwaddch(bigdeer4, 1, 18, (chtype) '\\');
+    mvwaddch(bigdeer4, 1, 20, (chtype) '/');
+    mvwaddch(bigdeer4, 2, 19, (chtype) '|');
+    mvwaddch(bigdeer4, 2, 20, (chtype) '_');
+    mvwaddch(bigdeer4, 3, 18, (chtype) '/');
+    mvwaddch(bigdeer4, 3, 19, (chtype) '^');
+    mvwaddch(bigdeer4, 3, 20, (chtype) '0');
+    mvwaddch(bigdeer4, 3, 21, (chtype) '\\');
+    mvwaddch(bigdeer4, 4, 17, (chtype) '/');
+    mvwaddch(bigdeer4, 4, 18, (chtype) '/');
+    mvwaddch(bigdeer4, 4, 19, (chtype) '\\');
+    mvwaddch(bigdeer4, 4, 22, (chtype) '\\');
+    mvwaddstr(bigdeer4, 5, 7, "^~~~~~~~~//  ~~U");
+    mvwaddstr(bigdeer4, 6, 6, "( )______( /");
+    mvwaddstr(bigdeer4, 7, 5, "(/          \\");
+    mvwaddstr(bigdeer4, 8, 0, "v___=             ----^");
+
+    /* lookdeer1 */
+    mvwaddstr(lookdeer1, 0, 16, "\\/     \\/");
+    mvwaddstr(lookdeer1, 1, 17, "\\Y/ \\Y/");
+    mvwaddstr(lookdeer1, 2, 19, "\\=/");
+    mvwaddstr(lookdeer1, 3, 17, "^\\o o/^");
+    mvwaddstr(lookdeer1, 4, 17, "//( )");
+    mvwaddstr(lookdeer1, 5, 7, "^~~~~~~~~// \\O/");
+    mvwaddstr(lookdeer1, 6, 7, "( \\_____( /");
+    mvwaddstr(lookdeer1, 7, 8, "( )    /");
+    mvwaddstr(lookdeer1, 8, 9, "\\\\   /");
+    mvwaddstr(lookdeer1, 9, 11, "\\>/>");
+
+    /* lookdeer2 */
+    mvwaddstr(lookdeer2, 0, 16, "\\/     \\/");
+    mvwaddstr(lookdeer2, 1, 17, "\\Y/ \\Y/");
+    mvwaddstr(lookdeer2, 2, 19, "\\=/");
+    mvwaddstr(lookdeer2, 3, 17, "^\\o o/^");
+    mvwaddstr(lookdeer2, 4, 17, "//( )");
+    mvwaddstr(lookdeer2, 5, 7, "^~~~~~~~~// \\O/");
+    mvwaddstr(lookdeer2, 6, 7, "(( )____( /");
+    mvwaddstr(lookdeer2, 7, 7, "( /      |");
+    mvwaddstr(lookdeer2, 8, 8, "\\/      |");
+    mvwaddstr(lookdeer2, 9, 9, "|>     |>");
+
+    /* lookdeer3 */
+    mvwaddstr(lookdeer3, 0, 16, "\\/     \\/");
+    mvwaddstr(lookdeer3, 1, 17, "\\Y/ \\Y/");
+    mvwaddstr(lookdeer3, 2, 19, "\\=/");
+    mvwaddstr(lookdeer3, 3, 17, "^\\o o/^");
+    mvwaddstr(lookdeer3, 4, 17, "//( )");
+    mvwaddstr(lookdeer3, 5, 7, "^~~~~~~~~// \\O/");
+    mvwaddstr(lookdeer3, 6, 6, "( ()_____( /");
+    mvwaddstr(lookdeer3, 7, 6, "/ /       /");
+    mvwaddstr(lookdeer3, 8, 5, "|/          \\");
+    mvwaddstr(lookdeer3, 9, 5, "/>           \\>");
+
+    /* lookdeer4 */
+    mvwaddstr(lookdeer4, 0, 16, "\\/     \\/");
+    mvwaddstr(lookdeer4, 1, 17, "\\Y/ \\Y/");
+    mvwaddstr(lookdeer4, 2, 19, "\\=/");
+    mvwaddstr(lookdeer4, 3, 17, "^\\o o/^");
+    mvwaddstr(lookdeer4, 4, 17, "//( )");
+    mvwaddstr(lookdeer4, 5, 7, "^~~~~~~~~// \\O/");
+    mvwaddstr(lookdeer4, 6, 6, "( )______( /");
+    mvwaddstr(lookdeer4, 7, 5, "(/          \\");
+    mvwaddstr(lookdeer4, 8, 0, "v___=             ----^");
+
+	/***********************************************/
+    cbreak();
+    nodelay(stdscr, TRUE);
+    for (;;) {
+	clear();
+	werase(treescrn);
+	touchwin(w_del_msg);
+	touchwin(treescrn);
+	werase(treescrn2);
+	touchwin(treescrn2);
+	werase(treescrn8);
+	touchwin(treescrn8);
+	refresh();
+	look_out(150);
+	boxit();
+	refresh();
+	look_out(150);
+	seas();
+	refresh();
+	look_out(150);
+	greet();
+	refresh();
+	look_out(150);
+	fromwho();
+	refresh();
+	look_out(150);
+	tree();
+	look_out(150);
+	balls();
+	look_out(150);
+	star();
+	look_out(150);
+	strng1();
+	strng2();
+	strng3();
+	strng4();
+	strng5();
+
+	/* set up the windows for our blinking trees */
+	/* **************************************** */
+	/* treescrn3 */
+
+	overlay(treescrn, treescrn3);
+
+	/*balls */
+	mvwaddch(treescrn3, 4, 18, ' ');
+	mvwaddch(treescrn3, 7, 6, ' ');
+	mvwaddch(treescrn3, 8, 19, ' ');
+	mvwaddch(treescrn3, 11, 22, ' ');
+
+	/*star */
+	mvwaddch(treescrn3, 0, 12, '*');
+
+	/*strng1 */
+	mvwaddch(treescrn3, 3, 11, ' ');
+
+	/*strng2 */
+	mvwaddch(treescrn3, 5, 13, ' ');
+	mvwaddch(treescrn3, 6, 10, ' ');
+
+	/*strng3 */
+	mvwaddch(treescrn3, 7, 16, ' ');
+	mvwaddch(treescrn3, 7, 14, ' ');
+
+	/*strng4 */
+	mvwaddch(treescrn3, 10, 13, ' ');
+	mvwaddch(treescrn3, 10, 10, ' ');
+	mvwaddch(treescrn3, 11, 8, ' ');
+
+	/*strng5 */
+	mvwaddch(treescrn3, 11, 18, ' ');
+	mvwaddch(treescrn3, 12, 13, ' ');
+
+	/* treescrn4 */
+
+	overlay(treescrn, treescrn4);
+
+	/*balls */
+	mvwaddch(treescrn4, 3, 9, ' ');
+	mvwaddch(treescrn4, 4, 16, ' ');
+	mvwaddch(treescrn4, 7, 6, ' ');
+	mvwaddch(treescrn4, 8, 19, ' ');
+	mvwaddch(treescrn4, 11, 2, ' ');
+	mvwaddch(treescrn4, 12, 23, ' ');
+
+	/*star */
+	wstandout(treescrn4);
+	mvwaddch(treescrn4, 0, 12, '*');
+	wstandend(treescrn4);
+
+	/*strng1 */
+	mvwaddch(treescrn4, 3, 13, ' ');
+
+	/*strng2 */
+
+	/*strng3 */
+	mvwaddch(treescrn4, 7, 15, ' ');
+	mvwaddch(treescrn4, 8, 11, ' ');
+
+	/*strng4 */
+	mvwaddch(treescrn4, 9, 16, ' ');
+	mvwaddch(treescrn4, 10, 12, ' ');
+	mvwaddch(treescrn4, 11, 8, ' ');
+
+	/*strng5 */
+	mvwaddch(treescrn4, 11, 18, ' ');
+	mvwaddch(treescrn4, 12, 14, ' ');
+
+	/* treescrn5 */
+
+	overlay(treescrn, treescrn5);
+
+	/*balls */
+	mvwaddch(treescrn5, 3, 15, ' ');
+	mvwaddch(treescrn5, 10, 20, ' ');
+	mvwaddch(treescrn5, 12, 1, ' ');
+
+	/*star */
+	mvwaddch(treescrn5, 0, 12, '*');
+
+	/*strng1 */
+	mvwaddch(treescrn5, 3, 11, ' ');
+
+	/*strng2 */
+	mvwaddch(treescrn5, 5, 12, ' ');
+
+	/*strng3 */
+	mvwaddch(treescrn5, 7, 14, ' ');
+	mvwaddch(treescrn5, 8, 10, ' ');
+
+	/*strng4 */
+	mvwaddch(treescrn5, 9, 15, ' ');
+	mvwaddch(treescrn5, 10, 11, ' ');
+	mvwaddch(treescrn5, 11, 7, ' ');
+
+	/*strng5 */
+	mvwaddch(treescrn5, 11, 17, ' ');
+	mvwaddch(treescrn5, 12, 13, ' ');
+
+	/* treescrn6 */
+
+	overlay(treescrn, treescrn6);
+
+	/*balls */
+	mvwaddch(treescrn6, 6, 7, ' ');
+	mvwaddch(treescrn6, 7, 18, ' ');
+	mvwaddch(treescrn6, 10, 4, ' ');
+	mvwaddch(treescrn6, 11, 23, ' ');
+
+	/*star */
+	wstandout(treescrn6);
+	mvwaddch(treescrn6, 0, 12, '*');
+	wstandend(treescrn6);
+
+	/*strng1 */
+
+	/*strng2 */
+	mvwaddch(treescrn6, 5, 11, ' ');
+
+	/*strng3 */
+	mvwaddch(treescrn6, 7, 13, ' ');
+	mvwaddch(treescrn6, 8, 9, ' ');
+
+	/*strng4 */
+	mvwaddch(treescrn6, 9, 14, ' ');
+	mvwaddch(treescrn6, 10, 10, ' ');
+	mvwaddch(treescrn6, 11, 6, ' ');
+
+	/*strng5 */
+	mvwaddch(treescrn6, 11, 16, ' ');
+	mvwaddch(treescrn6, 12, 12, ' ');
+
+	/* treescrn7 */
+
+	overlay(treescrn, treescrn7);
+
+	/*balls */
+	mvwaddch(treescrn7, 3, 15, ' ');
+	mvwaddch(treescrn7, 6, 7, ' ');
+	mvwaddch(treescrn7, 7, 18, ' ');
+	mvwaddch(treescrn7, 10, 4, ' ');
+	mvwaddch(treescrn7, 11, 22, ' ');
+
+	/*star */
+	mvwaddch(treescrn7, 0, 12, '*');
+
+	/*strng1 */
+	mvwaddch(treescrn7, 3, 12, ' ');
+
+	/*strng2 */
+	mvwaddch(treescrn7, 5, 13, ' ');
+	mvwaddch(treescrn7, 6, 9, ' ');
+
+	/*strng3 */
+	mvwaddch(treescrn7, 7, 15, ' ');
+	mvwaddch(treescrn7, 8, 11, ' ');
+
+	/*strng4 */
+	mvwaddch(treescrn7, 9, 16, ' ');
+	mvwaddch(treescrn7, 10, 12, ' ');
+	mvwaddch(treescrn7, 11, 8, ' ');
+
+	/*strng5 */
+	mvwaddch(treescrn7, 11, 18, ' ');
+	mvwaddch(treescrn7, 12, 14, ' ');
+
+	look_out(150);
+	reindeer();
+
+	touchwin(w_holiday);
+	wrefresh(w_holiday);
+	wrefresh(w_del_msg);
+
+	look_out(500);
+	for (loopy = 0; loopy < 100; loopy++) {
+	    blinkit();
+	}
+
+#ifdef NOLOOP
+	done(0);
+#endif
+    }
+    /*NOTREACHED */
+}
+
+static int
+boxit(void)
+{
+    int x = 0;
+
+    while (x < 20) {
+	mvaddch(x, 7, '|');
+	++x;
+    }
+
+    x = 8;
+
+    while (x < 80) {
+	mvaddch(19, x, '_');
+	++x;
+    }
+
+    x = 0;
+
+    while (x < 80) {
+	mvaddch(22, x, '_');
+	++x;
+    }
+
+    return (0);
+}
+
+static int
+seas(void)
+{
+    mvaddch(4, 1, 'S');
+    mvaddch(6, 1, 'E');
+    mvaddch(8, 1, 'A');
+    mvaddch(10, 1, 'S');
+    mvaddch(12, 1, 'O');
+    mvaddch(14, 1, 'N');
+    mvaddch(16, 1, '`');
+    mvaddch(18, 1, 'S');
+
+    return (0);
+}
+
+static int
+greet(void)
+{
+    mvaddch(3, 5, 'G');
+    mvaddch(5, 5, 'R');
+    mvaddch(7, 5, 'E');
+    mvaddch(9, 5, 'E');
+    mvaddch(11, 5, 'T');
+    mvaddch(13, 5, 'I');
+    mvaddch(15, 5, 'N');
+    mvaddch(17, 5, 'G');
+    mvaddch(19, 5, 'S');
+
+    return (0);
+}
+
+static int
+fromwho(void)
+{
+    mvaddstr(21, 13, FROMWHO);
+    return (0);
+}
+
+static int
+tree(void)
+{
+    set_color(treescrn, COLOR_GREEN);
+    mvwaddch(treescrn, 1, 11, (chtype) '/');
+    mvwaddch(treescrn, 2, 11, (chtype) '/');
+    mvwaddch(treescrn, 3, 10, (chtype) '/');
+    mvwaddch(treescrn, 4, 9, (chtype) '/');
+    mvwaddch(treescrn, 5, 9, (chtype) '/');
+    mvwaddch(treescrn, 6, 8, (chtype) '/');
+    mvwaddch(treescrn, 7, 7, (chtype) '/');
+    mvwaddch(treescrn, 8, 6, (chtype) '/');
+    mvwaddch(treescrn, 9, 6, (chtype) '/');
+    mvwaddch(treescrn, 10, 5, (chtype) '/');
+    mvwaddch(treescrn, 11, 3, (chtype) '/');
+    mvwaddch(treescrn, 12, 2, (chtype) '/');
+
+    mvwaddch(treescrn, 1, 13, (chtype) '\\');
+    mvwaddch(treescrn, 2, 13, (chtype) '\\');
+    mvwaddch(treescrn, 3, 14, (chtype) '\\');
+    mvwaddch(treescrn, 4, 15, (chtype) '\\');
+    mvwaddch(treescrn, 5, 15, (chtype) '\\');
+    mvwaddch(treescrn, 6, 16, (chtype) '\\');
+    mvwaddch(treescrn, 7, 17, (chtype) '\\');
+    mvwaddch(treescrn, 8, 18, (chtype) '\\');
+    mvwaddch(treescrn, 9, 18, (chtype) '\\');
+    mvwaddch(treescrn, 10, 19, (chtype) '\\');
+    mvwaddch(treescrn, 11, 21, (chtype) '\\');
+    mvwaddch(treescrn, 12, 22, (chtype) '\\');
+
+    mvwaddch(treescrn, 4, 10, (chtype) '_');
+    mvwaddch(treescrn, 4, 14, (chtype) '_');
+    mvwaddch(treescrn, 8, 7, (chtype) '_');
+    mvwaddch(treescrn, 8, 17, (chtype) '_');
+
+    mvwaddstr(treescrn, 13, 0, "//////////// \\\\\\\\\\\\\\\\\\\\\\\\");
+
+    mvwaddstr(treescrn, 14, 11, "| |");
+    mvwaddstr(treescrn, 15, 11, "|_|");
+
+    unset_color(treescrn);
+    wrefresh(treescrn);
+    wrefresh(w_del_msg);
+
+    return (0);
+}
+
+static int
+balls(void)
+{
+    overlay(treescrn, treescrn2);
+
+    set_color(treescrn2, COLOR_BLUE);
+    mvwaddch(treescrn2, 3, 9, (chtype) '@');
+    mvwaddch(treescrn2, 3, 15, (chtype) '@');
+    mvwaddch(treescrn2, 4, 8, (chtype) '@');
+    mvwaddch(treescrn2, 4, 16, (chtype) '@');
+    mvwaddch(treescrn2, 5, 7, (chtype) '@');
+    mvwaddch(treescrn2, 5, 17, (chtype) '@');
+    mvwaddch(treescrn2, 7, 6, (chtype) '@');
+    mvwaddch(treescrn2, 7, 18, (chtype) '@');
+    mvwaddch(treescrn2, 8, 5, (chtype) '@');
+    mvwaddch(treescrn2, 8, 19, (chtype) '@');
+    mvwaddch(treescrn2, 10, 4, (chtype) '@');
+    mvwaddch(treescrn2, 10, 20, (chtype) '@');
+    mvwaddch(treescrn2, 11, 2, (chtype) '@');
+    mvwaddch(treescrn2, 11, 22, (chtype) '@');
+    mvwaddch(treescrn2, 12, 1, (chtype) '@');
+    mvwaddch(treescrn2, 12, 23, (chtype) '@');
+
+    unset_color(treescrn2);
+    wrefresh(treescrn2);
+    wrefresh(w_del_msg);
+    return (0);
+}
+
+static int
+star(void)
+{
+    wattrset(treescrn2, A_BOLD | A_BLINK);
+    set_color(treescrn2, COLOR_YELLOW);
+
+    mvwaddch(treescrn2, 0, 12, (chtype) '*');
+    wstandend(treescrn2);
+
+    unset_color(treescrn2);
+    wrefresh(treescrn2);
+    wrefresh(w_del_msg);
+    return (0);
+}
+
+static int
+strng1(void)
+{
+    wattrset(treescrn2, A_BOLD | A_BLINK);
+    set_color(treescrn2, COLOR_WHITE);
+
+    mvwaddch(treescrn2, 3, 13, (chtype) '\'');
+    mvwaddch(treescrn2, 3, 12, (chtype) ':');
+    mvwaddch(treescrn2, 3, 11, (chtype) '.');
+
+    wattroff(treescrn2, A_BOLD | A_BLINK);
+    unset_color(treescrn2);
+
+    wrefresh(treescrn2);
+    wrefresh(w_del_msg);
+    return (0);
+}
+
+static int
+strng2(void)
+{
+    wattrset(treescrn2, A_BOLD | A_BLINK);
+    set_color(treescrn2, COLOR_WHITE);
+
+    mvwaddch(treescrn2, 5, 14, (chtype) '\'');
+    mvwaddch(treescrn2, 5, 13, (chtype) ':');
+    mvwaddch(treescrn2, 5, 12, (chtype) '.');
+    mvwaddch(treescrn2, 5, 11, (chtype) ',');
+    mvwaddch(treescrn2, 6, 10, (chtype) '\'');
+    mvwaddch(treescrn2, 6, 9, (chtype) ':');
+
+    wattroff(treescrn2, A_BOLD | A_BLINK);
+    unset_color(treescrn2);
+
+    wrefresh(treescrn2);
+    wrefresh(w_del_msg);
+    return (0);
+}
+
+static int
+strng3(void)
+{
+    wattrset(treescrn2, A_BOLD | A_BLINK);
+    set_color(treescrn2, COLOR_WHITE);
+
+    mvwaddch(treescrn2, 7, 16, (chtype) '\'');
+    mvwaddch(treescrn2, 7, 15, (chtype) ':');
+    mvwaddch(treescrn2, 7, 14, (chtype) '.');
+    mvwaddch(treescrn2, 7, 13, (chtype) ',');
+    mvwaddch(treescrn2, 8, 12, (chtype) '\'');
+    mvwaddch(treescrn2, 8, 11, (chtype) ':');
+    mvwaddch(treescrn2, 8, 10, (chtype) '.');
+    mvwaddch(treescrn2, 8, 9, (chtype) ',');
+
+    wattroff(treescrn2, A_BOLD | A_BLINK);
+    unset_color(treescrn2);
+
+    wrefresh(treescrn2);
+    wrefresh(w_del_msg);
+    return (0);
+}
+
+static int
+strng4(void)
+{
+    wattrset(treescrn2, A_BOLD | A_BLINK);
+    set_color(treescrn2, COLOR_WHITE);
+
+    mvwaddch(treescrn2, 9, 17, (chtype) '\'');
+    mvwaddch(treescrn2, 9, 16, (chtype) ':');
+    mvwaddch(treescrn2, 9, 15, (chtype) '.');
+    mvwaddch(treescrn2, 9, 14, (chtype) ',');
+    mvwaddch(treescrn2, 10, 13, (chtype) '\'');
+    mvwaddch(treescrn2, 10, 12, (chtype) ':');
+    mvwaddch(treescrn2, 10, 11, (chtype) '.');
+    mvwaddch(treescrn2, 10, 10, (chtype) ',');
+    mvwaddch(treescrn2, 11, 9, (chtype) '\'');
+    mvwaddch(treescrn2, 11, 8, (chtype) ':');
+    mvwaddch(treescrn2, 11, 7, (chtype) '.');
+    mvwaddch(treescrn2, 11, 6, (chtype) ',');
+    mvwaddch(treescrn2, 12, 5, (chtype) '\'');
+
+    wattroff(treescrn2, A_BOLD | A_BLINK);
+    unset_color(treescrn2);
+
+    wrefresh(treescrn2);
+    wrefresh(w_del_msg);
+    return (0);
+}
+
+static int
+strng5(void)
+{
+    wattrset(treescrn2, A_BOLD | A_BLINK);
+    set_color(treescrn2, COLOR_WHITE);
+
+    mvwaddch(treescrn2, 11, 19, (chtype) '\'');
+    mvwaddch(treescrn2, 11, 18, (chtype) ':');
+    mvwaddch(treescrn2, 11, 17, (chtype) '.');
+    mvwaddch(treescrn2, 11, 16, (chtype) ',');
+    mvwaddch(treescrn2, 12, 15, (chtype) '\'');
+    mvwaddch(treescrn2, 12, 14, (chtype) ':');
+    mvwaddch(treescrn2, 12, 13, (chtype) '.');
+    mvwaddch(treescrn2, 12, 12, (chtype) ',');
+
+    wattroff(treescrn2, A_BOLD | A_BLINK);
+    unset_color(treescrn2);
+
+    /* save a fully lit tree */
+    overlay(treescrn2, treescrn);
+
+    wrefresh(treescrn2);
+    wrefresh(w_del_msg);
+    return (0);
+}
+
+static int
+blinkit(void)
+{
+    static int cycle;
+
+    if (cycle > 4) {
+	cycle = 0;
+    }
+
+    touchwin(treescrn8);
+
+    switch (cycle) {
+    case 0:
+	overlay(treescrn3, treescrn8);
+	wrefresh(treescrn8);
+	wrefresh(w_del_msg);
+	break;
+    case 1:
+	overlay(treescrn4, treescrn8);
+	wrefresh(treescrn8);
+	wrefresh(w_del_msg);
+	break;
+    case 2:
+	overlay(treescrn5, treescrn8);
+	wrefresh(treescrn8);
+	wrefresh(w_del_msg);
+	break;
+    case 3:
+	overlay(treescrn6, treescrn8);
+	wrefresh(treescrn8);
+	wrefresh(w_del_msg);
+	break;
+    case 4:
+	overlay(treescrn7, treescrn8);
+	wrefresh(treescrn8);
+	wrefresh(w_del_msg);
+	break;
+    }
+    touchwin(treescrn8);
+
+    /*ALL ON************************************************** */
+
+    overlay(treescrn, treescrn8);
+    wrefresh(treescrn8);
+    wrefresh(w_del_msg);
+
+    ++cycle;
+    return (0);
+}
+
+static void
+deer_step(WINDOW *win, int y, int x)
+{
+    mvwin(win, y, x);
+    wrefresh(win);
+    wrefresh(w_del_msg);
+    look_out(5);
+}
+
+static int
+reindeer(void)
+{
+    int looper;
+    y_pos = 0;
+
+    for (x_pos = 70; x_pos > 62; x_pos--) {
+	if (x_pos < 62) {
+	    y_pos = 1;
+	}
+	for (looper = 0; looper < 4; looper++) {
+	    mvwaddch(dotdeer0, y_pos, x_pos, (chtype) '.');
+	    wrefresh(dotdeer0);
+	    wrefresh(w_del_msg);
+	    werase(dotdeer0);
+	    wrefresh(dotdeer0);
+	    wrefresh(w_del_msg);
+	    look_out(50);
+	}
+    }
+
+    y_pos = 2;
+
+    for (; x_pos > 50; x_pos--) {
+	for (looper = 0; looper < 4; looper++) {
+
+	    if (x_pos < 56) {
+		y_pos = 3;
+
+		mvwaddch(stardeer0, y_pos, x_pos, (chtype) '*');
+		wrefresh(stardeer0);
+		wrefresh(w_del_msg);
+		werase(stardeer0);
+		wrefresh(stardeer0);
+		wrefresh(w_del_msg);
+	    } else {
+		mvwaddch(dotdeer0, y_pos, x_pos, (chtype) '*');
+		wrefresh(dotdeer0);
+		wrefresh(w_del_msg);
+		werase(dotdeer0);
+		wrefresh(dotdeer0);
+		wrefresh(w_del_msg);
+	    }
+	}
+    }
+
+    x_pos = 58;
+
+    for (y_pos = 2; y_pos < 5; y_pos++) {
+
+	touchwin(lildeer0);
+	wrefresh(lildeer0);
+	wrefresh(w_del_msg);
+
+	for (looper = 0; looper < 4; looper++) {
+	    deer_step(lildeer3, y_pos, x_pos);
+	    deer_step(lildeer2, y_pos, x_pos);
+	    deer_step(lildeer1, y_pos, x_pos);
+	    deer_step(lildeer2, y_pos, x_pos);
+	    deer_step(lildeer3, y_pos, x_pos);
+
+	    touchwin(lildeer0);
+	    wrefresh(lildeer0);
+	    wrefresh(w_del_msg);
+
+	    x_pos -= 2;
+	}
+    }
+
+    x_pos = 35;
+
+    for (y_pos = 5; y_pos < 10; y_pos++) {
+
+	touchwin(middeer0);
+	wrefresh(middeer0);
+	wrefresh(w_del_msg);
+
+	for (looper = 0; looper < 2; looper++) {
+	    deer_step(middeer3, y_pos, x_pos);
+	    deer_step(middeer2, y_pos, x_pos);
+	    deer_step(middeer1, y_pos, x_pos);
+	    deer_step(middeer2, y_pos, x_pos);
+	    deer_step(middeer3, y_pos, x_pos);
+
+	    touchwin(middeer0);
+	    wrefresh(middeer0);
+	    wrefresh(w_del_msg);
+
+	    x_pos -= 3;
+	}
+    }
+
+    look_out(300);
+
+    y_pos = 1;
+
+    for (x_pos = 8; x_pos < 16; x_pos++) {
+	deer_step(bigdeer4, y_pos, x_pos);
+	deer_step(bigdeer3, y_pos, x_pos);
+	deer_step(bigdeer2, y_pos, x_pos);
+	deer_step(bigdeer1, y_pos, x_pos);
+	deer_step(bigdeer2, y_pos, x_pos);
+	deer_step(bigdeer3, y_pos, x_pos);
+	deer_step(bigdeer4, y_pos, x_pos);
+	deer_step(bigdeer0, y_pos, x_pos);
+    }
+
+    --x_pos;
+
+    for (looper = 0; looper < 6; looper++) {
+	deer_step(lookdeer4, y_pos, x_pos);
+	deer_step(lookdeer3, y_pos, x_pos);
+	deer_step(lookdeer2, y_pos, x_pos);
+	deer_step(lookdeer1, y_pos, x_pos);
+	deer_step(lookdeer2, y_pos, x_pos);
+	deer_step(lookdeer3, y_pos, x_pos);
+	deer_step(lookdeer4, y_pos, x_pos);
+    }
+
+    deer_step(lookdeer0, y_pos, x_pos);
+
+    for (; y_pos < 10; y_pos++) {
+	for (looper = 0; looper < 2; looper++) {
+	    deer_step(bigdeer4, y_pos, x_pos);
+	    deer_step(bigdeer3, y_pos, x_pos);
+	    deer_step(bigdeer2, y_pos, x_pos);
+	    deer_step(bigdeer1, y_pos, x_pos);
+	    deer_step(bigdeer2, y_pos, x_pos);
+	    deer_step(bigdeer3, y_pos, x_pos);
+	    deer_step(bigdeer4, y_pos, x_pos);
+	}
+	deer_step(bigdeer0, y_pos, x_pos);
+    }
+
+    --y_pos;
+
+    deer_step(lookdeer3, y_pos, x_pos);
+    return (0);
+}
+
+static RETSIGTYPE
+done(int sig GCC_UNUSED)
+{
+    CATCHALL(done);
+
+    move(LINES - 1, 0);
+    refresh();
+    endwin();
+    curs_set(1);
+
+#if NO_LEAKS
+    if (my_pairs != 0)
+	free(my_pairs);
+#endif
+
+    ExitProgram(EXIT_SUCCESS);
+}
diff --git a/test/xterm-16color.dat b/test/xterm-16color.dat
new file mode 100644
index 0000000..6d47d93
--- /dev/null
+++ b/test/xterm-16color.dat
@@ -0,0 +1,53 @@
+##############################################################################
+# Copyright (c) 2004,2006 Free Software Foundation, Inc.                     #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+# $Id: xterm-16color.dat,v 1.2 2006/04/22 21:40:00 tom Exp $
+# This illustrates the predefined colors for XFree86 xterm's "xterm-16color". 
+# If you set $TERM to "xterm-88color" (and have xterm compiled to support the
+# 88-color or 256-color feature), you can use the ncurses 'd' screen to
+# manipulate the colors shown in the screen.  The 'd' screen is limited to
+# the first 16 colors, and xterm happens to use the same first 16 colors in
+# the extended color models that support initc.
+#
+# The colors shown are for xterm patch #189.
+scale:255
+0:	  0   0   0		black
+1:	205   0	  0		red3
+2:	  0 205	  0		green3
+3:	205 205	  0		yellow3
+4:	 30 144 255		DodgerBlue1
+5:	205   0 205		magenta3
+6:	  0 205 205		cyan3
+7:	229 229 229 		gray90
+8:	127 127 127 		gray50
+9:	255   0   0		red
+10:	  0 255   0		green
+11:	255 255   0		yellow
+12:	 99 184 255		SteelBlue1
+13:	255   0 255		magenta
+14:	  0 255 255		cyan
+15:	255 255 255		white
diff --git a/test/xterm-88color.dat b/test/xterm-88color.dat
new file mode 100644
index 0000000..cd8aa1c
--- /dev/null
+++ b/test/xterm-88color.dat
@@ -0,0 +1,125 @@
+##############################################################################
+# Copyright (c) 2005,2006 Free Software Foundation, Inc.                     #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+# $Id: xterm-88color.dat,v 1.2 2006/04/22 21:40:00 tom Exp $
+# This illustrates the predefined colors for XFree86 xterm's "xterm-16color". 
+# If you set $TERM to "xterm-88color" (and have xterm compiled to support the
+# 88-color or 256-color feature), you can use the ncurses 'd' screen to
+# manipulate the colors shown in the screen.  The 'd' screen is limited to
+# the first 16 colors, and xterm happens to use the same first 16 colors in
+# the extended color models that support initc.
+#
+# The colors shown are for xterm patch #189.
+scale:255
+0:	  0   0   0		black
+1:	205   0	  0		red3
+2:	  0 205	  0		green3
+3:	205 205	  0		yellow3
+4:	 30 144 255		DodgerBlue1
+5:	205   0 205		magenta3
+6:	  0 205 205		cyan3
+7:	229 229 229 		gray90
+8:	127 127 127 		gray50
+9:	255   0   0		red
+10:	  0 255   0		green
+11:	255 255   0		yellow
+12:	 99 184 255		SteelBlue1
+13:	255   0 255		magenta
+14:	  0 255 255		cyan
+15:	255 255 255		white
+16:	  0   0   0
+17:	  0   0 139
+18:	  0   0 205
+19:	  0   0 255
+20:	  0 139   0
+21:	  0 139 139
+22:	  0 139 205
+23:	  0 139 255
+24:	  0 205   0
+25:	  0 205 139
+26:	  0 205 205
+27:	  0 205 255
+28:	  0 255   0
+29:	  0 255 139
+30:	  0 255 205
+31:	  0 255 255
+32:	139   0   0
+33:	139   0 139
+34:	139   0 205
+35:	139   0 255
+36:	139 139   0
+37:	139 139 139
+38:	139 139 205
+39:	139 139 255
+40:	139 205   0
+41:	139 205 139
+42:	139 205 205
+43:	139 205 255
+44:	139 255   0
+45:	139 255 139
+46:	139 255 205
+47:	139 255 255
+48:	205   0   0
+49:	205   0 139
+50:	205   0 205
+51:	205   0 255
+52:	205 139   0
+53:	205 139 139
+54:	205 139 205
+55:	205 139 255
+56:	205 205   0
+57:	205 205 139
+58:	205 205 205
+59:	205 205 255
+60:	205 255   0
+61:	205 255 139
+62:	205 255 205
+63:	205 255 255
+64:	255   0   0
+65:	255   0 139
+66:	255   0 205
+67:	255   0 255
+68:	255 139   0
+69:	255 139 139
+70:	255 139 205
+71:	255 139 255
+72:	255 205   0
+73:	255 205 139
+74:	255 205 205
+75:	255 205 255
+76:	255 255   0
+77:	255 255 139
+78:	255 255 205
+79:	255 255 255
+80:	 46  46  46
+81:	 92  92  92
+82:	113 113 113
+83:	139 139 139
+84:	162 162 162
+85:	185 185 185
+86:	208 208 208
+87:	231 231 231