]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/base/lib_color.c
ncurses 5.0
[ncurses.git] / ncurses / base / lib_color.c
similarity index 77%
rename from ncurses/lib_color.c
rename to ncurses/base/lib_color.c
index cf86420d53db232c197b3dbf83a0e380f52c84b3..297a14c36d6eaf518825f697d0c2918771d9fdb6 100644 (file)
 
 #include <term.h>
 
-MODULE_ID("$Id: lib_color.c,v 1.24 1998/02/11 12:13:58 tom Exp $")
-
-/*
- * Only 8 ANSI colors are defined; the ISO 6429 control sequences work only
- * for 8 values (0-7).
- */
-#define MAX_ANSI_COLOR 8
+MODULE_ID("$Id: lib_color.c,v 1.36 1999/10/03 00:20:37 Philippe.Blain Exp $")
 
 /*
  * These should be screen structure members.  They need to be globals for
@@ -89,33 +83,82 @@ static const color_t hls_palette[] =
        {0,     50,     100},   /* COLOR_WHITE */
 };
 
-int start_color(void)
+/*
+ * SVr4 curses is known to interchange color codes (1,4) and (3,6), possibly
+ * to maintain compatibility with a pre-ANSI scheme.  The same scheme is
+ * also used in the FreeBSD syscons.
+ */
+static int toggled_colors(int c)
 {
-       T((T_CALLED("start_color()")));
+    if (c < 16) {
+       static const int table[] =
+               { 0,  4,  2,  6,  1,  5,  3,  7,
+                 8, 12, 10, 14,  9, 13, 11, 15};
+       c = table[c];
+    }
+    return c;
+}
+
+static void set_background_color(int bg, int  (*outc)(int))
+{
+       if (set_a_background)
+       {
+           TPUTS_TRACE("set_a_background");
+           tputs(tparm(set_a_background, bg), 1, outc);
+       }
+       else
+       {
+           TPUTS_TRACE("set_background");
+           tputs(tparm(set_background, toggled_colors(bg)), 1, outc);
+       }
+}
 
-#ifdef orig_pair
-       if (orig_pair != NULL)
+static void set_foreground_color(int fg, int  (*outc)(int))
+{
+       if (set_a_foreground)
+       {
+           TPUTS_TRACE("set_a_foreground");
+           tputs(tparm(set_a_foreground, fg), 1, outc);
+       }
+       else
        {
+           TPUTS_TRACE("set_foreground");
+           tputs(tparm(set_foreground, toggled_colors(fg)), 1, outc);
+       }
+}
+
+static bool set_original_colors(void)
+{
+       if (orig_pair != 0) {
                TPUTS_TRACE("orig_pair");
                putp(orig_pair);
+               return TRUE;
        }
-#endif /* orig_pair */
-#ifdef orig_colors
-       if (orig_colors != NULL)
+       else if (orig_colors != NULL)
        {
                TPUTS_TRACE("orig_colors");
                putp(orig_colors);
+               return TRUE;
        }
-#endif /* orig_colors */
-#if defined(orig_pair) && defined(orig_colors)
-       if (!orig_pair && !orig_colors)
-               returnCode(ERR);
-#endif /* defined(orig_pair) && defined(orig_colors) */
+       return FALSE;
+}
+
+int start_color(void)
+{
+       T((T_CALLED("start_color()")));
+
+       if (set_original_colors() != TRUE)
+       {
+               set_foreground_color(COLOR_WHITE, _nc_outch);
+               set_background_color(COLOR_BLACK, _nc_outch);
+       }
+
        if (max_pairs != -1)
                COLOR_PAIRS = SP->_pair_count = max_pairs;
        else
                returnCode(ERR);
-       SP->_color_pairs = typeCalloc(unsigned short, max_pairs);
+       if ((SP->_color_pairs = typeCalloc(unsigned short, max_pairs)) == 0)
+               returnCode(ERR);
        SP->_color_pairs[0] = PAIR_OF(COLOR_WHITE, COLOR_BLACK);
        if (max_colors != -1)
                COLORS = SP->_color_count = max_colors;
@@ -123,32 +166,24 @@ int start_color(void)
                returnCode(ERR);
        SP->_coloron = 1;
 
-       SP->_color_table = malloc(sizeof(color_t) * COLORS);
-#ifdef hue_lightness_saturation
+       if ((SP->_color_table = typeMalloc(color_t, COLORS)) == 0)
+               returnCode(ERR);
        if (hue_lightness_saturation)
            memcpy(SP->_color_table, hls_palette, sizeof(color_t) * COLORS);
        else
-#endif /* hue_lightness_saturation */
            memcpy(SP->_color_table, cga_palette, sizeof(color_t) * COLORS);
 
-       if (orig_colors)
-       {
-           TPUTS_TRACE("orig_colors");
-           putp(orig_colors);
-       }
-
        T(("started color: COLORS = %d, COLOR_PAIRS = %d", COLORS, COLOR_PAIRS));
 
        returnCode(OK);
 }
 
