diff options
Diffstat (limited to 'ncurses-5.3/test')
36 files changed, 16325 insertions, 0 deletions
diff --git a/ncurses-5.3/test/Makefile.in b/ncurses-5.3/test/Makefile.in new file mode 100644 index 0000000..2ce2321 --- /dev/null +++ b/ncurses-5.3/test/Makefile.in @@ -0,0 +1,221 @@ +# $Id$ +############################################################################## +# Copyright (c) 1998,1999,2000,2001 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@ + +LIBTOOL = @LIBTOOL@ + +CC = @CC@ +CPP = @CPP@ + +CFLAGS = @CFLAGS@ +CPPFLAGS = -I../test -I$(srcdir) @CPPFLAGS@ -DHAVE_CONFIG_H + +CCFLAGS = $(CPPFLAGS) $(CFLAGS) + +CFLAGS_LIBTOOL = $(CCFLAGS) +CFLAGS_NORMAL = $(CCFLAGS) +CFLAGS_DEBUG = $(CCFLAGS) @CC_G_OPT@ -DTRACE +CFLAGS_PROFILE = $(CCFLAGS) -pg +CFLAGS_SHARED = $(CCFLAGS) @CC_SHARED_OPTS@ + +CFLAGS_DEFAULT = $(CFLAGS_@DFT_UPR_MODEL@) + +REL_VERSION = @cf_cv_rel_version@ +ABI_VERSION = @cf_cv_abi_version@ +LOCAL_LIBS = @TEST_DEPS@ +MATH_LIB = @MATH_LIB@ + +LD = @LD@ +LINK = @LINK_TESTS@ $(LIBTOOL) $(CC) $(CFLAGS) + +LDFLAGS = @LD_MODEL@ @TEST_ARGS@ @LIBS@ @EXTRA_LIBS@ @LOCAL_LDFLAGS@ @LDFLAGS@ + +LDFLAGS_LIBTOOL = $(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 \ + dots$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 \ + railroad$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) + +dots$x: $(MODEL)/dots.o $(LOCAL_LIBS) + @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/dots.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) + +railroad$x: $(MODEL)/railroad.o $(LOCAL_LIBS) + @ECHO_LINK@ $(LINK) -o $@ $(MODEL)/railroad.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) + +libs \ +install \ +install.libs \ +install.test: + +uninstall: +uninstall.libs: +uninstall.test: + +mostlyclean :: + -rm -f core tags TAGS *~ *.bak *.i *.ln *.atac trace + +clean :: mostlyclean + -rm -rf *.o screendump *.lis $(TESTS) .libs + +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/ncurses-5.3/test/README b/ncurses-5.3/test/README new file mode 100644 index 0000000..cd1767a --- /dev/null +++ b/ncurses-5.3/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/ncurses-5.3/test/blue.c b/ncurses-5.3/test/blue.c new file mode 100644 index 0000000..3af4bfa --- /dev/null +++ b/ncurses-5.3/test/blue.c @@ -0,0 +1,432 @@ +/***************************************************************************** + * * + * 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$ + */ + +#include <time.h> + +#include <test.priv.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(); + ExitProgram(EXIT_SUCCESS); +} + +static void +init_vars(void) +{ + int i; + + deck_size = PACK_SIZE; + for (i = 0; i < PACK_SIZE; i++) + deck[i] = i; + for (i = 0; i < 4; i++) + freeptr[i] = i * GRID_WIDTH; +} + +static void +shuffle(int size) +{ + int i, j, numswaps, swapnum, temp; + + numswaps = size * 10; /* an arbitrary figure */ + + for (swapnum = 0; swapnum < numswaps; swapnum++) { + i = rand() % size; + j = rand() % size; + temp = deck[i]; + deck[i] = deck[j]; + deck[j] = temp; + } +} + +static void +deal_cards(void) +{ + int ptr, card = 0, value, csuit, crank, suit, aces[4]; + + 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); + + setlocale(LC_ALL, ""); + + initscr(); + + /* + * We use COLOR_GREEN because COLOR_BLACK is wired to the wrong thing. + */ + start_color(); + init_pair(RED_ON_WHITE, COLOR_RED, COLOR_WHITE); + init_pair(BLUE_ON_WHITE, COLOR_BLUE, COLOR_WHITE); + init_pair(BLACK_ON_WHITE, COLOR_BLACK, COLOR_WHITE); + +#ifndef COLOR_PAIR + letters[0] = OR_COLORS('h', RED_ON_WHITE); /* hearts */ + letters[1] = OR_COLORS('s', BLACK_ON_WHITE); /* spades */ + letters[2] = OR_COLORS('d', RED_ON_WHITE); /* diamonds */ + letters[3] = OR_COLORS('c', BLACK_ON_WHITE); /* clubs */ +#if 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/ncurses-5.3/test/bs.6 b/ncurses-5.3/test/bs.6 new file mode 100644 index 0000000..38cfe82 --- /dev/null +++ b/ncurses-5.3/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/ncurses-5.3/test/bs.c b/ncurses-5.3/test/bs.c new file mode 100644 index 0000000..17e1444 --- /dev/null +++ b/ncurses-5.3/test/bs.c @@ -0,0 +1,1228 @@ +/* + * 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$ + */ + +#include <ctype.h> +#include <assert.h> +#include <time.h> + +#include <test.priv.h> + +#ifndef SIGIOT +#define SIGIOT SIGABRT +#endif + +static int getcoord(int); + +/* + * Constants for tuning the random-fire algorithm. It prefers moves that + * diagonal-stripe the board with a stripe separation of srchstep. If + * no such preferred moves are found, srchstep is decremented. + */ +#define BEGINSTEP 3 /* initial value of srchstep */ + +/* miscellaneous constants */ +#define SHIPTYPES 5 +#define OTHER (1-turn) +#define PLAYER 0 +#define COMPUTER 1 +#define MARK_HIT 'H' +#define MARK_MISS 'o' +#define CTRLC '\003' /* used as terminate command */ +#define FF '\014' /* used as redraw command */ + +/* coordinate handling */ +#define BWIDTH 10 +#define BDEPTH 10 + +/* display symbols */ +#define SHOWHIT '*' +#define SHOWSPLASH ' ' +#define IS_SHIP(c) (isupper(UChar(c)) ? TRUE : FALSE) + +/* how to position us on player board */ +#define PYBASE 3 +#define PXBASE 3 +#define PY(y) (PYBASE + (y)) +#define PX(x) (PXBASE + (x)*3) +#define pgoto(y, x) (void)move(PY(y), PX(x)) + +/* how to position us on cpu board */ +#define CYBASE 3 +#define CXBASE 48 +#define CY(y) (CYBASE + (y)) +#define CX(x) (CXBASE + (x)*3) +#define CYINV(y) ((y) - CYBASE) +#define CXINV(x) (((x) - CXBASE) / 3) +#define cgoto(y, x) (void)move(CY(y), CX(x)) + +#define ONBOARD(x, y) (x >= 0 && x < BWIDTH && y >= 0 && y < BDEPTH) + +/* other board locations */ +#define COLWIDTH 80 +#define PROMPTLINE 21 /* prompt line */ +#define SYBASE CYBASE + BDEPTH + 3 /* move key diagram */ +#define SXBASE 63 +#define MYBASE SYBASE - 1 /* diagram caption */ +#define MXBASE 64 +#define HYBASE SYBASE - 1 /* help area */ +#define HXBASE 0 + +/* this will need to be changed if BWIDTH changes */ +static char numbers[] = " 0 1 2 3 4 5 6 7 8 9"; + +static char carrier[] = "Aircraft Carrier"; +static char battle[] = "Battleship"; +static char sub[] = "Submarine"; +static char destroy[] = "Destroyer"; +static char ptboat[] = "PT Boat"; + +static char name[40]; +static char dftname[] = "stranger"; + +/* direction constants */ +#define E 0 +#define SE 1 +#define S 2 +#define SW 3 +#define W 4 +#define NW 5 +#define N 6 +#define NE 7 +static int xincr[8] = +{1, 1, 0, -1, -1, -1, 0, 1}; +static int yincr[8] = +{0, 1, 1, 1, 0, -1, -1, -1}; + +/* current ship position and direction */ +static int curx = (BWIDTH / 2); +static int cury = (BDEPTH / 2); + +typedef struct { + char *name; /* name of the ship type */ + int hits; /* how many times has this ship been hit? */ + char symbol; /* symbol for game purposes */ + int length; /* length of ship */ + int x, y; /* coordinates of ship start point */ + int dir; /* direction of `bow' */ + bool placed; /* has it been placed on the board? */ +} ship_t; + +static bool checkplace(int b, ship_t * ss, int vis); + +#define SHIPIT(name, symbol, length) { name, 0, symbol, length, 0,0, 0, FALSE } + +static ship_t plyship[SHIPTYPES] = +{ + SHIPIT(carrier, 'A', 5), + SHIPIT(battle, 'B', 4), + SHIPIT(destroy, 'D', 3), + SHIPIT(sub, 'S', 3), + SHIPIT(ptboat, 'P', 2), +}; + +static ship_t cpuship[SHIPTYPES] = +{ + SHIPIT(carrier, 'A', 5), + SHIPIT(battle, 'B', 4), + SHIPIT(destroy, 'D', 3), + SHIPIT(sub, 'S', 3), + SHIPIT(ptboat, 'P', 2), +}; + +/* "Hits" board, and main board. */ +static char hits[2][BWIDTH][BDEPTH]; +static char board[2][BWIDTH][BDEPTH]; + +static int turn; /* 0=player, 1=computer */ +static int plywon = 0, cpuwon = 0; /* How many games has each won? */ + +static int salvo, blitz, closepack; + +#define PR (void)addstr + +static RETSIGTYPE uninitgame(int sig) GCC_NORETURN; + +static RETSIGTYPE uninitgame(int sig GCC_UNUSED) +/* end the game, either normally or due to signal */ +{ + clear(); + (void) refresh(); + (void) reset_shell_mode(); + (void) echo(); + (void) endwin(); + ExitProgram(sig ? EXIT_FAILURE : EXIT_SUCCESS); +} + +static void +announceopts(void) +/* announce which game options are enabled */ +{ + if (salvo || blitz || closepack) { + (void) printw("Playing optional game ("); + if (salvo) + (void) printw("salvo, "); + else + (void) printw("nosalvo, "); + if (blitz) + (void) printw("blitz "); + else + (void) printw("noblitz, "); + if (closepack) + (void) printw("closepack)"); + else + (void) printw("noclosepack)"); + } else + (void) printw( + "Playing standard game (noblitz, nosalvo, noclosepack)"); +} + +static void +intro(void) +{ + char *tmpname; + + srand((unsigned) (time(0L) + getpid())); /* Kick the random number generator */ + + (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(); + keypad(stdscr, TRUE); + (void) def_prog_mode(); + (void) nonl(); + (void) cbreak(); + (void) noecho(); + +#ifdef PENGUIN + (void) clear(); + (void) mvaddstr(4, 29, "Welcome to Battleship!"); + (void) move(8, 0); + PR(" \\\n"); + PR(" \\ \\ \\\n"); + PR(" \\ \\ \\ \\ \\_____________\n"); + PR(" \\ \\ \\_____________ \\ \\/ |\n"); + PR(" \\ \\/ \\ \\/ |\n"); + PR(" \\/ \\_____/ |__\n"); + PR(" ________________/ |\n"); + PR(" \\ S.S. Penguin |\n"); + PR(" \\ /\n"); + PR(" \\___________________________________________________/\n"); + + (void) mvaddstr(22, 27, "Hit any key to continue..."); + (void) refresh(); + (void) getch(); +#endif /* PENGUIN */ + +#ifdef A_COLOR + start_color(); + + init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK); + init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK); + init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK); + init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK); + init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK); + init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); + init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK); + init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK); +#endif /* A_COLOR */ + +#ifdef NCURSES_MOUSE_VERSION + (void) mousemask(BUTTON1_CLICKED, (mmask_t *) NULL); +#endif /* NCURSES_MOUSE_VERSION */ +} + +/* VARARGS1 */ +static void +prompt(int n, NCURSES_CONST char *f, const char *s) +/* print a message at the prompt line */ +{ + (void) move(PROMPTLINE + n, 0); + (void) clrtoeol(); + (void) printw(f, s); + (void) refresh(); +} + +static void +error(NCURSES_CONST char *s) +{ + (void) move(PROMPTLINE + 2, 0); + (void) clrtoeol(); + if (s) { + (void) addstr(s); + (void) beep(); + } +} + +static void +placeship(int b, ship_t * ss, int vis) +{ + int l; + + for (l = 0; l < ss->length; ++l) { + int newx = ss->x + l * xincr[ss->dir]; + int newy = ss->y + l * yincr[ss->dir]; + + board[b][newx][newy] = ss->symbol; + if (vis) { + pgoto(newy, newx); + (void) addch((chtype) ss->symbol); + } + } + ss->hits = 0; +} + +static int +rnd(int n) +{ + return (((rand() & 0x7FFF) % n)); +} + +static void +randomplace(int b, ship_t * ss) +/* generate a valid random ship placement into px,py */ +{ + + do { + ss->dir = rnd(2) ? E : S; + ss->x = rnd(BWIDTH - (ss->dir == E ? ss->length : 0)); + ss->y = rnd(BDEPTH - (ss->dir == S ? ss->length : 0)); + } while + (!checkplace(b, ss, FALSE)); +} + +static void +initgame(void) +{ + int i, j, unplaced; + ship_t *ss; + + (void) clear(); + (void) mvaddstr(0, 35, "BATTLESHIPS"); + (void) move(PROMPTLINE + 2, 0); + announceopts(); + + memset(board, 0, sizeof(char) * BWIDTH * BDEPTH * 2); + memset(hits, 0, sizeof(char) * BWIDTH * BDEPTH * 2); + for (i = 0; i < SHIPTYPES; i++) { + ss = cpuship + i; + + ss->x = + ss->y = + ss->dir = + ss->hits = 0; + ss->placed = FALSE; + + ss = plyship + i; + + ss->x = + ss->y = + ss->dir = + ss->hits = 0; + ss->placed = FALSE; + } + + /* draw empty boards */ + (void) mvaddstr(PYBASE - 2, PXBASE + 5, "Main Board"); + (void) mvaddstr(PYBASE - 1, PXBASE - 3, numbers); + for (i = 0; i < BDEPTH; ++i) { + (void) mvaddch(PYBASE + i, PXBASE - 3, (chtype) (i + 'A')); +#ifdef A_COLOR + if (has_colors()) + attron(COLOR_PAIR(COLOR_BLUE)); +#endif /* A_COLOR */ + (void) addch(' '); + for (j = 0; j < BWIDTH; j++) + (void) addstr(" . "); +#ifdef A_COLOR + attrset(0); +#endif /* A_COLOR */ + (void) addch(' '); + (void) addch((chtype) (i + 'A')); + } + (void) mvaddstr(PYBASE + BDEPTH, PXBASE - 3, numbers); + (void) mvaddstr(CYBASE - 2, CXBASE + 7, "Hit/Miss Board"); + (void) mvaddstr(CYBASE - 1, CXBASE - 3, numbers); + for (i = 0; i < BDEPTH; ++i) { + (void) mvaddch(CYBASE + i, CXBASE - 3, (chtype) (i + 'A')); +#ifdef A_COLOR + if (has_colors()) + attron(COLOR_PAIR(COLOR_BLUE)); +#endif /* A_COLOR */ + (void) addch(' '); + for (j = 0; j < BWIDTH; j++) + (void) addstr(" . "); +#ifdef A_COLOR + attrset(0); +#endif /* A_COLOR */ + (void) addch(' '); + (void) addch((chtype) (i + 'A')); + } + + (void) mvaddstr(CYBASE + BDEPTH, CXBASE - 3, numbers); + + (void) mvprintw(HYBASE, HXBASE, + "To position your ships: move the cursor to a spot, then"); + (void) mvprintw(HYBASE + 1, HXBASE, + "type the first letter of a ship type to select it, then"); + (void) mvprintw(HYBASE + 2, HXBASE, + "type a direction ([hjkl] or [4862]), indicating how the"); + (void) mvprintw(HYBASE + 3, HXBASE, + "ship should be pointed. You may also type a ship letter"); + (void) mvprintw(HYBASE + 4, HXBASE, + "followed by `r' to position it randomly, or type `R' to"); + (void) mvprintw(HYBASE + 5, HXBASE, + "place all remaining ships randomly."); + + (void) mvaddstr(MYBASE, MXBASE, "Aiming keys:"); + (void) mvaddstr(SYBASE, SXBASE, "y k u 7 8 9"); + (void) mvaddstr(SYBASE + 1, SXBASE, " \\|/ \\|/ "); + (void) mvaddstr(SYBASE + 2, SXBASE, "h-+-l 4-+-6"); + (void) mvaddstr(SYBASE + 3, SXBASE, " /|\\ /|\\ "); + (void) mvaddstr(SYBASE + 4, SXBASE, "b j n 1 2 3"); + + /* have the computer place ships */ + for (ss = cpuship; ss < cpuship + SHIPTYPES; ss++) { + randomplace(COMPUTER, ss); + placeship(COMPUTER, ss, FALSE); + } + + ss = (ship_t *) NULL; + do { + char c, docked[SHIPTYPES + 2], *cp = docked; + + /* figure which ships still wait to be placed */ + *cp++ = 'R'; + for (i = 0; i < SHIPTYPES; i++) + if (!plyship[i].placed) + *cp++ = plyship[i].symbol; + *cp = '\0'; + + /* get a command letter */ + prompt(1, "Type one of [%s] to pick a ship.", docked + 1); + do { + c = getcoord(PLAYER); + } while + (!strchr(docked, c)); + + if (c == 'R') + (void) ungetch('R'); + else { + /* map that into the corresponding symbol */ + for (ss = plyship; ss < plyship + SHIPTYPES; ss++) + if (ss->symbol == c) + break; + + prompt(1, "Type one of [hjklrR] to place your %s.", ss->name); + pgoto(cury, curx); + } + + do { + c = getch(); + } while + (!strchr("hjklrR", c) || c == FF); + + if (c == FF) { + (void) clearok(stdscr, TRUE); + (void) refresh(); + } else if (c == 'r') { + 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': + case KEY_UP: + ny = cury + BDEPTH - 1; + nx = curx; + break; + case 'j': + case '2': + case KEY_DOWN: + ny = cury + 1; + nx = curx; + break; + case 'h': + case '4': + case KEY_LEFT: + ny = cury; + nx = curx + BWIDTH - 1; + break; + case 'l': + case '6': + case KEY_RIGHT: + ny = cury; + nx = curx + 1; + break; + case 'y': + case '7': + case KEY_A1: + ny = cury + BDEPTH - 1; + nx = curx + BWIDTH - 1; + break; + case 'b': + case '1': + case KEY_C1: + ny = cury + 1; + nx = curx + BWIDTH - 1; + break; + case 'u': + case '9': + case KEY_A3: + ny = cury + BDEPTH - 1; + nx = curx + 1; + break; + case 'n': + case '3': + case KEY_C3: + ny = cury + 1; + nx = curx + 1; + break; + case FF: + nx = curx; + ny = cury; + (void) clearok(stdscr, TRUE); + (void) refresh(); + break; +#ifdef NCURSES_MOUSE_VERSION + case KEY_MOUSE: + { + MEVENT myevent; + + getmouse(&myevent); + if (atcpu + && myevent.y >= CY(0) && myevent.y <= CY(BDEPTH) + && myevent.x >= CX(0) && myevent.x <= CX(BDEPTH)) { + curx = CXINV(myevent.x); + cury = CYINV(myevent.y); + return (' '); + } else { + beep(); + continue; + } + } + /* no fall through */ +#endif /* NCURSES_MOUSE_VERSION */ + + default: + if (atcpu) + (void) mvaddstr(CYBASE + BDEPTH + 1, CXBASE + 11, " "); + else + (void) mvaddstr(PYBASE + BDEPTH + 1, PXBASE + 11, " "); + return (c); + } + + curx = nx % BWIDTH; + cury = ny % BDEPTH; + } +} + +static bool +collidecheck(int b, int y, int x) +/* is this location on the selected zboard adjacent to a ship? */ +{ + bool collide; + + /* anything on the square */ + if ((collide = IS_SHIP(board[b][x][y])) != FALSE) + return (collide); + + /* anything on the neighbors */ + if (!closepack) { + int i; + + for (i = 0; i < 8; i++) { + int xend, yend; + + yend = y + yincr[i]; + xend = x + xincr[i]; + if (ONBOARD(xend, yend) + && IS_SHIP(board[b][xend][yend])) { + collide = TRUE; + break; + } + } + } + return (collide); +} + +static bool +checkplace(int b, ship_t * ss, int vis) +{ + int l, xend, yend; + + /* first, check for board edges */ + xend = ss->x + (ss->length - 1) * xincr[ss->dir]; + yend = ss->y + (ss->length - 1) * yincr[ss->dir]; + if (!ONBOARD(xend, yend)) { + if (vis) + switch (rnd(3)) { + case 0: + error("Ship is hanging from the edge of the world"); + break; + case 1: + error("Try fitting it on the board"); + break; + case 2: + error("Figure I won't find it if you put it there?"); + break; + } + return (FALSE); + } + + for (l = 0; l < ss->length; ++l) { + if (collidecheck(b, ss->y + l * yincr[ss->dir], ss->x + l * xincr[ss->dir])) { + if (vis) + switch (rnd(3)) { + case 0: + error("There's already a ship there"); + break; + case 1: + error("Collision alert! Aaaaaagh!"); + break; + case 2: + error("Er, Admiral, what about the other ship?"); + break; + } + return (FALSE); + } + } + return (TRUE); +} + +static int +awinna(void) +{ + int i, j; + ship_t *ss; + + for (i = 0; i < 2; ++i) { + ss = (i) ? cpuship : plyship; + for (j = 0; j < SHIPTYPES; ++j, ++ss) + if (ss->length > ss->hits) + break; + if (j == SHIPTYPES) + return (OTHER); + } + return (-1); +} + +static ship_t * +hitship(int x, int y) +/* register a hit on the targeted ship */ +{ + ship_t *sb, *ss; + char sym; + int oldx, oldy; + + getyx(stdscr, oldy, oldx); + sb = (turn) ? plyship : cpuship; + if ((sym = board[OTHER][x][y]) == 0) + return ((ship_t *) NULL); + for (ss = sb; ss < sb + SHIPTYPES; ++ss) + if (ss->symbol == sym) { + if (++ss->hits < ss->length) /* still afloat? */ + return ((ship_t *) NULL); + else { /* sunk! */ + int i, j; + + if (!closepack) + for (j = -1; j <= 1; j++) { + int bx = ss->x + j * xincr[(ss->dir + 2) % 8]; + int by = ss->y + j * yincr[(ss->dir + 2) % 8]; + + for (i = -1; i <= ss->length; ++i) { + int x1, y1; + + x1 = bx + i * xincr[ss->dir]; + y1 = by + i * yincr[ss->dir]; + if (ONBOARD(x1, y1)) { + hits[turn][x1][y1] = MARK_MISS; + if (turn % 2 == PLAYER) { + cgoto(y1, x1); +#ifdef A_COLOR + if (has_colors()) + attron(COLOR_PAIR(COLOR_GREEN)); +#endif /* A_COLOR */ + (void) addch(MARK_MISS); +#ifdef A_COLOR + attrset(0); +#endif /* A_COLOR */ + } else { + pgoto(y1, x1); + (void) addch(SHOWSPLASH); + } + } + } + } + + for (i = 0; i < ss->length; ++i) { + int x1 = ss->x + i * xincr[ss->dir]; + int y1 = ss->y + i * yincr[ss->dir]; + + hits[turn][x1][y1] = ss->symbol; + if (turn % 2 == PLAYER) { + cgoto(y1, x1); + (void) addch((chtype) (ss->symbol)); + } else { + pgoto(y1, x1); +#ifdef A_COLOR + if (has_colors()) + attron(COLOR_PAIR(COLOR_RED)); +#endif /* A_COLOR */ + (void) addch(SHOWHIT); +#ifdef A_COLOR + attrset(0); +#endif /* A_COLOR */ + } + } + + (void) move(oldy, oldx); + return (ss); + } + } + (void) move(oldy, oldx); + return ((ship_t *) NULL); +} + +static bool +plyturn(void) +{ + ship_t *ss; + bool hit; + NCURSES_CONST char *m = NULL; + + prompt(1, "Where do you want to shoot? ", ""); + for (;;) { + (void) getcoord(COMPUTER); + if (hits[PLAYER][curx][cury]) { + prompt(1, "You shelled this spot already! Try again.", ""); + beep(); + } else + break; + } + hit = IS_SHIP(board[COMPUTER][curx][cury]); + hits[PLAYER][curx][cury] = (hit ? MARK_HIT : MARK_MISS); + cgoto(cury, curx); +#ifdef A_COLOR + if (has_colors()) { + if (hit) + attron(COLOR_PAIR(COLOR_RED)); + else + attron(COLOR_PAIR(COLOR_GREEN)); + } +#endif /* A_COLOR */ + (void) addch((chtype) hits[PLAYER][curx][cury]); +#ifdef A_COLOR + attrset(0); +#endif /* A_COLOR */ + + prompt(1, "You %s.", hit ? "scored a hit" : "missed"); + if (hit && (ss = hitship(curx, cury))) { + switch (rnd(5)) { + case 0: + m = " You sank my %s!"; + break; + case 1: + m = " I have this sinking feeling about my %s...."; + break; + case 2: + m = " My %s has gone to Davy Jones's locker!"; + break; + case 3: + m = " Glub, glub -- my %s is headed for the bottom!"; + break; + case 4: + m = " You'll pick up survivors from my %s, I hope...!"; + break; + } + (void) printw(m, ss->name); + (void) beep(); + return (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!"); + ExitProgram(EXIT_FAILURE); + /*NOTREACHED */ + } +} + +#define S_MISS 0 +#define S_HIT 1 +#define S_SUNK -1 + +static int +cpufire(int x, int y) +/* fire away at given location */ +{ + bool hit, sunk; + ship_t *ss = NULL; + + hits[COMPUTER][x][y] = (hit = (board[PLAYER][x][y])) ? MARK_HIT : MARK_MISS; + (void) mvprintw(PROMPTLINE, 0, + "I shoot at %c%d. I %s!", y + 'A', x, hit ? "hit" : + "miss"); + if ((sunk = (hit && (ss = hitship(x, y)))) != 0) + (void) printw(" I've sunk your %s", ss->name); + (void) clrtoeol(); + + pgoto(y, x); +#ifdef A_COLOR + if (has_colors()) { + if (hit) + attron(COLOR_PAIR(COLOR_RED)); + else + attron(COLOR_PAIR(COLOR_GREEN)); + } +#endif /* A_COLOR */ + (void) addch((chtype) (hit ? SHOWHIT : SHOWSPLASH)); +#ifdef A_COLOR + attrset(0); +#endif /* A_COLOR */ + + return ((hit ? (sunk ? S_SUNK : S_HIT) : S_MISS) ? 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"); + ExitProgram(EXIT_FAILURE); + break; + case '-': + switch (op[i][1]) { + case 'b': + blitz = 1; + if (salvo == 1) { + (void) fprintf(stderr, + "Bad Arg: -b and -s are mutually exclusive\n"); + ExitProgram(EXIT_FAILURE); + } + break; + case 's': + salvo = 1; + if (blitz == 1) { + (void) fprintf(stderr, + "Bad Arg: -s and -b are mutually exclusive\n"); + ExitProgram(EXIT_FAILURE); + } + break; + case 'c': + closepack = 1; + break; + default: + (void) fprintf(stderr, + "Bad arg: type \"%s ?\" for usage message\n", + op[0]); + ExitProgram(EXIT_FAILURE); + } + } + } + } +} + +static int +scount(int who) +{ + register int i, shots; + register ship_t *sp; + + if (who) + sp = cpuship; /* count cpu shots */ + else + sp = plyship; /* count player shots */ + + for (i = 0, shots = 0; i < SHIPTYPES; i++, sp++) { + if (sp->hits >= sp->length) + continue; /* dead ship */ + else + shots++; + } + return (shots); +} + +int +main(int argc, char *argv[]) +{ + setlocale(LC_ALL, ""); + + do_options(argc, argv); + + intro(); + do { + initgame(); + while (awinna() == -1) { + if (!blitz) { + if (!salvo) { + if (turn) + (void) cputurn(); + else + (void) plyturn(); + } else { + register int i; + + i = scount(turn); + while (i--) { + if (turn) { + if (cputurn() && awinna() != -1) + i = 0; + } else { + if (plyturn() && awinna() != -1) + i = 0; + } + } + } + } else + while (turn ? cputurn() : plyturn()) + continue; + turn = OTHER; + } + } while + (playagain()); + uninitgame(0); + /*NOTREACHED */ +} + +/* bs.c ends here */ diff --git a/ncurses-5.3/test/cardfile.c b/ncurses-5.3/test/cardfile.c new file mode 100644 index 0000000..f9d5dcf --- /dev/null +++ b/ncurses-5.3/test/cardfile.c @@ -0,0 +1,534 @@ +/**************************************************************************** + * Copyright (c) 1999-2001,2002 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$ + * + * File format: text beginning in column 1 is a title; other text forms the content. + */ + +#include <test.priv.h> + +#if HAVE_FORM_H && HAVE_PANEL_H && HAVE_LIBFORM && HAVE_LIBPANEL + +#include <form.h> +#include <panel.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 const char * +skip(const char *buffer) +{ + while (isspace(UChar(*buffer))) + buffer++; + return buffer; +} + +static void +trim(char *buffer) +{ + unsigned n = strlen(buffer); + while (n-- && isspace(UChar(buffer[n]))) + buffer[n] = 0; +} + +/*******************************************************************************/ + +static CARD * +add_title(const char *title) +{ + CARD *card, *p, *q; + + for (p = all_cards, q = 0; p != 0; q = p, p = p->link) { + int cmp = strcmp(p->title, title); + if (cmp == 0) + return p; + if (cmp > 0) + break; + } + + card = (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, const 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 { + if (card->content != 0) + free(card->content); + card->content = (char *) malloc(total + 1); + } + strcpy(card->content + offset, content); + } +} + +static CARD * +new_card(void) +{ + CARD *card = add_title(""); + add_content(card, ""); + return card; +} + +static CARD * +find_card(char *title) +{ + CARD *card; + + for (card = all_cards; card != 0; card = card->link) + if (!strcmp(card->title, title)) + break; + + return card; +} + +static void +read_data(char *fname) +{ + FILE *fp; + CARD *card = 0; + char buffer[BUFSIZ]; + + if ((fp = fopen(fname, "r")) != 0) { + while (fgets(buffer, sizeof(buffer), fp)) { + trim(buffer); + if (isspace(UChar(*buffer))) { + if (card == 0) + card = add_title(""); + add_content(card, buffer); + } else if ((card = find_card(buffer)) == 0) { + card = add_title(buffer); + } + } + fclose(fp); + } +} + +/*******************************************************************************/ + +static void +write_data(const char *fname) +{ + FILE *fp; + CARD *p = 0; + int n; + + if (!strcmp(fname, default_name)) + fname = "cardfile.out"; + + if ((fp = fopen(fname, "w")) != 0) { + for (p = all_cards; p != 0; p = p->link) { + FIELD **f = form_fields(p->form); + for (n = 0; f[n] != 0; n++) { + char *s = field_buffer(f[n], 0); + if (s != 0 + && (s = strdup(s)) != 0) { + trim(s); + fprintf(fp, "%s%s\n", n ? "\t" : "", s); + free(s); + } + } + } + fclose(fp); + } +} + +/*******************************************************************************/ + +/* + * Count the cards + */ +static int +count_cards(void) +{ + CARD *p; + int count = 0; + + for (p = all_cards; p != 0; p = p->link) + count++; + + return count; +} + +/* + * Shuffle the panels to keep them in a natural hierarchy. + */ +static void +order_cards(CARD * first, int depth) +{ + if (first) { + if (depth && first->link) + order_cards(first->link, depth - 1); + 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 FIELD ** +make_fields(CARD * p, int form_high, int form_wide) +{ + FIELD **f = (FIELD **) calloc(3, sizeof(FIELD *)); + + 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; + return f; +} + +static void +show_legend(void) +{ + erase(); + move(LINES - 3, 0); + addstr("^Q/ESC -- exit form ^W -- writes data to file\n"); + addstr("^N -- go to next card ^P -- go to previous card\n"); + addstr("Arrow keys move left/right within a field, up/down between fields"); +} + +#if (defined(KEY_RESIZE) && HAVE_WRESIZE) || NO_LEAKS +static void +free_form_fields(FIELD ** f) +{ + int n; + + for (n = 0; f[n] != 0; ++n) { + free_field(f[n]); + } + free(f); +} +#endif + +/*******************************************************************************/ + +static void +cardfile(char *fname) +{ + WINDOW *win; + CARD *p; + CARD *top_card; + int visible_cards = 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 y = (visible_cards - 1) * OFFSET_CARD; + int x = 0; + int ch = ERR; + int last_ch; + int finished = FALSE; + + show_legend(); + + /* make a panel for each CARD */ + for (p = all_cards; p != 0; p = p->link) { + + win = newwin(panel_high, panel_wide, y, x); + keypad(win, TRUE); + p->panel = new_panel(win); + box(win, 0, 0); + + p->form = new_form(make_fields(p, form_high, form_wide)); + set_form_win(p->form, win); + set_form_sub(p->form, derwin(win, form_high, form_wide, 1, 1)); + post_form(p->form); + + y -= OFFSET_CARD; + x += OFFSET_CARD; + } + + order_cards(top_card = all_cards, visible_cards); + + while (!finished) { + update_panels(); + doupdate(); + + last_ch = ch; + ch = form_virtualize(panel_window(top_card->panel)); + switch (form_driver(top_card->form, ch)) { + case E_OK: + break; + case E_UNKNOWN_COMMAND: + switch (ch) { + case 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; +#if defined(KEY_RESIZE) && HAVE_WRESIZE + case KEY_RESIZE: + /* resizeterm already did "something" reasonable, but it cannot + * know much about layout. So let's make it nicer. + */ + panel_wide = COLS - (visible_cards * OFFSET_CARD); + panel_high = LINES - (visible_cards * OFFSET_CARD) - 5; + + form_wide = panel_wide - 2; + form_high = panel_high - 2; + + y = (visible_cards - 1) * OFFSET_CARD; + x = 0; + + show_legend(); + for (p = all_cards; p != 0; p = p->link) { + FIELD **oldf = form_fields(p->form); + WINDOW *olds = form_sub(p->form); + + win = form_win(p->form); + + /* move and resize the card as needed + * FIXME: if the windows are shrunk too much, this won't do + */ + mvwin(win, y, x); + wresize(win, panel_high, panel_wide); + + /* reconstruct each form. Forms are not resizable, and + * there appears to be no good way to reload the text in + * a resized window. + */ + werase(win); + + unpost_form(p->form); + free_form(p->form); + + p->form = new_form(make_fields(p, form_high, form_wide)); + set_form_win(p->form, win); + set_form_sub(p->form, derwin(win, form_high, form_wide, + 1, 1)); + post_form(p->form); + + free_form_fields(oldf); + delwin(olds); + + box(win, 0, 0); + + y -= OFFSET_CARD; + x += OFFSET_CARD; + } + break; +#endif + default: + beep(); + break; + } + break; + default: + flash(); + break; + } + } +#if NO_LEAKS + while (all_cards != 0) { + FIELD **f; + int count; + + p = all_cards; + all_cards = all_cards->link; + + f = form_fields(p->form); + count = field_count(p->form); + + unpost_form(p->form); /* ...so we can free it */ + free_form(p->form); /* this also disconnects the fields */ + + free_form_fields(f); + + del_panel(p->panel); + free(p->title); + free(p->content); + free(p); + } +#endif +} + +/*******************************************************************************/ + +int +main(int argc, char *argv[]) +{ + int n; + + setlocale(LC_ALL, ""); + + initscr(); + cbreak(); + noecho(); + + if (argc > 1) { + for (n = 1; n < argc; n++) + read_data(argv[n]); + if (count_cards() == 0) + new_card(); + cardfile(argv[1]); + } else { + read_data(default_name); + if (count_cards() == 0) + new_card(); + cardfile(default_name); + } + + endwin(); + + ExitProgram(EXIT_SUCCESS); +} +#else +int +main(void) +{ + printf("This program requires the curses form and panel libraries\n"); + ExitProgram(EXIT_FAILURE); +} +#endif diff --git a/ncurses-5.3/test/cardfile.dat b/ncurses-5.3/test/cardfile.dat new file mode 100644 index 0000000..deb4b76 --- /dev/null +++ b/ncurses-5.3/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/ncurses-5.3/test/configure b/ncurses-5.3/test/configure new file mode 100755 index 0000000..8d44c2b --- /dev/null +++ b/ncurses-5.3/test/configure @@ -0,0 +1,2401 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13.20000819 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF +cat <<EOF +--enable and --with options recognized: + --with-5lib use SunOS sysv-libraries + --with-ncursesw use wide ncurses-libraries (installed) + --with-ncurses use ncurses-libraries (installed) +EOF + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13.20000819" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=ncurses.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:533: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:563: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:614: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:646: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 657 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:693: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:721: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + + +CC_G_OPT="-g" +CC_SHARED_OPTS=unknown +CPPFLAGS="$CPPFLAGS" +DFT_DEP_SUFFIX="" +DFT_OBJ_SUBDIR=`pwd|sed -e's:.*/::'` +DFT_UPR_MODEL="NORMAL" +ECHO_LINK='@ echo linking $@ ... ;' +EXTRA_LIBS="" +LD="ld" +LDFLAGS_SHARED="" +LD_MODEL="" +LD_SHARED_OPTS="" +LIBTOOL="" +LIB_NAME=curses +LIB_PREFIX="-l" +LINK_TESTS="" +LINT=lint +LINT_OPTS="" +LOCAL_LDFLAGS="" +MATH_LIB="-lm" +PROG_EXT="" +TEST_ARGS="" +TEST_DEPS="" +cf_cv_abi_version="" +cf_cv_rel_version="" + + +# Check whether --with-5lib or --without-5lib was given. +if test "${with_5lib+set}" = set; then + withval="$with_5lib" + LIBS="-L/usr/5lib $LIBS" + CPPFLAGS="$CPPFLAGS -I/usr/5include" +fi + + + + +# Check whether --with-ncursesw or --without-ncursesw was given. +if test "${with_ncursesw+set}" = set; then + withval="$with_ncursesw" + + cat >> confdefs.h <<\EOF +#define _GNU_SOURCE 1 +EOF + + cat >> confdefs.h <<\EOF +#define _XOPEN_SOURCE_EXTENDED 1 +EOF + + echo $ac_n "checking for initscr""... $ac_c" 1>&6 +echo "configure:803: checking for initscr" >&5 +if eval "test \"`echo '$''{'ac_cv_func_initscr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 808 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char initscr(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char initscr(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_initscr) || defined (__stub___initscr) +choke me +#else +initscr(); +#endif + +; return 0; } +EOF +if { (eval echo configure:831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_initscr=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_initscr=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'initscr`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + + echo $ac_n "checking for Gpm_Open in -lgpm""... $ac_c" 1>&6 +echo "configure:850: checking for Gpm_Open in -lgpm" >&5 +ac_lib_var=`echo gpm'_'Gpm_Open | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgpm $LIBS" +cat > conftest.$ac_ext <<EOF +#line 858 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char Gpm_Open(); + +int main() { +Gpm_Open() +; return 0; } +EOF +if { (eval echo configure:869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo gpm | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lgpm $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + LIB_NAME=ncursesw + echo $ac_n "checking for putwc""... $ac_c" 1>&6 +echo "configure:898: checking for putwc" >&5 +if eval "test \"`echo '$''{'ac_cv_func_putwc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 903 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char putwc(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char putwc(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_putwc) || defined (__stub___putwc) +choke me +#else +putwc(); +#endif + +; return 0; } +EOF +if { (eval echo configure:926: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_putwc=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_putwc=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'putwc`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + +echo $ac_n "checking for putwc in libutf8""... $ac_c" 1>&6 +echo "configure:945: checking for putwc in libutf8" >&5 +if eval "test \"`echo '$''{'cf_cv_libutf8'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + cf_save_LIBS="$LIBS" + LIBS="-lutf8 $LIBS" +cat > conftest.$ac_ext <<EOF +#line 953 "configure" +#include "confdefs.h" + +#include <libutf8.h> +int main() { +putwc(0,0); +; return 0; } +EOF +if { (eval echo configure:961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_libutf8=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_libutf8=no +fi +rm -f conftest* + LIBS="$cf_save_LIBS" + +fi + +echo "$ac_t""$cf_cv_libutf8" 1>&6 + +if test "$cf_cv_libutf8" = yes ; then + cat >> confdefs.h <<\EOF +#define HAVE_LIBUTF8_H 1 +EOF + + LIBS="-lutf8 $LIBS" +fi + +fi + + for p in $HOME /usr/local /usr + do + if test -f $p/include/ncursesw/curses.h + then + CPPFLAGS="$CPPFLAGS -I$p/include/ncursesw" + test $p != /usr && CPPFLAGS="$CPPFLAGS -I$p/include" + 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 + +fi + +fi + + + +# Check whether --with-ncurses or --without-ncurses was given. +if test "${with_ncurses+set}" = set; then + withval="$with_ncurses" + echo $ac_n "checking for initscr""... $ac_c" 1>&6 +echo "configure:1016: checking for initscr" >&5 +if eval "test \"`echo '$''{'ac_cv_func_initscr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1021 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char initscr(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char initscr(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_initscr) || defined (__stub___initscr) +choke me +#else +initscr(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1044: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_initscr=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_initscr=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'initscr`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + + echo $ac_n "checking for Gpm_Open in -lgpm""... $ac_c" 1>&6 +echo "configure:1063: checking for Gpm_Open in -lgpm" >&5 +ac_lib_var=`echo gpm'_'Gpm_Open | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgpm $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1071 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char Gpm_Open(); + +int main() { +Gpm_Open() +; return 0; } +EOF +if { (eval echo configure:1082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo gpm | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lgpm $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + 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 && CPPFLAGS="$CPPFLAGS -I$p/include" + 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 + +fi + +fi + + + + +echo $ac_n "checking for initscr""... $ac_c" 1>&6 +echo "configure:1137: checking for initscr" >&5 +if eval "test \"`echo '$''{'ac_cv_func_initscr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1142 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char initscr(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char initscr(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_initscr) || defined (__stub___initscr) +choke me +#else +initscr(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_initscr=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_initscr=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'initscr`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 + +echo $ac_n "checking for initscr in -l$LIB_NAME""... $ac_c" 1>&6 +echo "configure:1184: checking for initscr in -l$LIB_NAME" >&5 +ac_lib_var=`echo $LIB_NAME'_'initscr | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-l$LIB_NAME $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1192 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char initscr(); + +int main() { +initscr() +; return 0; } +EOF +if { (eval echo configure:1203: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo $LIB_NAME | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-l$LIB_NAME $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +fi + +echo $ac_n "checking for form_driver in -lform""... $ac_c" 1>&6 +echo "configure:1233: checking for form_driver in -lform" >&5 +ac_lib_var=`echo form'_'form_driver | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lform $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1241 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char form_driver(); + +int main() { +form_driver() +; return 0; } +EOF +if { (eval echo configure:1252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo form | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lform $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for menu_driver in -lmenu""... $ac_c" 1>&6 +echo "configure:1280: checking for menu_driver in -lmenu" >&5 +ac_lib_var=`echo menu'_'menu_driver | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lmenu $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1288 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char menu_driver(); + +int main() { +menu_driver() +; return 0; } +EOF +if { (eval echo configure:1299: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo menu | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lmenu $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for new_panel in -lpanel""... $ac_c" 1>&6 +echo "configure:1327: checking for new_panel in -lpanel" >&5 +ac_lib_var=`echo panel'_'new_panel | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lpanel $LIBS" +cat > conftest.$ac_ext <<EOF +#line 1335 "configure" +#include "confdefs.h" +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char new_panel(); + +int main() { +new_panel() +; return 0; } +EOF +if { (eval echo configure:1346: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo panel | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <<EOF +#define $ac_tr_lib 1 +EOF + + LIBS="-lpanel $LIBS" + +else + echo "$ac_t""no" 1>&6 +fi + + +echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 +echo "configure:1375: checking return type of signal handlers" >&5 +if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1380 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <signal.h> +#ifdef signal +#undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int main() { +int i; +; return 0; } +EOF +if { (eval echo configure:1397: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_type_signal=void +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_type_signal=int +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_type_signal" 1>&6 +cat >> confdefs.h <<EOF +#define RETSIGTYPE $ac_cv_type_signal +EOF + + + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1417: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext <<EOF +#line 1432 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1438: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext <<EOF +#line 1449 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1455: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext <<EOF +#line 1466 "configure" +#include "confdefs.h" +#include <assert.h> +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1472: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1497: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1502 "configure" +#include "confdefs.h" +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1510: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 1527 "configure" +#include "confdefs.h" +#include <string.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext <<EOF +#line 1545 "configure" +#include "confdefs.h" +#include <stdlib.h> +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext <<EOF +#line 1566 "configure" +#include "confdefs.h" +#include <ctype.h> +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 +echo "configure:1601: checking whether time.h and sys/time.h may both be included" >&5 +if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1606 "configure" +#include "confdefs.h" +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> +int main() { +struct tm *tp; +; return 0; } +EOF +if { (eval echo configure:1615: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_header_time=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_time=no +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_time" 1>&6 +if test $ac_cv_header_time = yes; then + cat >> confdefs.h <<\EOF +#define TIME_WITH_SYS_TIME 1 +EOF + +fi + +for ac_hdr in \ +form.h \ +getopt.h \ +locale.h \ +menu.h \ +nc_alloc.h \ +nomacros.h \ +panel.h \ +sys/ioctl.h \ +sys/select.h \ +sys/time.h \ +termios.h \ +unistd.h \ + +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1652: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1657 "configure" +#include "confdefs.h" +#include <$ac_hdr> +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1662: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <<EOF +#define $ac_tr_hdr 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +for ac_func in \ +getnstr \ +gettimeofday \ +napms \ +resize_term \ +resizeterm \ +strdup \ +use_default_colors \ +vsscanf \ +wresize \ + +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:1702: checking for $ac_func" >&5 +if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1707 "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func(); below. */ +#include <assert.h> +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +$ac_func(); +#endif + +; return 0; } +EOF +if { (eval echo configure:1730: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_$ac_func=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_$ac_func=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <<EOF +#define $ac_tr_func 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi +done + + +echo $ac_n "checking for function curses_version""... $ac_c" 1>&6 +echo "configure:1756: checking for function curses_version" >&5 +if eval "test \"`echo '$''{'cf_cv_func_curses_version'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +if test "$cross_compiling" = yes; then + cf_cv_func_curses_version=unknown +else + cat > conftest.$ac_ext <<EOF +#line 1765 "configure" +#include "confdefs.h" + +#include <curses.h> +int main() +{ + char temp[1024]; + sprintf(temp, "%s\n", curses_version()); + exit(0); +} + +EOF +if { (eval echo configure:1777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + cf_cv_func_curses_version=yes + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + cf_cv_func_curses_version=no + +fi +rm -fr conftest* +fi + +rm -f core +fi + +echo "$ac_t""$cf_cv_func_curses_version" 1>&6 +test "$cf_cv_func_curses_version" = yes && cat >> confdefs.h <<\EOF +#define HAVE_CURSES_VERSION 1 +EOF + + +echo $ac_n "checking for alternate character set array""... $ac_c" 1>&6 +echo "configure:1801: checking for alternate character set array" >&5 +if eval "test \"`echo '$''{'cf_cv_curses_acs_map'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cf_cv_curses_acs_map=unknown +for name in acs_map _acs_map __acs_map _nc_acs_map +do +cat > conftest.$ac_ext <<EOF +#line 1810 "configure" +#include "confdefs.h" + +#include <curses.h> + +int main() { + +$name['k'] = ACS_PLUS + +; return 0; } +EOF +if { (eval echo configure:1821: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_curses_acs_map=$name; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$cf_cv_curses_acs_map" 1>&6 + +test "$cf_cv_curses_acs_map" != unknown && cat >> confdefs.h <<EOF +#define CURSES_ACS_ARRAY $cf_cv_curses_acs_map +EOF + + +echo $ac_n "checking for wide alternate character set array""... $ac_c" 1>&6 +echo "configure:1841: checking for wide alternate character set array" >&5 +if eval "test \"`echo '$''{'cf_cv_curses_wacs_map'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cf_cv_curses_wacs_map=unknown +for name in wacs_map _wacs_map __wacs_map _nc_wacs +do +cat > conftest.$ac_ext <<EOF +#line 1850 "configure" +#include "confdefs.h" + +#ifndef _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED +#endif +#include <curses.h> + +int main() { + +$name['k'] = *WACS_PLUS + +; return 0; } +EOF +if { (eval echo configure:1864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + cf_cv_curses_wacs_map=$name; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$cf_cv_curses_wacs_map" 1>&6 + +test "$cf_cv_curses_wacs_map" != unknown && cat >> confdefs.h <<EOF +#define CURSES_WACS_ARRAY $cf_cv_curses_wacs_map +EOF + + + + + +echo $ac_n "checking for type attr_t in curses.h""... $ac_c" 1>&6 +echo "configure:1887: checking for type attr_t in curses.h" >&5 +cat > conftest.$ac_ext <<EOF +#line 1889 "configure" +#include "confdefs.h" + +#ifndef _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED +#endif +#include <curses.h> +int main() { + +attr_t foo + +; return 0; } +EOF +if { (eval echo configure:1902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_result=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_result=no +fi +rm -f conftest* +echo "$ac_t""$cf_result" 1>&6 +if test $cf_result = yes ; then + +cf_result=`echo "have_type_attr_t" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` + + cat >> confdefs.h <<EOF +#define $cf_result 1 +EOF + +else + cat >> confdefs.h <<EOF +#define attr_t long +EOF + +fi + + +echo $ac_n "checking for type mbstate_t in curses.h""... $ac_c" 1>&6 +echo "configure:1930: checking for type mbstate_t in curses.h" >&5 +cat > conftest.$ac_ext <<EOF +#line 1932 "configure" +#include "confdefs.h" + +#ifndef _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED +#endif +#include <curses.h> +int main() { + +mbstate_t foo + +; return 0; } +EOF +if { (eval echo configure:1945: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_result=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_result=no +fi +rm -f conftest* +echo "$ac_t""$cf_result" 1>&6 +if test $cf_result = yes ; then + +cf_result=`echo "have_type_mbstate_t" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` + + cat >> confdefs.h <<EOF +#define $cf_result 1 +EOF + +else + cat >> confdefs.h <<EOF +#define mbstate_t long +EOF + +fi + + + +echo $ac_n "checking if sys/time.h works with sys/select.h""... $ac_c" 1>&6 +echo "configure:1974: checking if sys/time.h works with sys/select.h" >&5 +if eval "test \"`echo '$''{'cf_cv_sys_time_select'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +cat > conftest.$ac_ext <<EOF +#line 1980 "configure" +#include "confdefs.h" + +#include <sys/types.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif + +int main() { + +; return 0; } +EOF +if { (eval echo configure:1995: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cf_cv_sys_time_select=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + cf_cv_sys_time_select=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$cf_cv_sys_time_select" 1>&6 +test "$cf_cv_sys_time_select" = yes && cat >> confdefs.h <<\EOF +#define HAVE_SYS_TIME_SELECT 1 +EOF + + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13.20000819" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir + +trap 'rm -fr `echo "Makefile ncurses_cfg.h:ncurses_tst.hin" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@CC@%$CC%g +s%@CC_G_OPT@%$CC_G_OPT%g +s%@CC_SHARED_OPTS@%$CC_SHARED_OPTS%g +s%@DFT_DEP_SUFFIX@%$DFT_DEP_SUFFIX%g +s%@DFT_OBJ_SUBDIR@%$DFT_OBJ_SUBDIR%g +s%@DFT_UPR_MODEL@%$DFT_UPR_MODEL%g +s%@ECHO_LINK@%$ECHO_LINK%g +s%@EXTRA_LIBS@%$EXTRA_LIBS%g +s%@LD@%$LD%g +s%@LDFLAGS_SHARED@%$LDFLAGS_SHARED%g +s%@LD_MODEL@%$LD_MODEL%g +s%@LD_SHARED_OPTS@%$LD_SHARED_OPTS%g +s%@LIBTOOL@%$LIBTOOL%g +s%@LIB_NAME@%$LIB_NAME%g +s%@LIB_PREFIX@%$LIB_PREFIX%g +s%@LINK_TESTS@%$LINK_TESTS%g +s%@LINT@%$LINT%g +s%@LINT_OPTS@%$LINT_OPTS%g +s%@LOCAL_LDFLAGS@%$LOCAL_LDFLAGS%g +s%@MATH_LIB@%$MATH_LIB%g +s%@PROG_EXT@%$PROG_EXT%g +s%@TEST_ARGS@%$TEST_ARGS%g +s%@TEST_DEPS@%$TEST_DEPS%g +s%@cf_cv_abi_version@%$cf_cv_abi_version%g +s%@cf_cv_rel_version@%$cf_cv_rel_version%g +s%@CPP@%$CPP%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +if test "${CONFIG_HEADERS+set}" != set; then +EOF +cat >> $CONFIG_STATUS <<EOF + CONFIG_HEADERS="ncurses_cfg.h:ncurses_tst.hin" +EOF +cat >> $CONFIG_STATUS <<\EOF +fi +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + cat $ac_file_inputs > conftest.in + +EOF + + +# Transform confdefs.h into a list of #define's. We won't use it as a sed +# script, but as data to insert where we see @DEFS@. We expect AC_SAVE_DEFS to +# be either 'cat' or 'sort'. +sort confdefs.h >conftest.vals + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. + +rm -f conftest.tail +echo ' rm -f conftest.frag' >> $CONFIG_STATUS +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write chunks of a limited-size here document to conftest.frag. + echo ' cat >> conftest.frag <<CEOF' >> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +# Run sed to substitute the contents of conftest.frag into conftest.in at the +# marker @DEFS@. +echo ' cat >> conftest.edit <<CEOF +/@DEFS@/r conftest.frag +/@DEFS@/d +CEOF +sed -f conftest.edit conftest.in > conftest.out +rm -f conftest.in +mv conftest.out conftest.in +rm -f conftest.edit conftest.frag +' >> $CONFIG_STATUS + + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + fi + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + +EOF +cat >> $CONFIG_STATUS <<EOF +# Extra initialization commands, if any + +EOF +cat >> $CONFIG_STATUS <<\EOF +# Extra commands, if any + + 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 + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/ncurses-5.3/test/configure.in b/ncurses-5.3/test/configure.in new file mode 100644 index 0000000..afaba4f --- /dev/null +++ b/ncurses-5.3/test/configure.in @@ -0,0 +1,327 @@ +dnl*************************************************************************** +dnl Copyright (c) 1998-2000,2002 Free Software Foundation, Inc. * +dnl * +dnl Permission is hereby granted, free of charge, to any person obtaining a * +dnl copy of this software and associated documentation files (the * +dnl "Software"), to deal in the Software without restriction, including * +dnl without limitation the rights to use, copy, modify, merge, publish, * +dnl distribute, distribute with modifications, sublicense, and/or sell * +dnl copies of the Software, and to permit persons to whom the Software is * +dnl furnished to do so, subject to the following conditions: * +dnl * +dnl The above copyright notice and this permission notice shall be included * +dnl in all copies or substantial portions of the Software. * +dnl * +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * +dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * +dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * +dnl IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * +dnl DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * +dnl OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * +dnl THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +dnl * +dnl Except as contained in this notice, the name(s) of the above copyright * +dnl holders shall not be used in advertising or otherwise to promote the * +dnl sale, use or other dealings in this Software without prior written * +dnl authorization. * +dnl*************************************************************************** +dnl +dnl Author: Thomas E. Dickey 1996, etc. +dnl +dnl $Id$ +dnl This is a simple configuration-script for the ncurses test programs that +dnl allows the test-directory to be separately configured against a reference +dnl system (i.e., sysvr4 curses) +dnl +dnl If you're configuring ncurses, you shouldn't need to use this script. +dnl It's only for testing purposes. +dnl +dnl See http://invisible-island.net/autoconf/ for additional information. +dnl --------------------------------------------------------------------------- +AC_PREREQ(2.13.20000819) +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) +LDFLAGS_SHARED="" AC_SUBST(LDFLAGS_SHARED) +LD_MODEL="" AC_SUBST(LD_MODEL) +LD_SHARED_OPTS="" AC_SUBST(LD_SHARED_OPTS) +LIBTOOL="" AC_SUBST(LIBTOOL) +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 --------------------------------------------------------------------------- +dnl Check for libutf8 +AC_DEFUN([CF_LIBUTF8], +[ +AC_CACHE_CHECK(for putwc in libutf8,cf_cv_libutf8,[ + cf_save_LIBS="$LIBS" + LIBS="-lutf8 $LIBS" +AC_TRY_LINK([ +#include <libutf8.h>],[putwc(0,0);], + [cf_cv_libutf8=yes], + [cf_cv_libutf8=no]) + LIBS="$cf_save_LIBS" +]) + +if test "$cf_cv_libutf8" = yes ; then + AC_DEFINE(HAVE_LIBUTF8_H) + LIBS="-lutf8 $LIBS" +fi +])dnl + +dnl --------------------------------------------------------------------------- +dnl NcursesW, installed in conventional location +AC_ARG_WITH(ncursesw, + [ --with-ncursesw use wide ncurses-libraries (installed)], + [ + AC_DEFINE(_GNU_SOURCE) + AC_DEFINE(_XOPEN_SOURCE_EXTENDED) + AC_CHECK_FUNC(initscr,,[ + AC_CHECK_LIB(gpm,Gpm_Open) + LIB_NAME=ncursesw + AC_CHECK_FUNC(putwc,,[CF_LIBUTF8]) + for p in $HOME /usr/local /usr + do + if test -f $p/include/ncursesw/curses.h + then + CPPFLAGS="$CPPFLAGS -I$p/include/ncursesw" + test $p != /usr && CPPFLAGS="$CPPFLAGS -I$p/include" + 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 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 && CPPFLAGS="$CPPFLAGS -I$p/include" + 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 \ +locale.h \ +menu.h \ +nc_alloc.h \ +nomacros.h \ +panel.h \ +sys/ioctl.h \ +sys/select.h \ +sys/time.h \ +termios.h \ +unistd.h \ +) + +AC_CHECK_FUNCS( \ +getnstr \ +gettimeofday \ +napms \ +resize_term \ +resizeterm \ +strdup \ +use_default_colors \ +vsscanf \ +wresize \ +) + +dnl --------------------------------------------------------------------------- +dnl Solaris has a data item 'curses_version', which confuses AC_CHECK_FUNCS. +dnl It's a character string "SVR4", not documented. +AC_CACHE_CHECK(for function curses_version, cf_cv_func_curses_version,[ +AC_TRY_RUN([ +#include <curses.h> +int main() +{ + char temp[1024]; + sprintf(temp, "%s\n", curses_version()); + exit(0); +}] +,[cf_cv_func_curses_version=yes] +,[cf_cv_func_curses_version=no] +,[cf_cv_func_curses_version=unknown]) +rm -f core]) +test "$cf_cv_func_curses_version" = yes && AC_DEFINE(HAVE_CURSES_VERSION) + +dnl --------------------------------------------------------------------------- +dnl Check for likely values of acs_map[]: +AC_CACHE_CHECK(for alternate character set array, cf_cv_curses_acs_map,[ +cf_cv_curses_acs_map=unknown +for name in acs_map _acs_map __acs_map _nc_acs_map +do +AC_TRY_LINK([ +#include <curses.h> +],[ +$name['k'] = ACS_PLUS +],[cf_cv_curses_acs_map=$name; break]) +done +]) + +test "$cf_cv_curses_acs_map" != unknown && AC_DEFINE_UNQUOTED(CURSES_ACS_ARRAY,$cf_cv_curses_acs_map) + +dnl --------------------------------------------------------------------------- +dnl Check for likely values of wacs_map[]: +AC_CACHE_CHECK(for wide alternate character set array, cf_cv_curses_wacs_map,[ +cf_cv_curses_wacs_map=unknown +for name in wacs_map _wacs_map __wacs_map _nc_wacs +do +AC_TRY_LINK([ +#ifndef _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED +#endif +#include <curses.h> +],[ +$name['k'] = *WACS_PLUS +],[cf_cv_curses_wacs_map=$name; break]) +done +]) + +test "$cf_cv_curses_wacs_map" != unknown && AC_DEFINE_UNQUOTED(CURSES_WACS_ARRAY,$cf_cv_curses_wacs_map) + +dnl --------------------------------------------------------------------------- +dnl Make an uppercase version of a variable +dnl $1=uppercase($2) +AC_DEFUN([CF_UPPER], +[ +$1=`echo "$2" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%` +])dnl + +dnl --------------------------------------------------------------------------- +dnl Check if curses.h defines the given type +AC_DEFUN([CF_CURSES_TYPE], +[ +AC_MSG_CHECKING(for type $1 in curses.h) +AC_TRY_COMPILE([ +#ifndef _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED +#endif +#include <curses.h>],[ +$1 foo +],cf_result=yes,cf_result=no) +AC_MSG_RESULT($cf_result) +if test $cf_result = yes ; then + CF_UPPER(cf_result,have_type_$1) + AC_DEFINE_UNQUOTED($cf_result) +else + AC_DEFINE_UNQUOTED($1,$2) +fi +])dnl + +CF_CURSES_TYPE(attr_t,long) +CF_CURSES_TYPE(mbstate_t,long) + +dnl --------------------------------------------------------------------------- +dnl Check if we can include <sys/time.h> with <sys/select.h>; this breaks on +dnl older SCO configurations. +dnl [CF_SYS_TIME_SELECT] + +AC_MSG_CHECKING(if sys/time.h works with sys/select.h) +AC_CACHE_VAL(cf_cv_sys_time_select,[ +AC_TRY_COMPILE([ +#include <sys/types.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif +],[],[cf_cv_sys_time_select=yes], + [cf_cv_sys_time_select=no]) + ]) +AC_MSG_RESULT($cf_cv_sys_time_select) +test "$cf_cv_sys_time_select" = yes && AC_DEFINE(HAVE_SYS_TIME_SELECT) + +dnl --------------------------------------------------------------------------- + +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/ncurses-5.3/test/ditto.c b/ncurses-5.3/test/ditto.c new file mode 100644 index 0000000..ddd7806 --- /dev/null +++ b/ncurses-5.3/test/ditto.c @@ -0,0 +1,148 @@ +/**************************************************************************** + * Copyright (c) 1998,2001 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$ + * + * 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); + ExitProgram(EXIT_FAILURE); +} + +static void +usage(void) +{ + fprintf(stderr, "usage: ditto [terminal1 ...]\n"); + ExitProgram(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(); + } + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/dots.c b/ncurses-5.3/test/dots.c new file mode 100644 index 0000000..7739de2 --- /dev/null +++ b/ncurses-5.3/test/dots.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * Copyright (c) 1999-2001,2002 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$ + * + * A simple demo of the terminfo interface. + */ +#include <time.h> + +#include <test.priv.h> + +#define valid(s) ((s != 0) && s != (char *)-1) + +static bool interrupted = FALSE; + +static int +outc(int c) +{ + if (interrupted) { + char tmp = c; + write(STDOUT_FILENO, &tmp, 1); + } else { + putc(c, stdout); + } + return 0; +} + +static bool +outs(char *s) +{ + if (valid(s)) { + tputs(s, 1, outc); + return TRUE; + } + return FALSE; +} + +static void +cleanup(void) +{ + outs(exit_attribute_mode); + if (!outs(orig_colors)) + outs(orig_pair); + outs(clear_screen); + outs(cursor_normal); +} + +static void +onsig(int n GCC_UNUSED) +{ + interrupted = TRUE; + cleanup(); + ExitProgram(EXIT_FAILURE); +} + +static float +ranf(void) +{ + long r = (rand() & 077777); + return ((float) r / 32768.); +} + +int +main( + int argc GCC_UNUSED, + char *argv[]GCC_UNUSED) +{ + int x, y, z, j, p; + float r; + float c; + + for (j = SIGHUP; j <= SIGTERM; j++) + if (signal(j, SIG_IGN) != SIG_IGN) + signal(j, onsig); + + srand(time(0)); + setupterm((char *) 0, 1, (int *) 0); + outs(clear_screen); + outs(cursor_invisible); + if (max_colors > 1) { + if (!valid(set_a_foreground) + || !valid(set_a_background) + || (!valid(orig_colors) && !valid(orig_pair))) + max_colors = -1; + } + + r = (float) (lines - 4); + c = (float) (columns - 4); + + for (;;) { + x = (int) (c * ranf()) + 2; + y = (int) (r * ranf()) + 2; + p = (ranf() > 0.9) ? '*' : ' '; + + tputs(tparm3(cursor_address, y, x), 1, outc); + if (max_colors > 0) { + z = (int) (ranf() * max_colors); + if (ranf() > 0.01) { + tputs(tparm2(set_a_foreground, z), 1, outc); + } else { + tputs(tparm2(set_a_background, z), 1, outc); + } + } else if (valid(exit_attribute_mode) + && valid(enter_reverse_mode)) { + if (ranf() <= 0.01) + outs((ranf() > 0.6) ? enter_reverse_mode : + exit_attribute_mode); + } + outc(p); + fflush(stdout); + } +} diff --git a/ncurses-5.3/test/filter.c b/ncurses-5.3/test/filter.c new file mode 100644 index 0000000..1a6f620 --- /dev/null +++ b/ncurses-5.3/test/filter.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * Copyright (c) 1998-2001,2002 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$ + */ +#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. + */ + +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) +{ + char buffer[80]; + attr_t underline; + + filter(); + (void) newterm((char *) 0, stdout, stdin); + cbreak(); + keypad(stdscr, TRUE); + + if (has_colors()) { + int background = COLOR_BLACK; + start_color(); +#if HAVE_USE_DEFAULT_COLORS + if (use_default_colors() != ERR) + background = -1; +#endif + init_pair(1, COLOR_CYAN, background); + underline = COLOR_PAIR(1); + } else { + underline = A_UNDERLINE; + } + + while (new_command(buffer, sizeof(buffer) - 1, underline) != ERR + && strlen(buffer) != 0) { + reset_shell_mode(); + printf("\n"); + fflush(stdout); + system(buffer); + reset_prog_mode(); + touchwin(stdscr); + erase(); + refresh(); + } + printw("done"); + refresh(); + endwin(); + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/firework.c b/ncurses-5.3/test/firework.c new file mode 100644 index 0000000..5c99815 --- /dev/null +++ b/ncurses-5.3/test/firework.c @@ -0,0 +1,173 @@ +/* + * $Id$ + */ +#include <time.h> + +#include <test.priv.h> + +static int my_bg = COLOR_BLACK; + +static void +cleanup(void) +{ + curs_set(1); + endwin(); +} + +static RETSIGTYPE +onsig(int n GCC_UNUSED) +{ + cleanup(); + ExitProgram(EXIT_FAILURE); +} + +static void +showit(void) +{ + int ch; + napms(120); + if ((ch = getch()) != ERR) { +#ifdef KEY_RESIZE + if (ch == KEY_RESIZE) { + erase(); + } else +#endif + if (ch == 'q') { + cleanup(); + ExitProgram(EXIT_SUCCESS); + } else if (ch == 's') { + nodelay(stdscr, FALSE); + } else if (ch == ' ') { + nodelay(stdscr, TRUE); + } + } +} + +static +int +get_colour(chtype * bold) +{ + int attr; + attr = (rand() % 16) + 1; + + *bold = A_NORMAL; + if (attr > 8) { + *bold = A_BOLD; + attr &= 7; + } + return (attr); +} + +static +void +explode(int row, int col) +{ + chtype bold; + erase(); + mvprintw(row, col, "-"); + showit(); + + init_pair(1, get_colour(&bold), my_bg); + attrset(COLOR_PAIR(1) | bold); + mvprintw(row - 1, col - 1, " - "); + mvprintw(row + 0, col - 1, "-+-"); + mvprintw(row + 1, col - 1, " - "); + showit(); + + init_pair(1, get_colour(&bold), my_bg); + attrset(COLOR_PAIR(1) | bold); + mvprintw(row - 2, col - 2, " --- "); + mvprintw(row - 1, col - 2, "-+++-"); + mvprintw(row + 0, col - 2, "-+#+-"); + mvprintw(row + 1, col - 2, "-+++-"); + mvprintw(row + 2, col - 2, " --- "); + showit(); + + init_pair(1, get_colour(&bold), my_bg); + attrset(COLOR_PAIR(1) | bold); + mvprintw(row - 2, col - 2, " +++ "); + mvprintw(row - 1, col - 2, "++#++"); + mvprintw(row + 0, col - 2, "+# #+"); + mvprintw(row + 1, col - 2, "++#++"); + mvprintw(row + 2, col - 2, " +++ "); + showit(); + + init_pair(1, get_colour(&bold), my_bg); + attrset(COLOR_PAIR(1) | bold); + mvprintw(row - 2, col - 2, " # "); + mvprintw(row - 1, col - 2, "## ##"); + mvprintw(row + 0, col - 2, "# #"); + mvprintw(row + 1, col - 2, "## ##"); + mvprintw(row + 2, col - 2, " # "); + showit(); + + init_pair(1, get_colour(&bold), my_bg); + attrset(COLOR_PAIR(1) | bold); + mvprintw(row - 2, col - 2, " # # "); + mvprintw(row - 1, col - 2, "# #"); + mvprintw(row + 0, col - 2, " "); + mvprintw(row + 1, col - 2, "# #"); + mvprintw(row + 2, col - 2, " # # "); + showit(); +} + +int +main( + int argc GCC_UNUSED, + char *argv[]GCC_UNUSED) +{ + int 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(); + noecho(); + cbreak(); + keypad(stdscr, TRUE); + nodelay(stdscr, TRUE); + + if (has_colors()) { + start_color(); +#if HAVE_USE_DEFAULT_COLORS + if (use_default_colors() == OK) + my_bg = -1; +#endif + } + curs_set(0); + + seed = time((time_t *) 0); + srand(seed); + for (;;) { + do { + start = rand() % (COLS - 3); + end = rand() % (COLS - 3); + start = (start < 2) ? 2 : start; + end = (end < 2) ? 2 : end; + direction = (start > end) ? -1 : 1; + diff = abs(start - end); + } while (diff < 2 || diff >= LINES - 2); + attrset(A_NORMAL); + for (row = 0; row < diff; row++) { + mvprintw(LINES - row, start + (row * direction), + (direction < 0) ? "\\" : "/"); + if (flag++) { + showit(); + erase(); + flag = 0; + } + } + if (flag++) { + showit(); + flag = 0; + } + seed = time((time_t *) 0); + srand(seed); + explode(LINES - row, start + (diff * direction)); + erase(); + showit(); + } +} diff --git a/ncurses-5.3/test/firstlast.c b/ncurses-5.3/test/firstlast.c new file mode 100644 index 0000000..02c848e --- /dev/null +++ b/ncurses-5.3/test/firstlast.c @@ -0,0 +1,90 @@ +/* + * This test was written by Alexander V. Lukyanov to demonstrate difference + * between ncurses 4.1 and SVR4 curses + * + * $Id$ + */ + +#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(); + + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/gdc.6 b/ncurses-5.3/test/gdc.6 new file mode 100644 index 0000000..7fa60de --- /dev/null +++ b/ncurses-5.3/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/ncurses-5.3/test/gdc.c b/ncurses-5.3/test/gdc.c new file mode 100644 index 0000000..f107475 --- /dev/null +++ b/ncurses-5.3/test/gdc.c @@ -0,0 +1,316 @@ +/* + * 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$ + */ + +#include <time.h> + +#include <test.priv.h> + +#define YBASE 10 +#define XBASE 10 +#define XLENGTH 54 +#define YDEPTH 5 + +static short disp[11] = +{ + 075557, 011111, 071747, 071717, 055711, + 074717, 074757, 071111, 075757, 075717, 002020 +}; +static long older[6], next[6], newer[6], mask; + +static int sigtermed = 0; +static bool redirected = FALSE; +static bool hascolor = FALSE; + +static RETSIGTYPE +sighndl(int signo) +{ + signal(signo, sighndl); + sigtermed = signo; + if (redirected) { + endwin(); + ExitProgram(EXIT_FAILURE); + } +} + +static void +drawbox(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)); +} + +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 +set(int t, int n) +{ + int i, m; + + m = 7 << n; + for (i = 0; i < 5; i++) { + next[i] |= ((disp[t] >> ((4 - i) * 3)) & 07) << n; + mask |= (next[i] ^ older[i]) & m; + } + if (mask & m) + mask |= m; +} + +static void +usage(void) +{ + static const char *msg[] = + { + "Usage: gdc [options] [count]" + ,"" + ,"Options:" + ," -n redirect input to /dev/null" + ," -s scroll each number into place, rather than flipping" + ,"" + ,"If you specify a count, gdc runs for that number of seconds" + }; + unsigned j; + for (j = 0; j < SIZEOF(msg); j++) + fprintf(stderr, "%s\n", msg[j]); + ExitProgram(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + time_t now; + struct tm *tm; + long t, a; + int i, j, s, k; + int count = 0; + FILE *ofp = stdout; + FILE *ifp = stdin; + bool scrol = FALSE; + + setlocale(LC_ALL, ""); + + signal(SIGINT, sighndl); + signal(SIGTERM, sighndl); + + while ((k = getopt(argc, argv, "sn")) != EOF) { + switch (k) { + case 's': + scrol = TRUE; + break; + case 'n': + ifp = fopen("/dev/null", "r"); + redirected = TRUE; + break; + default: + usage(); + } + } + if (optind < argc) { + count = atoi(argv[optind++]); + } + if (optind < argc) + usage(); + + if (redirected) { + char *name = getenv("TERM"); + if (name == 0 + || newterm(name, ofp, ifp) == 0) { + fprintf(stderr, "cannot open terminal\n"); + ExitProgram(EXIT_FAILURE); + } + + } else { + initscr(); + } + cbreak(); + noecho(); + nodelay(stdscr, 1); + curs_set(0); + + hascolor = has_colors(); + + if (hascolor) { + int bg = COLOR_BLACK; + start_color(); +#if HAVE_USE_DEFAULT_COLORS + if (use_default_colors() == OK) + bg = -1; +#endif + init_pair(1, COLOR_BLACK, COLOR_RED); + init_pair(2, COLOR_RED, bg); + init_pair(3, COLOR_WHITE, bg); + attrset(COLOR_PAIR(2)); + } + + restart: + for (j = 0; j < 5; j++) + older[j] = newer[j] = next[j] = 0; + + clear(); + drawbox(); + + do { + char buf[30]; + + time(&now); + tm = localtime(&now); + + mask = 0; + set(tm->tm_sec % 10, 0); + set(tm->tm_sec / 10, 4); + set(tm->tm_min % 10, 10); + set(tm->tm_min / 10, 14); + set(tm->tm_hour % 10, 20); + set(tm->tm_hour / 10, 24); + set(10, 7); + set(10, 17); + + for (k = 0; k < 6; k++) { + if (scrol) { + for (i = 0; i < 5; i++) + newer[i] = (newer[i] & ~mask) | (newer[i + 1] & mask); + newer[5] = (newer[5] & ~mask) | (next[k] & mask); + } else + newer[k] = (newer[k] & ~mask) | (next[k] & mask); + next[k] = 0; + for (s = 1; s >= 0; s--) { + standt(s); + for (i = 0; i < 6; i++) { + if ((a = (newer[i] ^ older[i]) & (s ? newer : older)[i]) + != 0) { + for (j = 0, t = 1 << 26; t; t >>= 1, j++) { + if (a & t) { + if (!(a & (t << 1))) { + move(YBASE + i, XBASE + 2 * j); + } + addstr(" "); + } + } + } + if (!s) { + older[i] = newer[i]; + } + } + if (!s) { + if (scrol) + drawbox(); + refresh(); + /* + * If we're scrolling, space out the refreshes to fake + * movement. That's 7 frames, or 6 intervals, which would + * be 166 msec if we spread it out over a second. It looks + * better (but will well on a slow terminal, e.g., less + * than 9600bd) to squeeze that into a half-second, and use + * half of 170 msec to ensure that the program doesn't eat + * a lot of time when asking what time it is, at the top of + * this loop -TD + */ + if (scrol) + napms(85); + } + } + } + + /* this depends on the detailed format of ctime(3) */ + (void) strcpy(buf, ctime(&now)); + (void) strcpy(buf + 10, buf + 19); + mvaddstr(16, 30, buf); + + move(6, 0); + drawbox(); + refresh(); + + /* + * If we're not scrolling, wait 1000 msec (1 sec). Use napms() rather + * than sleep() because the latter does odd things on some systems, + * e.g., suspending output as well. + */ + if (scrol) + napms(500); + else + napms(1000); + + /* + * This is a safe way to check if we're interrupted - making the signal + * handler set a flag that we can check. Since we're running + * nodelay(), the wgetch() call returns immediately, and in particular + * will return an error if interrupted. This works only if we can + * read from the input, of course. + */ + switch (wgetch(stdscr)) { + case 'q': + count = 1; + break; + case 's': + nodelay(stdscr, FALSE); + break; + case ' ': + nodelay(stdscr, TRUE); + break; +#ifdef KEY_RESIZE + case KEY_RESIZE: +#endif + case '?': + goto restart; + case ERR: + if (sigtermed) { + standend(); + endwin(); + fprintf(stderr, "gdc terminated by signal %d\n", sigtermed); + ExitProgram(EXIT_FAILURE); + } + /* FALLTHRU */ + default: + continue; + } + } while (--count); + standend(); + endwin(); + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/hanoi.c b/ncurses-5.3/test/hanoi.c new file mode 100644 index 0000000..3901a54 --- /dev/null +++ b/ncurses-5.3/test/hanoi.c @@ -0,0 +1,303 @@ +/* + * 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$ + */ + +#include <test.priv.h> + +#define NPEGS 3 /* This is not configurable !! */ +#define MINTILES 3 +#define MAXTILES 9 +#define DEFAULTTILES 7 +#define TOPLINE 6 +#define BASELINE 16 +#define STATUSLINE (LINES-3) +#define LEFTPEG 19 +#define MIDPEG 39 +#define RIGHTPEG 59 + +#define LENTOIND(x) (((x)-1)/2) +#define OTHER(a,b) (3-((a)+(b))) + +struct Peg { + size_t Length[MAXTILES]; + int Count; +}; + +static struct Peg Pegs[NPEGS]; +static int PegPos[] = +{LEFTPEG, MIDPEG, RIGHTPEG}; +static int TileColour[] = +{ + COLOR_GREEN, /* Length 3 */ + COLOR_MAGENTA, /* Length 5 */ + COLOR_RED, /* Length 7 */ + COLOR_BLUE, /* Length 9 */ + COLOR_CYAN, /* Length 11 */ + COLOR_YELLOW, /* Length 13 */ + COLOR_GREEN, /* Length 15 */ + COLOR_MAGENTA, /* Length 17 */ + COLOR_RED, /* Length 19 */ +}; +static int NMoves = 0; + +static 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; + bool AutoFlag = 0; + + setlocale(LC_ALL, ""); + + switch (argc) { + case 1: + NTiles = DEFAULTTILES; + break; + case 2: + NTiles = atoi(argv[1]); + if (NTiles > MAXTILES || NTiles < MINTILES) { + fprintf(stderr, "Range %d to %d\n", MINTILES, MAXTILES); + ExitProgram(EXIT_FAILURE); + } + break; + case 3: + if (strcmp(argv[2], "a")) { + Usage(); + ExitProgram(EXIT_FAILURE); + } + NTiles = atoi(argv[1]); + if (NTiles > MAXTILES || NTiles < MINTILES) { + fprintf(stderr, "Range %d to %d\n", MINTILES, MAXTILES); + ExitProgram(EXIT_FAILURE); + } + AutoFlag = TRUE; + break; + default: + Usage(); + ExitProgram(EXIT_FAILURE); + } +#ifdef TRACE + trace(TRACE_MAXIMUM); +#endif + initscr(); + if (has_colors()) { + int i; + int bg = COLOR_BLACK; + start_color(); +#if HAVE_USE_DEFAULT_COLORS + if (use_default_colors() == OK) + bg = -1; +#endif + for (i = 0; i < 9; i++) + init_pair(i + 1, bg, TileColour[i]); + } + cbreak(); + if (LINES < 24) { + endwin(); + fprintf(stderr, "Min screen length 24 lines\n"); + ExitProgram(EXIT_FAILURE); + } + if (AutoFlag) { + curs_set(0); + leaveok(stdscr, TRUE); /* Attempt to remove cursor */ + } + InitTiles(NTiles); + DisplayTiles(); + if (AutoFlag) { + do { + noecho(); + AutoMove(0, 2, NTiles); + } while (!Solved(NTiles)); + sleep(2); + } else { + echo(); + for (;;) { + if (GetMove(&FromCol, &ToCol)) + break; + if (InvalidMove(FromCol, ToCol)) { + mvaddstr(STATUSLINE, 0, "Invalid Move !!"); + refresh(); + beep(); + continue; + } + MakeMove(FromCol, ToCol); + if (Solved(NTiles)) { + mvprintw(STATUSLINE, 0, + "Well Done !! You did it in %d moves", NMoves); + refresh(); + sleep(5); + break; + } + } + } + endwin(); + ExitProgram(EXIT_SUCCESS); +} + +static int +InvalidMove(int From, int To) +{ + if (From >= NPEGS) + return TRUE; + if (From < 0) + return TRUE; + if (To >= NPEGS) + return TRUE; + if (To < 0) + return TRUE; + if (From == To) + return TRUE; + if (!Pegs[From].Count) + return TRUE; + if (Pegs[To].Count && + Pegs[From].Length[Pegs[From].Count - 1] > + Pegs[To].Length[Pegs[To].Count - 1]) + return TRUE; + return FALSE; +} + +static void +InitTiles(int NTiles) +{ + int Size, SlotNo; + + for (Size = NTiles * 2 + 1, SlotNo = 0; Size >= 3; Size -= 2) + Pegs[0].Length[SlotNo++] = Size; + + Pegs[0].Count = NTiles; + Pegs[1].Count = 0; + Pegs[2].Count = 0; +} + +static void +DisplayTiles(void) +{ + int Line, peg, SlotNo; + char TileBuf[BUFSIZ]; + + erase(); + mvaddstr(1, 24, "T O W E R S O F H A N O I"); + mvaddstr(3, 34, "SJR 1990"); + mvprintw(19, 5, "Moves : %d", NMoves); + attrset(A_REVERSE); + mvaddstr(BASELINE, 8, + " "); + + for (Line = TOPLINE; Line < BASELINE; Line++) { + mvaddch(Line, LEFTPEG, ' '); + mvaddch(Line, MIDPEG, ' '); + mvaddch(Line, RIGHTPEG, ' '); + } + mvaddch(BASELINE, LEFTPEG, '1'); + mvaddch(BASELINE, MIDPEG, '2'); + mvaddch(BASELINE, RIGHTPEG, '3'); + attrset(A_NORMAL); + + /* Draw tiles */ + for (peg = 0; peg < NPEGS; peg++) { + for (SlotNo = 0; SlotNo < Pegs[peg].Count; SlotNo++) { + 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(void) +{ + fprintf(stderr, "Usage: hanoi [<No Of Tiles>] [a]\n"); + fprintf(stderr, + "The 'a' option causes the tower to be solved automatically\n"); +} diff --git a/ncurses-5.3/test/hashtest.c b/ncurses-5.3/test/hashtest.c new file mode 100644 index 0000000..aa5a7f0 --- /dev/null +++ b/ncurses-5.3/test/hashtest.c @@ -0,0 +1,228 @@ +/* + * hashtest.c -- test hash mapping + * + * Generate timing statistics for vertical-motion optimization. + * + * $Id$ + */ + +#ifdef TRACE +#define Trace(p) _tracef p +#define USE_TRACE 1 +#else +#define Trace(p) /* nothing */ +#define USE_TRACE 0 +#endif + +#include <ctype.h> + +#include <test.priv.h> + +#define LO_CHAR ' ' +#define HI_CHAR '~' + +static bool continuous = FALSE; +static bool reverse_loops = FALSE; +static bool single_step = FALSE; +static bool extend_corner = FALSE; +static int foot_lines = 0; +static int head_lines = 0; + +static void +cleanup(void) +{ + move(LINES - 1, 0); + clrtoeol(); + refresh(); + endwin(); +} + +static RETSIGTYPE +finish(int sig GCC_UNUSED) +{ + cleanup(); + ExitProgram(EXIT_FAILURE); +} + +static void +genlines(int base) +{ + int i, j; + +#if USE_TRACE + if (base == 'a') + Trace(("Resetting screen")); + else + Trace(("Painting `%c' screen", base)); +#endif + + /* Do this so writes to lower-right corner don't cause a spurious + * scrolling operation. This _shouldn't_ break the scrolling + * optimization, since that's computed in the refresh() call. + */ + scrollok(stdscr, FALSE); + + move(0, 0); + for (i = 0; i < head_lines; i++) + for (j = 0; j < COLS; j++) + addch((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 GCC_UNUSED) +{ + char ch; + int lo = continuous ? LO_CHAR : 'a' - LINES; + int hi = continuous ? HI_CHAR : 'a' + LINES; + + if (lo < LO_CHAR) + lo = LO_CHAR; + if (hi > HI_CHAR) + hi = HI_CHAR; + +#if defined(TRACE) || defined(NCURSES_TEST) + if (optimized) { + Trace(("With hash mapping")); + _nc_optimize_enable |= OPTIMIZE_HASHMAP; + } else { + Trace(("Without hash mapping")); + _nc_optimize_enable &= ~OPTIMIZE_HASHMAP; + } +#endif + + if (reverse_loops) + for (ch = hi; ch >= lo; ch--) + one_cycle(ch); + else + for (ch = lo; ch <= hi; ch++) + one_cycle(ch); +} + +static void +usage(void) +{ + static const char *const tbl[] = + { + "Usage: hashtest [options]" + ,"" + ,"Options:" + ," -c continuous (don't reset between refresh's)" + ," -f num leave 'num' lines constant for footer" + ," -h num leave 'num' lines constant for header" + ," -l num repeat test 'num' times" + ," -n test the normal optimizer" + ," -o test the hashed optimizer" + ," -r reverse the loops" + ," -s single-step" + ," -x assume lower-right corner extension" + }; + size_t n; + + for (n = 0; n < SIZEOF(tbl); n++) + fprintf(stderr, "%s\n", tbl[n]); + ExitProgram(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + int c; + int test_loops = 1; + int test_normal = FALSE; + int test_optimize = FALSE; + + setlocale(LC_ALL, ""); + + while ((c = getopt(argc, argv, "cf:h:l:norsx")) != 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 */ + ExitProgram(EXIT_SUCCESS); +} +/* hashtest.c ends here */ diff --git a/ncurses-5.3/test/keynames.c b/ncurses-5.3/test/keynames.c new file mode 100644 index 0000000..7ab38ad --- /dev/null +++ b/ncurses-5.3/test/keynames.c @@ -0,0 +1,17 @@ +/* + * $Id$ + */ + +#include <test.priv.h> + +int +main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) +{ + int n; + for (n = -1; n < 512; n++) { + char *result = keyname(n); + if (result != 0) + printf("%d(%5o):%s\n", n, n, result); + } + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/knight.c b/ncurses-5.3/test/knight.c new file mode 100644 index 0000000..974c6b5 --- /dev/null +++ b/ncurses-5.3/test/knight.c @@ -0,0 +1,702 @@ +/* + * 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$ + */ + +#include <ctype.h> + +#include <test.priv.h> + +/* board size */ +#define BDEPTH 8 +#define BWIDTH 8 + +/* where to start the instructions */ +#define INSTRY 2 +#define INSTRX 35 + +/* corner of board */ +#define BOARDY 2 +#define BOARDX 0 + +/* notification line */ +#define NOTIFYY 21 + +/* virtual color values */ +#define TRAIL_COLOR 1 +#define PLUS_COLOR 2 +#define MINUS_COLOR 3 + +#define CX(x) (2 + 4 * (x)) +#define CY(y) (1 + 2 * (y)) +#define cellmove(y, x) wmove(boardwin, CY(y), CX(x)) +#define CXINV(x) (((x) - 1) / 4) +#define CYINV(y) (((y) - 2) / 2) + +typedef struct { + short x, y; +} cell; + +static WINDOW *boardwin; /* the board window */ +static WINDOW *helpwin; /* the help window */ +static WINDOW *msgwin; /* the message window */ +static cell history[BDEPTH * BWIDTH + 1]; /* choice history */ +static chtype minus = '-'; /* possible-move character */ +static chtype oldch; +static chtype plus = '+'; /* cursor hot-spot character */ +static chtype trail = '#'; /* trail character */ +static int movecount; /* count of moves so far */ +static int trialcount; /* count of trials so far */ +static short board[BDEPTH][BWIDTH]; /* the squares */ +/* *INDENT-OFF* */ +static const struct { + int y; + int x; +} offsets[] = { + { 2, 1 }, + { 1, 2 }, + { -1, 2 }, + { -2, 1 }, + { -2, -1 }, + { -1, -2 }, + { 1, -2 }, + { 2, -1 }, +}; +/* *INDENT-ON* */ + +static void +init_program(void) +{ + setlocale(LC_ALL, ""); + + srand((unsigned) getpid()); + initscr(); + cbreak(); /* immediate char return */ + noecho(); /* no immediate echo */ + boardwin = newwin(BDEPTH * 2 + 1, BWIDTH * 4 + 1, BOARDY, BOARDX); + helpwin = newwin(0, 0, INSTRY, INSTRX); + msgwin = newwin(1, INSTRX - 1, NOTIFYY, 0); + scrollok(msgwin, TRUE); + keypad(boardwin, TRUE); + + if (has_colors()) { + int bg = COLOR_BLACK; + + start_color(); +#if HAVE_USE_DEFAULT_COLORS + if (use_default_colors() == OK) + bg = -1; +#endif + + (void) init_pair(TRAIL_COLOR, COLOR_CYAN, bg); + (void) init_pair(PLUS_COLOR, COLOR_RED, bg); + (void) init_pair(MINUS_COLOR, COLOR_GREEN, bg); + + trail |= COLOR_PAIR(TRAIL_COLOR); + plus |= COLOR_PAIR(PLUS_COLOR); + minus |= COLOR_PAIR(MINUS_COLOR); + } +#ifdef NCURSES_MOUSE_VERSION + (void) mousemask(BUTTON1_CLICKED, (mmask_t *) NULL); +#endif /* NCURSES_MOUSE_VERSION */ + + oldch = minus; +} + +static void +help1(void) +/* game explanation -- initial help screen */ +{ + (void) waddstr(helpwin, "Knight's move is a solitaire puzzle. Your\n"); + (void) waddstr(helpwin, "objective is to visit each square of the \n"); + (void) waddstr(helpwin, "chessboard exactly once by making knight's\n"); + (void) waddstr(helpwin, "moves (one square right or left followed \n"); + (void) waddstr(helpwin, "by two squares up or down, or two squares \n"); + (void) waddstr(helpwin, "right or left followed by one square up or\n"); + (void) waddstr(helpwin, "down). You may start anywhere.\n\n"); + + (void) waddstr(helpwin, "Use arrow keys to move the cursor around.\n"); + (void) waddstr(helpwin, "When you want to move your knight to the \n"); + (void) waddstr(helpwin, "cursor location, press <space> or Enter.\n"); + (void) waddstr(helpwin, "Illegal moves will be rejected with an \n"); + (void) waddstr(helpwin, "audible beep.\n\n"); + (void) waddstr(helpwin, "The program will detect if you solve the\n"); + (void) waddstr(helpwin, "puzzle; also inform you when you run out\n"); + (void) waddstr(helpwin, "of legal moves.\n\n"); + + (void) mvwaddstr(helpwin, NOTIFYY - INSTRY, 0, + "Press `?' to go to keystroke help."); +} + +static void +help2(void) +/* keystroke help screen */ +{ + (void) waddstr(helpwin, "Possible moves are shown with `-'.\n\n"); + + (void) waddstr(helpwin, "You can move around with the arrow keys or\n"); + (void) waddstr(helpwin, "with the rogue/hack movement keys. Other\n"); + (void) waddstr(helpwin, "commands allow you to undo moves or redraw.\n"); + (void) waddstr(helpwin, "Your mouse may work; try left-button to\n"); + (void) waddstr(helpwin, "move to the square under the pointer.\n\n"); + + (void) waddstr(helpwin, "x,q -- exit y k u 7 8 9\n"); + (void) waddstr(helpwin, "r -- redraw screen \\|/ \\|/ \n"); + (void) waddstr(helpwin, "bksp -- undo move h-+-l 4-+-6\n"); + (void) waddstr(helpwin, "a -- autojump /|\\ /|\\ \n"); + (void) waddstr(helpwin, " b j n 1 2 3\n"); + + (void) waddstr(helpwin, "\nYou can place your knight on the selected\n"); + (void) waddstr(helpwin, "square with spacebar, Enter, or the keypad\n"); + (void) waddstr(helpwin, "center key. Use F/B to review the path.\n"); + + (void) mvwaddstr(helpwin, NOTIFYY - INSTRY, 0, + "Press `?' to go to game explanation"); +} + +static void +show_help(bool * keyhelp) +{ + werase(helpwin); + if (*keyhelp) { + help1(); + *keyhelp = FALSE; + } else { + help2(); + *keyhelp = TRUE; + } + wrefresh(helpwin); +} + +static bool +chksqr(int r1, int c1) +{ + if ((r1 < 0) || (r1 > BDEPTH - 1)) + return (FALSE); + if ((c1 < 0) || (c1 > BWIDTH - 1)) + return (FALSE); + return ((!board[r1][c1]) ? TRUE : FALSE); +} + +static bool +chkmoves(int rw, int col) +/* check to see if valid moves are available */ +{ + unsigned n; + + for (n = 0; n < SIZEOF(offsets); n++) + if (chksqr(rw + offsets[n].y, col + offsets[n].x)) + return (TRUE); + return (FALSE); +} + +static void +dosquares(void) +{ + int i, j; + + mvaddstr(0, 20, "KNIGHT'S MOVE -- a logical solitaire"); + + move(BOARDY, BOARDX); + waddch(boardwin, ACS_ULCORNER); + for (j = 0; j < 7; j++) { + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_TTEE); + } + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_URCORNER); + + for (i = 1; i < BDEPTH; i++) { + move(BOARDY + i * 2 - 1, BOARDX); + waddch(boardwin, ACS_VLINE); + for (j = 0; j < BWIDTH; j++) { + waddch(boardwin, ' '); + waddch(boardwin, ' '); + waddch(boardwin, ' '); + waddch(boardwin, ACS_VLINE); + } + move(BOARDY + i * 2, BOARDX); + waddch(boardwin, ACS_LTEE); + for (j = 0; j < BWIDTH - 1; j++) { + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_PLUS); + } + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_RTEE); + } + + move(BOARDY + i * 2 - 1, BOARDX); + waddch(boardwin, ACS_VLINE); + for (j = 0; j < BWIDTH; j++) { + waddch(boardwin, ' '); + waddch(boardwin, ' '); + waddch(boardwin, ' '); + waddch(boardwin, ACS_VLINE); + } + + move(BOARDY + i * 2, BOARDX); + waddch(boardwin, ACS_LLCORNER); + for (j = 0; j < BWIDTH - 1; j++) { + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_BTEE); + } + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_HLINE); + waddch(boardwin, ACS_LRCORNER); +} + +static void +mark_possibles(int prow, int pcol, chtype mark) +{ + unsigned n; + + for (n = 0; n < SIZEOF(offsets); n++) { + if (chksqr(prow + offsets[n].y, pcol + offsets[n].x)) { + cellmove(prow + offsets[n].y, pcol + offsets[n].x); + waddch(boardwin, mark); + } + } +} + +static void +find_next_move(int *y, int *x) +{ + unsigned j, k; + int found = -1; + int first = -1; + int next = 0; + int oldy, oldx; + int newy, newx; + + if (movecount > 1) { + oldy = history[movecount - 1].y; + oldx = history[movecount - 1].x; + for (j = 0; j < SIZEOF(offsets) * 2; j++) { + k = j % SIZEOF(offsets); + newy = oldy + offsets[k].y; + newx = oldx + offsets[k].x; + if (chksqr(newy, newx)) { + if (first < 0) + first = k; + if (newy == *y + && newx == *x) { + found = k; + } else if (found >= 0) { + next = k; + break; + } + } + } + if (found < 0) + next = first; + if (next >= 0) { + *y = oldy + offsets[next].y; + *x = oldx + offsets[next].x; + } + } else { + beep(); + } +} + +static void +unmarkcell(int row, int column) +{ + cellmove(row, column); + waddch(boardwin, '\b'); + waddch(boardwin, ' '); + waddch(boardwin, minus); + waddch(boardwin, ' '); +} + +static void +markcell(chtype tchar, int row, int column) +{ + cellmove(row, column); + waddch(boardwin, '\b'); + waddch(boardwin, tchar); + waddch(boardwin, tchar); + waddch(boardwin, tchar); +} + +static void +drawmove(chtype tchar, int oldy, int oldx, int row, int column) +/* place the stars, update board & currents */ +{ + if (movecount <= 1) { + int i, j; + + for (i = 0; i < BDEPTH; i++) { + for (j = 0; j < BWIDTH; j++) { + if (movecount == 0) { + unmarkcell(i, j); + } else { + cellmove(i, j); + if (winch(boardwin) == minus) + waddch(boardwin, movecount ? ' ' : minus); + } + } + } + } else { + markcell(tchar, oldy, oldx); + mark_possibles(oldy, oldx, ' '); + } + + if (row != -1 && column != -1) { + markcell(trail, row, column); + mark_possibles(row, column, minus); + board[row][column] = TRUE; + } + + wprintw(msgwin, "\nMove %d", movecount); + if (trialcount != movecount) + wprintw(msgwin, " (%d tries)", trialcount); + wclrtoeol(msgwin); +} + +static int +iabs(int num) +{ + if (num < 0) + return (-num); + else + return (num); +} + +static bool +evalmove(int row, int column) +/* evaluate move */ +{ + if (movecount == 1) + return (TRUE); + else if (board[row][column] == TRUE) { + waddstr(msgwin, "\nYou've already been there."); + return (FALSE); + } else { + int rdif = iabs(row - history[movecount - 1].y); + int cdif = iabs(column - history[movecount - 1].x); + + if (!((rdif == 1) && (cdif == 2)) && !((rdif == 2) && (cdif == 1))) { + waddstr(msgwin, "\nThat's not a legal knight's move."); + return (FALSE); + } + } + + return (TRUE); +} + +static int +completed(void) +{ + int i, j, count = 0; + + for (i = 0; i < BDEPTH; i++) + for (j = 0; j < BWIDTH; j++) + if (board[i][j] != 0) + count += 1; + return (count == (BWIDTH * BDEPTH) ? -1 : count); +} + +static void +no_previous_move(void) +{ + waddstr(msgwin, "\nNo previous move."); + beep(); +} + +static void +play(void) +/* play the game */ +{ + bool keyhelp; /* TRUE if keystroke help is up */ + int i, j, count; + int lastcol = 0; /* last location visited */ + int lastrow = 0; + int ny = 0, nx = 0; + int review = 0; /* review history */ + int rw = 0, col = 0; /* current row and column */ + + do { + /* clear screen and draw board */ + werase(boardwin); + werase(helpwin); + werase(msgwin); + dosquares(); + help1(); + wnoutrefresh(stdscr); + wnoutrefresh(helpwin); + wnoutrefresh(msgwin); + wnoutrefresh(boardwin); + doupdate(); + + movecount = 0; + for (i = 0; i < BDEPTH; i++) { + for (j = 0; j < BWIDTH; j++) { + board[i][j] = FALSE; + unmarkcell(i, j); + } + } + memset(history, 0, sizeof(history)); + history[0].y = history[0].x = -1; + history[1].y = history[1].x = -1; + lastrow = lastcol = -2; + movecount = 1; + trialcount = 1; + keyhelp = FALSE; + show_help(&keyhelp); + + for (;;) { + if (rw != lastrow || col != lastcol) { + if (lastrow >= 0 && lastcol >= 0) { + cellmove(lastrow, lastcol); + if (board[lastrow][lastcol]) + waddch(boardwin, trail); + else + waddch(boardwin, oldch); + } + + cellmove(rw, col); + oldch = winch(boardwin); + + lastrow = rw; + lastcol = col; + } + cellmove(rw, col); + waddch(boardwin, plus); + cellmove(rw, col); + + wrefresh(msgwin); + + switch (wgetch(boardwin)) { + case 'k': + case '8': + case KEY_UP: + ny = rw + BDEPTH - 1; + nx = col; + break; + case 'j': + case '2': + case KEY_DOWN: + ny = rw + 1; + nx = col; + break; + case 'h': + case '4': + case KEY_LEFT: + ny = rw; + nx = col + BWIDTH - 1; + break; + case 'l': + case '6': + case KEY_RIGHT: + ny = rw; + nx = col + 1; + break; + case 'y': + case '7': + case KEY_A1: + ny = rw + BDEPTH - 1; + nx = col + BWIDTH - 1; + break; + case 'b': + case '1': + case KEY_C1: + ny = rw + 1; + nx = col + BWIDTH - 1; + break; + case 'u': + case '9': + case KEY_A3: + ny = rw + BDEPTH - 1; + nx = col + 1; + break; + case 'n': + case '3': + case KEY_C3: + ny = rw + 1; + nx = col + 1; + break; + +#ifdef NCURSES_MOUSE_VERSION + case KEY_MOUSE: + { + MEVENT myevent; + + getmouse(&myevent); + if (myevent.y >= CY(0) && myevent.y <= CY(BDEPTH) + && myevent.x >= CX(0) && myevent.x <= CX(BWIDTH)) { + nx = CXINV(myevent.x); + ny = CYINV(myevent.y); + ungetch('\n'); + break; + } else { + beep(); + continue; + } + } +#endif /* NCURSES_MOUSE_VERSION */ + + case KEY_B2: + case '\n': + case ' ': + review = 0; + if (evalmove(rw, col)) { + drawmove(trail, + history[movecount - 1].y, + history[movecount - 1].x, + rw, col); + history[movecount].y = rw; + history[movecount].x = col; + movecount++; + trialcount++; + + if (!chkmoves(rw, col)) { + if (completed() < 0) { + waddstr(msgwin, "\nYou won."); + } else { + waddstr(msgwin, + "\nNo further moves are possible."); + } + } + } else { + beep(); + } + break; + + case KEY_UNDO: + case KEY_BACKSPACE: + case '\b': + review = 0; + if (movecount <= 0) { + no_previous_move(); + } else if (movecount <= 1) { + ny = history[movecount].y; + nx = history[movecount].x; + if (nx < 0 || ny < 0) { + ny = lastrow; + nx = lastcol; + } + movecount = 0; + board[ny][nx] = FALSE; + oldch = minus; + drawmove(' ', ny, nx, -1, -1); + movecount = 1; + trialcount = 1; + no_previous_move(); + } else { + int oldy = history[movecount - 1].y; + int oldx = history[movecount - 1].x; + + if (!board[rw][col]) { + cellmove(rw, col); + waddch(boardwin, ' '); + } + + board[oldy][oldx] = FALSE; + --movecount; + ny = history[movecount - 1].y; + nx = history[movecount - 1].x; + if (nx < 0 || ny < 0) { + ny = oldy; + nx = oldx; + } + drawmove(' ', oldy, oldx, ny, nx); + + /* avoid problems if we just changed the current cell */ + cellmove(lastrow, lastcol); + oldch = winch(boardwin); + } + break; + + case 'a': + nx = col; + ny = rw; + find_next_move(&ny, &nx); + break; + + case 'F': + if (review > 0) { + review--; + ny = history[movecount - review - 1].y; + nx = history[movecount - review - 1].x; + } else { + beep(); + } + break; + + case 'B': + if (review < movecount - 2) { + review++; + ny = history[movecount - review - 1].y; + nx = history[movecount - review - 1].x; + } else { + beep(); + } + break; + + case KEY_REDO: + case '\f': + case 'r': + clearok(curscr, TRUE); + wnoutrefresh(stdscr); + wnoutrefresh(boardwin); + wnoutrefresh(msgwin); + wnoutrefresh(helpwin); + doupdate(); + break; + + case 'q': + case 'x': + goto dropout; + + case '?': + show_help(&keyhelp); + break; + + default: + beep(); + break; + } + + col = nx % BWIDTH; + rw = ny % BDEPTH; + } + + dropout: + if ((count = completed()) < 0) + wprintw(msgwin, "\nYou won. Care to try again? "); + else + wprintw(msgwin, "\n%d squares filled. Try again? ", count); + wclrtoeol(msgwin); + } while + (tolower(wgetch(msgwin)) == 'y'); +} + +int +main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) +{ + init_program(); + + play(); + + endwin(); + ExitProgram(EXIT_SUCCESS); +} + +/* knight.c ends here */ diff --git a/ncurses-5.3/test/lrtest.c b/ncurses-5.3/test/lrtest.c new file mode 100644 index 0000000..f47694d --- /dev/null +++ b/ncurses-5.3/test/lrtest.c @@ -0,0 +1,152 @@ +/* + * Test lower-right-hand corner access + * + * originally by Eric S. Raymond <esr@thyrsus.com>, written for animation + * and resizing -TD + * + * This can't be part of the ncurses test-program, because ncurses rips off the + * bottom line to do labels. + * + * $Id$ + */ + +#include <test.priv.h> + +typedef struct { + int y, x, mode, dir, inc; + chtype value; +} MARK; + +/* + * Make a couple of markers go 'round the border to demonstrate that we can + * really write to all positions properly. + */ +static void +show(MARK * m) +{ + mvaddch(m->y, m->x, m->value); + if (m->mode == 0) { /* along the x-direction */ + m->x += m->inc; + if (m->x >= COLS) { + m->x = COLS - 1; + m->inc = -m->dir * m->inc; + m->y += m->inc; + m->mode = 1; + } else if (m->x < 0) { + m->x = 0; + m->inc = -m->dir * m->inc; + m->y += m->inc; + m->mode = 1; + } + } else { /* along the y-direction */ + m->y += m->inc; + if (m->y >= LINES) { + m->y = LINES - 1; + m->inc = m->dir * m->inc; + m->x += m->inc; + m->mode = 0; + } else if (m->y < 0) { + m->y = 0; + m->inc = m->dir * m->inc; + m->x += m->inc; + m->mode = 0; + } + } +} + +int +main( + int argc GCC_UNUSED, + char *argv[]GCC_UNUSED) +{ + static MARK marks[] = + { + {0, 0, 0, -1, 1, '+' | A_BOLD}, + {0, 0, 1, 1, 2, 'X'}, + {0, 0, 1, -1, 3, 'Y'}, + {0, 8, 0, -1, 1, '+' | A_BOLD}, + {0, 9, 0, -1, 1, '+' | A_BOLD}, + {1, 0, 1, 1, 1, '*' | A_REVERSE}, + {2, 0, 1, 1, 1, '*' | A_REVERSE} + }; + + setlocale(LC_ALL, ""); + + initscr(); + noecho(); + cbreak(); + nodelay(stdscr, TRUE); + curs_set(0); + +#ifdef KEY_RESIZE + keypad(stdscr, TRUE); + restart: +#endif + move(LINES / 2 - 1, 4); + if (!(has_ic() + /* see PutCharLR() */ + || auto_right_margin + || (enter_am_mode && exit_am_mode))) { + addstr("Your terminal lacks the capabilities needed to address the\n"); + move(LINES / 2, 4); + addstr("lower-right-hand corner of the screen.\n"); + } else { + addstr("This is a test of access to the lower right corner.\n"); + move(LINES / 2, 4); + addstr("If the top of the box is missing, the test failed.\n"); + move(LINES / 2 + 1, 4); + addstr("Please report this (with a copy of your terminfo entry).\n"); + move(LINES / 2 + 2, 4); + addstr("to the ncurses maintainers, at bug-ncurses@gnu.org.\n"); + } + + for (;;) { + int ch; + unsigned n; + + box(stdscr, 0, 0); + for (n = 0; n < SIZEOF(marks); n++) { + show(&marks[n]); + } + + if ((ch = getch()) > 0) { + if (ch == 'q') + break; + else if (ch == 's') + nodelay(stdscr, FALSE); + else if (ch == ' ') + nodelay(stdscr, TRUE); +#ifdef TRACE + else if (ch == 'T') + trace(0); + else if (ch == 't') + trace(TRACE_CALLS|TRACE_ICALLS|TRACE_UPDATE); +#endif +#ifdef KEY_RESIZE + else if (ch == KEY_RESIZE) { + for (n = 0; n < SIZEOF(marks); n++) { + if (marks[n].mode == 0) { /* moving along x-direction */ + if (marks[n].y) + marks[n].y = LINES - 1; + } else { + if (marks[n].x) + marks[n].x = COLS - 1; + } + } + flash(); + erase(); + wrefresh(curscr); + goto restart; + } +#endif + } + napms(50); + refresh(); + } + + curs_set(1); + endwin(); + ExitProgram(EXIT_SUCCESS); +} + +/* lrtest.c ends here */ diff --git a/ncurses-5.3/test/modules b/ncurses-5.3/test/modules new file mode 100644 index 0000000..8e61243 --- /dev/null +++ b/ncurses-5.3/test/modules @@ -0,0 +1,59 @@ +# Test-Program modules +# $Id$ +############################################################################## +# Copyright (c) 1998,1999,2000 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) +dots progs $(srcdir) ../include/term.h +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 +railroad progs $(srcdir) ../include/termcap.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/ncurses-5.3/test/ncurses.c b/ncurses-5.3/test/ncurses.c new file mode 100644 index 0000000..64e7d68 --- /dev/null +++ b/ncurses-5.3/test/ncurses.c @@ -0,0 +1,4333 @@ +/**************************************************************************** + * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ +/**************************************************************************** + +NAME + ncurses.c --- ncurses library exerciser + +SYNOPSIS + ncurses + +DESCRIPTION + An interactive test module for the ncurses library. + +AUTHOR + Author: Eric S. Raymond <esr@snark.thyrsus.com> 1993 + Thomas E. Dickey (beginning revision 1.27 in 1996). + +$Id$ + +***************************************************************************/ + +#include <stdio.h> +#include <ctype.h> +#include <assert.h> + +#include <test.priv.h> + +#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 && HAVE_LIBPANEL +#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 + +#else + +#define mmask_t chtype /* not specified in XSI */ + +#ifdef CURSES_ACS_ARRAY +#define ACS_S3 (CURSES_ACS_ARRAY['p']) /* scan line 3 */ +#define ACS_S7 (CURSES_ACS_ARRAY['r']) /* scan line 7 */ +#define ACS_LEQUAL (CURSES_ACS_ARRAY['y']) /* less/equal */ +#define ACS_GEQUAL (CURSES_ACS_ARRAY['z']) /* greater/equal */ +#define ACS_PI (CURSES_ACS_ARRAY['{']) /* Pi */ +#define ACS_NEQUAL (CURSES_ACS_ARRAY['|']) /* not equal */ +#define ACS_STERLING (CURSES_ACS_ARRAY['}']) /* UK pound sign */ +#else +#define ACS_S3 (A_ALTCHARSET + 'p') /* scan line 3 */ +#define ACS_S7 (A_ALTCHARSET + 'r') /* scan line 7 */ +#define ACS_LEQUAL (A_ALTCHARSET + 'y') /* less/equal */ +#define ACS_GEQUAL (A_ALTCHARSET + 'z') /* greater/equal */ +#define ACS_PI (A_ALTCHARSET + '{') /* Pi */ +#define ACS_NEQUAL (A_ALTCHARSET + '|') /* not equal */ +#define ACS_STERLING (A_ALTCHARSET + '}') /* UK pound sign */ +#endif + +#ifdef CURSES_WACS_ARRAY +#define WACS_S3 (&(CURSES_WACS_ARRAY['p'])) /* scan line 3 */ +#define WACS_S7 (&(CURSES_WACS_ARRAY['r'])) /* scan line 7 */ +#define WACS_LEQUAL (&(CURSES_WACS_ARRAY['y'])) /* less/equal */ +#define WACS_GEQUAL (&(CURSES_WACS_ARRAY['z'])) /* greater/equal */ +#define WACS_PI (&(CURSES_WACS_ARRAY['{'])) /* Pi */ +#define WACS_NEQUAL (&(CURSES_WACS_ARRAY['|'])) /* not equal */ +#define WACS_STERLING (&(CURSES_WACS_ARRAY['}'])) /* UK pound sign */ +#endif + +#endif + +#define P(string) printw("%s\n", string) +#ifdef CTRL +#undef CTRL +#endif +#define CTRL(x) ((x) & 0x1f) + +#define QUIT CTRL('Q') +#define ESCAPE CTRL('[') +#define BLANK ' ' /* this is the background character */ + +#undef max_colors +static int max_colors; /* the actual number of colors we'll use */ + +#undef max_pairs +static int max_pairs; /* ...and the number of color pairs */ + +/* 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) + +#if USE_WIDEC_SUPPORT +static int +wGet_wchar(WINDOW *win, wint_t * result) +{ + int c; +#ifdef TRACE + while ((c = wget_wch(win, result)) == CTRL('T')) { + if (_nc_tracing) { + save_trace = _nc_tracing; + _tracef("TOGGLE-TRACING OFF"); + _nc_tracing = 0; + } else { + _nc_tracing = save_trace; + } + trace(_nc_tracing); + if (_nc_tracing) + _tracef("TOGGLE-TRACING ON"); + } +#else + c = wget_wch(win, result); +#endif + return c; +} +#define Get_wchar(result) wGet_wchar(stdscr, result) + +#endif + +static void +Pause(void) +{ + move(LINES - 1, 0); + addstr("Press any key to continue... "); + (void) Getchar(); +} + +static void +Cannot(const char *what) +{ + printw("\nThis %s terminal %s\n\n", getenv("TERM"), what); + Pause(); +} + +static void +ShellOut(bool message) +{ + if (message) + addstr("Shelling out..."); + def_prog_mode(); + endwin(); + system("sh"); + if (message) + addstr("returned from shellout.\n"); + refresh(); +} + +#ifdef NCURSES_MOUSE_VERSION +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 +setup_getch(WINDOW *win, bool flags[]) +{ + keypad(win, flags['k']); /* should be redundant, but for testing */ + meta(win, flags['m']); /* force this to a known state */ + if (flags['e']) + echo(); + else + noecho(); +} + +static void +wgetch_help(WINDOW *win, bool flags[]) +{ + static const char *help[] = + { + "e -- toggle echo mode" + ,"g -- triggers a getstr test" + ,"k -- toggle keypad/literal mode" + ,"m -- toggle meta (7-bit/8-bit) mode" + ,"q -- quit (x also exits)" + ,"s -- shell out\n" + ,"w -- create a new window" +#ifdef SIGTSTP + ,"z -- suspend this process" +#endif + }; + int y, x; + unsigned chk = ((SIZEOF(help) + 1) / 2); + unsigned n; + + getyx(win, y, x); + move(0, 0); + printw("Type any key to see its %s value. Also:\n", + flags['k'] ? "keypad" : "literal"); + for (n = 0; n < SIZEOF(help); ++n) { + int row = 1 + (n % chk); + int col = (n >= chk) ? COLS / 2 : 0; + int flg = ((strstr(help[n], "toggle") != 0) + && (flags[UChar(*help[n])] != FALSE)); + if (flg) + standout(); + mvprintw(row, col, "%s", help[n]); + if (col == 0) + clrtoeol(); + if (flg) + standend(); + } + wrefresh(stdscr); + wmove(win, y, x); +} + +static void +wgetch_wrap(WINDOW *win, int first_y) +{ + int last_y = getmaxy(win) - 1; + int y = getcury(win) + 1; + + if (y >= last_y) + y = first_y; + wmove(win, y, 0); + wclrtoeol(win); +} + +#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE +typedef struct { + WINDOW *text; + WINDOW *frame; +} WINSTACK; + +static WINSTACK *winstack = 0; +static unsigned len_winstack = 0; + +static void +remember_boxes(unsigned level, WINDOW *txt_win, WINDOW *box_win) +{ + unsigned need = (level + 1) * 2; + + if (winstack == 0) { + len_winstack = 20; + winstack = malloc(len_winstack * sizeof(WINSTACK)); + } else if (need >= len_winstack) { + len_winstack = need; + winstack = realloc(winstack, len_winstack * sizeof(WINSTACK)); + } + winstack[level].text = txt_win; + winstack[level].frame = box_win; +} + +/* + * For wgetch_test(), we create pairs of windows - one for a box, one for text. + * Resize both and paint the box in the parent. + */ +static void +resize_boxes(int level, WINDOW *win) +{ + unsigned n; + int base = 5; + int high = LINES - base; + int wide = COLS; + + touchwin(stdscr); + wnoutrefresh(stdscr); + + /* FIXME: this chunk should be done in resizeterm() */ + slk_touch(); + slk_clear(); + slk_noutrefresh(); + + for (n = 0; (int) n < level; ++n) { + wresize(winstack[n].frame, high, wide); + wresize(winstack[n].text, high - 2, wide - 2); + high -= 2; + wide -= 2; + werase(winstack[n].text); + box(winstack[n].frame, 0, 0); + wnoutrefresh(winstack[n].frame); + wprintw(winstack[n].text, + "size %dx%d\n", + getmaxy(winstack[n].text), + getmaxx(winstack[n].text)); + wnoutrefresh(winstack[n].text); + if (winstack[n].text == win) + break; + } + doupdate(); +} +#else +#define remember_boxes(level,text,frame) /* nothing */ +#endif + +static void +wgetch_test(int level, WINDOW *win, int delay) +{ + char buf[BUFSIZ]; + int first_y, first_x; + int c; + int incount = 0; + bool flags[256]; + bool blocking = (delay < 0); + int y, x; + + memset(flags, FALSE, sizeof(flags)); + flags['k'] = (win == stdscr); + + setup_getch(win, flags); + wtimeout(win, delay); + getyx(win, first_y, first_x); + + wgetch_help(win, flags); + wsetscrreg(win, first_y, getmaxy(win) - 1); + scrollok(win, TRUE); + + for (;;) { + while ((c = wGetchar(win)) == ERR) { + incount++; + if (blocking) { + (void) wprintw(win, "%05d: input error", incount); + break; + } else { + (void) wprintw(win, "%05d: input timed out", incount); + } + wgetch_wrap(win, first_y); + } + if (c == ERR && blocking) { + wprintw(win, "ERR"); + wgetch_wrap(win, first_y); + } else if (c == 'x' || c == 'q') { + break; + } else if (c == 'e') { + flags['e'] = !flags['e']; + setup_getch(win, flags); + wgetch_help(win, flags); + } else if (c == 'g') { + waddstr(win, "getstr test: "); + echo(); + wgetnstr(win, buf, sizeof(buf) - 1); + noecho(); + wprintw(win, "I saw %d characters:\n\t`%s'.", (int) strlen(buf), buf); + wclrtoeol(win); + wgetch_wrap(win, first_y); + } else if (c == 'k') { + flags['k'] = !flags['k']; + setup_getch(win, flags); + wgetch_help(win, flags); + } else if (c == 'm') { + flags['m'] = !flags['m']; + setup_getch(win, flags); + wgetch_help(win, flags); + } else if (c == 's') { + ShellOut(TRUE); + } else if (c == 'w') { + int high = getmaxy(win) - 1 - first_y + 1; + int wide = getmaxx(win) - first_x; + int old_y, old_x; + int new_y = first_y + getbegy(win); + int new_x = first_x + getbegx(win); + + getyx(win, old_y, old_x); + if (high > 2 && wide > 2) { + WINDOW *wb = newwin(high, wide, new_y, new_x); + WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1); + + box(wb, 0, 0); + wrefresh(wb); + wmove(wi, 0, 0); + remember_boxes(level, wi, wb); + wgetch_test(level + 1, wi, delay); + delwin(wi); + delwin(wb); + + wgetch_help(win, flags); + wmove(win, old_y, old_x); + touchwin(win); + wrefresh(win); + doupdate(); + } +#ifdef SIGTSTP + } else if (c == 'z') { + kill(getpid(), SIGTSTP); +#endif + } else { + wprintw(win, "Key pressed: %04o ", c); +#ifdef NCURSES_MOUSE_VERSION + if (c == KEY_MOUSE) { + MEVENT event; + + getmouse(&event); + wprintw(win, "KEY_MOUSE, %s", mouse_decode(&event)); + getyx(win, y, x); + move(event.y, event.x); + addch('*'); + wmove(win, y, x); + } else +#endif /* NCURSES_MOUSE_VERSION */ + if (c >= KEY_MIN) { +#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE + if (c == KEY_RESIZE) { + resize_boxes(level, win); + } +#endif + (void) waddstr(win, keyname(c)); + } else if (c > 0x80) { + int c2 = (c & 0x7f); + if (isprint(c2)) + (void) wprintw(win, "M-%c", c2); + else + (void) wprintw(win, "M-%s", unctrl(c2)); + waddstr(win, " (high-half character)"); + } else { + if (isprint(c)) + (void) wprintw(win, "%c (ASCII printable character)", c); + else + (void) wprintw(win, "%s (ASCII control character)", + unctrl(c)); + } + wgetch_wrap(win, first_y); + } + } + + wtimeout(win, -1); +} + +static int +begin_getch_test(void) +{ + char buf[BUFSIZ]; + int delay; + + refresh(); + +#ifdef NCURSES_MOUSE_VERSION + mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0); +#endif + + (void) printw("Delay in 10ths of a second (<CR> for blocking input)? "); + echo(); + getnstr(buf, sizeof(buf) - 1); + noecho(); + nonl(); + + if (isdigit(UChar(buf[0]))) { + delay = atoi(buf) * 100; + } else { + delay = -1; + } + raw(); + move(5, 0); + return delay; +} + +static void +finish_getch_test(void) +{ +#ifdef NCURSES_MOUSE_VERSION + mousemask(0, (mmask_t *) 0); +#endif + erase(); + noraw(); + nl(); + endwin(); +} + +static void +getch_test(void) +{ + int delay = begin_getch_test(); + wgetch_test(0, stdscr, delay); + finish_getch_test(); +} + +#if USE_WIDEC_SUPPORT +/* + * For wgetch_test(), we create pairs of windows - one for a box, one for text. + * Resize both and paint the box in the parent. + */ +static void +resize_wide_boxes(int level, WINDOW *win) +{ + unsigned n; + int base = 5; + int high = LINES - base; + int wide = COLS; + + touchwin(stdscr); + wnoutrefresh(stdscr); + + /* FIXME: this chunk should be done in resizeterm() */ + slk_touch(); + slk_clear(); + slk_noutrefresh(); + + for (n = 0; (int) n < level; ++n) { + wresize(winstack[n].frame, high, wide); + wresize(winstack[n].text, high - 2, wide - 2); + high -= 2; + wide -= 2; + werase(winstack[n].text); + box_set(winstack[n].frame, 0, 0); + wnoutrefresh(winstack[n].frame); + wprintw(winstack[n].text, + "size %dx%d\n", + getmaxy(winstack[n].text), + getmaxx(winstack[n].text)); + wnoutrefresh(winstack[n].text); + if (winstack[n].text == win) + break; + } + doupdate(); +} + +static void +wget_wch_test(int level, WINDOW *win, int delay) +{ + char buf[BUFSIZ]; + int first_y, first_x; + wint_t c; + int incount = 0; + bool flags[256]; + bool blocking = (delay < 0); + int y, x, code; + + memset(flags, FALSE, sizeof(flags)); + flags['k'] = (win == stdscr); + + setup_getch(win, flags); + wtimeout(win, delay); + getyx(win, first_y, first_x); + + wgetch_help(win, flags); + wsetscrreg(win, first_y, getmaxy(win) - 1); + scrollok(win, TRUE); + + for (;;) { + while ((code = wGet_wchar(win, &c)) == ERR) { + incount++; + if (blocking) { + (void) wprintw(win, "%05d: input error", incount); + break; + } else { + (void) wprintw(win, "%05d: input timed out", incount); + } + wgetch_wrap(win, first_y); + } + if (code == ERR && blocking) { + wprintw(win, "ERR"); + wgetch_wrap(win, first_y); + } else if (c == 'x' || c == 'q') { + break; + } else if (c == 'e') { + flags['e'] = !flags['e']; + setup_getch(win, flags); + wgetch_help(win, flags); + } else if (c == 'g') { + waddstr(win, "getstr test: "); + echo(); + wgetnstr(win, buf, sizeof(buf) - 1); + noecho(); + wprintw(win, "I saw %d characters:\n\t`%s'.", strlen(buf), buf); + wclrtoeol(win); + wgetch_wrap(win, first_y); + } else if (c == 'k') { + flags['k'] = !flags['k']; + setup_getch(win, flags); + wgetch_help(win, flags); + } else if (c == 'm') { + flags['m'] = !flags['m']; + setup_getch(win, flags); + wgetch_help(win, flags); + } else if (c == 's') { + ShellOut(TRUE); + } else if (c == 'w') { + int high = getmaxy(win) - 1 - first_y + 1; + int wide = getmaxx(win) - first_x; + int old_y, old_x; + int new_y = first_y + getbegy(win); + int new_x = first_x + getbegx(win); + + getyx(win, old_y, old_x); + if (high > 2 && wide > 2) { + WINDOW *wb = newwin(high, wide, new_y, new_x); + WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1); + + box_set(wb, 0, 0); + wrefresh(wb); + wmove(wi, 0, 0); + remember_boxes(level, wi, wb); + wget_wch_test(level + 1, wi, delay); + delwin(wi); + delwin(wb); + + wgetch_help(win, flags); + wmove(win, old_y, old_x); + touchwin(win); + wrefresh(win); + } +#ifdef SIGTSTP + } else if (c == 'z') { + kill(getpid(), SIGTSTP); +#endif + } else { + wprintw(win, "Key pressed: %04o ", c); +#ifdef NCURSES_MOUSE_VERSION + if (c == KEY_MOUSE) { + MEVENT event; + + getmouse(&event); + wprintw(win, "KEY_MOUSE, %s", mouse_decode(&event)); + getyx(win, y, x); + move(event.y, event.x); + addch('*'); + wmove(win, y, x); + } else +#endif /* NCURSES_MOUSE_VERSION */ + if (code == KEY_CODE_YES) { +#ifdef KEY_RESIZE + if (c == KEY_RESIZE) { + resize_wide_boxes(level, win); + } +#endif + (void) waddstr(win, key_name(c)); + } else { + if (c < 256 && iscntrl(c)) { + (void) wprintw(win, "%s (control character)", unctrl(c)); + } else { + wchar_t c2 = c; + waddnwstr(win, &c2, 1); + (void) wprintw(win, " = %#x (printable character)", c); + } + } + wgetch_wrap(win, first_y); + } + } + + wtimeout(win, -1); +} + +static void +get_wch_test(void) +{ + int delay = begin_getch_test(); + wget_wch_test(0, stdscr, delay); + finish_getch_test(); +} +#endif + +/**************************************************************************** + * + * Character attributes test + * + ****************************************************************************/ + +static int +show_attr(int row, int skip, chtype attr, const char *name) +{ + static const char *string = "abcde fghij klmno pqrst uvwxy z"; + int ncv = tigetnum("ncv"); + + mvprintw(row, 8, "%s mode:", name); + mvprintw(row, 24, "|"); + if (skip) + printw("%*s", skip, " "); + attrset(attr); + /* + * If we're to write a string in the alternate character set, it is not + * sufficient to just set A_ALTCHARSET. We have to perform the mapping + * that corresponds. This is not needed for vt100-compatible devices + * because the acs_map[] is 1:1, but for PC-style devices such as Linux + * console, the acs_map[] is scattered about the range. + * + * The addch/addstr functions do not themselves do this mapping, since it + * is possible to turn off the A_ALTCHARSET flag for the characters which + * are added, and it would be an unexpected result to have the mapped + * characters visible on the screen. + * + * This example works because the indices into acs_map[] are mostly from + * the lowercase characters. + */ + if (attr & A_ALTCHARSET) { + const char *s = string; + while (*s) { + int ch = *s++; +#ifdef CURSES_ACS_ARRAY + if ((ch = CURSES_ACS_ARRAY[ch]) == 0) + ch = ' '; +#endif + addch(ch); + } + } else { + addstr(string); + } + 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 chtype 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); 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 *ac) +{ + int ch = Getchar(); + + if (isdigit(ch)) { + *skip = (ch - '0'); + } else if (ch == CTRL('L')) { + touchwin(stdscr); + touchwin(curscr); + } else if (has_colors()) { + switch (ch) { + case 'a': + *ac = 0; + break; + case 'A': + *ac = A_ALTCHARSET; + break; + 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 >= max_colors) + *fg = 0; + if (*fg < 0) + *fg = max_colors - 1; + if (*bg >= max_colors) + *bg = 0; + if (*bg < 0) + *bg = max_colors - 1; + } else { + switch (ch) { + case 'a': + *ac = 0; + break; + case 'A': + *ac = A_ALTCHARSET; + break; + default: + return FALSE; + } + } + return TRUE; +} + +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; + int ac = 0; + bool *pairs = (bool *) calloc(max_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 * max_colors) + bg; + if (!pairs[pair]) { + init_pair(pair, fg, bg); + pairs[pair] = TRUE; + } + normal |= COLOR_PAIR(pair); + } + bkgd(normal); + bkgdset(normal); + erase(); + + box(stdscr, 0, 0); + mvaddstr(0, 20, "Character attribute test display"); + + row = show_attr(row, n, ac | A_STANDOUT, "STANDOUT"); + row = show_attr(row, n, ac | A_REVERSE, "REVERSE"); + row = show_attr(row, n, ac | A_BOLD, "BOLD"); + row = show_attr(row, n, ac | A_UNDERLINE, "UNDERLINE"); + row = show_attr(row, n, ac | A_DIM, "DIM"); + row = show_attr(row, n, ac | A_BLINK, "BLINK"); + row = show_attr(row, n, ac | A_PROTECT, "PROTECT"); + row = show_attr(row, n, ac | A_INVIS, "INVISIBLE"); + row = show_attr(row, n, ac | A_NORMAL, "NORMAL"); + + 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), a/A altcharset (%d)", + fg, bg, ac != 0); + else + printw(". a/A altcharset (%d)", ac != 0); + + refresh(); + } while (attr_getc(&n, &fg, &bg, &ac)); + + free((char *) pairs); + bkgdset(A_NORMAL | BLANK); + erase(); + endwin(); +} + +/**************************************************************************** + * + * Color support tests + * + ****************************************************************************/ + +static NCURSES_CONST char *the_color_names[] = +{ + "black", + "red", + "green", + "yellow", + "blue", + "magenta", + "cyan", + "white", + "BLACK", + "RED", + "GREEN", + "YELLOW", + "BLUE", + "MAGENTA", + "CYAN", + "WHITE" +}; + +static void +show_color_name(int y, int x, int color) +{ + if (max_colors > 8) + mvprintw(y, x, "%02d ", color); + else + mvaddstr(y, x, the_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 = (max_colors > 8) ? 4 : 8; + hello = (max_colors > 8) ? "Test" : "Hello"; + + for (base = 0; base < 2; base++) { + top = (max_colors > 8) ? 0 : base * (max_colors + 3); + clrtobot(); + (void) mvprintw(top + 1, 0, + "%dx%d matrix of foreground/background colors, bright *%s*\n", + max_colors, max_colors, + base ? "on" : "off"); + for (i = 0; i < max_colors; i++) + show_color_name(top + 2, (i + 1) * width, i); + for (i = 0; i < max_colors; i++) + show_color_name(top + 3 + i, 0, i); + for (i = 1; i < max_pairs; i++) { + init_pair(i, i % max_colors, i / max_colors); + attron((attr_t) COLOR_PAIR(i)); + if (base) + attron((attr_t) A_BOLD); + mvaddstr(top + 3 + (i / max_colors), (i % max_colors + 1) * + width, hello); + attrset(A_NORMAL); + } + if ((max_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 < max_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 < max_colors; i++) { + mvprintw(2 + i, 0, "%c %-8s:", + (i == current ? '>' : ' '), + (i < (int) SIZEOF(the_color_names) + ? the_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(max_colors + 3, 0, + "Use up/down to select a color, left/right to change fields."); + mvaddstr(max_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 ? (max_colors - 1) : current - 1); + break; + + case KEY_DOWN: + current = (current == (max_colors - 1) ? 0 : current + 1); + break; + + case KEY_RIGHT: + field = (field == 2 ? 0 : field + 1); + break; + + case KEY_LEFT: + field = (field == 0 ? 2 : field - 1); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + value = value * 10 + (this_c - '0'); + break; + + case '+': + change_color(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 void +show_box_chars(void) +{ + erase(); + attron(A_BOLD); + mvaddstr(0, 20, "Display of the ACS Line-Drawing Set"); + attroff(A_BOLD); + refresh(); + box(stdscr, 0, 0); + /* *INDENT-OFF* */ + mvhline(LINES / 2, 0, ACS_HLINE, COLS); + mvvline(0, COLS / 2, ACS_VLINE, LINES); + mvaddch(0, COLS / 2, ACS_TTEE); + mvaddch(LINES / 2, COLS / 2, ACS_PLUS); + mvaddch(LINES - 1, COLS / 2, ACS_BTEE); + mvaddch(LINES / 2, 0, ACS_LTEE); + mvaddch(LINES / 2, COLS - 1, ACS_RTEE); + /* *INDENT-ON* */ + +} + +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_URCORNER)); + n = show_1_acs(n, BOTH(ACS_LLCORNER)); + n = show_1_acs(n, BOTH(ACS_LRCORNER)); + + n = show_1_acs(n, BOTH(ACS_LTEE)); + n = show_1_acs(n, BOTH(ACS_RTEE)); + n = show_1_acs(n, BOTH(ACS_TTEE)); + n = show_1_acs(n, BOTH(ACS_BTEE)); + + n = show_1_acs(n, BOTH(ACS_HLINE)); + n = show_1_acs(n, BOTH(ACS_VLINE)); + + n = show_1_acs(n, BOTH(ACS_LARROW)); + n = show_1_acs(n, BOTH(ACS_RARROW)); + n = show_1_acs(n, BOTH(ACS_UARROW)); + n = show_1_acs(n, BOTH(ACS_DARROW)); + + n = show_1_acs(n, BOTH(ACS_BLOCK)); + n = show_1_acs(n, BOTH(ACS_BOARD)); + n = show_1_acs(n, BOTH(ACS_LANTERN)); + n = show_1_acs(n, BOTH(ACS_BULLET)); + n = show_1_acs(n, BOTH(ACS_CKBOARD)); + n = show_1_acs(n, BOTH(ACS_DEGREE)); + n = show_1_acs(n, BOTH(ACS_DIAMOND)); + n = show_1_acs(n, BOTH(ACS_PLMINUS)); + n = show_1_acs(n, BOTH(ACS_PLUS)); + + n = show_1_acs(n, BOTH(ACS_GEQUAL)); + n = show_1_acs(n, BOTH(ACS_NEQUAL)); + n = show_1_acs(n, BOTH(ACS_LEQUAL)); + + n = show_1_acs(n, BOTH(ACS_STERLING)); + n = show_1_acs(n, BOTH(ACS_PI)); + n = show_1_acs(n, BOTH(ACS_S1)); + n = show_1_acs(n, BOTH(ACS_S3)); + n = show_1_acs(n, BOTH(ACS_S7)); + n = show_1_acs(n, BOTH(ACS_S9)); +} + +static void +acs_display(void) +{ + int c = 'a'; + + do { + switch (c) { + case 'a': + show_acs_chars(); + break; + case 'b': + show_box_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, b=box, 0=C1, 1,2,3=GR characters, q=quit"); + refresh(); + } while ((c = Getchar()) != 'x' && c != 'q'); + + Pause(); + erase(); + endwin(); +} + +#if USE_WIDEC_SUPPORT +static void +show_upper_widechars(int first) +{ + cchar_t temp; + wchar_t code; + int last = first + 31; + + erase(); + attron(A_BOLD); + mvprintw(0, 20, "Display of Character Codes %d to %d", first, last); + attroff(A_BOLD); + refresh(); + + for (code = first; code <= last; code++) { + int row = 4 + ((code - first) % 16); + int col = ((code - first) / 16) * COLS / 2; + wchar_t codes[10]; + attr_t attrs = A_NORMAL; + char tmp[80]; + + memset(&codes, 0, sizeof(codes)); + codes[0] = code; + sprintf(tmp, "%3ld (0x%lx)", code, code); + mvprintw(row, col, "%*s: ", COLS / 4, tmp); + setcchar(&temp, codes, attrs, 0, 0); + echo_wchar(&temp); + } +} + +static int +show_1_wacs(int n, const char *name, const cchar_t * code) +{ + const int height = 16; + int row = 4 + (n % height); + int col = (n / height) * COLS / 2; + mvprintw(row, col, "%*s : ", COLS / 4, name); + add_wchnstr(code, 1); + return n + 1; +} + +static void +show_wacs_chars(void) +/* display the wide-ACS character set */ +{ + int n; + +/*#define BOTH2(name) #name, &(name) */ +#define BOTH2(name) #name, name + + erase(); + attron(A_BOLD); + mvaddstr(0, 20, "Display of the Wide-ACS Character Set"); + attroff(A_BOLD); + refresh(); + + n = show_1_wacs(0, BOTH2(WACS_ULCORNER)); + n = show_1_wacs(n, BOTH2(WACS_URCORNER)); + n = show_1_wacs(n, BOTH2(WACS_LLCORNER)); + n = show_1_wacs(n, BOTH2(WACS_LRCORNER)); + + n = show_1_wacs(n, BOTH2(WACS_LTEE)); + n = show_1_wacs(n, BOTH2(WACS_RTEE)); + n = show_1_wacs(n, BOTH2(WACS_TTEE)); + n = show_1_wacs(n, BOTH2(WACS_BTEE)); + + n = show_1_wacs(n, BOTH2(WACS_HLINE)); + n = show_1_wacs(n, BOTH2(WACS_VLINE)); + + n = show_1_wacs(n, BOTH2(WACS_LARROW)); + n = show_1_wacs(n, BOTH2(WACS_RARROW)); + n = show_1_wacs(n, BOTH2(WACS_UARROW)); + n = show_1_wacs(n, BOTH2(WACS_DARROW)); + + n = show_1_wacs(n, BOTH2(WACS_BLOCK)); + n = show_1_wacs(n, BOTH2(WACS_BOARD)); + n = show_1_wacs(n, BOTH2(WACS_LANTERN)); + n = show_1_wacs(n, BOTH2(WACS_BULLET)); + n = show_1_wacs(n, BOTH2(WACS_CKBOARD)); + n = show_1_wacs(n, BOTH2(WACS_DEGREE)); + n = show_1_wacs(n, BOTH2(WACS_DIAMOND)); + n = show_1_wacs(n, BOTH2(WACS_PLMINUS)); + n = show_1_wacs(n, BOTH2(WACS_PLUS)); + +#ifdef CURSES_WACS_ARRAY + n = show_1_wacs(n, BOTH2(WACS_GEQUAL)); + n = show_1_wacs(n, BOTH2(WACS_NEQUAL)); + n = show_1_wacs(n, BOTH2(WACS_LEQUAL)); + + n = show_1_wacs(n, BOTH2(WACS_STERLING)); + n = show_1_wacs(n, BOTH2(WACS_PI)); + n = show_1_wacs(n, BOTH2(WACS_S1)); + n = show_1_wacs(n, BOTH2(WACS_S3)); + n = show_1_wacs(n, BOTH2(WACS_S7)); + n = show_1_wacs(n, BOTH2(WACS_S9)); +#endif +} + +static void +show_wbox_chars(void) +{ + erase(); + attron(A_BOLD); + mvaddstr(0, 20, "Display of the Wide-ACS Line-Drawing Set"); + attroff(A_BOLD); + refresh(); + box_set(stdscr, 0, 0); + /* *INDENT-OFF* */ + mvhline_set(LINES / 2, 0, WACS_HLINE, COLS); + mvvline_set(0, COLS / 2, WACS_VLINE, LINES); + mvadd_wch(0, COLS / 2, WACS_TTEE); + mvadd_wch(LINES / 2, COLS / 2, WACS_PLUS); + mvadd_wch(LINES - 1, COLS / 2, WACS_BTEE); + mvadd_wch(LINES / 2, 0, WACS_LTEE); + mvadd_wch(LINES / 2, COLS - 1, WACS_RTEE); + /* *INDENT-ON* */ + +} + +static int +show_2_wacs(int n, const char *name, char *code) +{ + const int height = 16; + int row = 4 + (n % height); + int col = (n / height) * COLS / 2; + mvprintw(row, col, "%*s : ", COLS / 4, name); + addstr(code); + return n + 1; +} + +static void +show_utf8_chars(void) +/* display the wide-ACS character set */ +{ + int n; + + erase(); + attron(A_BOLD); + mvaddstr(0, 20, "Display of the Wide-ACS Character Set"); + attroff(A_BOLD); + refresh(); + /* *INDENT-OFF* */ + n = show_2_wacs(0, "WACS_ULCORNER", "\342\224\214"); + n = show_2_wacs(n, "WACS_URCORNER", "\342\224\220"); + n = show_2_wacs(n, "WACS_LLCORNER", "\342\224\224"); + n = show_2_wacs(n, "WACS_LRCORNER", "\342\224\230"); + + n = show_2_wacs(n, "WACS_LTEE", "\342\224\234"); + n = show_2_wacs(n, "WACS_RTEE", "\342\224\244"); + n = show_2_wacs(n, "WACS_TTEE", "\342\224\254"); + n = show_2_wacs(n, "WACS_BTEE", "\342\224\264"); + + n = show_2_wacs(n, "WACS_HLINE", "\342\224\200"); + n = show_2_wacs(n, "WACS_VLINE", "\342\224\202"); + + n = show_2_wacs(n, "WACS_LARROW", "\342\206\220"); + n = show_2_wacs(n, "WACS_RARROW", "\342\206\222"); + n = show_2_wacs(n, "WACS_UARROW", "\342\206\221"); + n = show_2_wacs(n, "WACS_DARROW", "\342\206\223"); + + n = show_2_wacs(n, "WACS_BLOCK", "\342\226\256"); + n = show_2_wacs(n, "WACS_BOARD", "\342\226\222"); + n = show_2_wacs(n, "WACS_LANTERN", "\342\230\203"); + n = show_2_wacs(n, "WACS_BULLET", "\302\267"); + n = show_2_wacs(n, "WACS_CKBOARD", "\342\226\222"); + n = show_2_wacs(n, "WACS_DEGREE", "\302\260"); + n = show_2_wacs(n, "WACS_DIAMOND", "\342\227\206"); + n = show_2_wacs(n, "WACS_PLMINUS", "\302\261"); + n = show_2_wacs(n, "WACS_PLUS", "\342\224\274"); + n = show_2_wacs(n, "WACS_GEQUAL", "\342\211\245"); + n = show_2_wacs(n, "WACS_NEQUAL", "\342\211\240"); + n = show_2_wacs(n, "WACS_LEQUAL", "\342\211\244"); + + n = show_2_wacs(n, "WACS_STERLING", "\302\243"); + n = show_2_wacs(n, "WACS_PI", "\317\200"); + n = show_2_wacs(n, "WACS_S1", "\342\216\272"); + n = show_2_wacs(n, "WACS_S3", "\342\216\273"); + n = show_2_wacs(n, "WACS_S7", "\342\216\274"); + n = show_2_wacs(n, "WACS_S9", "\342\216\275"); + /* *INDENT-OFF* */ +} + +static void +wide_acs_display(void) +{ + int c = 'a'; + + do { + switch (c) { + case 'a': + show_wacs_chars(); + break; + case 'b': + show_wbox_chars(); + break; + case 'u': + show_utf8_chars(); + break; + default: + if (isdigit(c)) + show_upper_widechars((c - '0') * 32 + 128); + break; + } + mvprintw(LINES - 2, 0, + "Select: a WACS, b box, u UTF-8, 0-9 non-ASCII characters, q=quit"); + refresh(); + } while ((c = Getchar()) != 'x' && c != 'q'); + + Pause(); + erase(); + endwin(); +} + +#endif + +/* + * 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; +}; + +#ifdef NCURSES_VERSION +#define keypad_active(win) (win)->_use_keypad +#define scroll_active(win) (win)->_scroll +#else +#define keypad_active(win) FALSE +#define scroll_active(win) FALSE +#endif + +/* We need to know if these flags are actually set, so don't look in FRAME. + * These names are known to work with SVr4 curses as well as ncurses. The + * _use_keypad name does not work with Solaris 8. + */ +static bool +HaveKeypad(FRAME * curp) +{ + WINDOW *win = (curp ? curp->wind : stdscr); + return keypad_active(win); +} + +static bool +HaveScroll(FRAME * curp) +{ + WINDOW *win = (curp ? curp->wind : stdscr); + return scroll_active(win); +} + +static void +newwin_legend(FRAME * curp) +{ + static const struct { + const char *msg; + int code; + } legend[] = { + { + "^C = create window", 0 + }, + { + "^N = next window", 0 + }, + { + "^P = previous window", 0 + }, + { + "^F = scroll forward", 0 + }, + { + "^B = scroll backward", 0 + }, + { + "^K = keypad(%s)", 1 + }, + { + "^S = scrollok(%s)", 2 + }, + { + "^W = save window to file", 0 + }, + { + "^R = restore window", 0 + }, +#if HAVE_WRESIZE + { + "^X = resize", 0 + }, +#endif + { + "^Q%s = exit", 3 + } + }; + size_t n; + int x; + bool do_keypad = HaveKeypad(curp); + bool do_scroll = HaveScroll(curp); + char buf[BUFSIZ]; + + move(LINES - 4, 0); + for (n = 0; n < SIZEOF(legend); n++) { + switch (legend[n].code) { + default: + strcpy(buf, legend[n].msg); + break; + case 1: + sprintf(buf, legend[n].msg, do_keypad ? "yes" : "no"); + break; + case 2: + sprintf(buf, legend[n].msg, do_scroll ? "yes" : "no"); + break; + case 3: + sprintf(buf, legend[n].msg, do_keypad ? "/ESC" : ""); + break; + } + x = getcurx(stdscr); + addstr((COLS < (x + 3 + (int) strlen(buf))) ? "\n" : (n ? ", " : "")); + addstr(buf); + } + clrtoeol(); +} + +static void +transient(FRAME * curp, NCURSES_CONST char *msg) +{ + newwin_legend(curp); + if (msg) { + mvaddstr(LINES - 1, 0, msg); + refresh(); + napms(1000); + } + + move(LINES - 1, 0); + printw("%s characters are echoed, window should %sscroll.", + HaveKeypad(curp) ? "Non-arrow" : "All other", + HaveScroll(curp) ? "" : "not "); + clrtoeol(); +} + +static void +newwin_report(FRAME * curp) +/* report on the cursor's current position, then restore it */ +{ + WINDOW *win = (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) { + transient(current, "Will not save/delete ONLY window"); + break; + } else if ((fp = fopen(DUMPFILE, "w")) == (FILE *) 0) { + transient(current, "Can't open screen dump file"); + } else { + (void) putwin(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; + +#if HAVE_WRESIZE + 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 /* HAVE_WRESIZE */ + + case KEY_F(10): /* undocumented --- use this to test area clears */ + selectcell(0, 0, LINES - 1, COLS - 1); + clrtobot(); + refresh(); + break; + + case KEY_UP: + newwin_move(current, -1, 0); + break; + case KEY_DOWN: + newwin_move(current, 1, 0); + break; + case KEY_LEFT: + newwin_move(current, 0, -1); + break; + case KEY_RIGHT: + newwin_move(current, 0, 1); + break; + + case KEY_BACKSPACE: + /* FALLTHROUGH */ + case KEY_DC: + { + int y, x; + getyx(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) && (keypad_active(usescr))) + && (c != ERR)); + + breakout: + while (current != 0) + current = delete_framed(current, FALSE); + + scrollok(stdscr, TRUE); /* reset to driver's default */ +#ifdef NCURSES_MOUSE_VERSION + mousemask(0, (mmask_t *) 0); +#endif + noraw(); + erase(); + endwin(); +} + +/**************************************************************************** + * + * Panels tester + * + ****************************************************************************/ + +#if USE_LIBPANEL +static 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 pending_pan = FALSE; +static bool show_panner_legend = TRUE; + +static int +panner_legend(int line) +{ + static const char *const legend[] = + { + "Use arrow keys (or U,D,L,R) to pan, q to quit, ! to shell-out.", + "Use +,- (or j,k) to grow/shrink the panner vertically.", + "Use <,> (or h,l) to grow/shrink the panner horizontally.", + "Number repeats. Toggle legend:?, timer:t, scroll mark:s." + }; + 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; + + case 'H': + case KEY_HOME: + case KEY_FIND: + basey = 0; + break; + + case 'E': + case KEY_END: + case KEY_SELECT: + basey = pymax - porty; + if (basey < 0) + basey = 0; + break; + + default: + beep(); + break; + } + + mvaddch(top_y - 1, top_x - 1, ACS_ULCORNER); + do_v_line(top_y, top_x - 1, ACS_VLINE, porty); + do_h_line(top_y - 1, top_x, ACS_HLINE, portx); + + if (scrollers && (pxmax > portx - 1)) { + int length = (portx - top_x - 1); + float ratio = ((float) length) / ((float) pxmax); + + lowend = (int) (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 (!pending_pan) { +#if HAVE_GETTIMEOFDAY + gettimeofday(&before, 0); +#endif + wnoutrefresh(stdscr); + + pnoutrefresh(pad, + basey, basex, + top_y, top_x, + porty - (pxmax > portx) - 1, + portx - (pymax > porty) - 1); + + doupdate(); +#if HAVE_GETTIMEOFDAY + if (timing) { + double elapsed; + gettimeofday(&after, 0); + elapsed = (after.tv_sec + after.tv_usec / 1.0e6) + - (before.tv_sec + before.tv_usec / 1.0e6); + move(LINES - 1, COLS - 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) +{ + static int count; + static int last; + int c; + + if ((pending_pan = (count > 0)) != FALSE) { + count--; + pending_pan = (count != 0); + } else { + for (;;) { + switch (c = wGetchar(win)) { + case '!': + ShellOut(FALSE); + /* FALLTHRU */ + case CTRL('r'): + endwin(); + refresh(); + c = KEY_REFRESH; + break; + case CTRL('l'): + c = KEY_REFRESH; + break; + case 'U': + c = KEY_UP; + break; + case 'D': + c = KEY_DOWN; + break; + case 'R': + c = KEY_RIGHT; + break; + case 'L': + c = KEY_LEFT; + break; + case '+': + c = KEY_IL; + break; + case '-': + c = KEY_DL; + break; + case '>': + c = KEY_IC; + break; + case '<': + c = KEY_DC; + break; + case ERR: /* FALLTHRU */ + case 'q': + count = 0; + c = KEY_EXIT; + break; + default: + if (c >= '0' && c <= '9') { + count = count * 10 + (c - '0'); + continue; + } + break; + } + last = c; + break; + } + if (count > 0) + count--; + } + return (last); +} + +#define PAD_HIGH 200 +#define PAD_WIDE 200 + +static void +demo_pad(void) +/* Demonstrate pads. */ +{ + int i, j; + unsigned gridcount = 0; + WINDOW *panpad = newpad(PAD_HIGH, PAD_WIDE); + + if (panpad == 0) { + Cannot("cannot create requested pad"); + return; + } + + for (i = 0; i < PAD_HIGH; i++) { + for (j = 0; j < PAD_WIDE; 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); + wbkgd(subWin, COLOR_PAIR(2) | ' '); + } +#endif + wattrset(subWin, A_BOLD); + box(subWin, ACS_VLINE, ACS_HLINE); + mvwaddstr(subWin, 2, 1, "This is a subwindow"); + wrefresh(win); + + /* + * This used to set 'nocbreak()'. However, Alexander Lukyanov says that + * it only happened to "work" on SVr4 because that implementation does not + * emulate nocbreak+noecho mode, whereas ncurses does. To get the desired + * test behavior, we're using 'cbreak()', which will allow a single + * character to return without needing a newline. - T.Dickey 1997/10/11. + */ + cbreak(); + mvwaddstr(win, 0, 1, "This is a test of the flushinp() call."); + + mvwaddstr(win, 2, 1, "Type random keys for 5 seconds."); + mvwaddstr(win, 3, 1, + "These should be discarded (not echoed) after the subwindow goes away."); + wrefresh(win); + + for (i = 0; i < 5; i++) { + mvwprintw(subWin, 1, 1, "Time = %d", i); + wrefresh(subWin); + napms(1000); + flushinp(); + } + + delwin(subWin); + werase(win); + flash(); + wrefresh(win); + napms(1000); + + mvwaddstr(win, 2, 1, + "If you were still typing when the window timer expired,"); + mvwaddstr(win, 3, 1, + "or else you typed nothing at all while it was running,"); + mvwaddstr(win, 4, 1, + "test was invalid. You'll see garbage or nothing at all. "); + mvwaddstr(win, 6, 1, "Press a key"); + wmove(win, 9, 10); + wrefresh(win); + echo(); + wGetchar(win); + flushinp(); + mvwaddstr(win, 12, 0, + "If you see any key other than what you typed, flushinp() is broken."); + Continue(win); + + wmove(win, 9, 10); + wdelch(win); + wrefresh(win); + wmove(win, 12, 0); + clrtoeol(); + waddstr(win, + "What you typed should now have been deleted; if not, wdelch() failed."); + Continue(win); + + cbreak(); +} + +/**************************************************************************** + * + * Menu test + * + ****************************************************************************/ + +#if USE_LIBMENU + +#define MENU_Y 8 +#define MENU_X 8 + +static int +menu_virtualize(int c) +{ + if (c == '\n' || c == KEY_EXIT) + return (MAX_COMMAND + 1); + else if (c == 'u') + return (REQ_SCR_ULINE); + else if (c == 'd') + return (REQ_SCR_DLINE); + else if (c == 'b' || c == KEY_NPAGE) + return (REQ_SCR_UPAGE); + else if (c == 'f' || c == KEY_PPAGE) + return (REQ_SCR_DPAGE); + else if (c == 'n' || c == KEY_DOWN) + return (REQ_NEXT_ITEM); + else if (c == 'p' || c == KEY_UP) + return (REQ_PREV_ITEM); + else if (c == ' ') + return (REQ_TOGGLE_ITEM); + else { + if (c != KEY_MOUSE) + beep(); + return (c); + } +} + +static const 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_DATABASE), + T_TBL(TRACE_ATTRS), + 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, nrow, nbuf; + + if (field_info(me, &rows, &cols, &frow, &fcol, &nrow, &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); 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(); + nonl(); /* lets us read ^M's */ + while (!finished) { + switch (form_driver(form, c = form_virtualize(form, w))) { + case E_OK: + mvaddstr(5, 57, field_buffer(secure, 1)); + clrtoeol(); + refresh(); + break; + case E_UNKNOWN_COMMAND: + finished = my_form_driver(form, c); + break; + default: + beep(); + break; + } + } + + erase_form(form); + + free_form(form); + for (c = 0; f[c] != 0; c++) + free_field(f[c]); + noraw(); + nl(); +} +#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; + +#if USE_WIDEC_SUPPORT + case 'A': + get_wch_test(); + break; +#endif + + 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_WIDEC_SUPPORT + case 'F': + wide_acs_display(); + break; +#endif + +#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:" +#ifdef NCURSES_VERSION + ," -a f,b set default-colors (assumed white-on-black)" + ," -d use default-colors if terminal supports them" +#endif + ," -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); n++) + fprintf(stderr, "%s\n", tbl[n]); + ExitProgram(EXIT_FAILURE); +} + +static void +set_terminal_modes(void) +{ + noraw(); + cbreak(); + noecho(); + scrollok(stdscr, TRUE); + idlok(stdscr, TRUE); + keypad(stdscr, TRUE); +} + +#ifdef SIGUSR1 +static RETSIGTYPE +announce_sig(int sig) +{ + (void) fprintf(stderr, "Handled signal %d\r\n", sig); +} +#endif + +static int +rip_footer(WINDOW *win, int cols) +{ + wbkgd(win, A_REVERSE); + werase(win); + wmove(win, 0, 0); + wprintw(win, "footer: %d columns", cols); + wnoutrefresh(win); + return OK; +} + +static int +rip_header(WINDOW *win, int cols) +{ + wbkgd(win, A_REVERSE); + werase(win); + wmove(win, 0, 0); + wprintw(win, "header: %d columns", cols); + wnoutrefresh(win); + return OK; +} + +/*+------------------------------------------------------------------------- + main(argc,argv) +--------------------------------------------------------------------------*/ + +int +main(int argc, char *argv[]) +{ + int command, c; + int my_e_param = 1; +#ifdef NCURSES_VERSION + int default_fg = COLOR_WHITE; + int default_bg = COLOR_BLACK; + bool assumed_colors = FALSE; + bool default_colors = FALSE; +#endif + + setlocale(LC_ALL, ""); + + while ((c = getopt(argc, argv, "a:de:fhs:t:")) != EOF) { + switch (c) { +#ifdef NCURSES_VERSION + case 'a': + assumed_colors = TRUE; + sscanf(optarg, "%d,%d", &default_fg, &default_bg); + break; + case 'd': + default_colors = TRUE; + break; +#endif + case 'e': + my_e_param = atoi(optarg); +#ifdef NCURSES_VERSION + if (my_e_param > 3) /* allow extended layouts */ + usage(); +#else + if (my_e_param > 1) + usage(); +#endif + break; + 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 */ + if (has_colors()) { + start_color(); +#ifdef NCURSES_VERSION_PATCH + max_colors = COLORS > 16 ? 16 : COLORS; +#if HAVE_USE_DEFAULT_COLORS + if (default_colors) + use_default_colors(); +#if NCURSES_VERSION_PATCH >= 20000708 + else if (assumed_colors) + assume_default_colors(default_fg, default_bg); +#endif +#endif +#else /* normal SVr4 curses */ + max_colors = COLORS > 8 ? 8 : COLORS; +#endif + max_pairs = (max_colors * max_colors); + if (max_pairs < COLOR_PAIRS) + max_pairs = COLOR_PAIRS; + } + set_terminal_modes(); + def_prog_mode(); + + /* + * Return to terminal mode, so we're guaranteed of being able to + * select terminal commands even if the capabilities are wrong. + */ + endwin(); + +#if HAVE_CURSES_VERSION + (void) printf("Welcome to %s. Press ? for help.\n", curses_version()); +#elif defined(NCURSES_VERSION_MAJOR) && defined(NCURSES_VERSION_MINOR) && defined(NCURSES_VERSION_PATCH) + (void) printf("Welcome to ncurses %d.%d.%d. Press ? for help.\n", + NCURSES_VERSION_MAJOR, + NCURSES_VERSION_MINOR, + NCURSES_VERSION_PATCH); +#else + (void) puts("Welcome to ncurses. Press ? for help."); +#endif + + do { + (void) puts("This is the ncurses main menu"); + (void) puts("a = keyboard and mouse input test"); +#if USE_WIDEC_SUPPORT + (void) puts("A = wide-character keyboard and mouse input test"); +#endif + (void) puts("b = character attribute test"); + (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"); +#if USE_WIDEC_SUPPORT + (void) puts("F = display Wide-ACS characters"); +#endif + (void) puts("g = display windows and scrolling"); + (void) puts("i = test of flushinp()"); + (void) puts("k = display character attributes"); +#if USE_LIBMENU + (void) puts("m = menu code test"); +#endif +#if USE_LIBPANEL + (void) puts("o = exercise panels library"); + (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(UChar(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/ncurses-5.3/test/ncurses_tst.hin b/ncurses-5.3/test/ncurses_tst.hin new file mode 100644 index 0000000..5444487 --- /dev/null +++ b/ncurses-5.3/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$ + * + * 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/ncurses-5.3/test/newdemo.c b/ncurses-5.3/test/newdemo.c new file mode 100644 index 0000000..ee7e8a2 --- /dev/null +++ b/ncurses-5.3/test/newdemo.c @@ -0,0 +1,358 @@ +/* + * newdemo.c - A demo program using PDCurses. The program illustrate + * the use of colours for text output. + * + * $Id$ + */ + +#include <time.h> + +#include <test.priv.h> + +#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", + "" +}; + +/* + * Trap interrupt + */ +static RETSIGTYPE +trap(int sig GCC_UNUSED) +{ + endwin(); + ExitProgram(EXIT_FAILURE); +} + +/* + * Wait for user + */ +static int +WaitForUser(WINDOW *win) +{ + time_t t; + chtype key; + + nodelay(win, TRUE); + t = time((time_t *) 0); + while (1) { + if ((int) (key = wgetch(win)) != ERR) { + if (key == 'q' || key == 'Q') + return 1; + else + return 0; + } + if (time((time_t *) 0) - t > 5) + return 0; + } +} + +static void +set_colors(WINDOW *win, int pair, int foreground, int background) +{ + if (has_colors()) { + if (pair > COLOR_PAIRS) + pair = COLOR_PAIRS; + init_pair(pair, foreground, background); + wattrset(win, COLOR_PAIR(pair)); + } +} + +static int +use_colors(WINDOW *win, int pair, int attrs) +{ + if (has_colors()) { + if (pair > COLOR_PAIRS) + pair = COLOR_PAIRS; + attrs |= COLOR_PAIR(pair); + } + wattrset(win, attrs); + return attrs; +} + +/* + * Test sub windows + */ +static int +SubWinTest(WINDOW *win) +{ + int w, h, sw, sh, bx, by; + WINDOW *swin1, *swin2, *swin3; + + getmaxyx(win, h, w); + getbegyx(win, by, bx); + sw = w / 3; + sh = h / 3; + if ((swin1 = subwin(win, sh, sw, by + 3, bx + 5)) == NULL) + return 1; + if ((swin2 = subwin(win, sh, sw, by + 4, bx + 8)) == NULL) + return 1; + if ((swin3 = subwin(win, sh, sw, by + 5, bx + 11)) == NULL) + return 1; + + set_colors(swin1, 8, COLOR_RED, COLOR_BLUE); + werase(swin1); + mvwaddstr(swin1, 0, 3, "Sub-window 1"); + wrefresh(swin1); + + set_colors(swin2, 9, COLOR_CYAN, COLOR_MAGENTA); + werase(swin2); + mvwaddstr(swin2, 0, 3, "Sub-window 2"); + wrefresh(swin2); + + set_colors(swin3, 10, COLOR_YELLOW, COLOR_GREEN); + werase(swin3); + mvwaddstr(swin3, 0, 3, "Sub-window 3"); + wrefresh(swin3); + + delwin(swin1); + delwin(swin2); + delwin(swin3); + WaitForUser(win); + return 0; +} + +static int +bounce(int n, int *dir, int len) +{ + if (*dir > 0) + ++n; + else + --n; + if (n <= 1 || n >= len - 2) + *dir = *dir ? 0 : 1; + return n; +} + +/* + * Bouncing balls + */ +static int +BouncingBalls(WINDOW *win) +{ + int w, h; + int x1, y1, xd1, yd1; + int x2, y2, xd2, yd2; + int x3, y3, xd3, yd3; + + getmaxyx(win, h, w); + + x1 = 2 + rand() % (w - 4); + y1 = 2 + rand() % (h - 4); + x2 = 2 + rand() % (w - 4); + y2 = 2 + rand() % (h - 4); + x3 = 2 + rand() % (w - 4); + y3 = 2 + rand() % (h - 4); + + xd1 = 1; + yd1 = 1; + xd2 = 1; + yd2 = 0; + xd3 = 0; + yd3 = 1; + + nodelay(win, TRUE); + + while (wgetch(win) == ERR) { + x1 = bounce(x1, &xd1, w); + y1 = bounce(y1, &yd1, h); + x2 = bounce(x2, &xd2, w); + y2 = bounce(y2, &yd2, h); + x3 = bounce(x3, &xd3, w); + y3 = bounce(y3, &yd3, h); + + set_colors(win, 11, COLOR_RED, COLOR_BLUE); + mvwaddch(win, y1, x1, 'O'); + + set_colors(win, 12, COLOR_BLUE, COLOR_RED); + mvwaddch(win, y2, x2, '*'); + + set_colors(win, 13, COLOR_YELLOW, COLOR_WHITE); + mvwaddch(win, y3, x3, '@'); + + wmove(win, 0, 0); + wrefresh(win); + delay_output(100); + } + return 0; +} + +/* + * Main driver + */ +int +main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) +{ + WINDOW *win; + int w, x, y, i, j, k; + char buffer[200]; + const char *message; + int width, height; + chtype save[80]; + chtype c; + + setlocale(LC_ALL, ""); + + initscr(); + if (has_colors()) + start_color(); + cbreak(); + curs_set(0); + 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(); + ExitProgram(EXIT_FAILURE); + } + + while (1) { + set_colors(win, 1, COLOR_WHITE, COLOR_BLUE); + werase(win); + + set_colors(win, 2, COLOR_RED, COLOR_RED); + box(win, ACS_VLINE, ACS_HLINE); + wrefresh(win); + /* Do ramdom output of a character */ + use_colors(win, 1, A_NORMAL); + c = 'a'; + for (i = 0; i < 5000; ++i) { + x = rand() % (width - 2) + 1; + y = rand() % (height - 2) + 1; + mvwaddch(win, y, x, c); + wrefresh(win); + nodelay(win, TRUE); + if (wgetch(win) != ERR) + break; + if (i == 2000) { + c = 'b'; + set_colors(win, 3, COLOR_CYAN, COLOR_YELLOW); + } + } + + SubWinTest(win); + /* Erase and draw green window */ + set_colors(win, 4, COLOR_YELLOW, COLOR_GREEN); + wbkgd(win, use_colors(win, 4, A_BOLD)); + werase(win); + wrefresh(win); + /* Draw RED bounding box */ + use_colors(win, 2, A_NORMAL); + box(win, ' ', ' '); + wrefresh(win); + /* Display Australia map */ + use_colors(win, 4, A_BOLD); + i = 0; + while (*AusMap[i]) { + mvwaddstr(win, i + 1, 8, AusMap[i]); + wrefresh(win); + delay_output(50); + ++i; + } + + set_colors(win, 5, COLOR_BLUE, COLOR_WHITE); + use_colors(win, 5, A_BLINK); + mvwaddstr(win, height - 2, 6, " PDCurses 2.1 for DOS, OS/2 and Unix"); + wrefresh(win); + + /* Draw running messages */ + set_colors(win, 6, COLOR_YELLOW, COLOR_WHITE); + message = messages[j = 0]; + i = 1; + w = width - 2; + strcpy(buffer, message); + while (j < NMESSAGES) { + while ((int) strlen(buffer) < w) { + strcat(buffer, " ... "); + strcat(buffer, messages[++j % NMESSAGES]); + } + + if (i < w) + mvwaddnstr(win, height / 2, w - i, buffer, i); + else + mvwaddnstr(win, height / 2, 1, buffer, w); + + wrefresh(win); + nodelay(win, TRUE); + if (wgetch(win) != ERR) { + flushinp(); + break; + } + if (i++ >= w) { + for (k = 0; (buffer[k] = buffer[k + 1]) != '\0'; k++) ; + } + delay_output(100); + } + + j = 0; + /* Draw running As across in RED */ + set_colors(win, 7, COLOR_RED, COLOR_GREEN); + for (i = 2; i < width - 4; ++i) { + k = mvwinch(win, 4, i); + if (k == ERR) + break; + save[j++] = c = k; + c &= A_CHARTEXT; + mvwaddch(win, 4, i, c); + } + wrefresh(win); + + /* Put a message up wait for a key */ + i = height - 2; + use_colors(win, 5, A_NORMAL); + mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit "); + wrefresh(win); + + if (WaitForUser(win) == 1) + break; + + j = 0; /* Restore the old line */ + for (i = 2; i < width - 4; ++i) + mvwaddch(win, 4, i, save[j++]); + wrefresh(win); + + BouncingBalls(win); + /* Put a message up wait for a key */ + i = height - 2; + use_colors(win, 5, A_NORMAL); + mvwaddstr(win, i, 5, " Type a key to continue or 'Q' to quit "); + wrefresh(win); + if (WaitForUser(win) == 1) + break; + } + endwin(); + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/railroad.c b/ncurses-5.3/test/railroad.c new file mode 100644 index 0000000..ff79d4c --- /dev/null +++ b/ncurses-5.3/test/railroad.c @@ -0,0 +1,242 @@ +/**************************************************************************** + * Copyright (c) 2000-2001,2002 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> 2000 + * + * $Id$ + * + * A simple demo of the termcap interface. + */ +#include <test.priv.h> + +#include <ctype.h> + +static char *wipeit; +static char *moveit; +static int length; +static int height; + +static char *finisC; +static char *finisS; +static char *finisU; + +static char *startC; +static char *startS; +static char *startU; + +static char *backup; + +static bool interrupted = FALSE; + +static int +outc(int c) +{ + if (interrupted) { + char tmp = c; + write(STDOUT_FILENO, &tmp, 1); + } else { + putc(c, stdout); + } + return 0; +} + +static void +PutChar(int ch) +{ + putchar(ch); + fflush(stdout); + napms(moveit ? 10 : 50); /* not really termcap... */ +} + +static void +Backup(void) +{ + tputs(backup != 0 ? backup : "\b", 1, outc); +} + +static void +ShowCursor(int flag) +{ + if (startC != 0 && finisC != 0) { + tputs(flag ? startC : finisC, 1, outc); + } +} + +static void +StandOut(int flag) +{ + if (startS != 0 && finisS != 0) { + tputs(flag ? startS : finisS, 1, outc); + } +} + +static void +Underline(int flag) +{ + if (startU != 0 && finisU != 0) { + tputs(flag ? startU : finisU, 1, outc); + } +} + +static void +ShowSign(char *string) +{ + char *base = string; + int ch, first, last; + + if (moveit != 0) { + tputs(tgoto(moveit, 0, height - 1), 1, outc); + tputs(wipeit, 1, outc); + } + + while (*string != 0) { + ch = *string; + if (ch != ' ') { + if (moveit != 0) { + for (first = length - 2; first >= (string - base); first--) { + if (first < length - 1) { + tputs(tgoto(moveit, first + 1, height - 1), 1, outc); + PutChar(' '); + } + tputs(tgoto(moveit, first, height - 1), 1, outc); + PutChar(ch); + } + } else { + last = ch; + if (isalpha(ch)) { + first = isupper(ch) ? 'A' : 'a'; + } else if (isdigit(ch)) { + first = '0'; + } else { + first = ch; + } + if (first < last) { + Underline(1); + while (first < last) { + PutChar(first); + Backup(); + first++; + } + Underline(0); + } + } + if (moveit != 0) + Backup(); + } + StandOut(1); + PutChar(ch); + StandOut(0); + fflush(stdout); + string++; + } + if (moveit != 0) + tputs(wipeit, 1, outc); + putchar('\n'); +} + +static void +cleanup(void) +{ + Underline(0); + StandOut(0); + ShowCursor(1); +} + +static void +onsig(int n GCC_UNUSED) +{ + interrupted = TRUE; + cleanup(); + ExitProgram(EXIT_FAILURE); +} + +static void +railroad(char **args) +{ + NCURSES_CONST char *name = getenv("TERM"); + char buffer[1024]; + char area[1024], *ap = area; + int j; + + if (name == 0) + name = "dumb"; + if (tgetent(buffer, name)) { + + wipeit = tgetstr("ce", &ap); + height = tgetnum("li"); + length = tgetnum("co"); + moveit = tgetstr("cm", &ap); + + if (wipeit == 0 + || moveit == 0 + || height <= 0 + || length <= 0) { + wipeit = 0; + moveit = 0; + height = 0; + length = 0; + } + + startS = tgetstr("so", &ap); + finisS = tgetstr("se", &ap); + + startU = tgetstr("us", &ap); + finisU = tgetstr("ue", &ap); + + backup = tgetstr("le", &ap); + + startC = tgetstr("ve", &ap); + finisC = tgetstr("vi", &ap); + + ShowCursor(0); + + for (j = SIGHUP; j <= SIGTERM; j++) + if (signal(j, SIG_IGN) != SIG_IGN) + signal(j, onsig); + + while (*args) { + ShowSign(*args++); + } + ShowCursor(1); + } +} + +int +main(int argc, char *argv[]) +{ + if (argc > 1) { + railroad(argv + 1); + } else { + static char world[] = "Hello World"; + static char *hello[] = + {world, 0}; + railroad(hello); + } + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/rain.c b/ncurses-5.3/test/rain.c new file mode 100644 index 0000000..3092af8 --- /dev/null +++ b/ncurses-5.3/test/rain.c @@ -0,0 +1,136 @@ +/* + * $Id$ + */ +#include <test.priv.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; + + setlocale(LC_ALL, ""); + + 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(); +#if HAVE_USE_DEFAULT_COLORS + if (use_default_colors() == OK) + bg = -1; +#endif + init_pair(1, COLOR_BLUE, bg); + init_pair(2, COLOR_CYAN, bg); + } + nl(); + noecho(); + curs_set(0); + timeout(0); + + 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(); + ExitProgram(EXIT_SUCCESS); + case 's': + nodelay(stdscr, FALSE); + break; + case ' ': + nodelay(stdscr, TRUE); + break; +#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(); + ExitProgram(EXIT_FAILURE); +} + +static float +ranf(void) +{ + long r = (rand() & 077777); + return ((float) r / 32768.); +} diff --git a/ncurses-5.3/test/tclock.c b/ncurses-5.3/test/tclock.c new file mode 100644 index 0000000..4b1a5af --- /dev/null +++ b/ncurses-5.3/test/tclock.c @@ -0,0 +1,250 @@ +/* $Id$ */ + +#include "test.priv.h" + +#include <math.h> + +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + +/* + tclock - analog/digital clock for curses. + If it gives you joy, then + (a) I'm glad + (b) you need to get out more :-) + + This program is copyright Howard Jones, September 1994 + (ha.jones@ic.ac.uk). It may be freely distributed as + long as this copyright message remains intact, and any + modifications are clearly marked as such. [In fact, if + you modify it, I wouldn't mind the modifications back, + especially if they add any nice features. A good one + would be a precalc table for the 60 hand positions, so + that the floating point stuff can be ditched. As I said, + it was a 20 hackup minute job.] + + COMING SOON: tfishtank. Be the envy of your mac-owning + colleagues. +*/ + +/* To compile: cc -o tclock tclock.c -lcurses -lm */ + +#ifndef PI +#define PI 3.141592654 +#endif + +#define sign(_x) (_x<0?-1:1) + +#define ASPECT 2.2 +#define ROUND(value) ((int)((value) + 0.5)) + +#define A2X(angle,radius) ROUND(ASPECT * radius * sin(angle)) +#define A2Y(angle,radius) ROUND(radius * cos(angle)) + +/* Plot a point */ +static void +plot(int x, int y, char col) +{ + mvaddch(y, x, (chtype) col); +} + +/* Draw a diagonal(arbitrary) line using Bresenham's alogrithm. */ +static void +dline(int pair, int from_x, int from_y, int x2, int y2, char ch) +{ + int dx, dy; + int ax, ay; + int sx, sy; + int x, y; + int d; + + if (has_colors()) + attrset(COLOR_PAIR(pair)); + + dx = x2 - from_x; + dy = y2 - from_y; + + ax = abs(dx * 2); + ay = abs(dy * 2); + + sx = sign(dx); + sy = sign(dy); + + x = from_x; + y = from_y; + + if (ax > ay) { + d = ay - (ax / 2); + + while (1) { + plot(x, y, ch); + if (x == x2) + return; + + if (d >= 0) { + y += sy; + d -= ax; + } + x += sx; + d += ay; + } + } else { + d = ax - (ay / 2); + + while (1) { + plot(x, y, ch); + if (y == y2) + return; + + if (d >= 0) { + x += sx; + d -= ay; + } + y += sy; + d += ax; + } + } +} + +int +main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) +{ + int i, cx, cy; + double cr, mradius, hradius, mangle, hangle; + double sangle, sradius, hours; + int hdx, hdy; + int mdx, mdy; + int sdx, sdy; + int ch; + int lastbeep = -1; + time_t tim; + struct tm *t; + char szChar[10]; + int my_bg = COLOR_BLACK; +#if HAVE_GETTIMEOFDAY + struct timeval current; + double fraction = 0.0; +#endif + + setlocale(LC_ALL, ""); + + initscr(); + noecho(); + cbreak(); + nodelay(stdscr, TRUE); + curs_set(0); + + if (has_colors()) { + start_color(); +#if HAVE_USE_DEFAULT_COLORS + if (use_default_colors() == OK) + my_bg = -1; +#endif + init_pair(1, COLOR_RED, my_bg); + init_pair(2, COLOR_MAGENTA, my_bg); + init_pair(3, COLOR_GREEN, my_bg); + } +#ifdef KEY_RESIZE + keypad(stdscr, TRUE); + restart: +#endif + cx = (COLS - 1) / 2; /* 39 */ + cy = LINES / 2; /* 12 */ + if (cx / ASPECT < cy) + cr = cx / ASPECT; + else + cr = cy; + sradius = (5 * cr) / 6; /* 10 */ + mradius = (3 * cr) / 4; /* 9 */ + hradius = cr / 2; /* 6 */ + + for (i = 0; i < 12; i++) { + sangle = (i + 1) * (2.0 * PI) / 12.0; + sdx = A2X(sangle, sradius); + sdy = A2Y(sangle, sradius); + sprintf(szChar, "%d", i + 1); + + mvaddstr(cy - sdy, cx + sdx, szChar); + } + + mvaddstr(0, 0, "ASCII Clock by Howard Jones (ha.jones@ic.ac.uk),1994"); + + sradius = (4 * sradius) / 5; + for (;;) { + napms(100); + + tim = time(0); + t = localtime(&tim); + + hours = (t->tm_hour + (t->tm_min / 60.0)); + if (hours > 12.0) + hours -= 12.0; + + mangle = ((t->tm_min + (t->tm_sec / 60.0)) * (2 * PI) / 60.0); + mdx = A2X(mangle, mradius); + mdy = A2Y(mangle, mradius); + + hangle = ((hours) * (2.0 * PI) / 12.0); + hdx = A2X(hangle, hradius); + hdy = A2Y(hangle, hradius); + +#if HAVE_GETTIMEOFDAY + gettimeofday(¤t, 0); + fraction = (current.tv_usec / 1.0e6); +#endif + sangle = ((t->tm_sec + fraction) * (2.0 * PI) / 60.0); + sdx = A2X(sangle, sradius); + sdy = A2Y(sangle, sradius); + + dline(3, cx, cy, cx + mdx, cy - mdy, '#'); + + attrset(A_REVERSE); + dline(2, cx, cy, cx + hdx, cy - hdy, '.'); + attroff(A_REVERSE); + + if (has_colors()) + attrset(COLOR_PAIR(1)); + + dline(1, cx, cy, cx + sdx, cy - sdy, 'O'); + + if (has_colors()) + attrset(COLOR_PAIR(0)); + + mvaddstr(LINES - 2, 0, ctime(&tim)); + refresh(); + if ((t->tm_sec % 5) == 0 + && t->tm_sec != lastbeep) { + lastbeep = t->tm_sec; + beep(); + } + + if ((ch = getch()) != ERR) { +#ifdef KEY_RESIZE + if (ch == KEY_RESIZE) { + flash(); + erase(); + wrefresh(curscr); + goto restart; + } +#endif + break; + } + + dline(0, cx, cy, cx + hdx, cy - hdy, ' '); + dline(0, cx, cy, cx + mdx, cy - mdy, ' '); + dline(0, cx, cy, cx + sdx, cy - sdy, ' '); + + } + + curs_set(1); + endwin(); + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/test.priv.h b/ncurses-5.3/test/test.priv.h new file mode 100644 index 0000000..148e1d6 --- /dev/null +++ b/ncurses-5.3/test/test.priv.h @@ -0,0 +1,218 @@ +/**************************************************************************** + * Copyright (c) 1998-2001,2002 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$ */ + +#if HAVE_CONFIG_H +#include <ncurses_cfg.h> +#else +#define HAVE_CURSES_VERSION 0 +#define HAVE_RESIZETERM 0 +#define HAVE_USE_DEFAULT_COLORS 0 +#define HAVE_WRESIZE 0 +#endif + +#ifndef HAVE_CURSES_VERSION +#define HAVE_CURSES_VERSION 0 +#endif + +#ifndef HAVE_FORM_H +#define HAVE_FORM_H 0 +#endif + +#ifndef HAVE_LIBFORM +#define HAVE_LIBFORM 0 +#endif + +#ifndef HAVE_LIBMENU +#define HAVE_LIBMENU 0 +#endif + +#ifndef HAVE_LIBPANEL +#define HAVE_LIBPANEL 0 +#endif + +#ifndef HAVE_LOCALE_H +#define HAVE_LOCALE_H 0 +#endif + +#ifndef HAVE_MENU_H +#define HAVE_MENU_H 0 +#endif + +#ifndef HAVE_NAPMS +#define HAVE_NAPMS 1 +#endif + +#ifndef HAVE_NC_ALLOC_H +#define HAVE_NC_ALLOC_H 0 +#endif + +#ifndef HAVE_PANEL_H +#define HAVE_PANEL_H 0 +#endif + +#ifndef HAVE_WRESIZE +#define HAVE_WRESIZE 0 +#endif + +#ifndef NCURSES_NOMACROS +#define NCURSES_NOMACROS 0 +#endif + +#ifndef NEED_PTEM_H +#define NEED_PTEM_H 0 +#endif + +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#if HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <signal.h> /* include before curses.h to work around glibc bug */ + +#include <curses.h> +#include <term.h> + +#if 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 */ + +#if HAVE_LOCALE_H +#include <locale.h> +#else +#define setlocale(name,string) /* nothing */ +#endif + +#ifndef GCC_NORETURN +#define GCC_NORETURN /* nothing */ +#endif +#ifndef GCC_UNUSED +#define GCC_UNUSED /* nothing */ +#endif + +#ifndef HAVE_GETNSTR +#define getnstr(s,n) getstr(s) +#endif + +#ifndef USE_WIDEC_SUPPORT +#if defined(_XOPEN_SOURCE_EXTENDED) && defined(WACS_ULCORNER) +#define USE_WIDEC_SUPPORT 1 +#else +#define USE_WIDEC_SUPPORT 0 +#endif +#endif + +#ifndef HAVE_TYPE_ATTR_T +#if !USE_WIDEC_SUPPORT +#define attr_t long +#endif +#endif + +#ifndef NCURSES_CH_T +#if !USE_WIDEC_SUPPORT +#define NCURSES_CH_T chtype +#else +#define NCURSES_CH_T cchar_t +#endif +#endif + +#ifndef CCHARW_MAX +#define CCHARW_MAX 5 +#endif + +#ifndef KEY_MIN +#define KEY_MIN 256 /* not defined in Solaris 8 */ +#endif + +#ifndef getcurx +#define getcurx(win) ((win)?(win)->_curx:ERR) +#define getcury(win) ((win)?(win)->_cury:ERR) +#endif + +#ifndef getbegx +#define getbegx(win) ((win)?(win)->_begx:ERR) +#define getbegy(win) ((win)?(win)->_begy:ERR) +#endif + +#ifndef getmaxx +#define getmaxx(win) ((win)?((win)->_maxx + 1):ERR) +#define getmaxy(win) ((win)?((win)->_maxy + 1):ERR) +#endif + +/* ncurses implements tparm() with varargs, X/Open with a fixed-parameter list + * (which is incompatible with legacy usage, doesn't solve any problems). + */ +#define tparm3(a,b,c) tparm(a,b,c,0,0,0,0,0,0,0) +#define tparm2(a,b) tparm(a,b,0,0,0,0,0,0,0,0) + +#define UChar(c) ((unsigned char)(c)) + +#define SIZEOF(table) (sizeof(table)/sizeof(table[0])) + +#if defined(NCURSES_VERSION) && HAVE_NC_ALLOC_H +#include <nc_alloc.h> +#else +#define typeMalloc(type,n) (type *) malloc((n) * sizeof(type)) +#define typeRealloc(type,n,p) (type *) realloc(p, (n) * sizeof(type)) +#endif + +#ifndef ExitProgram +#define ExitProgram(code) exit(code) +#endif + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +/* Use this to quiet gcc's -Wwrite-strings warnings, but accommodate SVr4 + * curses which doesn't have const parameters declared (so far) in the places + * that XSI shows. + */ +#ifndef NCURSES_CONST +#define NCURSES_CONST /* nothing */ +#endif diff --git a/ncurses-5.3/test/testaddch.c b/ncurses-5.3/test/testaddch.c new file mode 100644 index 0000000..13830d7 --- /dev/null +++ b/ncurses-5.3/test/testaddch.c @@ -0,0 +1,61 @@ +/* + * This is an example written by Alexander V. Lukyanov <lav@yars.free.net>, + * to demonstrate an inconsistency between ncurses and SVr4 curses. + * + * $Id$ + */ +#include <test.priv.h> + +static void +attr_addstr(const char *s, chtype a) +{ + while (*s) + addch(((unsigned char) (*s++)) | a); +} + +int +main( + int argc GCC_UNUSED, + char *argv[]GCC_UNUSED) +{ + unsigned i; + chtype back, set, attr; + + setlocale(LC_ALL, ""); + + initscr(); + start_color(); + init_pair(1, COLOR_WHITE, COLOR_BLUE); + init_pair(2, COLOR_WHITE, COLOR_RED); + init_pair(3, COLOR_BLACK, COLOR_MAGENTA); + init_pair(4, COLOR_BLACK, COLOR_GREEN); + init_pair(5, COLOR_BLACK, COLOR_CYAN); + init_pair(6, COLOR_BLACK, COLOR_YELLOW); + init_pair(7, COLOR_BLACK, COLOR_WHITE); + + for (i = 0; i < 8; i++) { + back = (i & 1) ? A_BOLD | 'B' : ' '; + set = (i & 2) ? A_REVERSE : 0; + attr = (i & 4) ? COLOR_PAIR(4) : 0; + + bkgdset(back); + attrset(set); + + attr_addstr("Test string with spaces -> <-\n", attr); + } + addch('\n'); + for (i = 0; i < 8; i++) { + back = (i & 1) ? A_BOLD | 'B' | COLOR_PAIR(1) : ' '; + set = (i & 2) ? A_REVERSE | COLOR_PAIR(2) : 0; + attr = (i & 4) ? COLOR_PAIR(4) : 0; + + bkgdset(back); + attrset(set); + + attr_addstr("Test string with spaces -> <-\n", attr); + } + + getch(); + endwin(); + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/testcurs.c b/ncurses-5.3/test/testcurs.c new file mode 100644 index 0000000..6230c86 --- /dev/null +++ b/ncurses-5.3/test/testcurs.c @@ -0,0 +1,708 @@ +/* + * + * 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$ + */ + +#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[] = +{ + {"General Test", introTest}, + {"Pad Test", padTest}, +#if defined(PDCURSES) && !defined(XCURSES) + {"Resize Test", resizeTest}, +#endif + {"Scroll Test", scrollTest}, + {"Input Test", inputTest}, + {"Output Test", outputTest} +}; +#define MAX_OPTIONS SIZEOF(command) + +#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 */ + +int width, height; + +int +main( + int argc GCC_UNUSED, + char *argv[]GCC_UNUSED) +{ + WINDOW *win; + int key; + int old_option = (-1); + int new_option = 0; + bool quit = FALSE; + unsigned n; + + setlocale(LC_ALL, ""); + +#ifdef PDCDEBUG + PDC_debug("testcurs started\n"); +#endif + if (!initTest(&win)) + ExitProgram(EXIT_FAILURE); + + erase(); + display_menu(old_option, new_option); + for (;;) { +#ifdef A_COLOR + if (has_colors()) { + init_pair(1, COLOR_WHITE, COLOR_BLUE); + wbkgd(win, COLOR_PAIR(1)); + } else + wbkgd(win, A_REVERSE); +#else + wbkgd(win, A_REVERSE); +#endif + werase(win); + + noecho(); + keypad(stdscr, TRUE); + raw(); + key = getch(); + if (key < KEY_MIN && key > 0 && isalpha(key)) { + if (islower(key)) + key = toupper(key); + for (n = 0; n < MAX_OPTIONS; ++n) { + if (key == command[n].text[0]) { + display_menu(old_option, new_option = n); + key = ' '; + break; + } + } + } + switch (key) { + case 10: + case 13: + case KEY_ENTER: + erase(); + refresh(); + (*command[new_option].function) (win); + erase(); + display_menu(old_option, new_option); + break; + case KEY_UP: + new_option = (new_option == 0) ? new_option : new_option - 1; + display_menu(old_option, new_option); + break; + case KEY_DOWN: + new_option = (new_option == MAX_OPTIONS - 1) ? new_option : + new_option + 1; + display_menu(old_option, new_option); + break; + case 'Q': + case 'q': + quit = TRUE; + break; + default: + beep(); + break; + case ' ': + break; + } + if (quit == TRUE) + break; + } + + delwin(win); + + endwin(); +#ifdef XCURSES + XCursesExit(); +#endif + ExitProgram(EXIT_SUCCESS); +} + +static void +Continue(WINDOW *win) +{ + int y1 = getmaxy(win); + int x1 = getmaxx(win); + int y0 = y1 < 10 ? y1 : 10; + int x0 = 1; + long save; + + save = mvwinch(win, y0, x1 - 1); + + mvwaddstr(win, y0, x0, " Press any key to continue"); + wclrtoeol(win); + getyx(win, y0, x0); + + mvwaddch(win, y0, x1 - 1, save); + + wmove(win, y0, x0); + raw(); + wgetch(win); +} + +static int +initTest(WINDOW **win) +{ +#ifdef PDCDEBUG + PDC_debug("initTest called\n"); +#endif +#ifdef TRACE + trace(TRACE_MAXIMUM); +#endif + initscr(); +#ifdef PDCDEBUG + PDC_debug("after initscr()\n"); +#endif +#ifdef A_COLOR + if (has_colors()) + start_color(); +#endif + width = 60; + height = 13; /* Create a drawing window */ + *win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2); + if (*win == NULL) { + endwin(); + return 0; + } + return 1; +} + +static void +introTest(WINDOW *win) +{ + wmove(win, height / 2 - 5, width / 2); + wvline(win, ACS_VLINE, 10); + wmove(win, height / 2, width / 2 - 10); + whline(win, ACS_HLINE, 20); + Continue(win); + + beep(); + werase(win); + + box(win, ACS_VLINE, ACS_HLINE); + wrefresh(win); + cbreak(); + mvwaddstr(win, 1, 1, + "You should have rectangle in the middle of the screen"); + mvwaddstr(win, 2, 1, "You should have heard a beep"); + Continue(win); + return; +} + +static void +scrollTest(WINDOW *win) +{ + int i; + int half; + int OldY; + NCURSES_CONST char *Message = "The window will now scroll slowly"; + + wclear(win); + OldY = getmaxy(win); + half = OldY / 2; + mvwprintw(win, OldY - 2, 1, Message); + wrefresh(win); + scrollok(win, TRUE); + for (i = 1; i <= OldY; i++) { + napms(600); + scroll(win); + wrefresh(win); + } + + werase(win); + for (i = 1; i < OldY; i++) { + mvwprintw(win, i, 1, "Line %d", i); + } + mvwprintw(win, OldY - 2, 1, "The top of the window will scroll"); + wmove(win, 1, 1); + wsetscrreg(win, 0, half - 1); + box(win, ACS_VLINE, ACS_HLINE); + wrefresh(win); + for (i = 1; i <= half; i++) { + napms(600); + scroll(win); + box(win, ACS_VLINE, ACS_HLINE); + wrefresh(win); + } + + werase(win); + for (i = 1; i < OldY; i++) { + mvwprintw(win, i, 1, "Line %d", i); + } + mvwprintw(win, 1, 1, "The bottom of the window will scroll"); + wmove(win, OldY - 2, 1); + wsetscrreg(win, half, --OldY); + box(win, ACS_VLINE, ACS_HLINE); + wrefresh(win); + for (i = half; i <= OldY; i++) { + napms(600); + wscrl(win, -1); + box(win, ACS_VLINE, ACS_HLINE); + wrefresh(win); + } + wsetscrreg(win, 0, OldY); +} + +static void +inputTest(WINDOW *win) +{ + int answered; + int repeat; + int w, h, bx, by, sw, sh, i, c, num; + char buffer[80]; + WINDOW *subWin; + wclear(win); + + getmaxyx(win, h, w); + getbegyx(win, by, bx); + sw = w / 3; + sh = h / 3; + if ((subWin = subwin(win, sh, sw, by + h - sh - 2, bx + w - sw - 2)) == NULL) + return; + +#ifdef A_COLOR + if (has_colors()) { + init_pair(2, COLOR_WHITE, COLOR_RED); + wbkgd(subWin, COLOR_PAIR(2) | A_BOLD); + } else + wbkgd(subWin, A_BOLD); +#else + wbkgd(subWin, A_BOLD); +#endif + box(subWin, ACS_VLINE, ACS_HLINE); + wrefresh(win); + + nocbreak(); + mvwaddstr(win, 2, 1, "Press some keys for 5 seconds"); + mvwaddstr(win, 1, 1, "Pressing ^C should do nothing"); + wrefresh(win); + + werase(subWin); + box(subWin, ACS_VLINE, ACS_HLINE); + for (i = 0; i < 5; i++) { + mvwprintw(subWin, 1, 1, "Time = %d", i); + wrefresh(subWin); + napms(1000); + flushinp(); + } + + delwin(subWin); + werase(win); + flash(); + wrefresh(win); + napms(500); + + mvwaddstr(win, 2, 1, "Press a key, followed by ENTER"); + wmove(win, 9, 10); + wrefresh(win); + echo(); + noraw(); + wgetch(win); + flushinp(); + + wmove(win, 9, 10); + wdelch(win); + mvwaddstr(win, 4, 1, "The character should now have been deleted"); + Continue(win); + + wclear(win); + mvwaddstr(win, 1, 1, "Press keys (or mouse buttons) to show their names"); + mvwaddstr(win, 2, 1, "Press spacebar to finish"); + wrefresh(win); + keypad(win, TRUE); + raw(); + noecho(); + typeahead(-1); +#if defined(PDCURSES) + mouse_set(ALL_MOUSE_EVENTS); +#endif + for (;;) { + wmove(win, 3, 5); + c = wgetch(win); + wclrtobot(win); + if (c >= KEY_MIN) + wprintw(win, "Key Pressed: %s", keyname(c)); + else if (isprint(c)) + wprintw(win, "Key Pressed: %c", c); + else + wprintw(win, "Key Pressed: %s", unctrl(c)); +#if defined(PDCURSES) + if (c == KEY_MOUSE) { + int button = 0; + request_mouse_pos(); + if (BUTTON_CHANGED(1)) + button = 1; + else if (BUTTON_CHANGED(2)) + button = 2; + else if (BUTTON_CHANGED(3)) + button = 3; + else + button = 0; + wmove(win, 4, 18); + wprintw(win, "Button %d: ", button); + if (MOUSE_MOVED) + wprintw(win, "moved: "); + else if ((BUTTON_STATUS(button) & BUTTON_ACTION_MASK) == BUTTON_PRESSED) + wprintw(win, "pressed: "); + else if ((BUTTON_STATUS(button) & BUTTON_ACTION_MASK) == BUTTON_DOUBLE_CLICKED) + wprintw(win, "double: "); + else + wprintw(win, "released: "); + wprintw(win, " Position: Y: %d X: %d", MOUSE_Y_POS, MOUSE_X_POS); + } +#endif + wrefresh(win); + if (c == ' ') + break; + } +#if 0 + nodelay(win, TRUE); + wgetch(win); + nodelay(win, FALSE); +#endif +#if defined(PDCURSES) + mouse_set(0L); +#endif + refresh(); + + repeat = 0; + do { + static const char *fmt[] = { + "%d %10s", + "%d %[a-zA-Z]s", + "%d %[][a-zA-Z]s", + "%d %[^0-9]" + }; + const char *format = fmt[repeat % SIZEOF(fmt)]; + + wclear(win); + mvwaddstr(win, 3, 2, "The window should have moved"); + mvwaddstr(win, 4, 2, + "This text should have appeared without you pressing a key"); + mvwprintw(win, 6, 2, + "Scanning with format \"%s\"", format); + mvwin(win, 2 + 2 * (repeat % 4), 1 + 2 * (repeat % 4)); + erase(); + refresh(); + wrefresh(win); + echo(); + noraw(); + num = 0; + *buffer = 0; + answered = mvwscanw(win, 7, 6, strdup(format), &num, buffer); + mvwprintw(win, 8, 6, + "String: %s Number: %d (%d values read)", + buffer, num, answered); + Continue(win); + ++repeat; + } while (answered > 0); +} + +static void +outputTest(WINDOW *win) +{ + WINDOW *win1; + char Buffer[80]; + chtype ch; + int by, bx; + + 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/ncurses-5.3/test/testscanw.c b/ncurses-5.3/test/testscanw.c new file mode 100644 index 0000000..668fca4 --- /dev/null +++ b/ncurses-5.3/test/testscanw.c @@ -0,0 +1,41 @@ +/* gleaned from a web-search, shows a bug combining scanw and implicit scroll. + * Date: 1997/03/17 + * From: bayern@morpheus.cis.yale.edu + * + * $Id$ + */ +#include <test.priv.h> +#include <ctype.h> + +int +main(int argc, char *argv[]) +{ + long badanswer = 1; + long *response = &badanswer; + + setlocale(LC_ALL, ""); + + initscr(); + scrollok(stdscr, TRUE); + idlok(stdscr, TRUE); + echo(); + +#if 0 + trace(TRACE_UPDATE | TRACE_CALLS); +#endif + while (argc > 1) { + if (isdigit(UChar(*argv[1]))) + move(atoi(argv[1]), 0); + else if (!strcmp(argv[1], "-k")) + keypad(stdscr, TRUE); + argc--, argv++; + } + + while (badanswer) { + printw("Enter a number (0 to quit):\n"); + printw("--> "); + scanw("%20ld", response); /* yes, it's a pointer */ + } + endwin(); + ExitProgram(EXIT_SUCCESS); +} diff --git a/ncurses-5.3/test/tracemunch b/ncurses-5.3/test/tracemunch new file mode 100755 index 0000000..fd89ff6 --- /dev/null +++ b/ncurses-5.3/test/tracemunch @@ -0,0 +1,151 @@ +#!/usr/bin/perl -w +# $Id$ +############################################################################## +# Copyright (c) 1998,2002 Free Software Foundation, Inc. # +# # +# Permission is hereby granted, free of charge, to any person obtaining a # +# copy of this software and associated documentation files (the "Software"), # +# to deal in the Software without restriction, including without limitation # +# the rights to use, copy, modify, merge, publish, distribute, distribute # +# with modifications, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the # +# following conditions: # +# # +# The above copyright notice and this permission notice shall be included in # +# all copies or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # +# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # +# DEALINGS IN THE SOFTWARE. # +# # +# Except as contained in this notice, the name(s) of the above copyright # +# holders shall not be used in advertising or otherwise to promote the sale, # +# use or other dealings in this Software without prior written # +# authorization. # +############################################################################## +# tracemunch -- compactify ncurses trace logs +# +# The error logs produced by ncurses with tracing enabled can be very tedious +# to wade through. This script helps by compacting runs of log lines that +# can be conveniently expressed as higher-level operations. +# + +$putattr="PutAttrChar\\('(.)' = 0x.., {A_NORMAL}\\) at \\(([0-9]+), ([0-9]+)\\)"; +$waddnstr="waddnstr\\(0x([0-9a-f]+),\"([^\"]+)\",[0-9]+\\) called {A_NORMAL}"; + +$win_nums=0; + +sub transaddr +{ + $arg = $_[0]; + + $arg =~ s/$curscr/curscr/ if ($curscr); + $arg =~ s/$newscr/newscr/ if ($newscr); + $arg =~ s/$stdscr/stdscr/ if ($stdscr); + for $n (0..$#win_addr) { + $arg =~ s/$win_addr[$n]/window$n/ if $win_addr[$n]; + } + + 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 ($_ =~ /^create :window 0x([0-9a-f]+)/) { + $addr = "0x$1"; + if ($awaiting eq "curscr") { + $curscr = $addr; + } elsif ($awaiting eq "newscr") { + $newscr = $addr; + } elsif ($awaiting eq "stdscr") { + $stdscr = $addr; + } else { + $win_addr[$win_nums] = $addr; + $win_nums = $win_nums + 1; + } + $awaiting = ""; + } elsif ($_ =~ /^\.\.\.deleted win=0x([0-9a-f]+)/) { + $addr = "0x$1"; + if ($addr eq $curscr) { + $curscr = ""; + } elsif ($addr eq $newscr) { + $newscr = ""; + } elsif ($addr eq $stdscr) { + $stdscr = ""; + } else { + for $n (0..$#win_addr) { + if ($win_addr[$n] eq $addr) { + $win_addr[$n] = ""; + } + } + } + } + + # Compactify runs of PutAttrChar calls (TR_CHARPUT) + if ($_ =~ /$putattr/) + { + $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/ncurses-5.3/test/view.c b/ncurses-5.3/test/view.c new file mode 100644 index 0000000..73c64d6 --- /dev/null +++ b/ncurses-5.3/test/view.c @@ -0,0 +1,512 @@ +/* + * view.c -- a silly little viewer program + * + * written by Eric S. Raymond <esr@snark.thyrsus.com> December 1994 + * to test the scrolling code in ncurses. + * + * modified by Thomas Dickey <dickey@clark.net> July 1995 to demonstrate + * the use of 'resizeterm()', and May 2000 to illustrate wide-character + * handling. + * + * Takes a filename argument. It's a simple file-viewer with various + * scroll-up and scroll-down commands. + * + * n -- scroll one line forward + * p -- scroll one line back + * + * Either command accepts a numeric prefix interpreted as a repeat count. + * Thus, typing `5n' should scroll forward 5 lines in the file. + * + * The way you can tell this is working OK is that, in the trace file, + * there should be one scroll operation plus a small number of line + * updates, as opposed to a whole-page update. This means the physical + * scroll operation worked, and the refresh() code only had to do a + * partial repaint. + * + * $Id$ + */ + +#include <ctype.h> +#include <time.h> + +#include <test.priv.h> + +#if HAVE_TERMIOS_H +# include <termios.h> +#else +# include <sgtty.h> +#endif + +#if !defined(sun) || !HAVE_TERMIOS_H +# if HAVE_SYS_IOCTL_H +# include <sys/ioctl.h> +# endif +#endif + +#define my_pair 1 + +/* This is needed to compile 'struct winsize' */ +#if NEED_PTEM_H +#include <sys/stream.h> +#include <sys/ptem.h> +#endif + +static RETSIGTYPE finish(int sig) GCC_NORETURN; +static void show_all(const char *tag); + +#if defined(SIGWINCH) && defined(TIOCGWINSZ) && HAVE_RESIZETERM +#define CAN_RESIZE 1 +#else +#define CAN_RESIZE 0 +#endif + +#if CAN_RESIZE +static RETSIGTYPE adjust(int sig); +static int interrupted; +#endif + +static bool waiting = FALSE; +static int shift = 0; +static bool try_color = FALSE; + +static char *fname; +static NCURSES_CH_T **my_lines; +static NCURSES_CH_T **lptr; + +static void +usage(void) +{ + static const char *msg[] = + { + "Usage: view [options] file" + ,"" + ,"Options:" + ," -c use color if terminal supports it" + ," -i ignore INT, QUIT, TERM signals" + ," -n NUM specify maximum number of lines (default 1000)" +#if defined(KEY_RESIZE) + ," -r use old-style sigwinch handler rather than KEY_RESIZE" +#endif +#ifdef TRACE + ," -t trace screen updates" + ," -T NUM specify trace mask" +#endif + }; + size_t n; + for (n = 0; n < SIZEOF(msg); n++) + fprintf(stderr, "%s\n", msg[n]); + ExitProgram(EXIT_FAILURE); +} + +static int +ch_len(NCURSES_CH_T * src) +{ + int result = 0; +#if USE_WIDEC_SUPPORT +#endif + +#if USE_WIDEC_SUPPORT + while (getcchar(src++, NULL, NULL, NULL, NULL) > 0) + result++; +#else + while (*src++) + result++; +#endif + return result; +} + +/* + * Allocate a string into an array of chtype's. If UTF-8 mode is + * active, translate the string accordingly. + */ +static NCURSES_CH_T * +ch_dup(char *src) +{ + unsigned len = strlen(src); + NCURSES_CH_T *dst = typeMalloc(NCURSES_CH_T, len + 1); + unsigned j, k; +#if USE_WIDEC_SUPPORT + wchar_t wstr[CCHARW_MAX + 1]; + wchar_t wch; + int l = 0; + mbstate_t state; + size_t rc; + int width; +#endif + +#if USE_WIDEC_SUPPORT + memset(&state, 0, sizeof(state)); +#endif + for (j = k = 0; j < len; j++) { +#if USE_WIDEC_SUPPORT + rc = mbrtowc(&wch, src + j, len - j, &state); + if (rc == (size_t) -1 || rc == (size_t) -2) + break; + j += rc - 1; + if ((width = wcwidth(wch)) < 0) + break; + if ((width > 0 && l > 0) || l == CCHARW_MAX) { + wstr[l] = L'\0'; + l = 0; + if (setcchar(dst + k, wstr, 0, 0, NULL) != OK) + break; + ++k; + } + if (width == 0 && l == 0) + wstr[l++] = L' '; + wstr[l++] = wch; +#else + dst[k++] = src[j]; +#endif + } +#if USE_WIDEC_SUPPORT + if (l > 0) { + wstr[l] = L'\0'; + if (setcchar(dst + k, wstr, 0, 0, NULL) == OK) + ++k; + } + setcchar(dst + k, L"", 0, 0, NULL); +#else + dst[k] = 0; +#endif + return dst; +} + +int +main(int argc, char *argv[]) +{ + int MAXLINES = 1000; + FILE *fp; + char buf[BUFSIZ]; + int i; + int my_delay = 0; + NCURSES_CH_T **olptr; + int length = 0; + int value = 0; + bool done = FALSE; + bool got_number = FALSE; +#if CAN_RESIZE + bool nonposix_resize = FALSE; +#endif + const char *my_label = "Input"; + + setlocale(LC_ALL, ""); + +#ifndef NCURSES_VERSION + /* + * We know ncurses will catch SIGINT if we don't establish our own handler. + * Other versions of curses may/may not catch it. + */ + (void) signal(SIGINT, finish); /* arrange interrupts to terminate */ +#endif + + while ((i = getopt(argc, argv, "cin:rtT:")) != EOF) { + switch (i) { + case 'c': + try_color = TRUE; + break; + case 'i': + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGTERM, SIG_IGN); + break; + case 'n': + if ((MAXLINES = atoi(optarg)) < 1) + usage(); + break; +#if CAN_RESIZE + case 'r': + nonposix_resize = TRUE; + 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 ((my_lines = typeMalloc(NCURSES_CH_T *, MAXLINES + 2)) == 0) + usage(); + + fname = argv[optind]; + if ((fp = fopen(fname, "r")) == 0) { + perror(fname); + ExitProgram(EXIT_FAILURE); + } +#if CAN_RESIZE + if (nonposix_resize) + (void) signal(SIGWINCH, adjust); /* arrange interrupts to resize */ +#endif + + /* slurp the file */ + for (lptr = &my_lines[0]; (lptr - my_lines) < MAXLINES; lptr++) { + char temp[BUFSIZ], *s, *d; + int col; + + if (fgets(buf, sizeof(buf), fp) == 0) + break; + + /* convert tabs so that shift will work properly */ + for (s = buf, d = temp, col = 0; (*d = *s) != '\0'; s++) { + if (*d == '\n') { + *d = '\0'; + break; + } else if (*d == '\t') { + col = (col | 7) + 1; + while ((d - temp) != col) + *d++ = ' '; + } else +#if USE_WIDEC_SUPPORT + col++, d++; +#else + if (isprint(UChar(*d))) { + col++; + d++; + } else { + sprintf(d, "\\%03o", UChar(*s)); + d += strlen(d); + col = (d - temp); + } +#endif + } + *lptr = ch_dup(temp); + } + (void) fclose(fp); + length = lptr - my_lines; + + (void) initscr(); /* initialize the curses library */ + keypad(stdscr, TRUE); /* enable keyboard mapping */ + (void) nonl(); /* tell curses not to do NL->CR/NL on output */ + (void) cbreak(); /* take input chars one at a time, no wait for \n */ + (void) noecho(); /* don't echo input */ + nodelay(stdscr, TRUE); + idlok(stdscr, TRUE); /* allow use of insert/delete line */ + + if (try_color) { + if (has_colors()) { + start_color(); + init_pair(my_pair, COLOR_WHITE, COLOR_BLUE); + bkgd(COLOR_PAIR(my_pair)); + } else { + try_color = FALSE; + } + } + + lptr = my_lines; + while (!done) { + int n, c; + + if (!got_number) + show_all(my_label); + + n = 0; + for (;;) { +#if CAN_RESIZE + if (interrupted) { + adjust(0); + my_label = "interrupt"; + } +#endif + waiting = TRUE; + c = getch(); + waiting = FALSE; + if ((c < 127) && isdigit(c)) { + if (!got_number) { + mvprintw(0, 0, "Count: "); + clrtoeol(); + } + addch(c); + value = 10 * value + (c - '0'); + got_number = TRUE; + } else + break; + } + if (got_number && value) { + n = value; + } else { + n = 1; + } + + if (c != ERR) + my_label = keyname(c); + switch (c) { + case KEY_DOWN: + case 'n': + olptr = lptr; + for (i = 0; i < n; i++) + if ((lptr - my_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 > my_lines) + lptr--; + else + break; + wscrl(stdscr, lptr - olptr); + break; + + case 'h': + case KEY_HOME: + lptr = my_lines; + break; + + case 'e': + case KEY_END: + if (length > LINES) + lptr = my_lines + length - LINES + 1; + else + lptr = my_lines; + break; + + case 'r': + case KEY_RIGHT: + shift += n; + break; + + case 'l': + case KEY_LEFT: + shift -= n; + if (shift < 0) { + shift = 0; + beep(); + } + break; + + case 'q': + done = TRUE; + break; + +#ifdef KEY_RESIZE + case KEY_RESIZE: /* ignore this; ncurses will repaint */ + break; +#endif + case 's': + if (got_number) { + halfdelay(my_delay = n); + } else { + nodelay(stdscr, FALSE); + my_delay = -1; + } + break; + case ' ': + nodelay(stdscr, TRUE); + my_delay = 0; + break; + case ERR: + if (!my_delay) + napms(50); + break; + default: + beep(); + break; + } + if (c >= KEY_MIN || (c > 0 && !isdigit(c))) { + got_number = FALSE; + value = 0; + } + } + + finish(0); /* we're done */ +} + +static RETSIGTYPE +finish(int sig) +{ + endwin(); + ExitProgram(sig != 0 ? EXIT_FAILURE : EXIT_SUCCESS); +} + +#if CAN_RESIZE +/* + * This uses functions that are "unsafe", but it seems to work on SunOS and + * Linux. Usually: the "unsafe" refers to the functions that POSIX lists + * which may be called from a signal handler. Those do not include buffered + * I/O, which is used for instance in wrefresh(). To be really portable, you + * should use the KEY_RESIZE return (which relies on ncurses' sigwinch + * handler). + * + * The 'wrefresh(curscr)' is needed to force the refresh to start from the top + * of the screen -- some xterms mangle the bitmap while resizing. + */ +static RETSIGTYPE +adjust(int sig) +{ + if (waiting || sig == 0) { + struct winsize size; + + if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) { + resize_term(size.ws_row, size.ws_col); + wrefresh(curscr); /* Linux needs this */ + show_all(sig ? "SIGWINCH" : "interrupt"); + } + interrupted = FALSE; + } else { + interrupted = TRUE; + } + (void) signal(SIGWINCH, adjust); /* some systems need this */ +} +#endif /* CAN_RESIZE */ + +static void +show_all(const char *tag) +{ + int i; + char temp[BUFSIZ]; + NCURSES_CH_T *s; + time_t this_time; + +#if CAN_RESIZE + sprintf(temp, "%s (%3dx%3d) col %d ", tag, 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(); + this_time = time((time_t *) 0); + strcpy(temp, ctime(&this_time)); + if ((i = strlen(temp)) != 0) { + temp[--i] = 0; + if (move(0, COLS - i - 2) != ERR) + printw(" %s", temp); + } + + scrollok(stdscr, FALSE); /* prevent screen from moving */ + for (i = 1; i < LINES; i++) { + move(i, 0); + printw("%3ld:", (long) (lptr + i - my_lines)); + clrtoeol(); + if ((s = lptr[i - 1]) != 0) { + int len = ch_len(s); + if (len > shift) +#if USE_WIDEC_SUPPORT + add_wchstr(s + shift); +#else + addchstr(s + shift); +#endif + if (try_color) + wchgat(stdscr, -1, A_NORMAL, my_pair, NULL); + } + } + setscrreg(1, LINES - 1); + scrollok(stdscr, TRUE); + refresh(); +} diff --git a/ncurses-5.3/test/worm.c b/ncurses-5.3/test/worm.c new file mode 100644 index 0000000..4fd8cf5 --- /dev/null +++ b/ncurses-5.3/test/worm.c @@ -0,0 +1,427 @@ +/* + + @@@ @@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@ + @@@ @@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@ + @@@ @@@ @@@@ @@@@ @@@@ @@@@ @@@ @@@@ + @@@ @@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ + @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ + @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ + @@@@@@@@@@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ + @@@@ @@@@ @@@@@@@@@@@@ @@@ @@@ @@@ @@@ + @@ @@ @@@@@@@@@@ @@@ @@@ @@@ @@@ + + 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$ +*/ + +#include <test.priv.h> + +static chtype flavor[] = +{ + 'O', '*', '#', '$', '%', '0', '@', +}; +static const short xinc[] = +{ + 1, 1, 1, 0, -1, -1, -1, 0 +}, yinc[] = +{ + -1, 0, 1, 1, 1, 0, -1, -1 +}; +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 */ +/* *INDENT-OFF* */ +static const struct options { + int nopts; + int opts[3]; +} normal[8]={ + { 3, { 7, 0, 1 } }, + { 3, { 0, 1, 2 } }, + { 3, { 1, 2, 3 } }, + { 3, { 2, 3, 4 } }, + { 3, { 3, 4, 5 } }, + { 3, { 4, 5, 6 } }, + { 3, { 5, 6, 7 } }, + { 3, { 6, 7, 0 } } +}, upper[8]={ + { 1, { 1, 0, 0 } }, + { 2, { 1, 2, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 2, { 4, 5, 0 } }, + { 1, { 5, 0, 0 } }, + { 2, { 1, 5, 0 } } +}, left[8]={ + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 2, { 2, 3, 0 } }, + { 1, { 3, 0, 0 } }, + { 2, { 3, 7, 0 } }, + { 1, { 7, 0, 0 } }, + { 2, { 7, 0, 0 } } +}, right[8]={ + { 1, { 7, 0, 0 } }, + { 2, { 3, 7, 0 } }, + { 1, { 3, 0, 0 } }, + { 2, { 3, 4, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 2, { 6, 7, 0 } } +}, lower[8]={ + { 0, { 0, 0, 0 } }, + { 2, { 0, 1, 0 } }, + { 1, { 1, 0, 0 } }, + { 2, { 1, 5, 0 } }, + { 1, { 5, 0, 0 } }, + { 2, { 5, 6, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } } +}, upleft[8]={ + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 1, { 3, 0, 0 } }, + { 2, { 1, 3, 0 } }, + { 1, { 1, 0, 0 } } +}, upright[8]={ + { 2, { 3, 5, 0 } }, + { 1, { 3, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 1, { 5, 0, 0 } } +}, lowleft[8]={ + { 3, { 7, 0, 1 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 1, { 1, 0, 0 } }, + { 2, { 1, 7, 0 } }, + { 1, { 7, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } } +}, lowright[8]={ + { 0, { 0, 0, 0 } }, + { 1, { 7, 0, 0 } }, + { 2, { 5, 7, 0 } }, + { 1, { 5, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } }, + { 0, { 0, 0, 0 } } +}; +/* *INDENT-ON* */ + +static void +cleanup(void) +{ + standend(); + refresh(); + curs_set(1); + endwin(); +} + +static RETSIGTYPE +onsig(int sig GCC_UNUSED) +{ + cleanup(); + ExitProgram(EXIT_FAILURE); +} + +static float +ranf(void) +{ + long r = (rand() & 077777); + return ((float) r / 32768.); +} + +int +main(int argc, char *argv[]) +{ + short **ref; + int x, y; + int n; + struct worm *w; + const struct options *op; + int h; + short *ip; + int last, bottom; + + setlocale(LC_ALL, ""); + + for (x = 1; x < argc; x++) { + char *p; + p = argv[x]; + if (*p == '-') + p++; + switch (*p) { + case 'f': + field = "WORM"; + break; + case 'l': + if (++x == argc) + goto usage; + if ((length = atoi(argv[x])) < 2 || length > 1024) { + fprintf(stderr, "%s: Invalid length\n", *argv); + ExitProgram(EXIT_FAILURE); + } + break; + case 'n': + if (++x == argc) + goto usage; + if ((number = atoi(argv[x])) < 1 || number > 40) { + fprintf(stderr, "%s: Invalid number of worms\n", *argv); + ExitProgram(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); + ExitProgram(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(); +#if HAVE_USE_DEFAULT_COLORS + if (use_default_colors() == OK) + bg = -1; +#endif + +#define SET_COLOR(num, fg) \ + init_pair(num+1, fg, bg); \ + flavor[num] |= COLOR_PAIR(num+1) | A_BOLD + + SET_COLOR(0, COLOR_GREEN); + SET_COLOR(1, COLOR_RED); + SET_COLOR(2, COLOR_CYAN); + SET_COLOR(3, COLOR_WHITE); + SET_COLOR(4, COLOR_MAGENTA); + SET_COLOR(5, COLOR_BLUE); + SET_COLOR(6, COLOR_YELLOW); + } +#endif /* A_COLOR */ + + ref = typeMalloc(short *, LINES); + for (y = 0; y < LINES; y++) { + ref[y] = typeMalloc(short, COLS); + for (x = 0; x < COLS; x++) { + ref[y][x] = 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 = typeMalloc(short, (length + 1)))) { + fprintf(stderr, "%s: out of memory\n", *argv); + ExitProgram(EXIT_FAILURE); + } + w->xpos = ip; + for (x = length; --x >= 0;) + *ip++ = -1; + if (!(ip = typeMalloc(short, (length + 1)))) { + fprintf(stderr, "%s: out of memory\n", *argv); + ExitProgram(EXIT_FAILURE); + } + w->ypos = ip; + for (y = length; --y >= 0;) + *ip++ = -1; + } + if (field) { + const char *p; + p = field; + for (y = bottom; --y >= 0;) { + for (x = COLS; --x >= 0;) { + addch((chtype) (*p++)); + if (!*p) + p = field; + } + } + } + napms(10); + refresh(); +#ifndef TRACE + nodelay(stdscr, TRUE); +#endif + + 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++; + } +#else + int ch; + + if ((ch = getch()) > 0) { +#ifdef KEY_RESIZE + if (ch == KEY_RESIZE) { + if (last != COLS - 1) { + for (y = 0; y <= bottom; y++) { + ref[y] = typeRealloc(short, COLS, ref[y]); + for (x = last + 1; x < COLS; x++) + ref[y][x] = 0; + } + last = COLS - 1; + } + if (bottom != LINES - 1) { + for (y = LINES; y <= bottom; y++) + free(ref[y]); + ref = typeRealloc(short *, LINES, ref); + for (y = bottom + 1; y < LINES; y++) { + ref[y] = typeMalloc(short, COLS); + for (x = 0; x < COLS; x++) + ref[y][x] = 0; + } + bottom = LINES - 1; + } + } +#endif + /* + * Make it simple to put this into single-step mode, or resume + * normal operation -TD + */ + if (ch == 'q') { + cleanup(); + ExitProgram(EXIT_SUCCESS); + } else if (ch == 's') { + nodelay(stdscr, FALSE); + } else if (ch == ' ') { + nodelay(stdscr, TRUE); + } + } +#endif /* TRACE */ + + for (n = 0, w = &worm[0]; n < number; n++, w++) { + if ((x = w->xpos[h = w->head]) < 0) { + move(y = w->ypos[h] = bottom, x = w->xpos[h] = 0); + addch(flavor[n % SIZEOF(flavor)]); + ref[y][x]++; + } else { + y = w->ypos[h]; + } + if (x > last) + x = last; + if (y > bottom) + y = bottom; + if (++h == length) + h = 0; + if (w->xpos[w->head = h] >= 0) { + int x1, y1; + x1 = w->xpos[h]; + y1 = w->ypos[h]; + if (y1 < LINES + && x1 < COLS + && --ref[y1][x1] == 0) { + move(y1, x1); + 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: + cleanup(); + ExitProgram(EXIT_SUCCESS); + case 1: + w->orientation = op->opts[0]; + break; + default: + w->orientation = op->opts[(int) (ranf() * (float) op->nopts)]; + } + move(y += yinc[w->orientation], x += xinc[w->orientation]); + + if (y < 0) + y = 0; + addch(flavor[n % SIZEOF(flavor)]); + ref[w->ypos[h] = y][w->xpos[h] = x]++; + } + napms(10); + refresh(); + } +} diff --git a/ncurses-5.3/test/xmas.c b/ncurses-5.3/test/xmas.c new file mode 100644 index 0000000..90183ff --- /dev/null +++ b/ncurses-5.3/test/xmas.c @@ -0,0 +1,1159 @@ +/******************************************************************************/ +/* 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$ + */ +#include <test.priv.h> + +#define FROMWHO "Mark Hessling - (M.Hessling@gu.edu.au)" + +static int my_bg = COLOR_BLACK; +static int y_pos, x_pos; + +static WINDOW *treescrn; +static WINDOW *treescrn2; +static WINDOW *treescrn3; +static WINDOW *treescrn4; +static WINDOW *treescrn5; +static WINDOW *treescrn6; +static WINDOW *treescrn7; +static WINDOW *treescrn8; +static WINDOW *dotdeer0; +static WINDOW *stardeer0; +static WINDOW *lildeer0; +static WINDOW *lildeer1; +static WINDOW *lildeer2; +static WINDOW *lildeer3; +static WINDOW *middeer0; +static WINDOW *middeer1; +static WINDOW *middeer2; +static WINDOW *middeer3; +static WINDOW *bigdeer0; +static WINDOW *bigdeer1; +static WINDOW *bigdeer2; +static WINDOW *bigdeer3; +static WINDOW *bigdeer4; +static WINDOW *lookdeer0; +static WINDOW *lookdeer1; +static WINDOW *lookdeer2; +static WINDOW *lookdeer3; +static WINDOW *lookdeer4; +static WINDOW *w_holiday; +static WINDOW *w_del_msg; + +static 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; + + setlocale(LC_ALL, ""); + + 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(); +#if HAVE_USE_DEFAULT_COLORS + 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); + ExitProgram(EXIT_SUCCESS); +} |