aboutsummaryrefslogtreecommitdiff
path: root/contrib/ncurses/test
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ncurses/test')
-rw-r--r--contrib/ncurses/test/Makefile.in207
-rw-r--r--contrib/ncurses/test/README22
-rw-r--r--contrib/ncurses/test/blue.c440
-rw-r--r--contrib/ncurses/test/bs.642
-rw-r--r--contrib/ncurses/test/bs.c1268
-rw-r--r--contrib/ncurses/test/cardfile.c420
-rw-r--r--contrib/ncurses/test/cardfile.dat13
-rw-r--r--contrib/ncurses/test/configure.in176
-rw-r--r--contrib/ncurses/test/ditto.c148
-rw-r--r--contrib/ncurses/test/filter.c109
-rw-r--r--contrib/ncurses/test/firework.c154
-rw-r--r--contrib/ncurses/test/firstlast.c89
-rw-r--r--contrib/ncurses/test/gdc.622
-rw-r--r--contrib/ncurses/test/gdc.c235
-rw-r--r--contrib/ncurses/test/hanoi.c297
-rw-r--r--contrib/ncurses/test/hashtest.c219
-rw-r--r--contrib/ncurses/test/keynames.c14
-rw-r--r--contrib/ncurses/test/knight.c565
-rw-r--r--contrib/ncurses/test/lrtest.c49
-rw-r--r--contrib/ncurses/test/modules57
-rw-r--r--contrib/ncurses/test/ncurses.c3270
-rw-r--r--contrib/ncurses/test/ncurses_tst.hin56
-rw-r--r--contrib/ncurses/test/newdemo.c348
-rw-r--r--contrib/ncurses/test/rain.c131
-rw-r--r--contrib/ncurses/test/tclock.c184
-rw-r--r--contrib/ncurses/test/test.priv.h90
-rw-r--r--contrib/ncurses/test/testaddch.c60
-rw-r--r--contrib/ncurses/test/testcurs.c640
-rw-r--r--contrib/ncurses/test/testscanw.c38
-rwxr-xr-xcontrib/ncurses/test/tracemunch98
-rw-r--r--contrib/ncurses/test/view.c362
-rw-r--r--contrib/ncurses/test/worm.c372
-rw-r--r--contrib/ncurses/test/xmas.c1148
33 files changed, 11343 insertions, 0 deletions
diff --git a/contrib/ncurses/test/Makefile.in b/contrib/ncurses/test/Makefile.in
new file mode 100644
index 000000000000..3626f2420e80
--- /dev/null
+++ b/contrib/ncurses/test/Makefile.in
@@ -0,0 +1,207 @@
+# $Id: Makefile.in,v 1.51 1999/04/10 21:31:59 tom Exp $
+##############################################################################
+# 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> 1996,1997,1998
+#
+# Makefile for ncurses tests.
+
+# turn off _all_ suffix rules; we'll generate our own
+.SUFFIXES:
+
+SHELL = /bin/sh
+
+x = @PROG_EXT@
+
+MODEL = ../@DFT_OBJ_SUBDIR@
+srcdir = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CC = @CC@
+
+CFLAGS = @CFLAGS@
+CPPFLAGS = -I../test -I$(srcdir) @CPPFLAGS@ -DHAVE_CONFIG_H
+
+CCFLAGS = $(CPPFLAGS) $(CFLAGS)
+
+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_LIBS = @TEST_DEPS@
+MATH_LIB = @MATH_LIB@
+
+LD = @LD@
+LINK = @LINK_TESTS@ $(CC)
+
+LDFLAGS = @LD_MODEL@ @TEST_ARGS@ @LIBS@ @EXTRA_LIBS@ @LOCAL_LDFLAGS@ @LDFLAGS@
+
+LDFLAGS_NORMAL = $(LDFLAGS)
+LDFLAGS_DEBUG = $(LDFLAGS) @CC_G_OPT@
+LDFLAGS_PROFILE = $(LDFLAGS) -pg
+LDFLAGS_SHARED = $(LDFLAGS) @LD_SHARED_OPTS@
+
+LDFLAGS_DEFAULT = $(LDFLAGS_@DFT_UPR_MODEL@)
+
+LINT = @LINT@
+LINT_OPTS = @LINT_OPTS@
+LINT_LIBS = -lform -lmenu -lpanel -lncurses @LIBS@
+
+TESTS = \
+ blue$x \
+ bs$x \
+ cardfile$x \
+ ditto$x \
+ filter$x \
+ firework$x \
+ firstlast$x \
+ gdc$x \
+ hanoi$x \
+ hashtest$x \
+ keynames$x \
+ knight$x \
+ lrtest$x \
+ ncurses$x \
+ newdemo$x \
+ rain$x \
+ tclock$x \
+ testaddch$x \
+ testcurs$x \
+ testscanw$x \
+ view$x \
+ worm$x \
+ xmas$x
+
+all: $(TESTS)
+
+sources:
+
+blue$x: $(MODEL)/blue.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/blue.o $(LDFLAGS_DEFAULT)
+
+bs$x: $(MODEL)/bs.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/bs.o $(LDFLAGS_DEFAULT)
+
+cardfile$x: $(MODEL)/cardfile.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/cardfile.o $(LDFLAGS_DEFAULT)
+
+ditto$x: $(MODEL)/ditto.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/ditto.o $(LDFLAGS_DEFAULT)
+
+filter$x: $(MODEL)/filter.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/filter.o $(LDFLAGS_DEFAULT)
+
+firework$x: $(MODEL)/firework.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/firework.o $(LDFLAGS_DEFAULT)
+
+firstlast$x: $(MODEL)/firstlast.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/firstlast.o $(LDFLAGS_DEFAULT)
+
+gdc$x: $(MODEL)/gdc.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/gdc.o $(LDFLAGS_DEFAULT)
+
+hanoi$x: $(MODEL)/hanoi.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/hanoi.o $(LDFLAGS_DEFAULT)
+
+hashtest$x: $(MODEL)/hashtest.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/hashtest.o $(LDFLAGS_DEFAULT)
+
+keynames$x: $(MODEL)/keynames.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/keynames.o $(LDFLAGS_DEFAULT)
+
+knight$x: $(MODEL)/knight.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/knight.o $(LDFLAGS_DEFAULT)
+
+lrtest$x: $(MODEL)/lrtest.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/lrtest.o $(LDFLAGS_DEFAULT)
+
+ncurses$x: $(MODEL)/ncurses.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/ncurses.o $(LDFLAGS_DEFAULT)
+
+newdemo$x: $(MODEL)/newdemo.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/newdemo.o $(LDFLAGS_DEFAULT)
+
+rain$x: $(MODEL)/rain.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/rain.o $(LDFLAGS_DEFAULT)
+
+tclock$x: $(MODEL)/tclock.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/tclock.o $(LDFLAGS_DEFAULT) $(MATH_LIB)
+
+testaddch$x: $(MODEL)/testaddch.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/testaddch.o $(LDFLAGS_DEFAULT)
+
+testcurs$x: $(MODEL)/testcurs.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/testcurs.o $(LDFLAGS_DEFAULT)
+
+testscanw$x: $(MODEL)/testscanw.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/testscanw.o $(LDFLAGS_DEFAULT)
+
+view$x: $(MODEL)/view.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/view.o $(LDFLAGS_DEFAULT)
+
+worm$x: $(MODEL)/worm.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/worm.o $(LDFLAGS_DEFAULT)
+
+xmas$x: $(MODEL)/xmas.o $(LOCAL_LIBS)
+ @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/xmas.o $(LDFLAGS_DEFAULT)
+
+install:
+install.libs:
+install.test:
+
+uninstall:
+uninstall.libs:
+uninstall.test:
+
+mostlyclean ::
+ -rm -f core tags TAGS *~ *.ln *.atac trace
+
+clean :: mostlyclean
+ -rm -rf *.o screendump *.lis $(TESTS)
+
+distclean :: clean
+ -rm -f Makefile ncurses_cfg.h config.*
+
+realclean :: distclean
+
+lint:
+ sh -c 'for N in $(TESTS); do echo LINT:$$N; $(LINT) $(LINT_OPTS) $(CPPFLAGS) $(srcdir)/$$N.c $(LINT_LIBS); done'
+
+# Use this to get a list of test-programs for the standalone configure script.
+echo_tests :
+ @echo "$(TESTS)"
+echo_suffix :
+ @echo "$x"
diff --git a/contrib/ncurses/test/README b/contrib/ncurses/test/README
new file mode 100644
index 000000000000..cd1767a179b2
--- /dev/null
+++ b/contrib/ncurses/test/README
@@ -0,0 +1,22 @@
+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
diff --git a/contrib/ncurses/test/blue.c b/contrib/ncurses/test/blue.c
new file mode 100644
index 000000000000..4f7335132bba
--- /dev/null
+++ b/contrib/ncurses/test/blue.c
@@ -0,0 +1,440 @@
+/*****************************************************************************
+ * *
+ * 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.18 1999/01/17 00:11:56 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <string.h>
+#include <signal.h>
+#include <time.h>
+
+#include <term.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__)
+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 */
+};
+#endif /* __i386__ */
+
+static chtype *suits = letters; /* this may change to glyphs below */
+
+static RETSIGTYPE die(int onsig)
+{
+ (void) signal(onsig, SIG_IGN);
+ endwin();
+ exit(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];
+
+ 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[])
+{
+ (void) signal(SIGINT, die);
+ 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 defined(__i386__) && defined(A_ALTCHARSET)
+ 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 defined(__i386__) && defined(A_ALTCHARSET)
+ if (tigetstr("smpch"))
+ suits = glyphs;
+#endif /* __i386__ && A_ALTCHARSET */
+
+ 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/contrib/ncurses/test/bs.6 b/contrib/ncurses/test/bs.6
new file mode 100644
index 000000000000..38cfe82a9811
--- /dev/null
+++ b/contrib/ncurses/test/bs.6
@@ -0,0 +1,42 @@
+.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/contrib/ncurses/test/bs.c b/contrib/ncurses/test/bs.c
new file mode 100644
index 000000000000..368abcd8f28d
--- /dev/null
+++ b/contrib/ncurses/test/bs.c
@@ -0,0 +1,1268 @@
+/*
+ * 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.24 1999/08/21 23:14:38 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <signal.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+
+#ifndef SIGIOT
+#define SIGIOT SIGABRT
+#endif
+
+#ifndef A_UNDERLINE /* BSD curses */
+#define beep() write(1,"\007",1);
+#define cbreak crmode
+#define saveterm savetty
+#define resetterm resetty
+#define nocbreak nocrmode
+#define strchr index
+#endif /* !A_UNDERLINE */
+
+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(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 */
+ char x, y; /* coordinates of ship start point */
+ unsigned char 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)resetterm();
+ (void)echo();
+ (void)endwin();
+ exit(EXIT_FAILURE);
+}
+
+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 */
+
+ (void) signal(SIGINT,uninitgame);
+ (void) signal(SIGINT,uninitgame);
+ (void) signal(SIGIOT,uninitgame); /* for assert(3) */
+ if(signal(SIGQUIT,SIG_IGN) != SIG_IGN)
+ (void)signal(SIGQUIT,uninitgame);
+
+ if((tmpname = getlogin()) != 0)
+ {
+ (void)strcpy(name,tmpname);
+ name[0] = toupper(name[0]);
+ }
+ else
+ (void)strcpy(name,dftname);
+
+ (void)initscr();
+#ifdef KEY_MIN
+ keypad(stdscr, TRUE);
+#endif /* KEY_MIN */
+ (void)saveterm();
+ (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 */
+{
+ register int bwidth = BWIDTH - ss->length;
+ register int bdepth = BDEPTH - ss->length;
+
+ do {
+ ss->y = rnd(bdepth);
+ ss->x = rnd(bwidth);
+ ss->dir = rnd(2) ? E : S;
+ } 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')
+ {
+ 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))
+ {
+ 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':
+#ifdef KEY_MIN
+ case KEY_UP:
+#endif /* KEY_MIN */
+ ny = cury+BDEPTH-1; nx = curx;
+ break;
+ case 'j': case '2':
+#ifdef KEY_MIN
+ case KEY_DOWN:
+#endif /* KEY_MIN */
+ ny = cury+1; nx = curx;
+ break;
+ case 'h': case '4':
+#ifdef KEY_MIN
+ case KEY_LEFT:
+#endif /* KEY_MIN */
+ ny = cury; nx = curx+BWIDTH-1;
+ break;
+ case 'l': case '6':
+#ifdef KEY_MIN
+ case KEY_RIGHT:
+#endif /* KEY_MIN */
+ ny = cury; nx = curx+1;
+ break;
+ case 'y': case '7':
+#ifdef KEY_MIN
+ case KEY_A1:
+#endif /* KEY_MIN */
+ ny = cury+BDEPTH-1; nx = curx+BWIDTH-1;
+ break;
+ case 'b': case '1':
+#ifdef KEY_MIN
+ case KEY_C1:
+#endif /* KEY_MIN */
+ ny = cury+1; nx = curx+BWIDTH-1;
+ break;
+ case 'u': case '9':
+#ifdef KEY_MIN
+ case KEY_A3:
+#endif /* KEY_MIN */
+ ny = cury+BDEPTH-1; nx = curx+1;
+ break;
+ case 'n': case '3':
+#ifdef KEY_MIN
+ case KEY_C3:
+#endif /* KEY_MIN */
+ 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 * xincr[ss->dir];
+ yend = ss->y + ss->length * 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 */
+ }
+ }
+ }
+ }
+
+ 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));
+ }
+ }
+
+ (void) move(oldy, oldx);
+ return(ss);
+ }
+ }
+ (void) move(oldy, oldx);
+ return((ship_t *)NULL);
+}
+
+static int 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(awinna() == -1);
+ }
+ 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!");
+ exit(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) ? TRUE : FALSE);
+}
+
+/*
+ * 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.
+ */
+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
+ {
+ for (d = 0, n = rnd(navail) + 1; n; n--)
+ while (used[d])
+ d++;
+
+ assert(d <= 4);
+
+ used[d] = FALSE;
+ 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;
+ 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: /* kill squares not caught on first pass */
+ 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;
+ }
+
+ /* check for continuation and/or winner */
+ if (salvo)
+ {
+ (void)refresh();
+ (void)sleep(1);
+ }
+ if (awinna() != -1)
+ return(FALSE);
+
+#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");
+ exit(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");
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 's':
+ salvo = 1;
+ if (blitz == 1)
+ {
+ (void) fprintf(stderr,
+ "Bad Arg: -s and -b are mutually exclusive\n");
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'c':
+ closepack = 1;
+ break;
+ default:
+ (void) fprintf(stderr,
+ "Bad arg: type \"%s ?\" for usage message\n", op[0]);
+ exit(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[])
+{
+ 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())
+ continue;
+ turn = OTHER;
+ }
+ } while
+ (playagain());
+ uninitgame(0);
+ /*NOTREACHED*/
+}
+
+/* bs.c ends here */
diff --git a/contrib/ncurses/test/cardfile.c b/contrib/ncurses/test/cardfile.c
new file mode 100644
index 000000000000..bc2e1adb14cc
--- /dev/null
+++ b/contrib/ncurses/test/cardfile.c
@@ -0,0 +1,420 @@
+/****************************************************************************
+ * Copyright (c) 1999 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: cardfile.c,v 1.2 1999/06/16 00:41:57 tom Exp $
+ *
+ * File format: text beginning in column 1 is a title; other text forms the content.
+ */
+
+#include <test.priv.h>
+
+#include <form.h>
+#include <panel.h>
+
+#include <string.h>
+#include <ctype.h>
+
+#define VISIBLE_CARDS 10
+#define OFFSET_CARD 2
+
+#ifndef CTRL
+#define CTRL(x) ((x) & 0x1f)
+#endif
+
+typedef struct _card {
+ struct _card *link;
+ PANEL *panel;
+ FORM *form;
+ char *title;
+ char *content;
+} CARD;
+
+static CARD *all_cards;
+static char default_name[] = "cardfile.dat";
+
+#if !HAVE_STRDUP
+#define strdup my_strdup
+static char *strdup (char *s)
+{
+ char *p = (char *)malloc(strlen(s)+1);
+ if (p)
+ strcpy(p, s);
+ return(p);
+}
+#endif /* not HAVE_STRDUP */
+
+static char *skip(char *buffer)
+{
+ while (isspace(*buffer))
+ buffer++;
+ return buffer;
+}
+
+static void trim(char *buffer)
+{
+ unsigned n = strlen(buffer);
+ while (n-- && isspace(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 = (CARD *)calloc(1, sizeof(CARD));
+ 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, char *content)
+{
+ unsigned total, offset;
+
+ content = skip(content);
+ if ((total = strlen(content)) != 0)
+ {
+ if ((offset = strlen(card->content)) != 0)
+ {
+ total += 1 + offset;
+ card->content = (char *)realloc(card->content, total + 1);
+ strcpy(card->content + offset++, " ");
+ }
+ else
+ {
+ card->content = (char *)malloc(total + 1);
+ }
+ strcpy(card->content + offset, content);
+ }
+}
+
+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(*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);
+ top_panel(first->panel);
+ }
+}
+
+/*
+ * Return the next card in the list
+ */
+static CARD *next_card(CARD *now)
+{
+ if (now->link)
+ now = now->link;
+ 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)
+ return p;
+ return now;
+}
+
+
+/*******************************************************************************/
+
+static int form_virtualize(WINDOW *w)
+{
+ int c = wgetch(w);
+
+ switch(c)
+ {
+ case CTRL('W'):
+ return(MAX_FORM_COMMAND + 4);
+ case CTRL('N'):
+ return(MAX_FORM_COMMAND + 3);
+ case CTRL('P'):
+ return(MAX_FORM_COMMAND + 2);
+ case CTRL('Q'):
+ case 033:
+ return(MAX_FORM_COMMAND + 1);
+
+ 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 void cardfile(char *fname)
+{
+ WINDOW *win;
+ CARD *p;
+ CARD *top_card;
+ int visible_cards = count_cards();
+ int panel_wide = COLS - (visible_cards * OFFSET_CARD);
+ int panel_high = LINES - (visible_cards * OFFSET_CARD) - 5;
+ int form_wide = panel_wide - 2;
+ int form_high = panel_high - 2;
+ int x = (visible_cards - 1) * OFFSET_CARD;
+ int y = 0;
+ int ch;
+ int finished = FALSE;
+
+ 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");
+
+ /* make a panel for each CARD */
+ for (p = all_cards; p != 0; p = p->link)
+ {
+ FIELD **f = (FIELD **)calloc(3, sizeof(FIELD *));
+
+ win = newwin(panel_high, panel_wide, x, y);
+ keypad(win, TRUE);
+ p->panel = new_panel(win);
+ box(win, 0, 0);
+
+ /* ...and a form in each panel */
+ 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);
+
+ 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);
+
+ f[2] = 0;
+
+ p->form = new_form(f);
+ set_form_win(p->form, win);
+ set_form_sub(p->form, derwin(win, form_high, form_wide, 1, 1));
+ post_form(p->form);
+
+ x -= OFFSET_CARD;
+ y += OFFSET_CARD;
+ }
+
+ order_cards(top_card = all_cards, visible_cards);
+
+ update_panels();
+
+ while (!finished)
+ {
+ update_panels();
+ doupdate();
+
+ switch(form_driver(top_card->form, ch = form_virtualize(panel_window(top_card->panel))))
+ {
+ case E_OK:
+ break;
+ case E_UNKNOWN_COMMAND:
+ switch (ch) {
+ case MAX_FORM_COMMAND+1:
+ finished = TRUE;
+ break;
+ case MAX_FORM_COMMAND+2:
+ top_card = prev_card(top_card);
+ order_cards(top_card, visible_cards);
+ break;
+ case MAX_FORM_COMMAND+3:
+ top_card = next_card(top_card);
+ order_cards(top_card, visible_cards);
+ break;
+ case MAX_FORM_COMMAND+4:
+ write_data(fname);
+ break;
+ default:
+ beep();
+ break;
+ }
+ break;
+ default:
+ flash();
+ break;
+ }
+ }
+}
+
+/*******************************************************************************/
+
+int main(int argc, char *argv[])
+{
+ int n;
+
+ initscr();
+ cbreak();
+ noecho();
+
+ if (argc > 1)
+ {
+ for (n = 1; n < argc; n++)
+ read_data(argv[n]);
+ cardfile(argv[1]);
+ }
+ else
+ {
+ read_data(default_name);
+ cardfile(default_name);
+ }
+
+ endwin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/ncurses/test/cardfile.dat b/contrib/ncurses/test/cardfile.dat
new file mode 100644
index 000000000000..deb4b76a7d85
--- /dev/null
+++ b/contrib/ncurses/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/contrib/ncurses/test/configure.in b/contrib/ncurses/test/configure.in
new file mode 100644
index 000000000000..acbad8a55bea
--- /dev/null
+++ b/contrib/ncurses/test/configure.in
@@ -0,0 +1,176 @@
+dnl***************************************************************************
+dnl Copyright (c) 1998 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 <dickey@clark.net> 1996,1997,1998
+dnl
+dnl $Id: configure.in,v 1.24 1998/05/16 20:48:14 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 dickey@clark.net (Thomas Dickey)
+AC_PREREQ(2.12)
+AC_INIT(ncurses.c)
+AC_CONFIG_HEADER(ncurses_cfg.h:ncurses_tst.hin)
+
+AC_PROG_CC
+
+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)
+ECHO_LINK='@ echo linking $@ ... ;' AC_SUBST(ECHO_LINK)
+EXTRA_LIBS="" AC_SUBST(EXTRA_LIBS)
+LD="ld" AC_SUBST(LD)
+LD_MODEL="" AC_SUBST(LD_MODEL)
+LDFLAGS_SHARED="" AC_SUBST(LDFLAGS_SHARED)
+LIB_NAME=curses AC_SUBST(LIB_NAME)
+LIB_PREFIX="-l" AC_SUBST(LIB_PREFIX)
+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)
+PROG_EXT="" AC_SUBST(PROG_EXT)
+TEST_ARGS="" AC_SUBST(TEST_ARGS)
+TEST_DEPS="" AC_SUBST(TEST_DEPS)
+cf_cv_abi_version="" AC_SUBST(cf_cv_abi_version)
+cf_cv_rel_version="" AC_SUBST(cf_cv_rel_version)
+
+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 Ncurses, installed in conventional location
+AC_ARG_WITH(ncurses,
+ [ --with-ncurses use ncurses-libraries (installed)],
+ [AC_CHECK_FUNC(initscr,,[
+ AC_CHECK_LIB(gpm,Gpm_Open)
+ LIB_NAME=ncurses
+ for p in $HOME /usr/local /usr
+ do
+ if test -f $p/include/ncurses/curses.h
+ then
+ CPPFLAGS="$CPPFLAGS -I$p/include/ncurses"
+ test $p != /usr && LIBS="-L$p/lib $LIBS"
+ break
+ elif test $p != /usr
+ then
+ if test -f $p/include/curses.h
+ then
+ CPPFLAGS="$CPPFLAGS -I$p/include"
+ LIBS="-L$p/lib $LIBS"
+ break
+ fi
+ fi
+ done
+ ],[test -d /usr/ccs/lib && LIBS="-L/usr/ccs/lib $LIBS"])])
+
+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
+
+AC_CHECK_FUNC(initscr,,[
+AC_CHECK_LIB($LIB_NAME,initscr)])
+AC_CHECK_LIB(form,form_driver)
+AC_CHECK_LIB(menu,menu_driver)
+AC_CHECK_LIB(panel,new_panel)
+
+AC_TYPE_SIGNAL
+
+AC_STDC_HEADERS
+AC_HEADER_TIME
+AC_CHECK_HEADERS( \
+form.h \
+getopt.h \
+menu.h \
+nc_alloc.h \
+panel.h \
+sys/ioctl.h \
+sys/select.h \
+sys/time.h \
+termios.h \
+unistd.h \
+)
+
+AC_CHECK_FUNCS( \
+gettimeofday \
+napms \
+resizeterm \
+strdup \
+vsscanf \
+)
+
+dnl ---------------------------------------------------------------------------
+dnl [CF_SYS_TIME_SELECT]
+AC_MSG_CHECKING(if sys/time.h conflicts with sys/select.h)
+AC_CACHE_VAL(cf_cv_sys_time_select,[
+AC_TRY_COMPILE([
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#if 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 ---------------------------------------------------------------------------
+
+AC_OUTPUT(Makefile,[
+ 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=`make echo_tests`
+LAST=`make echo_suffix`
+for n in $LIST
+do
+ N=`echo $n | sed -e s/${LAST}\$//`
+ 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
+],[],sort)
diff --git a/contrib/ncurses/test/ditto.c b/contrib/ncurses/test/ditto.c
new file mode 100644
index 000000000000..8ceafe5de11a
--- /dev/null
+++ b/contrib/ncurses/test/ditto.c
@@ -0,0 +1,148 @@
+/****************************************************************************
+ * 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: ditto.c,v 1.3 1998/08/15 23:39:34 tom Exp $
+ *
+ * The program illustrates how to set up multiple screens from a single
+ * program. 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>
+
+typedef struct {
+ FILE *input;
+ FILE *output;
+ SCREEN *screen;
+} DITTO;
+
+static void
+failed(const char *s)
+{
+ perror(s);
+ exit(EXIT_FAILURE);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: ditto [terminal1 ...]\n");
+ exit(EXIT_FAILURE);
+}
+
+static FILE *
+open_tty(char *path)
+{
+ FILE *fp;
+ 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, "a+");
+ if (fp == 0)
+ failed(path);
+ printf("opened %s\n", path);
+ return fp;
+}
+
+int
+main(
+ int argc GCC_UNUSED,
+ char *argv[] GCC_UNUSED)
+{
+ int j;
+ int active_tty = 0;
+ DITTO *data;
+
+ if (argc <= 1)
+ usage();
+
+ if ((data = (DITTO *)calloc(argc, sizeof(DITTO))) == 0)
+ failed("calloc data");
+
+ data[0].input = stdin;
+ data[0].output = stdout;
+ for (j = 1; j < argc; j++) {
+ data[j].input =
+ data[j].output = open_tty(argv[j]);
+ }
+
+ /*
+ * If we got this far, we have open connection(s) to the terminal(s).
+ * Set up the screens.
+ */
+ for (j = 0; j < argc; j++) {
+ active_tty++;
+ data[j].screen = newterm(
+ (char *)0, /* assume $TERM is the same */
+ data[j].output,
+ data[j].input);
+ if (data[j].screen == 0)
+ failed("newterm");
+ cbreak();
+ noecho();
+ scrollok(stdscr, TRUE);
+ }
+
+ /*
+ * Loop, reading characters from any of the inputs and writing to all
+ * of the screens.
+ */
+ for(;;) {
+ int ch;
+ set_term(data[0].screen);
+ ch = getch();
+ if (ch == ERR)
+ continue;
+ if (ch == 4)
+ break;
+ for (j = 0; j < argc; j++) {
+ set_term(data[j].screen);
+ addch(ch);
+ refresh();
+ }
+ }
+
+ /*
+ * Cleanup and exit
+ */
+ for (j = argc-1; j >= 0; j--) {
+ set_term(data[j].screen);
+ endwin();
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/ncurses/test/filter.c b/contrib/ncurses/test/filter.c
new file mode 100644
index 000000000000..6057396a89c6
--- /dev/null
+++ b/contrib/ncurses/test/filter.c
@@ -0,0 +1,109 @@
+/****************************************************************************
+ * 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: filter.c,v 1.2 1998/05/10 00:39:27 tom Exp $
+ */
+#include <test.priv.h>
+
+/*
+ * 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.
+ */
+
+#ifndef NCURSES_VERSION
+#define attr_t long
+#define getnstr(s,n) getstr(s)
+#endif
+
+static int new_command(char *buffer, int length, attr_t underline)
+{
+ int code;
+
+ attron(A_BOLD);
+ printw("Command: ");
+ attron(underline);
+ code = getnstr(buffer, length);
+ attroff(underline);
+ attroff(A_BOLD);
+ printw("\n");
+
+ return code;
+}
+
+int main(
+ int argc GCC_UNUSED,
+ char *argv[] GCC_UNUSED)
+{
+ SCREEN *sp;
+ char buffer[80];
+ attr_t underline;
+
+ filter();
+ sp = newterm((char *)0, stdout, stdin);
+ cbreak();
+ keypad(stdscr, TRUE);
+
+ if (has_colors()) {
+ int background = COLOR_BLACK;
+ start_color();
+#ifdef NCURSES_VERSION
+ 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();
+ return 0;
+}
diff --git a/contrib/ncurses/test/firework.c b/contrib/ncurses/test/firework.c
new file mode 100644
index 000000000000..1a37e0490997
--- /dev/null
+++ b/contrib/ncurses/test/firework.c
@@ -0,0 +1,154 @@
+/*
+ * $Id: firework.c,v 1.11 1997/11/01 19:36:25 tom Exp $
+ */
+#include <test.priv.h>
+
+#include <term.h> /* for tparm() */
+
+#include <signal.h>
+#include <ctype.h>
+#include <time.h>
+
+static int get_colour(chtype *);
+static void explode(int row, int col);
+static void showit(void);
+static RETSIGTYPE onsig(int sig);
+
+static int my_bg = COLOR_BLACK;
+
+int main(
+ int argc GCC_UNUSED,
+ char *argv[] GCC_UNUSED)
+{
+int j;
+int start,end,row,diff,flag = 0,direction;
+unsigned seed;
+
+ for (j=SIGHUP;j<=SIGTERM;j++)
+ if (signal(j,SIG_IGN)!=SIG_IGN)
+ signal(j,onsig);
+
+ initscr();
+ if (has_colors()) {
+ start_color();
+#ifdef NCURSES_VERSION
+ if (use_default_colors() == OK)
+ my_bg = -1;
+#endif
+ }
+ curs_set(0);
+
+ seed = time((time_t *)0);
+ srand(seed);
+ cbreak();
+ 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();
+ }
+}
+
+static RETSIGTYPE
+onsig(int n GCC_UNUSED)
+{
+ curs_set(1);
+ endwin();
+ exit(EXIT_FAILURE);
+}
+
+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,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, 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, 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, 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, col-2," ");
+ mvprintw(row+1,col-2,"# #");
+ mvprintw(row+2,col-2," # # ");
+ showit();
+}
+
+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
+showit(void)
+{
+ refresh();
+ napms(120);
+}
diff --git a/contrib/ncurses/test/firstlast.c b/contrib/ncurses/test/firstlast.c
new file mode 100644
index 000000000000..f9515dcb5b38
--- /dev/null
+++ b/contrib/ncurses/test/firstlast.c
@@ -0,0 +1,89 @@
+/*
+ * This test was written by Alexander V. Lukyanov to demonstrate difference
+ * between ncurses 4.1 and SVR4 curses
+ *
+ * $Id: firstlast.c,v 1.2 1997/10/18 21:34:53 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,*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();
+
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/ncurses/test/gdc.6 b/contrib/ncurses/test/gdc.6
new file mode 100644
index 000000000000..7fa60de9edf8
--- /dev/null
+++ b/contrib/ncurses/test/gdc.6
@@ -0,0 +1,22 @@
+.TH GDC 6
+.SH NAME
+gdc \- grand digital clock (curses)
+.SH SYNOPSIS
+.B gdc
+[-s] [
+.I n
+]
+.SH DESCRIPTION
+.I Gdc
+runs a digital clock made of reverse-video blanks on a curses
+compatible VDU screen. With an optional numeric argument
+.I n
+it stops after
+.I n
+seconds (default never).
+The optional
+.B -s
+flag makes digits scroll as they change. In this curses mode implementation,
+the scrolling option has trouble keeping up.
+.SH AUTHOR
+Amos Shapir, modified for curses by John Lupien.
diff --git a/contrib/ncurses/test/gdc.c b/contrib/ncurses/test/gdc.c
new file mode 100644
index 000000000000..ecef2bb1e1d1
--- /dev/null
+++ b/contrib/ncurses/test/gdc.c
@@ -0,0 +1,235 @@
+/*
+ * 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.10 1997/10/18 20:06:06 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <time.h>
+#include <signal.h>
+#include <string.h>
+
+#define YBASE 10
+#define XBASE 10
+#define XLENGTH 54
+#define YDEPTH 5
+
+/* it won't be */
+static time_t now; /* yeah! */
+static struct tm *tm;
+
+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 char scrol;
+
+static int sigtermed = 0;
+
+static int hascolor = 0;
+
+static void set(int, int);
+static void standt(int);
+static void movto(int, int);
+
+static
+RETSIGTYPE sighndl(int signo)
+{
+ signal(signo, sighndl);
+ sigtermed=signo;
+}
+
+static void
+drawbox(void)
+{
+ chtype bottom[XLENGTH+1];
+ int n;
+
+ if(hascolor)
+ attrset(COLOR_PAIR(3));
+
+ 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);
+ mvinchnstr(YBASE + YDEPTH, XBASE, bottom, XLENGTH);
+ for (n = 0; n < XLENGTH; n++)
+ 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(2));
+}
+
+int
+main(int argc, char *argv[])
+{
+long t, a;
+int i, j, s, k;
+int n = 0;
+
+ signal(SIGINT,sighndl);
+ signal(SIGTERM,sighndl);
+ signal(SIGKILL,sighndl);
+
+ initscr();
+ cbreak();
+ noecho();
+ nodelay(stdscr, 1);
+ curs_set(0);
+
+ hascolor = has_colors();
+
+ if(hascolor) {
+ int bg = COLOR_BLACK;
+ start_color();
+#ifdef NCURSES_VERSION
+ if (use_default_colors() == OK)
+ bg = -1;
+#endif
+ init_pair(1, COLOR_BLACK, COLOR_RED);
+ init_pair(2, COLOR_RED, bg);
+ init_pair(3, COLOR_WHITE, bg);
+ attrset(COLOR_PAIR(2));
+ }
+
+ clear();
+ refresh();
+ while(--argc > 0) {
+ if(**++argv == '-')
+ scrol = 1;
+ else
+ n = atoi(*argv);
+ }
+
+ drawbox();
+ do {
+ char buf[30];
+
+ mask = 0;
+ time(&now);
+ tm = localtime(&now);
+ 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))) {
+ movto(YBASE + i, XBASE + 2*j);
+ }
+ addstr(" ");
+ }
+ }
+ }
+ if(!s) {
+ older[i] = newer[i];
+ }
+ }
+ if(!s) {
+ if (scrol)
+ drawbox();
+ refresh();
+ if (scrol)
+ napms(150);
+ }
+ }
+ }
+
+ /* this depends on the detailed format of ctime(3) */
+ (void) strcpy(buf, ctime(&now));
+ (void) strcpy(buf + 10, buf + 19);
+ mvaddstr(16, 30, buf);
+
+ movto(6, 0);
+ drawbox();
+ refresh();
+ sleep(1);
+ while(wgetch(stdscr) != ERR)
+ continue;
+ if (sigtermed) {
+ standend();
+ clear();
+ refresh();
+ curs_set(1);
+ endwin();
+ fprintf(stderr, "gdc terminated by signal %d\n", sigtermed);
+ return EXIT_FAILURE;
+ }
+ } while(--n);
+ standend();
+ clear();
+ refresh();
+ curs_set(1);
+ endwin();
+ return EXIT_SUCCESS;
+}
+
+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
+standt(int on)
+{
+ if (on) {
+ if(hascolor) {
+ attron(COLOR_PAIR(1));
+ } else {
+ attron(A_STANDOUT);
+ }
+ } else {
+ if(hascolor) {
+ attron(COLOR_PAIR(2));
+ } else {
+ attroff(A_STANDOUT);
+ }
+ }
+}
+
+static void
+movto(int line, int col)
+{
+ move(line, col);
+}
diff --git a/contrib/ncurses/test/hanoi.c b/contrib/ncurses/test/hanoi.c
new file mode 100644
index 000000000000..25d906ea04a7
--- /dev/null
+++ b/contrib/ncurses/test/hanoi.c
@@ -0,0 +1,297 @@
+/*
+ * 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.15 1997/10/18 20:11:20 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <string.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 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;
+unsigned char AutoFlag = 0;
+
+ 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);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 3:
+ if (strcmp(argv[2], "a")) {
+ Usage();
+ return EXIT_FAILURE;
+ }
+ NTiles = atoi(argv[1]);
+ if (NTiles > MAXTILES || NTiles < MINTILES) {
+ fprintf(stderr, "Range %d to %d\n", MINTILES, MAXTILES);
+ return EXIT_FAILURE;
+ }
+ AutoFlag = TRUE;
+ break;
+ default:
+ Usage();
+ return EXIT_FAILURE;
+ }
+#ifdef NCURSES_VERSION
+ trace(TRACE_MAXIMUM);
+#endif
+ initscr();
+ if (has_colors()) {
+ int i;
+ int bg = COLOR_BLACK;
+ start_color();
+#ifdef NCURSES_VERSION
+ 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");
+ return EXIT_FAILURE;
+ }
+ if(AutoFlag)
+ 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;
+ }
+ }
+ }
+ curs_set(1);
+ endwin();
+ return 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++) {
+ memset(TileBuf, ' ', Pegs[peg].Length[SlotNo]);
+ TileBuf[Pegs[peg].Length[SlotNo]] = '\0';
+ if (has_colors())
+ attrset(COLOR_PAIR(LENTOIND(Pegs[peg].Length[SlotNo])));
+ else
+ attrset(A_REVERSE);
+ mvaddstr(BASELINE-(SlotNo+1),
+ (int)(PegPos[peg] - Pegs[peg].Length[SlotNo]/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();
+ 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()
+{
+ 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/contrib/ncurses/test/hashtest.c b/contrib/ncurses/test/hashtest.c
new file mode 100644
index 000000000000..514ac89656ab
--- /dev/null
+++ b/contrib/ncurses/test/hashtest.c
@@ -0,0 +1,219 @@
+/*
+ * hashtest.c -- test hash mapping
+ *
+ * Generate timing statistics for vertical-motion optimization.
+ *
+ * $Id: hashtest.c,v 1.14 1998/06/13 22:45:39 tom Exp $
+ */
+
+#ifdef TRACE
+#define Trace(p) _tracef p
+#define USE_TRACE 1
+#else
+#define Trace(p) /* nothing */
+#endif
+
+#include <test.priv.h>
+
+#include <string.h>
+#include <ctype.h>
+#include <signal.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();
+ exit(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((j % 8 == 0) ? ('A' + j/8) : '-');
+
+ move(head_lines, 0);
+ for (i = head_lines; i < LINES - foot_lines; i++) {
+ int 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((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)
+{
+ 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)/sizeof(tbl[0]); n++)
+ fprintf(stderr, "%s\n", tbl[n]);
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char *argv[])
+{
+ int c;
+ int test_loops = 1;
+ int test_normal = FALSE;
+ int test_optimize = FALSE;
+
+ while ((c = getopt(argc, argv, "cf:h:l:norsx")) != EOF) {
+ 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);
+ 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
+
+ (void) signal(SIGINT, 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 */
+ return(EXIT_SUCCESS);
+}
+/* hashtest.c ends here */
diff --git a/contrib/ncurses/test/keynames.c b/contrib/ncurses/test/keynames.c
new file mode 100644
index 000000000000..88cadd2f8a84
--- /dev/null
+++ b/contrib/ncurses/test/keynames.c
@@ -0,0 +1,14 @@
+/*
+ * $Id: keynames.c,v 1.2 1998/06/06 22:45:13 tom Exp $
+ */
+
+#include <test.priv.h>
+
+int main(int argc GCC_UNUSED, char *argv[] GCC_UNUSED)
+{
+ int n;
+ for (n = -1; n < 512; n++) {
+ printf("%d(%5o):%s\n", n, n, keyname(n));
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/ncurses/test/knight.c b/contrib/ncurses/test/knight.c
new file mode 100644
index 000000000000..fe3101198776
--- /dev/null
+++ b/contrib/ncurses/test/knight.c
@@ -0,0 +1,565 @@
+/*
+ * 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.14 1997/08/20 16:22:38 hjl Exp $
+ */
+
+#include <test.priv.h>
+
+#include <ctype.h>
+#include <signal.h>
+#include <string.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 short board[BDEPTH][BWIDTH]; /* the squares */
+static int rw,col; /* current row and column */
+static int lastrow,lastcol; /* last location visited */
+static cell history[BDEPTH*BWIDTH]; /* choice history */
+static int movecount; /* count of moves so far */
+static WINDOW *boardwin; /* the board window */
+static WINDOW *helpwin; /* the help window */
+static WINDOW *msgwin; /* the message window */
+static chtype trail = '#'; /* trail character */
+static chtype plus = '+'; /* cursor hot-spot character */
+static chtype minus = '-'; /* possible-move character */
+static chtype oldch;
+
+static void init(void);
+static void play(void);
+static void dosquares(void);
+static void drawmove(char, int, int, int, int);
+static bool evalmove(int, int);
+static bool chkmoves(void);
+static bool chksqr(int, int);
+static int iabs(int);
+
+int main(
+ int argc GCC_UNUSED,
+ char *argv[] GCC_UNUSED)
+{
+ init();
+
+ play();
+
+ endwin();
+ return EXIT_SUCCESS;
+}
+
+static void init (void)
+{
+ 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();
+#ifdef NCURSES_VERSION
+ 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, "u -- undo move h-+-l 4-+-6\n");
+ (void)waddstr(helpwin, " /|\\ /|\\ \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. You can quit with `x' or `q'.\n");
+
+ (void)mvwaddstr(helpwin, NOTIFYY-INSTRY, 0,
+ "Press `?' to go to game explanation");
+}
+
+static void play (void)
+/* play the game */
+{
+ bool keyhelp; /* TRUE if keystroke help is up */
+ int c, ny = 0, nx = 0;
+ int i, j, count;
+
+ do {
+ /* clear screen and draw board */
+ werase(boardwin);
+ werase(helpwin);
+ werase(msgwin);
+ dosquares();
+ help1();
+ wnoutrefresh(stdscr);
+ wnoutrefresh(helpwin);
+ wnoutrefresh(msgwin);
+ wnoutrefresh(boardwin);
+ doupdate();
+
+ for (i = 0; i < BDEPTH; i++)
+ for (j = 0; j < BWIDTH; j++)
+ {
+ board[i][j] = FALSE;
+ cellmove(i, j);
+ waddch(boardwin, minus);
+ }
+ memset(history, '\0', sizeof(history));
+ history[0].y = history[0].x = -1;
+ lastrow = lastcol = -2;
+ movecount = 1;
+ keyhelp = FALSE;
+
+ 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);
+
+ c = wgetch(boardwin);
+
+ werase(msgwin);
+
+ switch (c)
+ {
+ 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 ' ':
+ 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++;
+
+ if (!chkmoves())
+ goto dropout;
+ }
+ else
+ beep();
+ break;
+
+ case KEY_REDO:
+ case '\f':
+ case 'r':
+ clearok(curscr, TRUE);
+ wnoutrefresh(stdscr);
+ wnoutrefresh(boardwin);
+ wnoutrefresh(msgwin);
+ wnoutrefresh(helpwin);
+ doupdate();
+ break;
+
+ case KEY_UNDO:
+ case KEY_BACKSPACE:
+ case '\b':
+ if (movecount == 1)
+ {
+ ny = lastrow;
+ nx = lastcol;
+ waddstr(msgwin, "\nNo previous move.");
+ beep();
+ }
+ else
+ {
+ int oldy = history[movecount-1].y;
+ int oldx = history[movecount-1].x;
+
+ board[oldy][oldx] = FALSE;
+ --movecount;
+ ny = history[movecount-1].y;
+ nx = history[movecount-1].x;
+ drawmove(' ', oldy, oldx, ny, nx);
+
+ /* avoid problems if we just changed the current cell */
+ cellmove(lastrow, lastcol);
+ oldch = winch(boardwin);
+ }
+ break;
+
+ case 'q':
+ case 'x':
+ goto dropout;
+
+ case '?':
+ werase(helpwin);
+ if (keyhelp)
+ {
+ help1();
+ keyhelp = FALSE;
+ }
+ else
+ {
+ help2();
+ keyhelp = TRUE;
+ }
+ wrefresh(helpwin);
+ break;
+
+ default:
+ beep();
+ break;
+ }
+
+ col = nx % BWIDTH;
+ rw = ny % BDEPTH;
+ }
+
+ dropout:
+ count = 0;
+ for (i = 0; i < BDEPTH; i++)
+ for (j = 0; j < BWIDTH; j++)
+ if (board[i][j] != 0)
+ count += 1;
+ if (count == (BWIDTH * BDEPTH))
+ wprintw(msgwin, "\nYou won. Care to try again? ");
+ else
+ wprintw(msgwin, "\n%d squares filled. Try again? ", count);
+ } while
+ (tolower(wgetch(msgwin)) == 'y');
+}
+
+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)
+{
+ if (chksqr(prow+2,pcol+1)){cellmove(prow+2,pcol+1);waddch(boardwin,mark);};
+ if (chksqr(prow+2,pcol-1)){cellmove(prow+2,pcol-1);waddch(boardwin,mark);};
+ if (chksqr(prow-2,pcol+1)){cellmove(prow-2,pcol+1);waddch(boardwin,mark);};
+ if (chksqr(prow-2,pcol-1)){cellmove(prow-2,pcol-1);waddch(boardwin,mark);};
+ if (chksqr(prow+1,pcol+2)){cellmove(prow+1,pcol+2);waddch(boardwin,mark);};
+ if (chksqr(prow+1,pcol-2)){cellmove(prow+1,pcol-2);waddch(boardwin,mark);};
+ if (chksqr(prow-1,pcol+2)){cellmove(prow-1,pcol+2);waddch(boardwin,mark);};
+ if (chksqr(prow-1,pcol-2)){cellmove(prow-1,pcol-2);waddch(boardwin,mark);};
+}
+
+static void drawmove(char 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++)
+ {
+ cellmove(i, j);
+ if (winch(boardwin) == minus)
+ waddch(boardwin, movecount ? ' ' : minus);
+ }
+ }
+ else
+ {
+ cellmove(oldy, oldx);
+ waddch(boardwin, '\b');
+ waddch(boardwin, tchar);
+ waddch(boardwin, tchar);
+ waddch(boardwin, tchar);
+ mark_possibles(oldy, oldx, ' ');
+ }
+
+ if (row != -1 && column != -1)
+ {
+ cellmove(row, column);
+ waddch(boardwin, '\b');
+ waddch(boardwin, trail);
+ waddch(boardwin, trail);
+ waddch(boardwin, trail);
+ mark_possibles(row, column, minus);
+ board[row][column] = TRUE;
+ }
+
+ wprintw(msgwin, "\nMove %d", movecount);
+}
+
+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 bool chkmoves (void)
+/* check to see if valid moves are available */
+{
+ if (chksqr(rw+2,col+1)) return(TRUE);
+ if (chksqr(rw+2,col-1)) return(TRUE);
+ if (chksqr(rw-2,col+1)) return(TRUE);
+ if (chksqr(rw-2,col-1)) return(TRUE);
+ if (chksqr(rw+1,col+2)) return(TRUE);
+ if (chksqr(rw+1,col-2)) return(TRUE);
+ if (chksqr(rw-1,col+2)) return(TRUE);
+ if (chksqr(rw-1,col-2)) return(TRUE);
+ return (FALSE);
+}
+
+static int iabs(int num)
+{
+ if (num < 0) return (-num);
+ else return (num);
+}
+
+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);
+}
+
+/* knight.c ends here */
diff --git a/contrib/ncurses/test/lrtest.c b/contrib/ncurses/test/lrtest.c
new file mode 100644
index 000000000000..893e1cde9e7c
--- /dev/null
+++ b/contrib/ncurses/test/lrtest.c
@@ -0,0 +1,49 @@
+/*
+ * Test lower-right-hand corner access
+ *
+ * by Eric S. Raymond <esr@thyrsus.com>
+ *
+ * This can't be part of the ncurses test-program, because ncurses rips off the
+ * bottom line to do labels.
+ *
+ * $Id: lrtest.c,v 0.7 1998/02/12 23:49:11 tom Exp $
+ */
+
+#include <test.priv.h>
+
+int
+main(
+ int argc GCC_UNUSED,
+ char *argv[] GCC_UNUSED)
+{
+ initscr();
+
+ move(LINES/2-1, 4);
+ if (!has_ic())
+ {
+ 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");
+ }
+
+ box(stdscr, 0, 0);
+ move(LINES-1, COLS-1);
+
+ refresh();
+
+ getch();
+ endwin();
+ return 0;
+}
+
+/* lrtest.c ends here */
diff --git a/contrib/ncurses/test/modules b/contrib/ncurses/test/modules
new file mode 100644
index 000000000000..3e70d49b2bea
--- /dev/null
+++ b/contrib/ncurses/test/modules
@@ -0,0 +1,57 @@
+# Test-Program modules
+# $Id: modules,v 1.10 1999/04/10 21:36:00 tom Exp $
+##############################################################################
+# Copyright (c) 1999 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> 1997
+#
+
+@ base
+blue progs $(srcdir) ../include/term.h
+bs progs $(srcdir)
+cardfile progs $(srcdir) ../include/panel.h ../include/menu.h ../include/form.h
+ditto progs $(srcdir)
+filter progs $(srcdir)
+firework progs $(srcdir) ../include/term.h
+firstlast progs $(srcdir)
+gdc progs $(srcdir)
+hanoi progs $(srcdir)
+hashtest progs $(srcdir)
+keynames progs $(srcdir)
+knight progs $(srcdir)
+lrtest progs $(srcdir)
+ncurses progs $(srcdir) ../include/panel.h ../include/menu.h ../include/form.h
+newdemo progs $(srcdir)
+rain progs $(srcdir) ../include/term.h
+tclock progs $(srcdir)
+testaddch progs $(srcdir)
+testcurs progs $(srcdir)
+testscanw progs $(srcdir)
+view progs $(srcdir)
+worm progs $(srcdir)
+xmas progs $(srcdir)
diff --git a/contrib/ncurses/test/ncurses.c b/contrib/ncurses/test/ncurses.c
new file mode 100644
index 000000000000..667d2ef6ffc9
--- /dev/null
+++ b/contrib/ncurses/test/ncurses.c
@@ -0,0 +1,3270 @@
+/****************************************************************************
+ * 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. *
+ ****************************************************************************/
+/****************************************************************************
+
+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
+
+$Id: ncurses.c,v 1.118 1999/08/10 00:37:30 tom Exp $
+
+***************************************************************************/
+
+#include <test.priv.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+
+#if HAVE_LOCALE_H
+#include <locale.h>
+#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 HAVE_PANEL_H
+#define USE_LIBPANEL 1
+#include <panel.h>
+#else
+#define USE_LIBPANEL 0
+#endif
+
+#if HAVE_MENU_H && HAVE_LIBMENU
+#define USE_LIBMENU 1
+#include <menu.h>
+#else
+#define USE_LIBMENU 0
+#endif
+
+#if HAVE_FORM_H && HAVE_LIBFORM
+#define USE_LIBFORM 1
+#include <form.h>
+#else
+#define USE_LIBFORM 0
+#endif
+
+#ifdef NCURSES_VERSION
+
+#ifdef TRACE
+static int save_trace = TRACE_ORDINARY|TRACE_CALLS;
+extern int _nc_tracing;
+#endif
+
+#if !HAVE_NAPMS
+#define HAVE_NAPMS 1
+#endif
+
+#else
+
+#define mmask_t chtype /* not specified in XSI */
+#define attr_t chtype /* not specified in XSI */
+#define ACS_S3 (acs_map['p']) /* scan line 3 */
+#define ACS_S7 (acs_map['r']) /* scan line 7 */
+#define ACS_LEQUAL (acs_map['y']) /* less/equal */
+#define ACS_GEQUAL (acs_map['z']) /* greater/equal */
+#define ACS_PI (acs_map['{']) /* Pi */
+#define ACS_NEQUAL (acs_map['|']) /* not equal */
+#define ACS_STERLING (acs_map['}']) /* UK pound sign */
+
+#endif
+
+#define P(string) printw("%s\n", string)
+#ifndef CTRL
+#define CTRL(x) ((x) & 0x1f)
+#endif
+
+#define QUIT CTRL('Q')
+#define ESCAPE CTRL('[')
+#define BLANK ' ' /* this is the background character */
+
+/* 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));
+}
+
+/* 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;
+ _tracef("TOGGLE-TRACING OFF");
+ _nc_tracing = 0;
+ } else {
+ _nc_tracing = save_trace;
+ }
+ trace(_nc_tracing);
+ if (_nc_tracing)
+ _tracef("TOGGLE-TRACING ON");
+ }
+#else
+ c = wgetch(win);
+#endif
+ return c;
+}
+#define Getchar() wGetchar(stdscr)
+
+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
+static const char *mouse_decode(MEVENT const *ep)
+{
+ static char buf[80];
+
+ (void) sprintf(buf, "id %2d at (%2d, %2d, %2d) state %4lx = {",
+ ep->id, ep->x, ep->y, ep->z, 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")
+ SHOW(BUTTON1_RESERVED_EVENT, "reserved-1")
+ 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")
+ SHOW(BUTTON2_RESERVED_EVENT, "reserved-2")
+ 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")
+ SHOW(BUTTON3_RESERVED_EVENT, "reserved-3")
+ 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")
+ SHOW(BUTTON4_RESERVED_EVENT, "reserved-4")
+ 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 getch_test(void)
+/* test the keypad feature */
+{
+char buf[BUFSIZ];
+int c;
+int incount = 0, firsttime = 0;
+bool blocking = TRUE;
+int y, x;
+
+ 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();
+ getstr(buf);
+ noecho();
+ nonl();
+
+ if (isdigit(buf[0]))
+ {
+ timeout(atoi(buf) * 100);
+ blocking = FALSE;
+ }
+
+ c = '?';
+ raw();
+ for (;;)
+ {
+ if (firsttime++)
+ {
+ printw("Key pressed: %04o ", c);
+#ifdef NCURSES_MOUSE_VERSION
+ if (c == KEY_MOUSE)
+ {
+ MEVENT event;
+
+ getmouse(&event);
+ printw("KEY_MOUSE, %s\n", mouse_decode(&event));
+ }
+ else
+#endif /* NCURSES_MOUSE_VERSION */
+ if (c >= KEY_MIN)
+ {
+ (void) addstr(keyname(c));
+ addch('\n');
+ }
+ else if (c > 0x80)
+ {
+ int c2 = (c & 0x7f);
+ if (isprint(c2))
+ (void) printw("M-%c", c2);
+ else
+ (void) printw("M-%s", unctrl(c2));
+ addstr(" (high-half character)\n");
+ }
+ else
+ {
+ if (isprint(c))
+ (void) printw("%c (ASCII printable character)\n", c);
+ else
+ (void) printw("%s (ASCII control character)\n", unctrl(c));
+ }
+ getyx(stdscr, y, x);
+ if (y >= LINES-1)
+ move(0,0);
+ clrtoeol();
+ }
+
+ if (c == 'g')
+ {
+ addstr("getstr test: ");
+ echo(); getstr(buf); noecho();
+ printw("I saw `%s'.\n", buf);
+ }
+ if (c == 's')
+ {
+ ShellOut(TRUE);
+ }
+ if (c == 'x' || c == 'q' || (c == ERR && blocking))
+ break;
+ if (c == '?')
+ {
+ addstr("Type any key to see its keypad value. Also:\n");
+ addstr("g -- triggers a getstr test\n");
+ addstr("s -- shell out\n");
+ addstr("q -- quit\n");
+ addstr("? -- repeats this help message\n");
+ }
+
+ while ((c = Getchar()) == ERR)
+ if (!blocking)
+ (void) printw("%05d: input timed out\n", incount++);
+ else {
+ (void) printw("%05d: input error\n", incount++);
+ break;
+ }
+ }
+
+#ifdef NCURSES_MOUSE_VERSION
+ mousemask(0, (mmask_t *)0);
+#endif
+ timeout(-1);
+ erase();
+ noraw();
+ nl();
+ endwin();
+}
+
+static int show_attr(int row, int skip, chtype attr, const char *name, bool once)
+{
+ int ncv = tigetnum("ncv");
+
+ mvprintw(row, 8, "%s mode:", name);
+ mvprintw(row, 24, "|");
+ if (skip) printw("%*s", skip, " ");
+ if (once)
+ attron(attr);
+ else
+ attrset(attr);
+ addstr("abcde fghij klmno pqrst uvwxy z");
+ if (once)
+ attroff(attr);
+ if (skip) printw("%*s", skip, " ");
+ printw("|");
+ if (attr != A_NORMAL) {
+ if (!(termattrs() & attr)) {
+ printw(" (N/A)");
+ } else if (ncv > 0 && (getbkgd(stdscr) & A_COLOR)) {
+ static const attr_t table[] = {
+ A_STANDOUT,
+ A_UNDERLINE,
+ A_REVERSE,
+ A_BLINK,
+ A_DIM,
+ A_BOLD,
+ A_INVIS,
+ A_PROTECT,
+ A_ALTCHARSET
+ };
+ unsigned n;
+ bool found = FALSE;
+ for (n = 0; n < sizeof(table)/sizeof(table[0]); n++) {
+ if ((table[n] & attr) != 0
+ && ((1 << n) & ncv) != 0) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (found)
+ printw(" (NCV)");
+ }
+ }
+ return row + 2;
+}
+
+static bool attr_getc(int *skip, int *fg, int *bg)
+{
+ int ch = Getchar();
+
+ if (isdigit(ch)) {
+ *skip = (ch - '0');
+ return TRUE;
+ } else if (ch == CTRL('L')) {
+ touchwin(stdscr);
+ touchwin(curscr);
+ return TRUE;
+ } else if (has_colors()) {
+ switch (ch) {
+ case 'f': *fg = (*fg + 1); break;
+ case 'F': *fg = (*fg - 1); break;
+ case 'b': *bg = (*bg + 1); break;
+ case 'B': *bg = (*bg - 1); break;
+ default:
+ return FALSE;
+ }
+ if (*fg >= COLORS) *fg = 0;
+ if (*fg < 0) *fg = COLORS - 1;
+ if (*bg >= COLORS) *bg = 0;
+ if (*bg < 0) *bg = COLORS - 1;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void attr_test(void)
+/* test text attributes */
+{
+ int n;
+ int skip = tigetnum("xmc");
+ int fg = COLOR_BLACK; /* color pair 0 is special */
+ int bg = COLOR_BLACK;
+ bool *pairs = (bool *)calloc(COLOR_PAIRS, sizeof(bool));
+ pairs[0] = TRUE;
+
+ if (skip < 0)
+ skip = 0;
+
+ n = skip; /* make it easy */
+
+ do {
+ int row = 2;
+ int normal = A_NORMAL | BLANK;
+
+ if (has_colors()) {
+ int pair = (fg * COLORS) + bg;
+ if (!pairs[pair]) {
+ init_pair(pair, fg, bg);
+ pairs[pair] = TRUE;
+ }
+ normal |= COLOR_PAIR(pair);
+ }
+ bkgdset(normal);
+ erase();
+
+ mvaddstr(0, 20, "Character attribute test display");
+
+ row = show_attr(row, n, A_STANDOUT, "STANDOUT", TRUE);
+ row = show_attr(row, n, A_REVERSE, "REVERSE", TRUE);
+ row = show_attr(row, n, A_BOLD, "BOLD", TRUE);
+ row = show_attr(row, n, A_UNDERLINE, "UNDERLINE", TRUE);
+ row = show_attr(row, n, A_DIM, "DIM", TRUE);
+ row = show_attr(row, n, A_BLINK, "BLINK", TRUE);
+ row = show_attr(row, n, A_PROTECT, "PROTECT", TRUE);
+ row = show_attr(row, n, A_INVIS, "INVISIBLE", TRUE);
+ row = show_attr(row, n, A_NORMAL, "NORMAL", FALSE);
+
+ mvprintw(row, 8,
+ "This terminal does %shave the magic-cookie glitch",
+ tigetnum("xmc") > -1 ? "" : "not ");
+ mvprintw(row+1, 8,
+ "Enter a digit to set gaps on each side of displayed attributes");
+ mvprintw(row+2, 8,
+ "^L = repaint");
+ if (has_colors())
+ printw(". f/F/b/F toggle colors (now %d/%d)", fg, bg);
+
+ refresh();
+ } while (attr_getc(&n, &fg, &bg));
+
+ free((char *)pairs);
+ bkgdset(A_NORMAL | BLANK);
+ erase();
+ endwin();
+}
+
+/****************************************************************************
+ *
+ * Color support tests
+ *
+ ****************************************************************************/
+
+static NCURSES_CONST char *color_names[] =
+{
+ "black",
+ "red",
+ "green",
+ "yellow",
+ "blue",
+ "magenta",
+ "cyan",
+ "white"
+};
+
+static void show_color_name(int y, int x, int color)
+{
+ if (COLORS > 8)
+ mvprintw(y, x, "%02d ", color);
+ else
+ mvaddstr(y, x, color_names[color]);
+}
+
+static void color_test(void)
+/* generate a color test pattern */
+{
+ int i;
+ int base, top, width;
+ NCURSES_CONST char *hello;
+
+ refresh();
+ (void) printw("There are %d color pairs\n", COLOR_PAIRS);
+
+ width = (COLORS > 8) ? 4 : 8;
+ hello = (COLORS > 8) ? "Test" : "Hello";
+
+ for (base = 0; base < 2; base++)
+ {
+ top = (COLORS > 8) ? 0 : base * (COLORS+3);
+ clrtobot();
+ (void) mvprintw(top + 1, 0,
+ "%dx%d matrix of foreground/background colors, bright *%s*\n",
+ COLORS, COLORS,
+ base ? "on" : "off");
+ for (i = 0; i < COLORS; i++)
+ show_color_name(top + 2, (i+1) * width, i);
+ for (i = 0; i < COLORS; i++)
+ show_color_name(top + 3 + i, 0, i);
+ for (i = 1; i < COLOR_PAIRS; i++)
+ {
+ init_pair(i, i % COLORS, i / COLORS);
+ attron((attr_t)COLOR_PAIR(i));
+ if (base)
+ attron((attr_t)A_BOLD);
+ mvaddstr(top + 3 + (i / COLORS), (i % COLORS + 1) * width, hello);
+ attrset(A_NORMAL);
+ }
+ if ((COLORS > 8) || base)
+ Pause();
+ }
+
+ erase();
+ endwin();
+}
+
+static void change_color(int current, int field, int value, int usebase)
+{
+ short red, green, blue;
+
+ if (usebase)
+ color_content(current, &red, &green, &blue);
+ else
+ red = green = blue = 0;
+
+ switch (field) {
+ case 0:
+ red += value;
+ break;
+ case 1:
+ green += value;
+ break;
+ case 2:
+ blue += value;
+ break;
+ }
+
+ if (init_color(current, red, green, blue) == ERR)
+ beep();
+}
+
+static void color_edit(void)
+/* display the color test pattern, without trying to edit colors */
+{
+ int i, this_c = 0, value = 0, current = 0, field = 0;
+ int last_c;
+
+ refresh();
+
+ for (i = 0; i < COLORS; i++)
+ init_pair(i, COLOR_WHITE, 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 = 0; i < COLORS; i++)
+ {
+ mvprintw(2 + i, 0, "%c %-8s:",
+ (i == current ? '>' : ' '),
+ (i < (int) SIZEOF(color_names)
+ ? color_names[i] : ""));
+ attrset(COLOR_PAIR(i));
+ addstr(" ");
+ attrset(A_NORMAL);
+
+ /*
+ * Note: this refresh should *not* be necessary! It works around
+ * a bug in attribute handling that apparently causes the A_NORMAL
+ * attribute sets to interfere with the actual emission of the
+ * color setting somehow. This needs to be fixed.
+ */
+ refresh();
+
+ color_content(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);
+ addstr(")");
+ }
+
+ mvaddstr(COLORS + 3, 0,
+ "Use up/down to select a color, left/right to change fields.");
+ mvaddstr(COLORS + 4, 0,
+ "Modify field by typing nnn=, nnn-, or nnn+. ? for help.");
+
+ move(2 + current, 0);
+
+ last_c = this_c;
+ this_c = Getchar();
+ if (isdigit(this_c) && !isdigit(last_c))
+ value = 0;
+
+ switch (this_c)
+ {
+ case KEY_UP:
+ current = (current == 0 ? (COLORS - 1) : current - 1);
+ break;
+
+ case KEY_DOWN:
+ current = (current == (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(current, field, value, 1);
+ break;
+
+ case '-':
+ change_color(current, field, -value, 1);
+ break;
+
+ case '=':
+ change_color(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("To quit, do `x' or 'q'");
+
+ Pause();
+ erase();
+ break;
+
+ case 'x':
+ case 'q':
+ break;
+
+ default:
+ beep();
+ break;
+ }
+ mvprintw(LINES-2, 0, "Number: %d", value);
+ clrtoeol();
+ } while
+ (this_c != 'x' && this_c != 'q');
+
+ erase();
+ endwin();
+}
+
+/****************************************************************************
+ *
+ * Soft-key label test
+ *
+ ****************************************************************************/
+
+static void slk_test(void)
+/* exercise the soft keys */
+{
+ int c, fmt = 1;
+ char buf[9];
+
+ c = CTRL('l');
+ do {
+ move(0, 0);
+ switch(c)
+ {
+ case CTRL('l'):
+ erase();
+ attron(A_BOLD);
+ mvaddstr(0, 20, "Soft Key Exerciser");
+ attroff(A_BOLD);
+
+ move(2, 0);
+ P("Available commands are:");
+ P("");
+ P("^L -- refresh screen");
+ P("a -- activate or restore soft keys");
+ P("d -- disable soft keys");
+ P("c -- set centered format for labels");
+ P("l -- set left-justified format for labels");
+ P("r -- set right-justified format for labels");
+ P("[12345678] -- set label; labels are numbered 1 through 8");
+ P("e -- erase stdscr (should not erase labels)");
+ P("s -- test scrolling of shortened screen");
+ P("x, q -- return to main menu");
+ P("");
+ P("Note: if activating the soft keys causes your terminal to");
+ P("scroll up one line, your terminal auto-scrolls when anything");
+ P("is written to the last screen position. The ncurses code");
+ P("does not yet handle this gracefully.");
+ refresh();
+ /* fall through */
+
+ case 'a':
+ slk_restore();
+ break;
+
+ case 'e':
+ wclear(stdscr);
+ break;
+
+ case 's':
+ mvprintw(20, 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(20, 0, "Please enter the label value: ");
+ echo();
+ wgetnstr(stdscr, buf, 8);
+ noecho();
+ slk_set((c - '0'), buf, fmt);
+ slk_refresh();
+ move(20, 0); clrtoeol();
+ break;
+
+ case 'x':
+ case 'q':
+ goto done;
+
+ default:
+ beep();
+ }
+ } while
+ ((c = Getchar()) != EOF);
+
+ done:
+ erase();
+ endwin();
+}
+
+/****************************************************************************
+ *
+ * Alternate character-set stuff
+ *
+ ****************************************************************************/
+
+/* 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(int first)
+{
+ bool C1 = (first == 128);
+ int code;
+ int 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 row = 4 + ((code - first) % 16);
+ int col = ((code - first) / 16) * COLS / 2;
+ char tmp[80];
+ sprintf(tmp, "%3d (0x%x)", code, code);
+ mvprintw(row, col, "%*s: ", COLS/4, tmp);
+ if (C1)
+ nodelay(stdscr, TRUE);
+ echochar(code);
+ if (C1) {
+ /* (yes, this _is_ crude) */
+ while ((reply = Getchar()) != ERR) {
+ addch(reply);
+ napms(10);
+ }
+ nodelay(stdscr, FALSE);
+ }
+ }
+}
+
+static int show_1_acs(int n, const char *name, chtype code)
+{
+ const int height = 16;
+ int row = 4 + (n % height);
+ int col = (n / height) * COLS / 2;
+ mvprintw(row, col, "%*s : ", COLS/4, name);
+ addch(code);
+ return n + 1;
+}
+
+static void show_acs_chars(void)
+/* display the ACS character set */
+{
+ int n;
+
+#define BOTH(name) #name, name
+
+ erase();
+ attron(A_BOLD);
+ mvaddstr(0, 20, "Display of the ACS Character Set");
+ attroff(A_BOLD);
+ refresh();
+
+ n = show_1_acs(0, BOTH(ACS_ULCORNER));
+ n = show_1_acs(n, BOTH(ACS_LLCORNER));
+ n = show_1_acs(n, BOTH(ACS_URCORNER));
+ n = show_1_acs(n, BOTH(ACS_LRCORNER));
+ n = show_1_acs(n, BOTH(ACS_RTEE));
+ n = show_1_acs(n, BOTH(ACS_LTEE));
+ n = show_1_acs(n, BOTH(ACS_BTEE));
+ n = show_1_acs(n, BOTH(ACS_TTEE));
+ n = show_1_acs(n, BOTH(ACS_HLINE));
+ n = show_1_acs(n, BOTH(ACS_VLINE));
+ n = show_1_acs(n, BOTH(ACS_PLUS));
+ n = show_1_acs(n, BOTH(ACS_S1));
+ n = show_1_acs(n, BOTH(ACS_S9));
+ n = show_1_acs(n, BOTH(ACS_DIAMOND));
+ n = show_1_acs(n, BOTH(ACS_CKBOARD));
+ n = show_1_acs(n, BOTH(ACS_DEGREE));
+ n = show_1_acs(n, BOTH(ACS_PLMINUS));
+ n = show_1_acs(n, BOTH(ACS_BULLET));
+ n = show_1_acs(n, BOTH(ACS_LARROW));
+ n = show_1_acs(n, BOTH(ACS_RARROW));
+ n = show_1_acs(n, BOTH(ACS_DARROW));
+ n = show_1_acs(n, BOTH(ACS_UARROW));
+ n = show_1_acs(n, BOTH(ACS_BOARD));
+ n = show_1_acs(n, BOTH(ACS_LANTERN));
+ n = show_1_acs(n, BOTH(ACS_BLOCK));
+ n = show_1_acs(n, BOTH(ACS_S3));
+ n = show_1_acs(n, BOTH(ACS_S7));
+ n = show_1_acs(n, BOTH(ACS_LEQUAL));
+ n = show_1_acs(n, BOTH(ACS_GEQUAL));
+ n = show_1_acs(n, BOTH(ACS_PI));
+ n = show_1_acs(n, BOTH(ACS_NEQUAL));
+ n = show_1_acs(n, BOTH(ACS_STERLING));
+}
+
+static void acs_display(void)
+{
+ int c = 'a';
+
+ do {
+ switch (c) {
+ case 'a':
+ show_acs_chars();
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ show_upper_chars((c - '0') * 32 + 128);
+ break;
+ }
+ mvprintw(LINES-3,0, "Note: ANSI terminals may not display C1 characters.");
+ mvprintw(LINES-2,0, "Select: a=ACS, 0=C1, 1,2,3=GR characters, q=quit");
+ refresh();
+ } while ((c = Getchar()) != 'x' && c != 'q');
+
+ Pause();
+ erase();
+ endwin();
+}
+
+/*
+ * Graphic-rendition test (adapted from vttest)
+ */
+static void
+test_sgr_attributes(void)
+{
+ int pass;
+
+ for (pass = 0; pass < 2; pass++) {
+ int normal = ((pass == 0 ? A_NORMAL : A_REVERSE)) | BLANK;
+
+ /* Use non-default colors if possible to exercise bce a little */
+ if (has_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;
+};
+
+/* 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.
+ */
+static bool HaveKeypad(FRAME *curp)
+{
+ WINDOW *win = (curp ? curp->wind : stdscr);
+ return win->_use_keypad;
+}
+
+static bool HaveScroll(FRAME *curp)
+{
+ WINDOW *win = (curp ? curp->wind : stdscr);
+ return win->_scroll;
+}
+
+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 },
+#ifdef NCURSES_VERSION
+ { "^X = resize", 0 },
+#endif
+ { "^Q%s = exit", 3 }
+ };
+ size_t n;
+ int y, 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;
+ }
+ getyx(stdscr, y, x);
+ 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 = (curp != 0) ? curp->wind : stdscr;
+ 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 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;
+ }
+}
+
+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 = (curp != 0) ? curp->wind : stdscr;
+ 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;
+
+ 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, i;
+ FILE *fp;
+ FRAME *current = (FRAME *)0, *neww;
+ WINDOW *usescr = stdscr;
+
+#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'):
+ neww = (FRAME *) calloc(1, sizeof(FRAME));
+ if ((neww->wind = getwindow()) == (WINDOW *)0)
+ 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(current->wind, 1);
+ break;
+
+ case CTRL('B'): /* scroll current window backwards */
+ if (current)
+ wscrl(current->wind, -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;
+
+ case CTRL('W'): /* save and delete window */
+ if (current == current->next)
+ break;
+ if ((fp = fopen(DUMPFILE, "w")) == (FILE *)0)
+ transient(current, "Can't open screen dump file");
+ else
+ {
+ (void) putwin(current->wind, 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
+ {
+ neww = (FRAME *) calloc(1, sizeof(FRAME));
+
+ neww->next = current->next;
+ neww->last = current;
+ neww->last->next = neww;
+ neww->next->last = neww;
+
+ neww->wind = getwin(fp);
+ (void) fclose(fp);
+
+ wrefresh(neww->wind);
+ }
+ break;
+
+#ifdef NCURSES_VERSION
+ case CTRL('X'): /* resize window */
+ if (current)
+ {
+ pair *tmp, ul, lr;
+ int 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 /* NCURSES_VERSION */
+
+ 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(current->wind, y, x);
+ if (--x < 0) {
+ if (--y < 0)
+ break;
+ x = getmaxx(current->wind) - 1;
+ }
+ mvwdelch(current->wind, y, x);
+ }
+ break;
+
+ case '\r':
+ c = '\n';
+ /* FALLTHROUGH */
+
+ default:
+ if (current)
+ waddch(current->wind, (chtype)c);
+ else
+ beep();
+ break;
+ }
+ newwin_report(current);
+ usescr = (current ? current->wind : stdscr);
+ wrefresh(usescr);
+ } while
+ ((c = wGetchar(usescr)) != QUIT
+ && !((c == ESCAPE) && (usescr->_use_keypad))
+ && (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 unsigned long nap_msec = 1;
+
+static NCURSES_CONST char *mod[] =
+{
+ "test ",
+ "TEST ",
+ "(**) ",
+ "*()* ",
+ "<--> ",
+ "LAST "
+};
+
+/*+-------------------------------------------------------------------------
+ wait_a_while(msec)
+--------------------------------------------------------------------------*/
+static void
+wait_a_while(unsigned long 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 > 1000L)
+ sleep((int)msec/1000L);
+ 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);
+ waddstr(stdscr, text);
+} /* end of saywhat */
+
+/*+-------------------------------------------------------------------------
+ mkpanel(rows,cols,tly,tlx) - alloc a win and panel and associate them
+--------------------------------------------------------------------------*/
+static PANEL *
+mkpanel(int 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 (has_colors()) {
+ int fg = (color == COLOR_BLUE) ? COLOR_WHITE : COLOR_BLACK;
+ int bg = color;
+ init_pair(color, fg, bg);
+ wbkgdset(win, 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
+fill_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,num);
+ }
+ }
+} /* end of fill_panel */
+
+static void demo_panels(void)
+{
+int itmp;
+register int y,x;
+
+ refresh();
+
+ for(y = 0; y < LINES - 1; y++)
+ {
+ for(x = 0; x < COLS; x++)
+ wprintw(stdscr,"%d",(y + x) % 10);
+ }
+ for(y = 0; y < 5; y++)
+ {
+ PANEL *p1;
+ PANEL *p2;
+ PANEL *p3;
+ PANEL *p4;
+ PANEL *p5;
+
+ p1 = mkpanel(COLOR_RED, LINES/2 - 2, COLS/8 + 1, 0, 0);
+ set_panel_userptr(p1,"p1");
+
+ p2 = mkpanel(COLOR_GREEN, LINES/2 + 1, COLS/7, LINES/4, COLS/10);
+ set_panel_userptr(p2,"p2");
+
+ p3 = mkpanel(COLOR_YELLOW, LINES/4, COLS/10, LINES/2, COLS/9);
+ set_panel_userptr(p3,"p3");
+
+ p4 = mkpanel(COLOR_BLUE, LINES/2 - 2, COLS/8, LINES/2 - 2, COLS/3);
+ set_panel_userptr(p4,"p4");
+
+ p5 = mkpanel(COLOR_MAGENTA, LINES/2 - 2, COLS/8, LINES/2, COLS/2 - 2);
+ set_panel_userptr(p5,"p5");
+
+ fill_panel(p1);
+ fill_panel(p2);
+ fill_panel(p3);
+ fill_panel(p4);
+ fill_panel(p5);
+ hide_panel(p4);
+ hide_panel(p5);
+ pflush();
+ saywhat("press any key to continue");
+ wait_a_while(nap_msec);
+
+ saywhat("h3 s1 s2 s4 s5; press any key to continue");
+ move_panel(p1,0,0);
+ hide_panel(p3);
+ show_panel(p1);
+ show_panel(p2);
+ show_panel(p4);
+ show_panel(p5);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("s1; press any key to continue");
+ show_panel(p1);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("s2; press any key to continue");
+ show_panel(p2);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("m2; press any key to continue");
+ move_panel(p2, LINES/3 + 1, COLS / 8);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("s3;");
+ show_panel(p3);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("m3; press any key to continue");
+ move_panel(p3, LINES/4 + 1, COLS / 15);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("b3; press any key to continue");
+ bottom_panel(p3);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("s4; press any key to continue");
+ show_panel(p4);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("s5; press any key to continue");
+ show_panel(p5);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("t3; press any key to continue");
+ top_panel(p3);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("t1; press any key to continue");
+ top_panel(p1);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("t2; press any key to continue");
+ top_panel(p2);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("t3; press any key to continue");
+ top_panel(p3);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("t4; press any key to continue");
+ top_panel(p4);
+ pflush();
+ wait_a_while(nap_msec);
+
+ for(itmp = 0; itmp < 6; itmp++)
+ {
+ WINDOW *w4 = panel_window(p4);
+ WINDOW *w5 = panel_window(p5);
+
+ saywhat("m4; press any key to continue");
+ wmove(w4, LINES/8, 1);
+ waddstr(w4,mod[itmp]);
+ move_panel(p4, LINES/6, itmp*(COLS/8));
+ wmove(w5, LINES/6, 1);
+ waddstr(w5,mod[itmp]);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("m5; press any key to continue");
+ wmove(w4, LINES/6, 1);
+ waddstr(w4,mod[itmp]);
+ move_panel(p5, LINES/3 - 1,(itmp*10) + 6);
+ wmove(w5, LINES/8, 1);
+ waddstr(w5,mod[itmp]);
+ pflush();
+ wait_a_while(nap_msec);
+ }
+
+ saywhat("m4; press any key to continue");
+ move_panel(p4, LINES/6, itmp*(COLS/8));
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("t5; press any key to continue");
+ top_panel(p5);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("t2; press any key to continue");
+ top_panel(p2);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("t1; press any key to continue");
+ top_panel(p1);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("d2; press any key to continue");
+ rmpanel(p2);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("h3; press any key to continue");
+ hide_panel(p3);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("d1; press any key to continue");
+ rmpanel(p1);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("d4; press any key to continue");
+ rmpanel(p4);
+ pflush();
+ wait_a_while(nap_msec);
+
+ saywhat("d5; press any key to continue");
+ rmpanel(p5);
+ pflush();
+ wait_a_while(nap_msec);
+ if(nap_msec == 1)
+ break;
+ nap_msec = 100L;
+ }
+
+ erase();
+ endwin();
+}
+
+/****************************************************************************
+ *
+ * Pad tester
+ *
+ ****************************************************************************/
+
+#define GRIDSIZE 3
+
+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, q to quit (?,t,s flags)",
+ "Use ! to shell-out. Toggle legend:?, timer:t, scroll mark:s.",
+ "Use +,- (or j,k) to grow/shrink the panner vertically.",
+ "Use <,> (or h,l) to grow/shrink the panner horizontally."
+ };
+ int n = (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 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 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;
+#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;
+
+ 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)(top_x + (basex * ratio));
+ highend = (int)(top_x + ((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)(top_y + (basey * ratio));
+ highend = (int)(top_y + ((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 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-20);
+ 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)
+{
+ int c;
+
+ switch(c = wGetchar(win))
+ {
+ case '!': ShellOut(FALSE); return KEY_REFRESH;
+ case CTRL('r'): endwin(); refresh(); return KEY_REFRESH;
+ case CTRL('l'): return KEY_REFRESH;
+ case 'U': return(KEY_UP);
+ case 'D': return(KEY_DOWN);
+ case 'R': return(KEY_RIGHT);
+ case 'L': return(KEY_LEFT);
+ case '+': return(KEY_IL);
+ case '-': return(KEY_DL);
+ case '>': return(KEY_IC);
+ case '<': return(KEY_DC);
+ case ERR: /* FALLTHRU */
+ case 'q': return(KEY_EXIT);
+ default: return(c);
+ }
+}
+
+static void demo_pad(void)
+/* Demonstrate pads. */
+{
+ int i, j;
+ unsigned gridcount = 0;
+ WINDOW *panpad = newpad(200, 200);
+
+ for (i = 0; i < 200; i++)
+ {
+ for (j = 0; j < 200; j++)
+ if (i % GRIDSIZE == 0 && j % GRIDSIZE == 0)
+ {
+ if (i == 0 || j == 0)
+ waddch(panpad, '+');
+ else
+ waddch(panpad, (chtype)('A' + (gridcount++ % 26)));
+ }
+ else if (i % GRIDSIZE == 0)
+ waddch(panpad, '-');
+ else if (j % GRIDSIZE == 0)
+ waddch(panpad, '|');
+ else
+ waddch(panpad, ' ');
+ }
+ 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();
+}
+#endif /* USE_LIBPANEL */
+
+/****************************************************************************
+ *
+ * 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 (has_colors())
+ {
+ init_pair(2,COLOR_CYAN,COLOR_BLUE);
+ wattrset(subWin, COLOR_PAIR(2) | A_BOLD);
+ }
+ else
+ wattrset(subWin, A_BOLD);
+#else
+ wattrset(subWin, A_BOLD);
+#endif
+ 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 char *animals[] =
+{
+ "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 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++)
+ *ip++ = new_item(*ap, "");
+ *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_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;
+ int 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_MAXIMUM),
+ { (char *)0, 0 }
+};
+
+static char *tracetrace(int 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 = (char *)malloc(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, 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++)
+ *ip++ = new_item(t_tbl[n].name, "");
+ *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++) {
+ int 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);
+ _tracef("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, strlen(label), frow, fcol, 0, 0);
+
+ if (f)
+ {
+ set_field_buffer(f, 0, label);
+ set_field_opts(f, 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, nbuf;
+
+ if (field_info(me, &rows, &cols, &frow, &fcol, (int *)0, &nbuf) == E_OK
+ && nbuf > 0) {
+ char temp[80];
+ long len;
+
+ strcpy(temp, field_buffer(me, 1));
+ len = (long)(char *) field_userptr(me);
+ if (c <= KEY_MAX) {
+ if (isgraph(c)) {
+ temp[len++] = 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)
+{
+ 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 }
+ };
+
+ static int mode = REQ_INS_MODE;
+ int c = wGetchar(w);
+ unsigned n;
+ FIELD *me = current_field(f);
+
+ 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)/sizeof(lookup[0]); n++) {
+ if (lookup[n].code == c) {
+ c = lookup[n].result;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Force the field that the user is typing into to be in reverse video,
+ * while the other fields are shown underlined.
+ */
+ if (c <= KEY_MAX) {
+ c = edit_secure(me, c);
+ set_field_back(me, A_REVERSE);
+ } else if (c <= MAX_FORM_COMMAND) {
+ 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);
+ }
+}
+
+static void demo_forms(void)
+{
+ WINDOW *w;
+ FORM *form;
+ FIELD *f[12], *secure;
+ int finished = 0, c;
+ unsigned n = 0;
+
+ move(18, 0);
+ addstr("Defined form-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.");
+
+ mvaddstr(4, 57, "Forms Entry Test");
+
+ refresh();
+
+ /* describe the form */
+ 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);
+ f[n++] = make_label(2, 20, "First Name");
+ f[n++] = make_field(3, 20, 1, 12, FALSE);
+ f[n++] = make_label(2, 34, "Middle Name");
+ f[n++] = make_field(3, 34, 1, 12, FALSE);
+ 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);
+ f[n++] = (FIELD *)0;
+
+ form = new_form(f);
+
+ display_form(form);
+
+ w = form_win(form);
+ raw();
+ 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]);
+ noraw();
+}
+#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, 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, ch);
+ }
+ }
+}
+
+static void overlap_test(void)
+/* test effects of overlapping windows */
+{
+ int ch;
+
+ WINDOW *win1 = newwin(9, 20, 3, 3);
+ WINDOW *win2 = newwin(9, 20, 9, 16);
+
+ 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");
+
+
+ move(18, 0);
+ printw("a = refresh A, then B, then doupdate. b = refresh B, then A, then doupdaute\n");
+ printw("c = fill window A with letter A. d = fill window B with letter B.\n");
+ printw("e = cross pattern in window A. f = cross pattern in window B.\n");
+ printw("g = clear window A. h = clear window B.\n");
+ printw("i = overwrite A onto B. j = overwrite B onto A.\n");
+ printw("^Q/ESC = terminate test.");
+
+ while ((ch = Getchar()) != QUIT && ch != ESCAPE)
+ switch (ch)
+ {
+ case 'a': /* refresh window A first, then B */
+ wnoutrefresh(win1);
+ wnoutrefresh(win2);
+ doupdate();
+ break;
+
+ case 'b': /* refresh window B first, then A */
+ wnoutrefresh(win2);
+ wnoutrefresh(win1);
+ doupdate();
+ break;
+
+ case 'c': /* fill window A so it's visible */
+ fillwin(win1, 'A');
+ break;
+
+ case 'd': /* fill window B so it's visible */
+ fillwin(win2, 'B');
+ break;
+
+ case 'e': /* cross test pattern in window A */
+ crosswin(win1, 'A');
+ break;
+
+ case 'f': /* cross test pattern in window A */
+ crosswin(win2, 'B');
+ break;
+
+ case 'g': /* clear window A */
+ wclear(win1);
+ wmove(win1, 0, 0);
+ break;
+
+ case 'h': /* clear window B */
+ wclear(win2);
+ wmove(win2, 0, 0);
+ break;
+
+ case 'i': /* overwrite A onto B */
+ overwrite(win1, win2);
+ break;
+
+ case 'j': /* overwrite B onto A */
+ overwrite(win2, win1);
+ break;
+ }
+
+ delwin(win2);
+ delwin(win1);
+ erase();
+ endwin();
+}
+
+/****************************************************************************
+ *
+ * Main sequence
+ *
+ ****************************************************************************/
+
+static bool
+do_single_test(const char c)
+/* perform a single specified test */
+{
+ switch (c)
+ {
+ case 'a':
+ getch_test();
+ break;
+
+ case 'b':
+ attr_test();
+ break;
+
+ case 'c':
+ if (!has_colors())
+ Cannot("does not support color.");
+ else
+ color_test();
+ break;
+
+ case 'd':
+ if (!has_colors())
+ Cannot("does not support color.");
+ else if (!can_change_color())
+ Cannot("has hardwired color values.");
+ else
+ color_edit();
+ break;
+
+ case 'e':
+ slk_test();
+ break;
+
+ case 'f':
+ acs_display();
+ break;
+
+#if USE_LIBPANEL
+ case 'o':
+ demo_panels();
+ 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
+
+#if USE_LIBPANEL
+ case 'p':
+ demo_pad();
+ break;
+#endif
+
+#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:"
+ ," -e fmt specify format for soft-keys test (e)"
+ ," -f rip-off footer line (can repeat)"
+ ," -h rip-off header line (can repeat)"
+ ," -s msec specify nominal time for panel-demo (default: 1, to hold)"
+#ifdef TRACE
+ ," -t mask specify default trace-level (may toggle with ^T)"
+#endif
+ };
+ size_t n;
+ for (n = 0; n < sizeof(tbl)/sizeof(tbl[0]); n++)
+ fprintf(stderr, "%s\n", tbl[n]);
+ exit(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
+
+static int rip_footer(WINDOW *win, int columns)
+{
+ wbkgd(win, A_REVERSE);
+ werase(win);
+ wmove(win, 0, 0);
+ wprintw(win, "footer: %d columns", columns);
+ wnoutrefresh(win);
+ return OK;
+}
+
+static int rip_header(WINDOW *win, int columns)
+{
+ wbkgd(win, A_REVERSE);
+ werase(win);
+ wmove(win, 0, 0);
+ wprintw(win, "header: %d columns", columns);
+ wnoutrefresh(win);
+ return OK;
+}
+
+/*+-------------------------------------------------------------------------
+ main(argc,argv)
+--------------------------------------------------------------------------*/
+
+int
+main(int argc, char *argv[])
+{
+ int command, c;
+ int my_e_param = 1;
+
+#if HAVE_LOCALE_H
+ setlocale(LC_CTYPE, "");
+#endif
+
+ while ((c = getopt(argc, argv, "e:fhs:t:")) != EOF) {
+ switch (c) {
+ 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;
+ case 'f':
+ ripoffline(-1, rip_footer);
+ break;
+ case 'h':
+ ripoffline(1, rip_header);
+ break;
+#if USE_LIBPANEL
+ case 's':
+ nap_msec = atol(optarg);
+ break;
+#endif
+#ifdef TRACE
+ case 't':
+ save_trace = atoi(optarg);
+ 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 */
+
+ /* tell it we're going to play with soft keys */
+ slk_init(my_e_param);
+
+#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 */
+ start_color();
+ 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();
+
+ (void) puts("Welcome to ncurses. Press ? for help.");
+
+ do {
+ (void) puts("This is the ncurses main menu");
+ (void) puts("a = keyboard and mouse input test");
+ (void) puts("b = character attribute test");
+ (void) puts("c = color test pattern");
+ (void) puts("d = edit RGB color values");
+ (void) puts("e = exercise soft keys");
+ (void) puts("f = display ACS characters");
+ (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");
+ (void) puts("p = exercise pad features");
+ (void) puts("q = quit");
+#endif
+#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;
+ if (read(fileno(stdin), &ch, 1) <= 0) {
+ if (command == 0)
+ command = 'q';
+ break;
+ } else if (command == 0 && !isspace(ch)) {
+ command = ch;
+ } else if (ch == '\n' || ch == '\r') {
+ 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. The commands `x' or `q' will exit.");
+ }
+ continue;
+ }
+ } while
+ (command != 'q');
+
+ ExitProgram(EXIT_SUCCESS);
+}
+
+/* ncurses.c ends here */
diff --git a/contrib/ncurses/test/ncurses_tst.hin b/contrib/ncurses/test/ncurses_tst.hin
new file mode 100644
index 000000000000..1d77cbd3fee2
--- /dev/null
+++ b/contrib/ncurses/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/contrib/ncurses/test/newdemo.c b/contrib/ncurses/test/newdemo.c
new file mode 100644
index 000000000000..d47d275e35a2
--- /dev/null
+++ b/contrib/ncurses/test/newdemo.c
@@ -0,0 +1,348 @@
+/*
+ * newdemo.c - A demo program using PDCurses. The program illustrate
+ * the use of colours for text output.
+ *
+ * $Id: newdemo.c,v 1.17 1997/09/20 15:11:26 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <signal.h>
+#include <time.h>
+#include <string.h>
+
+static int SubWinTest(WINDOW *win);
+static int WaitForUser(WINDOW *win);
+static int BouncingBalls(WINDOW *win);
+static RETSIGTYPE trap(int);
+
+#define delay_output(x) napms(x)
+
+/*
+ * The Australian map
+ */
+const 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
+
+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",
+ ""
+};
+
+/*
+ * 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;
+
+ initscr();
+ start_color();
+ cbreak();
+ signal(SIGINT, trap);
+ width = 48;
+ height = 14; /* Create a drawing window */
+ win = newwin(height, width, (LINES-height)/2, (COLS-width)/2);
+ if(win == NULL)
+ { endwin();
+ return 1;
+ }
+
+ while(1)
+ { init_pair(1,COLOR_WHITE,COLOR_BLUE);
+ wattrset(win, COLOR_PAIR(1));
+ werase(win);
+
+ init_pair(2,COLOR_RED,COLOR_RED);
+ wattrset(win, COLOR_PAIR(2));
+ box(win, ACS_VLINE, ACS_HLINE);
+ wrefresh(win);
+ /* Do ramdom output of a character */
+ wattrset(win, COLOR_PAIR(1));
+ 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';
+ init_pair(3,COLOR_CYAN,COLOR_YELLOW);
+ wattron(win, COLOR_PAIR(3));
+ }
+ }
+
+ SubWinTest(win);
+ /* Erase and draw green window */
+ init_pair(4,COLOR_YELLOW,COLOR_GREEN);
+ wbkgd(win, COLOR_PAIR(4) | A_BOLD);
+ wattrset(win, COLOR_PAIR(4) | A_BOLD);
+ werase(win);
+ wrefresh(win);
+ /* Draw RED bounding box */
+ wattrset(win, COLOR_PAIR(2));
+ box(win, ' ', ' ');
+ wrefresh(win);
+ /* Display Australia map */
+ wattrset(win, COLOR_PAIR(4) | A_BOLD);
+ i = 0;
+ while(*AusMap[i])
+ { mvwaddstr(win, i+1, 8, AusMap[i]);
+ wrefresh(win);
+ delay_output(50);
+ ++i;
+ }
+
+ init_pair(5,COLOR_BLUE,COLOR_WHITE);
+ wattrset(win, COLOR_PAIR(5) | A_BLINK);
+ mvwaddstr(win, height-2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix");
+ wrefresh(win);
+
+ /* Draw running messages */
+ init_pair(6,COLOR_YELLOW,COLOR_WHITE);
+ wattrset(win, COLOR_PAIR(6));
+ 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 */
+ init_pair(7,COLOR_RED,COLOR_GREEN);
+ wattron(win, COLOR_PAIR(7));
+ 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;
+ wattrset(win, COLOR_PAIR(5));
+ 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;
+ wattrset(win, COLOR_PAIR(5));
+ mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit ");
+ wrefresh(win);
+ if(WaitForUser(win) == 1)
+ break;
+ }
+ endwin();
+ return 0;
+}
+
+/*
+ * 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;
+
+ init_pair(8,COLOR_RED,COLOR_BLUE);
+ wattrset(swin1, COLOR_PAIR(8));
+ werase(swin1);
+ mvwaddstr(swin1, 0, 3, "Sub-window 1");
+ wrefresh(swin1);
+
+ init_pair(8,COLOR_CYAN,COLOR_MAGENTA);
+ wattrset(swin2, COLOR_PAIR(8));
+ werase(swin2);
+ mvwaddstr(swin2, 0, 3, "Sub-window 2");
+ wrefresh(swin2);
+
+ init_pair(8,COLOR_YELLOW,COLOR_GREEN);
+ wattrset(swin3, COLOR_PAIR(8));
+ werase(swin3);
+ mvwaddstr(swin3, 0, 3, "Sub-window 3");
+ wrefresh(swin3);
+
+ delwin(swin1);
+ delwin(swin2);
+ delwin(swin3);
+ WaitForUser(win);
+ return 0;
+}
+
+/*
+ * 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 = xd1 > 0 ? ++x1 : --x1;
+ if(x1 <= 1 || x1 >= w - 2)
+ xd1 = xd1 ? 0 : 1;
+ y1 = yd1 > 0 ? ++y1 : --y1;
+ if(y1 <= 1 || y1 >= h - 2)
+ yd1 = yd1 ? 0 : 1;
+
+ x2 = xd2 > 0 ? ++x2 : --x2;
+ if(x2 <= 1 || x2 >= w - 2)
+ xd2 = xd2 ? 0 : 1;
+ y2 = yd2 > 0 ? ++y2 : --y2;
+ if(y2 <= 1 || y2 >= h - 2)
+ yd2 = yd2 ? 0 : 1;
+
+ x3 = xd3 > 0 ? ++x3 : --x3;
+ if(x3 <= 1 || x3 >= w - 2)
+ xd3 = xd3 ? 0 : 1;
+ y3 = yd3 > 0 ? ++y3 : --y3;
+ if(y3 <= 1 || y3 >= h - 2)
+ yd3 = yd3 ? 0 : 1;
+
+ init_pair(8,COLOR_RED,COLOR_BLUE);
+ wattrset(win, COLOR_PAIR(8));
+ mvwaddch(win, y1, x1, 'O');
+ init_pair(8,COLOR_BLUE,COLOR_RED);
+ wattrset(win, COLOR_PAIR(8));
+ mvwaddch(win, y2, x2, '*');
+ init_pair(8,COLOR_YELLOW,COLOR_WHITE);
+ wattrset(win, COLOR_PAIR(8));
+ mvwaddch(win, y3, x3, '@');
+ wmove(win, 0, 0);
+ wrefresh(win);
+ delay_output(100);
+ }
+ return 0;
+}
+
+/*
+ * 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;
+ }
+}
+
+/*
+ * Trap interrupt
+ */
+static RETSIGTYPE trap(int sig GCC_UNUSED)
+{
+ endwin();
+ exit(EXIT_FAILURE);
+}
+
+/* End of DEMO.C */
diff --git a/contrib/ncurses/test/rain.c b/contrib/ncurses/test/rain.c
new file mode 100644
index 000000000000..4132a43826fe
--- /dev/null
+++ b/contrib/ncurses/test/rain.c
@@ -0,0 +1,131 @@
+/*
+ * $Id: rain.c,v 1.11 1997/09/18 18:36:46 tom Exp $
+ */
+#include <test.priv.h>
+
+#include <term.h> /* for tparm() */
+
+#include <signal.h>
+
+/* rain 11/3/1980 EPS/CITHEP */
+
+static float ranf(void);
+static void onsig(int sig);
+
+static int next_j(int j)
+{
+ if (j==0) j=4; else --j;
+ if (has_colors()) {
+ int z = (int)(3*ranf());
+ chtype color = COLOR_PAIR(z);
+ if (z)
+ color |= A_BOLD;
+ attrset(color);
+ }
+ return j;
+}
+
+int
+main(
+ int argc GCC_UNUSED,
+ char *argv[] GCC_UNUSED)
+{
+int x, y, j;
+static int xpos[5], ypos[5];
+float r;
+float c;
+
+ for (j=SIGHUP;j<=SIGTERM;j++)
+ if (signal(j,SIG_IGN)!=SIG_IGN) signal(j,onsig);
+
+ initscr();
+ if (has_colors()) {
+ int bg = COLOR_BLACK;
+ start_color();
+#ifdef NCURSES_VERSION
+ 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);
+
+ r = (float)(LINES - 4);
+ c = (float)(COLS - 4);
+ for (j=5;--j>=0;) {
+ xpos[j]=(int)(c* ranf())+2;
+ ypos[j]=(int)(r* ranf())+2;
+ }
+
+ for (j=0;;) {
+ x=(int)(c*ranf())+2;
+ y=(int)(r*ranf())+2;
+
+ mvaddch(y,x, '.');
+
+ mvaddch(ypos[j], xpos[j], 'o');
+
+ j = next_j(j);
+ mvaddch(ypos[j], xpos[j], 'O');
+
+ j = next_j(j);
+ mvaddch( ypos[j]-1, xpos[j], '-');
+ mvaddstr(ypos[j], xpos[j]-1, "|.|");
+ mvaddch( ypos[j]+1, xpos[j], '-');
+
+ j = next_j(j);
+ mvaddch( ypos[j]-2, xpos[j], '-');
+ mvaddstr(ypos[j]-1, xpos[j]-1, "/ \\");
+ mvaddstr(ypos[j], xpos[j]-2, "| O |");
+ mvaddstr(ypos[j]+1, xpos[j]-1, "\\ /");
+ mvaddch( ypos[j]+2, xpos[j], '-');
+
+ j = next_j(j);
+ mvaddch( ypos[j]-2, xpos[j], ' ');
+ mvaddstr(ypos[j]-1, xpos[j]-1, " ");
+ mvaddstr(ypos[j], xpos[j]-2, " ");
+ mvaddstr(ypos[j]+1, xpos[j]-1, " ");
+ mvaddch( ypos[j]+2, xpos[j], ' ');
+
+ xpos[j] = x; ypos[j] = y;
+
+ switch(getch())
+ {
+ case('q'):
+ case('Q'):
+ curs_set(1);
+ endwin();
+ return(EXIT_SUCCESS);
+#ifdef KEY_RESIZE
+ case(KEY_RESIZE):
+ r = (float)(LINES - 4);
+ c = (float)(COLS - 4);
+ break;
+#endif
+ }
+ napms(50);
+ }
+}
+
+static void
+onsig(int n GCC_UNUSED)
+{
+ curs_set(1);
+ endwin();
+ exit(EXIT_FAILURE);
+}
+
+static float
+ranf(void)
+{
+ float rv;
+ long r = rand();
+
+ r &= 077777;
+ rv =((float)r/32767.);
+ return rv;
+}
diff --git a/contrib/ncurses/test/tclock.c b/contrib/ncurses/test/tclock.c
new file mode 100644
index 000000000000..bccce31d1373
--- /dev/null
+++ b/contrib/ncurses/test/tclock.c
@@ -0,0 +1,184 @@
+#include "test.priv.h"
+
+#include <float.h>
+#include <math.h>
+#include <time.h>
+
+/*
+ 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 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;
+
+ 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 mradius, hradius, mangle, hangle;
+ double sangle, sradius, hours;
+ int hdx, hdy;
+ int mdx, mdy;
+ int sdx, sdy;
+ time_t tim;
+ struct tm *t;
+ char szChar[10];
+
+ initscr();
+ noecho();
+
+ cx=39;
+ cy=12;
+ mradius=9;
+ hradius=6;
+ sradius=8;
+
+ for(i=0;i<12;i++)
+ {
+ sangle=(i+1)*(2.0*PI)/12.0;
+ sradius=10;
+ sdx = A2X(sangle, sradius);
+ sdy = A2Y(sangle, sradius);
+ sprintf(szChar,"%d",i+1);
+
+ mvaddstr((int)(cy-sdy),(int)(cx+sdx),szChar);
+ }
+
+ mvaddstr(0,0,"ASCII Clock by Howard Jones (ha.jones@ic.ac.uk),1994");
+
+ sradius=8;
+ for(;;)
+ {
+ napms(1000);
+
+ 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) * (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);
+
+ sangle = ((t->tm_sec) * (2.0 * PI)/60.0);
+ sdx = A2X(sangle, sradius);
+ sdy = A2Y(sangle, sradius);
+
+ plot(cx+sdx,cy-sdy,'O');
+ dline(cx,cy,cx+hdx,cy-hdy,'.');
+ dline(cx,cy,cx+mdx,cy-mdy,'#');
+
+ mvaddstr(23,0,ctime(&tim));
+ refresh();
+ if ((t->tm_sec % 5) == 0) beep();
+
+ plot(cx+sdx,cy-sdy,' ');
+ dline(cx,cy,cx+hdx,cy-hdy,' ');
+ dline(cx,cy,cx+mdx,cy-mdy,' ');
+
+ }
+
+ return 0;
+}
diff --git a/contrib/ncurses/test/test.priv.h b/contrib/ncurses/test/test.priv.h
new file mode 100644
index 000000000000..0ae433195e42
--- /dev/null
+++ b/contrib/ncurses/test/test.priv.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * 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> 1996 *
+ ****************************************************************************/
+/* $Id: test.priv.h,v 1.15 1998/02/11 12:14:04 tom Exp $ */
+#if HAVE_CONFIG_H
+#include <ncurses_cfg.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <curses.h>
+
+#ifdef NCURSES_NOMACROS
+#include <nomacros.h>
+#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 */
+
+#ifndef GCC_NORETURN
+#define GCC_NORETURN /* nothing */
+#endif
+#ifndef GCC_UNUSED
+#define GCC_UNUSED /* nothing */
+#endif
+
+#define SIZEOF(table) (sizeof(table)/sizeof(table[0]))
+
+#if defined(NCURSES_VERSION) && HAVE_NC_ALLOC_H
+#include <nc_alloc.h>
+#endif
+
+#ifndef ExitProgram
+#define ExitProgram(code) return 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
diff --git a/contrib/ncurses/test/testaddch.c b/contrib/ncurses/test/testaddch.c
new file mode 100644
index 000000000000..444da0a14beb
--- /dev/null
+++ b/contrib/ncurses/test/testaddch.c
@@ -0,0 +1,60 @@
+/*
+ * 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.3 1997/10/18 21:35:15 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;
+
+ 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();
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/ncurses/test/testcurs.c b/contrib/ncurses/test/testcurs.c
new file mode 100644
index 000000000000..ff776570e2e8
--- /dev/null
+++ b/contrib/ncurses/test/testcurs.c
@@ -0,0 +1,640 @@
+/*
+ *
+ * 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.19 1999/02/14 00:42:28 tom Exp $
+ */
+
+#include <test.priv.h>
+#include <ctype.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;
+
+const COMMAND command[] =
+{
+ {"Intro 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 ((sizeof(command)/sizeof(command[0])))
+
+int width, height;
+
+int
+main(
+ int argc GCC_UNUSED,
+ char *argv[] GCC_UNUSED)
+{
+WINDOW *win;
+int key,old_option=(-1),new_option=0;
+bool quit=FALSE;
+
+#ifdef PDCDEBUG
+ PDC_debug("testcurs started\n");
+#endif
+ if (!initTest (&win)) return EXIT_FAILURE;
+
+#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
+
+ erase();
+ display_menu(old_option,new_option);
+ while(1)
+ {
+ noecho();
+ keypad(stdscr,TRUE);
+ raw();
+ key = getch();
+ 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: break;
+ }
+ if (quit == TRUE)
+ break;
+ }
+
+ delwin (win);
+
+ endwin();
+#ifdef XCURSES
+ XCursesExit();
+#endif
+ return EXIT_SUCCESS;
+}
+
+static
+void Continue (WINDOW *win)
+{
+ wmove(win, 10, 1);
+ wclrtoeol(win);
+ mvwaddstr(win, 10, 1, " Press any key to continue");
+ wrefresh(win);
+ raw();
+ wgetch(win);
+}
+
+static int
+initTest (WINDOW **win)
+{
+#ifdef PDCDEBUG
+ PDC_debug("initTest called\n");
+#endif
+#ifdef NCURSES_VERSION
+ 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 OldX, OldY;
+ NCURSES_CONST char *Message = "The window will now scroll slowly";
+
+ wclear(win);
+ mvwprintw (win, height - 2, 1, Message);
+ wrefresh (win);
+ scrollok(win, TRUE);
+ for (i = 1; i <= height; i++) {
+ napms(250);
+ scroll(win);
+ wrefresh (win);
+ }
+
+ getmaxyx (win, OldY, OldX);
+ mvwprintw (win, 6, 1, "The top of the window will scroll");
+ wmove (win, 1, 1);
+ wsetscrreg (win, 0, 4);
+ box(win, ACS_VLINE, ACS_HLINE);
+ wrefresh (win);
+ for (i = 1; i <= 5; i++) {
+ napms(500);
+ scroll(win);
+ wrefresh (win);
+ }
+
+ mvwprintw (win, 3, 1, "The bottom of the window will scroll");
+ wmove (win, 8, 1);
+ wsetscrreg (win, 5, --OldY);
+ box(win, ACS_VLINE, ACS_HLINE);
+ wrefresh (win);
+ for (i = 5; i <= OldY; i++) {
+ napms (300);
+ wscrl(win,-1);
+ wrefresh (win);
+ }
+ wsetscrreg (win, 0, OldY);
+
+}
+
+static void
+inputTest (WINDOW *win)
+{
+ 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();
+ typeahead(-1);
+#if defined(PDCURSES)
+ mouse_set(ALL_MOUSE_EVENTS);
+#endif
+ while(1) {
+ 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(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();
+ 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");
+ mvwaddstr(win, 6, 2, "Enter a number then a string separated by space");
+ mvwin(win, 2, 1);
+ wrefresh(win);
+ echo();
+ noraw();
+ num = 0;
+ *buffer = 0;
+ mvwscanw(win, 7, 6, "%d %s", &num,buffer);
+ mvwprintw(win, 8, 6, "String: %s Number: %d", buffer,num);
+ Continue(win);
+}
+
+static void
+outputTest (WINDOW *win)
+{
+ WINDOW *win1;
+ char Buffer [80];
+ chtype ch;
+ int by, bx;
+
+ 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);
+
+ mvwinsstr( win, 6, 2, "A1B2C3D4E5" );
+ Continue(win);
+
+ 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") != 0) {
+ wclear(win);
+ curs_set(2);
+ mvwaddstr(win, 1, 1, "The cursor should appear as a block (visible)");
+ Continue(win);
+ }
+
+ if (tigetstr("civis") != 0) {
+ wclear(win);
+ curs_set(0);
+ mvwaddstr(win, 1, 1, "The cursor should have disappeared (invisible)");
+ Continue(win);
+ }
+
+ if (tigetstr("cnorm") != 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);
+ 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.");
+
+ 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;
+
+ pad = newpad(50,100);
+ 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)
+{
+ register size_t i;
+
+ attrset(A_NORMAL);
+ mvaddstr(3,20,"PDCurses Test Program");
+
+ for (i=0;i<MAX_OPTIONS;i++)
+ mvaddstr(5+i,25,command[i].text);
+ if (old_option != (-1))
+ 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/contrib/ncurses/test/testscanw.c b/contrib/ncurses/test/testscanw.c
new file mode 100644
index 000000000000..8420ea0fc55a
--- /dev/null
+++ b/contrib/ncurses/test/testscanw.c
@@ -0,0 +1,38 @@
+/* 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.5 1997/09/20 14:16:20 tom Exp $
+ */
+#include <test.priv.h>
+#include <ctype.h>
+
+int main(int argc, char *argv[])
+{
+ long badanswer = 1;
+ long *response = &badanswer;
+
+ initscr();
+ scrollok(stdscr, TRUE);
+ idlok(stdscr, TRUE);
+ echo();
+
+#if 0
+ trace(TRACE_UPDATE|TRACE_CALLS);
+#endif
+ while (argc > 1) {
+ if (isdigit(*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();
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/ncurses/test/tracemunch b/contrib/ncurses/test/tracemunch
new file mode 100755
index 000000000000..d6761cd04219
--- /dev/null
+++ b/contrib/ncurses/test/tracemunch
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+#
+# 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.
+#
+# ($Id: tracemunch,v 1.2 1995/10/06 15:02:37 esr Exp $)
+
+$putattr="PutAttrChar\\('(.)' = 0x.., {A_NORMAL}\\) at \\(([0-9]+), ([0-9]+)\\)";
+$waddnstr="waddnstr\\(0x([0-9a-f]+),\"([^\"]+)\",[0-9]+\\) called {A_NORMAL}";
+
+sub transaddr
+{
+ $arg = $_[0];
+
+ $arg =~ s/$curscr/curscr/ if ($curscr);
+ $arg =~ s/$newscr/newscr/ if ($newscr);
+ $arg =~ s/$stdscr/stdscr/ if ($stdscr);
+
+ return $arg;
+}
+
+while (<STDIN>)
+{
+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 ($awaiting && $_ =~ /newwin: returned window is 0x([0-9a-f]+)/)
+ {
+ $curscr = "0x$1" if ($awaiting eq "curscr");
+ $newscr = "0x$1" if ($awaiting eq "newscr");
+ $stdscr = "0x$1" if ($awaiting eq "stdscr");
+ $awaiting = "";
+ }
+
+ # Compactify runs of PutAttrChar calls (TR_CHARPUT)
+ if ($_ =~ /$putattr/)
+ {
+ $putattr_chars = $1;
+ $starty = $2;
+ $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/)
+ {
+ $waddnstr_chars = $2;
+ $winaddr = $1;
+ while (<STDIN>)
+ {
+ if ($_ =~ /$waddnstr/ && $1 eq $winaddr) {
+ $waddnstr_chars .= $2;
+ } else {
+ last;
+ }
+ }
+ $winaddstr = &transaddr($winaddr);
+ print "RUN of waddnstr()s: $winaddr, \"$waddnstr_chars\"\n";
+ redo CLASSIFY;
+ }
+
+ # More transformations can go here
+
+ # Repeated runs of anything
+ $anyline = &transaddr($_);
+ $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/contrib/ncurses/test/view.c b/contrib/ncurses/test/view.c
new file mode 100644
index 000000000000..8381dc8898c4
--- /dev/null
+++ b/contrib/ncurses/test/view.c
@@ -0,0 +1,362 @@
+/*
+ * 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()'.
+ *
+ * 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.27 1998/08/22 18:33:41 tom Exp $
+ */
+
+#include <test.priv.h>
+
+#include <string.h>
+#include <ctype.h>
+#include <signal.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
+
+/* This is needed to compile 'struct winsize' */
+#if NEED_PTEM_H
+#include <sys/stream.h>
+#include <sys/ptem.h>
+#endif
+
+static RETSIGTYPE finish(int sig) GCC_NORETURN;
+static void show_all(void);
+
+#if defined(SIGWINCH) && defined(TIOCGWINSZ) && defined(NCURSES_VERSION)
+#define CAN_RESIZE 1
+#else
+#define CAN_RESIZE 0
+#endif
+
+#if CAN_RESIZE
+static RETSIGTYPE adjust(int sig);
+static int interrupted;
+#endif
+
+static int waiting;
+static int shift;
+
+static char *fname;
+static char **lines;
+static char **lptr;
+
+#if !HAVE_STRDUP
+#define strdup my_strdup
+static char *strdup (char *s)
+{
+ char *p;
+
+ p = malloc(strlen(s)+1);
+ if (p)
+ strcpy(p,s);
+ return(p);
+}
+#endif /* not HAVE_STRDUP */
+
+static void usage(void)
+{
+ static const char *msg[] = {
+ "Usage: view [options] file"
+ ,""
+ ,"Options:"
+ ," -n NUM specify maximum number of lines (default 1000)"
+#if defined(KEY_RESIZE)
+ ," -r use experimental KEY_RESIZE rather than our own handler"
+#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]);
+ exit (EXIT_FAILURE);
+}
+
+int main(int argc, char *argv[])
+{
+int MAXLINES = 1000;
+FILE *fp;
+char buf[BUFSIZ];
+int i;
+char **olptr;
+int done = FALSE;
+int length = 0;
+#if CAN_RESIZE
+bool use_resize = TRUE;
+#endif
+
+ while ((i = getopt(argc, argv, "n:rtT:")) != EOF) {
+ switch (i) {
+ case 'n':
+ if ((MAXLINES = atoi(optarg)) < 1)
+ usage();
+ break;
+#if CAN_RESIZE
+ case 'r':
+ use_resize = FALSE;
+ break;
+#endif
+#ifdef TRACE
+ case 'T':
+ trace(atoi(optarg));
+ break;
+ case 't':
+ trace(TRACE_CALLS);
+ break;
+#endif
+ default:
+ usage();
+ }
+ }
+ if (optind + 1 != argc)
+ usage();
+
+ if ((lines = (char **)calloc(MAXLINES+2, sizeof(*lines))) == 0)
+ usage();
+
+ fname = argv[optind];
+ if ((fp = fopen(fname, "r")) == 0) {
+ perror(fname);
+ return EXIT_FAILURE;
+ }
+
+ (void) signal(SIGINT, finish); /* arrange interrupts to terminate */
+#if CAN_RESIZE
+ if (use_resize)
+ (void) signal(SIGWINCH, adjust); /* arrange interrupts to resize */
+#endif
+
+ /* slurp the file */
+ for (lptr = &lines[0]; (lptr - 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 (isprint(*d)) {
+ col++;
+ d++;
+ } else {
+ sprintf(d, "\\%03o", *s & 0xff);
+ d += strlen(d);
+ col = (d - temp);
+ }
+ }
+ *lptr = strdup(temp);
+ }
+ (void) fclose(fp);
+ length = lptr - 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 */
+ idlok(stdscr, TRUE); /* allow use of insert/delete line */
+
+ lptr = lines;
+ while (!done) {
+ int n, c;
+ bool got_number;
+
+ show_all();
+
+ got_number = FALSE;
+ n = 0;
+ for (;;) {
+#if CAN_RESIZE
+ if (interrupted)
+ adjust(0);
+#endif
+ waiting = TRUE;
+ c = getch();
+ waiting = FALSE;
+ if ((c < 127) && isdigit(c)) {
+ if (!got_number) {
+ mvprintw(0,0, "Count: ");
+ clrtoeol();
+ }
+ addch(c);
+ n = 10 * n + (c - '0');
+ got_number = TRUE;
+ }
+ else
+ break;
+ }
+ if (!got_number && n == 0)
+ n = 1;
+
+ switch(c) {
+ case KEY_DOWN:
+ case 'n':
+ olptr = lptr;
+ for (i = 0; i < n; i++)
+ if ((lptr - lines) < (length - LINES + 1))
+ lptr++;
+ else
+ break;
+ wscrl(stdscr, lptr - olptr);
+ break;
+
+ case KEY_UP:
+ case 'p':
+ olptr = lptr;
+ for (i = 0; i < n; i++)
+ if (lptr > lines)
+ lptr--;
+ else
+ break;
+ wscrl(stdscr, lptr - olptr);
+ break;
+
+ case 'h':
+ case KEY_HOME:
+ lptr = lines;
+ break;
+
+ case 'e':
+ case KEY_END:
+ if (length > LINES)
+ lptr = lines + length - LINES + 1;
+ else
+ lptr = lines;
+ break;
+
+ case 'r':
+ case KEY_RIGHT:
+ shift++;
+ break;
+
+ case 'l':
+ case KEY_LEFT:
+ if (shift)
+ shift--;
+ else
+ beep();
+ break;
+
+ case 'q':
+ done = TRUE;
+ break;
+
+#ifdef KEY_RESIZE
+ case KEY_RESIZE: /* ignore this; ncurses will repaint */
+ break;
+#endif
+#if CAN_RESIZE
+ case ERR:
+ break;
+#endif
+ default:
+ beep();
+ }
+ }
+
+ finish(0); /* we're done */
+}
+
+static RETSIGTYPE finish(int sig)
+{
+ endwin();
+ exit(sig != 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+#if CAN_RESIZE
+/*
+ * This uses functions that are "unsafe", but it seems to work on SunOS and
+ * Linux. 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) {
+ resizeterm(size.ws_row, size.ws_col);
+ wrefresh(curscr); /* Linux needs this */
+ show_all();
+ }
+ interrupted = FALSE;
+ } else {
+ interrupted = TRUE;
+ }
+ (void) signal(SIGWINCH, adjust); /* some systems need this */
+}
+#endif /* CAN_RESIZE */
+
+static void show_all(void)
+{
+ int i;
+ char temp[BUFSIZ];
+ char *s;
+
+#if CAN_RESIZE
+ sprintf(temp, "(%3dx%3d) col %d ", LINES, COLS, shift);
+ i = strlen(temp);
+ sprintf(temp+i, "view %.*s", (int)(sizeof(temp)-7-i), fname);
+#else
+ sprintf(temp, "view %.*s", (int)sizeof(temp)-7, fname);
+#endif
+ move(0,0);
+ printw("%.*s", COLS, temp);
+ clrtoeol();
+
+ scrollok(stdscr, FALSE); /* prevent screen from moving */
+ for (i = 1; i < LINES; i++) {
+ move(i, 0);
+ if ((s = lptr[i-1]) != 0 && (int)strlen(s) > shift)
+ printw("%3ld:%.*s", (long) (lptr+i-lines), COLS-4, s + shift);
+ else
+ printw("%3ld:", (long) (lptr+i-lines));
+ clrtoeol();
+ }
+ setscrreg(1, LINES-1);
+ scrollok(stdscr, TRUE);
+ refresh();
+}
+
+/* view.c ends here */
+
diff --git a/contrib/ncurses/test/worm.c b/contrib/ncurses/test/worm.c
new file mode 100644
index 000000000000..a02113b370f0
--- /dev/null
+++ b/contrib/ncurses/test/worm.c
@@ -0,0 +1,372 @@
+/*
+
+ @@@ @@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
+ @@@ @@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@
+ @@@ @@@ @@@@ @@@@ @@@@ @@@@ @@@ @@@@
+ @@@ @@ @@@ @@@ @@@ @@@ @@@ @@@ @@@
+ @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@
+ @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@
+ @@@@@@@@@@@@ @@@@ @@@@ @@@ @@@ @@@ @@@
+ @@@@ @@@@ @@@@@@@@@@@@ @@@ @@@ @@@ @@@
+ @@ @@ @@@@@@@@@@ @@@ @@@ @@@ @@@
+
+ 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.23 1999/03/06 22:52:04 tom Exp $
+*/
+
+#include <test.priv.h>
+
+#include <term.h> /* for tparm() */
+
+#include <signal.h>
+
+#define cursor(col,row) move(row,col)
+
+short *ref[128];
+static chtype flavor[]={
+ 'O' , '*', '#', '$', '%', '0', '@',
+};
+#define MAXWORMS (sizeof(flavor)/sizeof(chtype))
+static const short xinc[]={
+ 1, 1, 1, 0, -1, -1, -1, 0
+}, yinc[]={
+ -1, 0, 1, 1, 1, 0, -1, -1
+};
+static struct worm {
+ int orientation, head;
+ short *xpos, *ypos;
+} worm[40];
+
+static const char *field;
+static int length=16, number=3;
+static chtype trail=' ';
+
+#ifdef TRACE
+int generation, trace_start, trace_end, singlestep;
+#endif /* TRACE */
+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 } }
+};
+
+static RETSIGTYPE onsig(int sig);
+static float ranf(void);
+
+int
+main(int argc, char *argv[])
+{
+int x, y;
+int n;
+struct worm *w;
+const struct options *op;
+int h;
+short *ip;
+int last, bottom;
+
+ for (x=1;x<argc;x++) {
+ register 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>1024) {
+ fprintf(stderr,"%s: Invalid length\n",*argv);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 'n':
+ if (++x==argc) goto usage;
+ if ((number=atoi(argv[x]))<1||number>40) {
+ fprintf(stderr,"%s: Invalid number of worms\n",*argv);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 't':
+ trail='.';
+ break;
+#ifdef TRACE
+ case 'S':
+ singlestep = TRUE;
+ break;
+ 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);
+ return EXIT_FAILURE;
+ }
+ }
+
+ signal(SIGINT, onsig);
+ initscr();
+ noecho();
+ cbreak();
+ nonl();
+
+ curs_set(0);
+
+ bottom = LINES-1;
+ last = COLS-1;
+
+#ifdef A_COLOR
+ if (has_colors())
+ {
+ int bg = COLOR_BLACK;
+ start_color();
+#ifdef NCURSES_VERSION
+ if (use_default_colors() == OK)
+ bg = -1;
+#endif
+
+ init_pair(COLOR_GREEN, COLOR_GREEN, bg);
+ init_pair(COLOR_RED, COLOR_RED, bg);
+ init_pair(COLOR_CYAN, COLOR_CYAN, bg);
+ init_pair(COLOR_WHITE, COLOR_WHITE, bg);
+ init_pair(COLOR_MAGENTA, COLOR_MAGENTA, bg);
+ init_pair(COLOR_BLUE, COLOR_BLUE, bg);
+ init_pair(COLOR_YELLOW, COLOR_YELLOW, bg);
+
+ flavor[0] |= COLOR_PAIR(COLOR_GREEN) | A_BOLD;
+ flavor[1] |= COLOR_PAIR(COLOR_RED) | A_BOLD;
+ flavor[2] |= COLOR_PAIR(COLOR_CYAN) | A_BOLD;
+ flavor[3] |= COLOR_PAIR(COLOR_WHITE) | A_BOLD;
+ flavor[4] |= COLOR_PAIR(COLOR_MAGENTA) | A_BOLD;
+ flavor[5] |= COLOR_PAIR(COLOR_BLUE) | A_BOLD;
+ flavor[6] |= COLOR_PAIR(COLOR_YELLOW) | A_BOLD;
+ }
+#endif /* A_COLOR */
+
+ ip=(short *)malloc(LINES*COLS*sizeof (short));
+
+ for (n=0;n<LINES;) {
+ ref[n++]=ip; ip+=COLS;
+ }
+ for (ip=ref[0],n=LINES*COLS;--n>=0;) *ip++=0;
+
+#ifdef BADCORNER
+ /* if addressing the lower right corner doesn't work in your curses */
+ ref[bottom][last]=1;
+#endif /* BADCORNER */
+
+ for (n=number, w= &worm[0];--n>=0;w++) {
+ w->orientation=w->head=0;
+ if (!(ip=(short *)malloc((length+1)*sizeof (short)))) {
+ fprintf(stderr,"%s: out of memory\n",*argv);
+ return EXIT_FAILURE;
+ }
+ w->xpos=ip;
+ for (x=length;--x>=0;) *ip++ = -1;
+ if (!(ip=(short *)malloc((length+1)*sizeof (short)))) {
+ fprintf(stderr,"%s: out of memory\n",*argv);
+ return EXIT_FAILURE;
+ }
+ w->ypos=ip;
+ for (y=length;--y>=0;) *ip++ = -1;
+ }
+ if (field) {
+ register const char *p;
+ p=field;
+ for (y=bottom;--y>=0;) {
+ for (x=COLS;--x>=0;) {
+ addch((chtype)(*p++));
+ if (!*p) p=field;
+ }
+ addch('\n');
+ }
+ }
+ napms(10);
+ refresh();
+
+ for (;;) {
+#ifdef TRACE
+ if (trace_start || trace_end) {
+ if (generation == trace_start) {
+ trace(TRACE_CALLS);
+ getch();
+ } else if (generation == trace_end) {
+ trace(0);
+ getch();
+ }
+
+ if (singlestep && generation > trace_start && generation < trace_end)
+ getch();
+
+ generation++;
+ }
+#endif /* TRACE */
+
+ for (n=0,w= &worm[0];n<number;n++,w++) {
+ if ((x=w->xpos[h=w->head])<0) {
+ cursor(x=w->xpos[h]=0,y=w->ypos[h]=bottom);
+ addch(flavor[n % MAXWORMS]);
+ ref[y][x]++;
+ }
+ else y=w->ypos[h];
+ if (++h==length) h=0;
+ if (w->xpos[w->head=h]>=0) {
+ register int x1, y1;
+ x1=w->xpos[h]; y1=w->ypos[h];
+ if (--ref[y1][x1]==0) {
+ cursor(x1,y1); addch(trail);
+ }
+ }
+ op= &(x==0 ? (y==0 ? upleft : (y==bottom ? lowleft : left)) :
+ (x==last ? (y==0 ? upright : (y==bottom ? lowright : right)) :
+ (y==0 ? upper : (y==bottom ? lower : normal))))[w->orientation];
+ switch (op->nopts) {
+ case 0:
+ refresh();
+ curs_set(1);
+ endwin();
+ return EXIT_SUCCESS;
+ case 1:
+ w->orientation=op->opts[0];
+ break;
+ default:
+ w->orientation=op->opts[(int)(ranf()*(float)op->nopts)];
+ }
+ cursor(x+=xinc[w->orientation], y+=yinc[w->orientation]);
+
+ if (y < 0 ) y = 0;
+ addch(flavor[n % MAXWORMS]);
+ ref[w->ypos[h]=y][w->xpos[h]=x]++;
+ }
+ napms(10);
+ refresh();
+ }
+}
+
+static RETSIGTYPE
+onsig(int sig GCC_UNUSED)
+{
+ standend();
+ refresh();
+ curs_set(1);
+ endwin();
+ exit(EXIT_FAILURE);
+}
+
+static float
+ranf(void)
+{
+float rv;
+long r = rand();
+
+ r &= 077777;
+ rv =((float)r/32767.);
+ return rv;
+}
diff --git a/contrib/ncurses/test/xmas.c b/contrib/ncurses/test/xmas.c
new file mode 100644
index 000000000000..3923c771d97a
--- /dev/null
+++ b/contrib/ncurses/test/xmas.c
@@ -0,0 +1,1148 @@
+/******************************************************************************/
+/* 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.12 1998/01/18 01:13:47 tom Exp $
+ */
+#include <test.priv.h>
+
+#include <signal.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, *treescrn2,*treescrn3, *treescrn4,*treescrn5, *treescrn6,
+ *treescrn7, *treescrn8,
+ *dotdeer0,
+ *stardeer0,
+ *lildeer0, *lildeer1, *lildeer2, *lildeer3,
+ *middeer0, *middeer1, *middeer2, *middeer3,
+ *bigdeer0, *bigdeer1, *bigdeer2, *bigdeer3, *bigdeer4,
+ *lookdeer0, *lookdeer1, *lookdeer2, *lookdeer3, *lookdeer4,
+ *w_holiday,
+ *w_del_msg;
+
+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()) {
+ static bool *pairs;
+ int n = (color + 1);
+ if (pairs == 0)
+ pairs = (bool *)calloc(COLORS+1, sizeof(bool));
+ if (!pairs[n]) {
+ init_pair(n, color, my_bg);
+ 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;
+
+ initscr();
+ noecho();
+ nonl();
+ refresh();
+ signal(SIGINT,done);
+ signal(SIGTERM,done);
+#if !defined DOS && !defined OS2
+ signal(SIGHUP,done);
+ signal(SIGQUIT,done);
+#endif
+ if (has_colors()) {
+ start_color();
+#ifdef NCURSES_VERSION
+ if (use_default_colors() == OK)
+ my_bg = -1;
+#endif
+ }
+ curs_set(0);
+
+ treescrn = newwin(16,27,3,53);
+ treescrn2 = newwin(16,27,3,53);
+ treescrn3 = newwin(16,27,3,53);
+ treescrn4 = newwin(16,27,3,53);
+ treescrn5 = newwin(16,27,3,53);
+ treescrn6 = newwin(16,27,3,53);
+ treescrn7 = newwin(16,27,3,53);
+ treescrn8 = newwin(16,27,3,53);
+
+ dotdeer0 = newwin(3,71,0,8);
+
+ stardeer0 = newwin(4,56,0,8);
+
+ lildeer0 = newwin(7,53,0,8);
+ lildeer1 = newwin(2,4,0,0);
+ lildeer2 = newwin(2,4,0,0);
+ lildeer3 = newwin(2,4,0,0);
+
+ middeer0 = newwin(15,42,0,8);
+ middeer1 = newwin(3,7,0,0);
+ middeer2 = newwin(3,7,0,0);
+ middeer3 = newwin(3,7,0,0);
+
+ bigdeer0 = newwin(10,23,0,0);
+ bigdeer1 = newwin(10,23,0,0);
+ bigdeer2 = newwin(10,23,0,0);
+ bigdeer3 = newwin(10,23,0,0);
+ bigdeer4 = newwin(10,23,0,0);
+
+ lookdeer0 = newwin(10,25,0,0);
+ lookdeer1 = newwin(10,25,0,0);
+ lookdeer2 = newwin(10,25,0,0);
+ lookdeer3 = newwin(10,25,0,0);
+ lookdeer4 = newwin(10,25,0,0);
+
+ w_holiday = newwin(1,26,3,27);
+
+ w_del_msg = newwin(1,19,23,60);
+
+ 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)
+{
+ signal(SIGINT,done);
+ signal(SIGTERM,done);
+#if !defined DOS && !defined OS2
+ signal(SIGHUP,done);
+ signal(SIGQUIT,done);
+#endif
+ move(LINES-1,0);
+ refresh();
+ endwin();
+ curs_set(1);
+ exit(EXIT_SUCCESS);
+}