ncurses 5.7 - patch 20090124
authorThomas E. Dickey <dickey@invisible-island.net>
Sun, 25 Jan 2009 02:04:12 +0000 (02:04 +0000)
committerThomas E. Dickey <dickey@invisible-island.net>
Sun, 25 Jan 2009 02:04:12 +0000 (02:04 +0000)
+ modify init_pair() to allow caller to create extra color pairs beyond
  the color_pairs limit, which use default colors (request by Emanuele
  Giaquinta).
+ add misc/terminfo.tmp and misc/*.pc to "sources" rule.
+ fix typo "==" where "=" is needed in ncurses-config.in and
  gen-pkgconfig.in files (Debian #512161).

13 files changed:
NEWS
dist.mk
man/curs_color.3x
misc/Makefile.in
misc/gen-pkgconfig.in
misc/ncurses-config.in
ncurses/base/lib_color.c
ncurses/base/lib_colorset.c
ncurses/base/lib_slkatr_set.c
ncurses/base/lib_slkcolor.c
ncurses/curses.priv.h
ncurses/tty/tty_update.c
test/ncurses.c

diff --git a/NEWS b/NEWS
index 2d96145ee6ae30480f97a8d380dc3314794b8a21..ac58ef9edbc96127c9aab31739f391758259a909 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -25,7 +25,7 @@
 -- sale, use or other dealings in this Software without prior written        --
 -- authorization.                                                            --
 -------------------------------------------------------------------------------
--- $Id: NEWS,v 1.1358 2009/01/17 23:54:20 tom Exp $
+-- $Id: NEWS,v 1.1360 2009/01/24 23:06:51 tom Exp $
 -------------------------------------------------------------------------------
 
 This is a log of changes that ncurses has gone through since Zeyd started
@@ -45,6 +45,14 @@ See the AUTHORS file for the corresponding full names.
 Changes through 1.9.9e did not credit all contributions;
 it is not possible to add this information.
 
+20090124
+       + modify init_pair() to allow caller to create extra color pairs beyond
+         the color_pairs limit, which use default colors (request by Emanuele
+         Giaquinta).
+       + add misc/terminfo.tmp and misc/*.pc to "sources" rule.
+       + fix typo "==" where "=" is needed in ncurses-config.in and
+         gen-pkgconfig.in files (Debian #512161).
+
 20090117
        + add -shared option to MK_SHARED_LIB when -Bsharable is used, for
          *BSD's, without which "main" might be one of the shared library's
diff --git a/dist.mk b/dist.mk
index c46b7705a8803fcd407e093e6cc50c9a07b5359a..bafe8c975fd75d1e56cdc930b7cc5d9578d86269 100644 (file)
--- a/dist.mk
+++ b/dist.mk
@@ -25,7 +25,7 @@
 # use or other dealings in this Software without prior written               #
 # authorization.                                                             #
 ##############################################################################
-# $Id: dist.mk,v 1.683 2009/01/17 16:29:15 tom Exp $
+# $Id: dist.mk,v 1.684 2009/01/24 20:49:01 tom Exp $
 # Makefile for creating ncurses distributions.
 #
 # This only needs to be used directly as a makefile by developers, but
@@ -37,7 +37,7 @@ SHELL = /bin/sh
 # These define the major/minor/patch versions of ncurses.
 NCURSES_MAJOR = 5
 NCURSES_MINOR = 7
-NCURSES_PATCH = 20090117
+NCURSES_PATCH = 20090124
 
 # We don't append the patch to the version, since this only applies to releases
 VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
index 99e63eff136e4ba99da8b4cda3c632b04d7dad39..801ac9fa6b0029f3e8a09939a5ed554a2729880c 100644 (file)
@@ -1,5 +1,5 @@
 .\"***************************************************************************
-.\" Copyright (c) 1998-2004,2005 Free Software Foundation, Inc.              *
+.\" Copyright (c) 1998-2005,2009 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            *
@@ -26,7 +26,7 @@
 .\" authorization.                                                           *
 .\"***************************************************************************
 .\"
-.\" $Id: curs_color.3x,v 1.28 2005/12/18 00:00:37 tom Exp $
+.\" $Id: curs_color.3x,v 1.29 2009/01/24 23:10:02 tom Exp $
 .TH curs_color 3X ""
 .na
 .hy 0
@@ -96,7 +96,10 @@ For portable applications:
 .TP 5
 -
 The value of the first argument
-must be between \fB1\fR and \fBCOLOR_PAIRS-1\fR.
+must be between \fB1\fR and \fBCOLOR_PAIRS-1\fR,
+except that if default colors are used (see \fBuse_default_colors\fP)
+the upper limit is adjusted to allow for extra pairs which use
+a default color in foreground and/or background.
 .TP 5
 -
 The value of the second and
index 15480ee77b7b9ca22977fe4948a7ee30bee0dea2..bfd83a993fb18f188a28d413d5ede6e0194b67c5 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.48 2009/01/03 23:52:41 tom Exp $
+# $Id: Makefile.in,v 1.50 2009/01/24 21:42:15 tom Exp $
 ##############################################################################
 # Copyright (c) 1998-2008,2009 Free Software Foundation, Inc.                #
 #                                                                            #
@@ -76,7 +76,7 @@ all : terminfo.tmp
 
 depend :
 
-sources :
+sources :: terminfo.tmp 
 
 install : install.data install.libs
 
@@ -111,6 +111,7 @@ install.libs :: $(DESTDIR)$(bindir) ncurses-config
 @MAKE_PC_FILES@install.libs :: pc-files
 @MAKE_PC_FILES@        $(SHELL) -c 'for name in *.pc; do $(INSTALL_DATA) $$name $(PKG_CONFIG_LIBDIR)/$$name; done'
 
+@MAKE_PC_FILES@sources :: pc-files
 @MAKE_PC_FILES@pc-files :
 @MAKE_PC_FILES@        $(SHELL) ./gen-pkgconfig
 @MAKE_PC_FILES@        touch $@
index 36220d3d47c5b099681dcf47d30952d93ecb941b..75e95b3bfbf3dfd0d9347c91b7a9354cf1e4c1b8 100644 (file)
@@ -1,5 +1,5 @@
 #!@SHELL@
-# $Id: gen-pkgconfig.in,v 1.4 2009/01/04 21:52:33 tom Exp $
+# $Id: gen-pkgconfig.in,v 1.5 2009/01/24 21:06:36 tom Exp $
 ##############################################################################
 # Copyright (c) 2009 Free Software Foundation, Inc.                          #
 #                                                                            #
@@ -59,9 +59,9 @@ for lib in ../lib/*
 do
        name=`basename $lib`
        root=`basename $name "$DFT_DEP_SUFFIX"`
-       if test "$name" == "$root" ; then
+       if test "$name" = "$root" ; then
                root=`basename $name "$CXX_LIB_SUFFIX"`
-               if test "$name" == "$root" ; then
+               if test "$name" = "$root" ; then
                        continue
                fi
        fi
index bb1dd9aecb0b3b4e7e0c4bfef1103e141606880f..bc4a46bbe11e1ee21841032dd41f0e3d1d075331 100644 (file)
@@ -1,5 +1,5 @@
 #!@SHELL@
-# $Id: ncurses-config.in,v 1.21 2009/01/06 01:06:21 tom Exp $
+# $Id: ncurses-config.in,v 1.22 2009/01/24 21:06:45 tom Exp $
 ##############################################################################
 # Copyright (c) 2006-2007,2009 Free Software Foundation, Inc.                #
 #                                                                            #
@@ -74,7 +74,7 @@ while test $# -gt 0; do
                if test "${includedir}" != /usr/include ; then
                        INCS="-I${includedir}"
                fi
-               if test "x@WITH_OVERWRITE@" == xno ; then
+               if test "x@WITH_OVERWRITE@" = xno ; then
                        INCS="$INCS -I${includedir}/${THIS}"
                fi
                sed -e 's,^[ ]*,,' -e 's, [ ]*, ,g' -e 's,[ ]*$,,' <<-ENDECHO
index 9cae495436fecc4f3a3b80546e6a18d05fe4dbec..db560c6194d23e8e14d7f62a486ef55e1e63d91f 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2007,2009 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            *
@@ -42,7 +42,7 @@
 #include <term.h>
 #include <tic.h>
 
-MODULE_ID("$Id: lib_color.c,v 1.85 2007/04/07 17:07:28 tom Exp $")
+MODULE_ID("$Id: lib_color.c,v 1.87 2009/01/25 00:25:31 tom Exp $")
 
 /*
  * These should be screen structure members.  They need to be globals for
@@ -108,6 +108,13 @@ static const color_t hls_palette[] =
 };
 /* *INDENT-ON* */
 