-#ifdef hue_lightness_saturation
 /* This function was originally written by Daniel Weaver <danw@znyx.com> */
 static void rgb2hls(short r, short g, short b, short *h, short *l, short *s)
 /* convert RGB to HLS system */
 {
     short min, max, t;
-    
+
     if ((min = g < r ? g : r) > b) min = b;
     if ((max = g > r ? g : r) < b) max = b;
 
@@ -178,7 +213,6 @@ static void rgb2hls(short r, short g, short b, short *h, short *l, short *s)
 
     *h = t % 360;
 }
-#endif /* hue_lightness_saturation */
 
 /*
  * Extension (1997/1/18) - Allow negative f/b values to set default color
@@ -186,6 +220,8 @@ static void rgb2hls(short r, short g, short b, short *h, short *l, short *s)
  */
 int init_pair(short pair, short f, short b)
 {
+       unsigned result;
+
        T((T_CALLED("init_pair(%d,%d,%d)"), pair, f, b));
 
        if ((pair < 1) || (pair >= COLOR_PAIRS))
@@ -207,16 +243,37 @@ int init_pair(short pair, short f, short b)
                returnCode(ERR);
 
        /*
-        * FIXME: when a pair's content is changed, replace its colors
-        * (if pair was initialized before a screen update is performed
-        * replacing original pair colors with the new ones)
+        * When a pair's content is changed, replace its colors (if pair was
+        * initialized before a screen update is performed replacing original
+        * pair colors with the new ones).
         */
-
-       SP->_color_pairs[pair] = PAIR_OF(f,b);
+       result = PAIR_OF(f,b);
+       if (SP->_color_pairs[pair] != 0
+        && SP->_color_pairs[pair] != result) {
+           int y, x;
+           attr_t z = COLOR_PAIR(pair);
+
+           for (y = 0; y <= curscr->_maxy; y++) {
+               struct ldat *ptr = &(curscr->_line[y]);
+               bool changed = FALSE;
+               for (x = 0; x <= curscr->_maxx; x++) {
+                   if ((ptr->text[x] & A_COLOR) == z) {
+                       /* Set the old cell to zero to ensure it will be
+                          updated on the next doupdate() */
+                       ptr->text[x] = 0;
+                       CHANGED_CELL(ptr,x);
+                       changed = TRUE;
+                   }
+               }
+               if (changed)
+                       _nc_make_oldhash(y);
+           }
+       }
+       SP->_color_pairs[pair] = result;
 
        if (initialize_pair)
        {
-           const color_t       *tp = hue_lightness_saturation ? hls_palette : cga_palette;
+           const color_t *tp = hue_lightness_saturation ? hls_palette : cga_palette;
 
            T(("initializing pair: pair = %d, fg=(%d,%d,%d), bg=(%d,%d,%d)",
               pair,
@@ -239,37 +296,32 @@ int init_pair(short pair, short f, short b)
 int init_color(short color, short r, short g, short b)
 {
        T((T_CALLED("init_color(%d,%d,%d,%d)"), color, r, g, b));
-#ifdef initialize_color
+
        if (initialize_color == NULL)
                returnCode(ERR);
-#endif /* initialize_color */
 
        if (color < 0 || color >= COLORS)
                returnCode(ERR);
        if (r < 0 || r > 1000 || g < 0 ||  g > 1000 || b < 0 || b > 1000)
                returnCode(ERR);
 
-#ifdef hue_lightness_saturation
        if (hue_lightness_saturation)
            rgb2hls(r, g, b,
                      &SP->_color_table[color].red,
                      &SP->_color_table[color].green,
                      &SP->_color_table[color].blue);
        else
-#endif /* hue_lightness_saturation */
        {
                SP->_color_table[color].red = r;
                SP->_color_table[color].green = g;
                SP->_color_table[color].blue = b;
        }
 
-#ifdef initialize_color
        if (initialize_color)
        {
                TPUTS_TRACE("initialize_color");
                putp(tparm(initialize_color, color, r, g, b));
        }
-#endif /* initialize_color */
        returnCode(OK);
 }
 
@@ -282,8 +334,7 @@ bool can_change_color(void)
 bool has_colors(void)
 {
        T((T_CALLED("has_colors()")));
-       returnCode (((orig_pair != NULL || orig_colors != NULL)
-                    && (max_colors != -1) && (max_pairs != -1)
+       returnCode (((max_colors != -1) && (max_pairs != -1)
                     && (((set_foreground != NULL)
                          && (set_background != NULL))
                         || ((set_a_foreground != NULL)
@@ -294,7 +345,7 @@ bool has_colors(void)
 int color_content(short color, short *r, short *g, short *b)
 {
     T((T_CALLED("color_content(%d,%p,%p,%p)"), color, r, g, b));
-    if (color < 0 || color > COLORS)
+    if (color < 0 || color >= COLORS)
        returnCode(ERR);
 
     if (r) *r = SP->_color_table[color].red;
@@ -307,7 +358,7 @@ int 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))
+       if ((pair < 0) || (pair >= COLOR_PAIRS))
                returnCode(ERR);
        if (f) *f = ((SP->_color_pairs[pair] >> C_SHIFT) & C_MASK);
        if (b) *b =  (SP->_color_pairs[pair] & C_MASK);
@@ -315,29 +366,10 @@ int pair_content(short pair, short *f, short *b)
        returnCode(OK);
 }
 
-/*
- * SVr4 curses is known to interchange color codes (1,4) and (3,6), possibly
- * to maintain compatibility with a pre-ANSI scheme.  The same scheme is
- * also used in the FreeBSD syscons.
- */
-static int toggled_colors(int c)
-{
-    if (c < 16) {
-       static const int table[] =
-               { 0,  4,  2,  6,  1,  5,  3,  7,
-                 8, 12, 10, 14,  9, 13, 11, 15};
-       c = table[c];
-    }
-    return c;
-}
-
-void _nc_do_color(int pair, bool reverse, int  (*outc)(int))
+void _nc_do_color(int pair, bool reverse, int (*outc)(int))
 {
     short fg, bg;
 
-    if (reverse)
-       pair = -pair;
-
     if (pair == 0)
     {
        if (orig_pair)
@@ -345,6 +377,16 @@ void _nc_do_color(int pair, bool reverse, int  (*outc)(int))
            TPUTS_TRACE("orig_pair");
            tputs(orig_pair, 1, outc);
        }
+       else if (set_color_pair)
+       {
+           TPUTS_TRACE("set_color_pair");
+           tputs(tparm(set_color_pair, pair), 1, outc);
+       }
+       else
+       {
+           set_foreground_color(COLOR_WHITE, outc);
+           set_background_color(COLOR_BLACK, outc);
+       }
     }
     else
     {
@@ -366,42 +408,21 @@ void _nc_do_color(int pair, bool reverse, int  (*outc)(int))
 
            if (fg == C_MASK || bg == C_MASK)
            {
-               if (orig_pair)
-               {
-                   TPUTS_TRACE("orig_pair");
-                   tputs(orig_pair, 1, outc);
-               }
-               else
+               if (set_original_colors() != TRUE)
                {
-                   TPUTS_TRACE("orig_colors");
-                   tputs(orig_colors, 1, outc);
+                       if (fg == C_MASK)
+                               set_foreground_color(COLOR_WHITE, outc);
+                       if (bg == C_MASK)
+                               set_background_color(COLOR_BLACK, outc);
                }
            }
            if (fg != C_MASK)
            {
-               if (set_a_foreground && fg <= MAX_ANSI_COLOR)
-               {
-                   TPUTS_TRACE("set_a_foreground");
-                   tputs(tparm(set_a_foreground, fg), 1, outc);
-               }
-               else
-               {
-                   TPUTS_TRACE("set_foreground");
-                   tputs(tparm(set_foreground, toggled_colors(fg)), 1, outc);
-               }
+               set_foreground_color(fg, outc);
            }
            if (bg != C_MASK)
            {
-               if (set_a_background && bg <= MAX_ANSI_COLOR)
-               {
-                   TPUTS_TRACE("set_a_background");
-                   tputs(tparm(set_a_background, bg), 1, outc);
-               }
-               else
-               {
-                   TPUTS_TRACE("set_background");
-                   tputs(tparm(set_background, toggled_colors(bg)), 1, outc);
-               }
+               set_background_color(bg, outc);
            }
        }
     }