+/*
+ * Ensure that we use color pairs only when colors have been started, and also
+ * that the index is within the limits of the table which we allocated.
+ */
+#define ValidPair(pair) \
+    ((SP != 0) && (pair >= 0) && (pair < SP->_pair_limit) && SP->_coloron)
+
 #if NCURSES_EXT_FUNCS
 /*
  * These are called from _nc_do_color(), which in turn is called from
@@ -255,6 +262,15 @@ start_color(void)
        }
 
        if (max_pairs > 0 && max_colors > 0) {
+           SP->_pair_limit = max_pairs;
+
+#if NCURSES_EXT_FUNCS
+           /*
+            * If using default colors, allocate extra space in table to
+            * allow for default-color as a component of a color-pair.
+            */
+           SP->_pair_limit += (1 + (2 * max_colors));
+#endif
            SP->_pair_count = max_pairs;
            SP->_color_count = max_colors;
 #if !USE_REENTRANT
@@ -263,7 +279,7 @@ start_color(void)
 #endif
 
            if ((SP->_color_pairs = TYPE_CALLOC(colorpair_t,
-                                               max_pairs)) != 0) {
+                                               SP->_pair_limit)) != 0) {
                if ((SP->_color_table = TYPE_CALLOC(color_t,
                                                    max_colors)) != 0) {
                    SP->_color_pairs[0] = PAIR_OF(default_fg(), default_bg());
@@ -331,21 +347,69 @@ NCURSES_EXPORT(int)
 init_pair(short pair, short f, short b)
 {
     colorpair_t result;
+    colorpair_t previous;
 
     T((T_CALLED("init_pair(%d,%d,%d)"), pair, f, b));
 
-    if ((pair < 0) || (pair >= COLOR_PAIRS) || SP == 0 || !SP->_coloron)
+    if (!ValidPair(pair))
        returnCode(ERR);
+
+    previous = SP->_color_pairs[pair];
 #if NCURSES_EXT_FUNCS
     if (SP->_default_color) {
-       if (f < 0)
+       bool isDefault = FALSE;
+       bool wasDefault = FALSE;
+       int default_pairs = SP->_default_pairs;
+
+       /*
+        * Map caller's color number, e.g., -1, 0, 1, .., 7, etc., into
+        * internal unsigned values which we will store in the _color_pairs[]
+        * table.
+        */
+       if (isDefaultColor(f)) {
            f = COLOR_DEFAULT;
-       if (b < 0)
+           isDefault = TRUE;
+       } else if (!OkColorHi(f)) {
+           returnCode(ERR);
+       }
+
+       if (isDefaultColor(b)) {
            b = COLOR_DEFAULT;
-       if (!OkColorHi(f) && !isDefaultColor(f))
+           isDefault = TRUE;
+       } else if (!OkColorHi(b)) {
            returnCode(ERR);
-       if (!OkColorHi(b) && !isDefaultColor(b))
+       }
+
+       /*
+        * Check if the table entry that we are going to init/update used
+        * default colors.
+        */
+       if ((FORE_OF(previous) == COLOR_DEFAULT)
+           || (BACK_OF(previous) == COLOR_DEFAULT))
+           wasDefault = TRUE;
+
+       /*
+        * Keep track of the number of entries in the color pair table which
+        * used a default color.
+        */
+       if (isDefault && !wasDefault) {
+           ++default_pairs;
+       } else if (wasDefault && !isDefault) {
+           --default_pairs;
+       }
+
+       /*
+        * As an extension, ncurses allows the pair number to exceed the
+        * terminal's color_pairs value for pairs using a default color.
+        *
+        * Note that updating a pair which used a default color with one
+        * that does not will decrement the count - and possibly interfere
+        * with sequentially adding new pairs.
+        */
+       if (pair > (SP->_pair_count + default_pairs)) {
            returnCode(ERR);
+       }
+       SP->_default_pairs = default_pairs;
     } else
 #endif
     {
@@ -361,8 +425,8 @@ init_pair(short pair, short f, short b)
      * pair colors with the new ones).
      */
     result = PAIR_OF(f, b);
-    if (SP->_color_pairs[pair] != 0
-       && SP->_color_pairs[pair] != result) {
+    if (previous != 0
+       && previous != result) {
        int y, x;
 
        for (y = 0; y <= curscr->_maxy; y++) {
@@ -496,11 +560,11 @@ pair_content(short pair, short *f, short *b)
 
     T((T_CALLED("pair_content(%d,%p,%p)"), pair, f, b));
 
-    if ((pair < 0) || (pair >= COLOR_PAIRS) || SP == 0 || !SP->_coloron) {
+    if (!ValidPair(pair)) {
        result = ERR;
     } else {
-       NCURSES_COLOR_T fg = ((SP->_color_pairs[pair] >> C_SHIFT) & C_MASK);
-       NCURSES_COLOR_T bg = (SP->_color_pairs[pair] & C_MASK);
+       NCURSES_COLOR_T fg = FORE_OF(SP->_color_pairs[pair]);
+       NCURSES_COLOR_T bg = BACK_OF(SP->_color_pairs[pair]);
 
 #if NCURSES_EXT_FUNCS
        if (fg == COLOR_DEFAULT)
@@ -527,7 +591,7 @@ _nc_do_color(short old_pair, short pair, bool reverse, int (*outc) (int))
     NCURSES_COLOR_T bg = COLOR_DEFAULT;
     NCURSES_COLOR_T old_fg, old_bg;
 
-    if (pair < 0 || pair >= COLOR_PAIRS) {
+    if (!ValidPair(pair)) {
        return;
     } else if (pair != 0) {
        if (set_color_pair) {
index a973c5350c8facbe70cd3a71a706d4160e7a182b..831efdc8ecd3c6f3f1e2085ae3ada3e935ab894e 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2005,2009 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            *
@@ -28,7 +28,7 @@
 
 /****************************************************************************
  *  Author: Juergen Pfeifer,  1998                                          *
- *     and: Thomas E. Dickey, 2005                                          *
+ *     and: Thomas E. Dickey, 2005-on                                       *
  ****************************************************************************/
 
 /*
 #include <curses.priv.h>
 #include <ctype.h>
 
-MODULE_ID("$Id: lib_colorset.c,v 1.11 2005/01/29 21:40:51 tom Exp $")
+MODULE_ID("$Id: lib_colorset.c,v 1.12 2009/01/25 00:44:40 tom Exp $")
 
 NCURSES_EXPORT(int)
 wcolor_set(WINDOW *win, short color_pair_number, void *opts)
 {
+    int code = ERR;
+
     T((T_CALLED("wcolor_set(%p,%d)"), win, color_pair_number));
     if (win
        && !opts
+       && (SP != 0)
        && (color_pair_number >= 0)
-       && (color_pair_number < COLOR_PAIRS)) {
+       && (color_pair_number < SP->_pair_limit)) {
        TR(TRACE_ATTRS, ("... current %ld", (long) GET_WINDOW_PAIR(win)));
        SET_WINDOW_PAIR(win, color_pair_number);
        if_EXT_COLORS(win->_color = color_pair_number);
-       returnCode(OK);
-    } else
-       returnCode(ERR);
+       code = OK;
+    }
+    returnCode(code);
 }
index f83616beaf1735f1dc64703f389452540bad8914..9a5709f37f3a0ab7dc5f04ef26aca7e9ec378e87 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2005,2009 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            *
@@ -28,7 +28,7 @@
 
 /****************************************************************************
  *  Author:  Juergen Pfeifer, 1998                                          *
- *     and:  Thomas E. Dickey 2005                                          *
+ *     and:  Thomas E. Dickey 2005-on                                       *
  ****************************************************************************/
 
 /*
  */
 #include <curses.priv.h>
 
-MODULE_ID("$Id: lib_slkatr_set.c,v 1.10 2005/01/28 21:11:53 tom Exp $")
+MODULE_ID("$Id: lib_slkatr_set.c,v 1.11 2009/01/25 00:47:15 tom Exp $")
 
 NCURSES_EXPORT(int)
 slk_attr_set(const attr_t attr, short color_pair_number, void *opts)
 {
+    int code = ERR;
+
     T((T_CALLED("slk_attr_set(%s,%d)"), _traceattr(attr), color_pair_number));
 
-    if (SP != 0 && SP->_slk != 0 && !opts &&
-       color_pair_number >= 0 && color_pair_number < COLOR_PAIRS) {
+    if (SP != 0
+       && SP->_slk != 0
+       && !opts
+       && color_pair_number >= 0
+       && color_pair_number < SP->_pair_limit) {
        TR(TRACE_ATTRS, ("... current %s", _tracech_t(CHREF(SP->_slk->attr))));
        SetAttr(SP->_slk->attr, attr);
        if (color_pair_number > 0) {
            SetPair(SP->_slk->attr, color_pair_number);
        }
        TR(TRACE_ATTRS, ("new attribute is %s", _tracech_t(CHREF(SP->_slk->attr))));
-       returnCode(OK);
-    } else
-       returnCode(ERR);
+       code = OK;
+    }
+    returnCode(code);
 }
index b677b65a529a51daf3ebfe768afa0a406bb7e48b..01af185b16fd717c9f679961ff13422de789fb03 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2005,2009 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            *
@@ -28,7 +28,7 @@
 
 /****************************************************************************
  *  Author:  Juergen Pfeifer, 1998                                          *
- *     and:  Thomas E. Dickey 2005                                          *
+ *     and:  Thomas E. Dickey 2005-on                                       *
  ****************************************************************************/
 
 /*
  */
 #include <curses.priv.h>
 
-MODULE_ID("$Id: lib_slkcolor.c,v 1.12 2005/01/28 21:11:53 tom Exp $")
+MODULE_ID("$Id: lib_slkcolor.c,v 1.13 2009/01/25 00:48:07 tom Exp $")
 
 NCURSES_EXPORT(int)
 slk_color(short color_pair_number)
 {
+    int code = ERR;
+
     T((T_CALLED("slk_color(%d)"), color_pair_number));
 
-    if (SP != 0 && SP->_slk != 0 &&
-       color_pair_number >= 0 && color_pair_number < COLOR_PAIRS) {
+    if (SP != 0
+       && SP->_slk != 0
+       && color_pair_number >= 0
+       && color_pair_number < SP->_pair_limit) {
        TR(TRACE_ATTRS, ("... current is %s", _tracech_t(CHREF(SP->_slk->attr))));
        SetPair(SP->_slk->attr, color_pair_number);
        TR(TRACE_ATTRS, ("new attribute is %s", _tracech_t(CHREF(SP->_slk->attr))));
-       returnCode(OK);
-    } else
-       returnCode(ERR);
+       code = OK;
+    }
+    returnCode(code);
 }
index 13edc36f743ba5a3d0249953c3288ae0b1770d13..05f3331f28efcffe1505eaac8da418d4aabeaa86 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2008,2009 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            *
@@ -34,7 +34,7 @@
 
 
 /*
- * $Id: curses.priv.h,v 1.395 2008/11/23 00:09:04 tom Exp $
+ * $Id: curses.priv.h,v 1.396 2009/01/24 23:04:59 tom Exp $
  *
  *     curses.priv.h
  *
@@ -404,6 +404,8 @@ typedef unsigned colorpair_t;       /* type big enough to store PAIR_OF() */
 #define C_SHIFT 9              /* we need more bits than there are colors */
 #define C_MASK                 ((1 << C_SHIFT) - 1)
 #define PAIR_OF(fg, bg)                ((((fg) & C_MASK) << C_SHIFT) | ((bg) & C_MASK))
+#define FORE_OF(c)             (((c) >> C_SHIFT) & C_MASK)
+#define BACK_OF(c)             ((c) & C_MASK)
 #define isDefaultColor(c)      ((c) >= COLOR_DEFAULT || (c) < 0)
 
 #define COLOR_DEFAULT          C_MASK
@@ -794,11 +796,13 @@ struct screen {
        int             _color_count;   /* count of colors in palette        */
        colorpair_t     *_color_pairs;  /* screen's color pair list          */
        int             _pair_count;    /* count of color pairs              */
+       int             _pair_limit;    /* actual limit of color-pairs       */
 #if NCURSES_EXT_FUNCS
        bool            _default_color; /* use default colors                */
        bool            _has_sgr_39_49; /* has ECMA default color support    */
        int             _default_fg;    /* assumed default foreground        */
        int             _default_bg;    /* assumed default background        */
+       int             _default_pairs; /* count pairs using default color   */
 #endif
        chtype          _ok_attributes; /* valid attributes for terminal     */
        chtype          _xmc_suppress;  /* attributes to suppress if xmc     */
index 6a3a0c8e9341ece94e67edc7ec78db47a5845c82..215747da82c2b381b35f43eb691b843a4d36493f 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2008,2009 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            *
@@ -78,7 +78,7 @@
 #include <ctype.h>
 #include <term.h>
 
-MODULE_ID("$Id: tty_update.c,v 1.246 2008/08/30 20:08:19 tom Exp $")
+MODULE_ID("$Id: tty_update.c,v 1.247 2009/01/25 00:48:36 tom Exp $")
 
 /*
  * This define controls the line-breakout optimization.  Every once in a
@@ -1165,8 +1165,8 @@ TransformLine(int const lineno)
                newPair = GetPair(newLine[n]);
                if (oldPair != newPair
                    && unColor(oldLine[n]) == unColor(newLine[n])) {
-                   if (oldPair < COLOR_PAIRS
-                       && newPair < COLOR_PAIRS
+                   if (oldPair < SP->_pair_limit
+                       && newPair < SP->_pair_limit
                        && SP->_color_pairs[oldPair] == SP->_color_pairs[newPair]) {
                        SetPair(oldLine[n], GetPair(newLine[n]));
                    }
index c879d2c826ce8d5425009a80ce20c01a708aac91..7a025fea39efba6847dc61d158871cebf844fbfb 100644 (file)
@@ -40,7 +40,7 @@ AUTHOR
    Author: Eric S. Raymond <esr@snark.thyrsus.com> 1993
            Thomas E. Dickey (beginning revision 1.27 in 1996).
 
-$Id: ncurses.c,v 1.334 2008/12/20 17:13:27 tom Exp $
+$Id: ncurses.c,v 1.336 2009/01/25 00:39:14 tom Exp $
 
 ***************************************************************************/
 
@@ -1859,6 +1859,8 @@ show_color_name(int y, int x, int color, bool wide)
            width = 4;
        } else if (color >= 8) {
            sprintf(temp, "[%02d]", color);
+       } else if (color < 0) {
+           strcpy(temp, "default");
        } else {
            strcpy(temp, the_color_names[color]);
        }
@@ -1892,6 +1894,8 @@ color_legend(WINDOW *helpwin, bool wide)
              "  b/B     toggle bold off/on");
     mvwprintw(helpwin, row++, col,
              "  n/N     toggle text/number on/off");
+    mvwprintw(helpwin, row++, col,
+             "  r/R     toggle reverse on/off");
     mvwprintw(helpwin, row++, col,
              "  w/W     toggle width between 8/16 colors");
 #if USE_WIDEC_SUPPORT
@@ -1925,12 +1929,19 @@ color_test(void)
     bool done = FALSE;
     bool opt_acsc = FALSE;
     bool opt_bold = FALSE;
-    bool opt_wide = FALSE;
+    bool opt_revs = FALSE;
     bool opt_nums = FALSE;
+    bool opt_wide = FALSE;
     WINDOW *helpwin;
 
-    if (pairs_max > COLOR_PAIRS)
-       pairs_max = COLOR_PAIRS;
+    if (COLORS * COLORS == COLOR_PAIRS) {
+       int limit = (COLORS - min_colors) * (COLORS - min_colors);
+       if (pairs_max > limit)
+           pairs_max = limit;
+    } else {
+       if (pairs_max > COLOR_PAIRS)
+           pairs_max = COLOR_PAIRS;
+    }
 
     while (!done) {
        int shown = 0;
@@ -1945,12 +1956,14 @@ color_test(void)
            hello = "Hello";
            per_row = 8;
        }
+       per_row -= min_colors;
 
        row_limit = (pairs_max + per_row - 1) / per_row;
 
        move(0, 0);
-       (void) printw("There are %d color pairs and %d colors\n",
-                     pairs_max, COLORS);
+       (void) printw("There are %d color pairs and %d colors%s\n",
+                     pairs_max, COLORS,
+                     min_colors ? " besides 'default'" : "");
 
        clrtobot();
        (void) mvprintw(top + 1, 0,
@@ -1961,7 +1974,7 @@ color_test(void)
 
        /* show color names/numbers across the top */
        for (i = 0; i < per_row; i++)
-           show_color_name(top + 2, (i + 1) * width, i, opt_wide);
+           show_color_name(top + 2, (i + 1) * width, i + min_colors, opt_wide);
 
        /* show a grid of colors, with color names/ numbers on the left */
        for (i = (short) (base_row * per_row); i < pairs_max; i++) {
@@ -1969,9 +1982,11 @@ color_test(void)
            int col = (i % per_row + 1) * width;
            short pair = i;
 
+#define InxToFG(i) (short) ((i % (COLORS - min_colors)) + min_colors)
+#define InxToBG(i) (short) ((i / (COLORS - min_colors)) + min_colors)
            if (row >= 0 && move(row, col) != ERR) {
-               short fg = (short) (i % COLORS);
-               short bg = (short) (i / COLORS);
+               short fg = InxToFG(i);
+               short bg = InxToBG(i);
 
                init_pair(pair, fg, bg);
                attron((attr_t) COLOR_PAIR(pair));
@@ -1979,6 +1994,8 @@ color_test(void)
                    attron((attr_t) A_ALTCHARSET);
                if (opt_bold)
                    attron((attr_t) A_BOLD);
+               if (opt_revs)
+                   attron((attr_t) A_REVERSE);
 
                if (opt_nums) {
                    sprintf(numbered, "{%02X}", i);
@@ -1987,8 +2004,8 @@ color_test(void)
                printw("%-*.*s", width, width, hello);
                attrset(A_NORMAL);
 
-               if ((i % per_row) == 0 && (i % COLORS) == 0) {
-                   show_color_name(row, 0, i / COLORS, opt_wide);
+               if ((i % per_row) == 0 && InxToFG(i) == min_colors) {
+                   show_color_name(row, 0, InxToBG(i), opt_wide);
                }
                ++shown;
            } else if (shown) {
@@ -2015,6 +2032,12 @@ color_test(void)
        case 'N':
            opt_nums = TRUE;
            break;
+       case 'r':
+           opt_revs = FALSE;
+           break;
+       case 'R':
+           opt_revs = TRUE;
+           break;
        case case_QUIT:
            done = TRUE;
            continue;
@@ -2092,7 +2115,7 @@ wide_color_test(void)
     int base_row = 0;
     int grid_top = top + 3;
     int page_size = (LINES - grid_top);
-    int pairs_max = COLOR_PAIRS;
+    int pairs_max = (unsigned short) (-1);
     int row_limit;
     int per_row;
     char numbered[80];
@@ -2100,12 +2123,22 @@ wide_color_test(void)
     bool done = FALSE;
     bool opt_acsc = FALSE;
     bool opt_bold = FALSE;
+    bool opt_revs = FALSE;
     bool opt_wide = FALSE;
     bool opt_nums = FALSE;
     bool opt_xchr = FALSE;
     wchar_t buffer[10];
     WINDOW *helpwin;
 
+    if (COLORS * COLORS == COLOR_PAIRS) {
+       int limit = (COLORS - min_colors) * (COLORS - min_colors);
+       if (pairs_max > limit)
+           pairs_max = limit;
+    } else {
+       if (pairs_max > COLOR_PAIRS)
+           pairs_max = COLOR_PAIRS;
+    }
+
     while (!done) {
        int shown = 0;
 
@@ -2119,6 +2152,8 @@ wide_color_test(void)
            hello = "Hello";
            per_row = 8;
        }
+       per_row -= min_colors;
+
        if (opt_xchr) {
            make_fullwidth_text(buffer, hello);
            width *= 2;
@@ -2130,8 +2165,9 @@ wide_color_test(void)
        row_limit = (pairs_max + per_row - 1) / per_row;
 
        move(0, 0);
-       (void) printw("There are %d color pairs and %d colors\n",
-                     pairs_max, COLORS);
+       (void) printw("There are %d color pairs and %d colors%s\n",
+                     pairs_max, COLORS,
+                     min_colors ? " besides 'default'" : "");
 
        clrtobot();
        (void) mvprintw(top + 1, 0,
@@ -2142,7 +2178,7 @@ wide_color_test(void)
 
        /* show color names/numbers across the top */
        for (i = 0; i < per_row; i++)
-           show_color_name(top + 2, (i + 1) * width, i, opt_wide);
+           show_color_name(top + 2, (i + 1) * width, i + min_colors, opt_wide);
 
        /* show a grid of colors, with color names/ numbers on the left */
        for (i = (base_row * per_row); i < pairs_max; i++) {
@@ -2151,12 +2187,14 @@ wide_color_test(void)
            short pair = (short) i;
 
            if (row >= 0 && move(row, col) != ERR) {
-               init_pair(pair, (short) (i % COLORS), (short) (i / COLORS));
+               init_pair(pair, InxToFG(i), InxToBG(i));
                color_set(pair, NULL);
                if (opt_acsc)
                    attr_on((attr_t) A_ALTCHARSET, NULL);
                if (opt_bold)
                    attr_on((attr_t) A_BOLD, NULL);
+               if (opt_revs)
+                   attr_on((attr_t) A_REVERSE, NULL);
 
                if (opt_nums) {
                    sprintf(numbered, "{%02X}", i);
@@ -2169,8 +2207,8 @@ wide_color_test(void)
                addnwstr(buffer, width);
                attr_set(A_NORMAL, 0, NULL);
 
-               if ((i % per_row) == 0 && (i % COLORS) == 0) {
-                   show_color_name(row, 0, i / COLORS, opt_wide);
+               if ((i % per_row) == 0 && InxToFG(i) == min_colors) {
+                   show_color_name(row, 0, InxToBG(i), opt_wide);
                }
                ++shown;
            } else if (shown) {
@@ -2197,6 +2235,12 @@ wide_color_test(void)
        case 'N':
            opt_nums = TRUE;
            break;
+       case 'r':
+           opt_revs = FALSE;
+           break;
+       case 'R':
+           opt_revs = TRUE;
+           break;
        case case_QUIT:
            done = TRUE;
            continue;