Hi!

After a while, I remembered, that usual pure pc console can handle only
64 color combinations, but curses also reserves colorpair 0 so,
programmer have only 63 color pairs and operates 'default' colors. Thus,
I decided to switch to on-demand colorpair allocation. Attached patch
does this. It also takes into account COLOR_PAIRS, thus, if terminal
have more than 64 color pairs, they will be used (though, you should
have really rainbow color scheme to achieve this :). Also those two new
colors now are named 'gray' (bright black) and 'darkwhite' (not bright
white).

Looks like it is working.

-- 
Михайло Даниленко
-------------------------------
jabber: <[email protected]>
icq:    200352743
--- a/src/gui/curses/gui-curses-chat.c	2009-03-14 23:42:49.000000000 +0200
+++ b/src/gui/curses/gui-curses-chat.c	2009-05-22 20:45:28.000000000 +0300
@@ -131,17 +131,7 @@
 void
 gui_chat_set_color (t_gui_window *window, int fg, int bg)
 {
-    if (((fg == -1) || (fg == 99))
-        && ((bg == -1) || (bg == 99)))
-        wattron (GUI_CURSES(window)->win_chat, COLOR_PAIR(63));
-    else
-    {
-        if ((fg == -1) || (fg == 99))
-            fg = WEECHAT_COLOR_WHITE;
-        if ((bg == -1) || (bg == 99))
-            bg = 0;
-        wattron (GUI_CURSES(window)->win_chat, COLOR_PAIR((bg * 8) + fg));
-    }
+    wattron (GUI_CURSES(window)->win_chat, COLOR_PAIR(gui_color_get_pair_fgbg (fg, bg)));
 }
 
 /*
--- a/src/gui/curses/gui-curses-color.c	2009-03-14 23:42:49.000000000 +0200
+++ b/src/gui/curses/gui-curses-color.c	2009-05-22 21:53:52.000000000 +0300
@@ -38,6 +38,7 @@
 t_gui_color gui_weechat_colors[] =
 { { -1,                    0, 0,        "default"      },
   { WEECHAT_COLOR_BLACK,   0, 0,        "black"        },
+  { WEECHAT_COLOR_BLACK,   0, A_BOLD,   "gray"         },
   { WEECHAT_COLOR_RED,     0, 0,        "red"          },
   { WEECHAT_COLOR_RED,     0, A_BOLD,   "lightred"     },
   { WEECHAT_COLOR_GREEN,   0, 0,        "green"        },
@@ -50,6 +51,7 @@
   { WEECHAT_COLOR_MAGENTA, 0, A_BOLD,   "lightmagenta" },
   { WEECHAT_COLOR_CYAN,    0, 0,        "cyan"         },
   { WEECHAT_COLOR_CYAN,    0, A_BOLD,   "lightcyan"    },
+  { WEECHAT_COLOR_WHITE,   0, 0,        "darkwhite"    },
   { WEECHAT_COLOR_WHITE,   0, A_BOLD,   "white"        },
   { 0,                     0, 0,        NULL           }
 };
@@ -75,6 +77,19 @@
 
 t_gui_color *gui_color[GUI_NUM_COLORS];
 
+static int gui_color_pairs_allocated = 0;
+/* black ... white, default */
+static int gui_color_pairs[9][9] = {
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+};
 
 /*
  * gui_color_assign: assign a WeeChat color (read from config)
@@ -450,6 +465,51 @@
 }
 
 /*
+ * gui_color_get_pair_fgbg: get color pair with foreground and background ncurses color values
+ */
+
+static const char gui_curses_color_mapping[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+int
+gui_color_get_pair_fgbg (int fg, int bg)
+{
+    if (!has_colors ())
+        /* XXX: no idea, what to return here, this is not initialized either */
+        return gui_color_pairs[8][8];
+
+    if (fg == 99)
+        fg = -1;
+    if (bg == 99)
+        bg = -1;
+
+    if (gui_color_pairs[bg == -1 ? 8 : bg][fg == -1 ? 8 : fg])
+        return gui_color_pairs[bg == -1 ? 8 : bg][fg == -1 ? 8 : fg];
+
+    if (gui_color_pairs_allocated+1 >= COLOR_PAIRS)
+        /*
+         * FIXME: on first encounter, issue an error message like:
+         * ERROR: Color pairs resource exausted.
+         * This means, that we can no more allocate new background-foreground color pairs.
+         * Thus, any elements, colored with new color pair will be shown in default colors.
+         * If you have modified color settings, you can try to restart program to
+         * get rid of no more used color pairs. Or, either you have too much rainbow-like
+         * scheme, or your terminal have much less than 64 color pairs.
+         */
+        return gui_color_pairs[8][8];
+    
+    if (init_pair (++gui_color_pairs_allocated, (fg != -1) ? gui_curses_color_mapping[fg%8] : fg,
+                                                (bg != -1) ? gui_curses_color_mapping[bg%8] : bg) == ERR) {
+        /* XXX: error message? */
+        gui_color_pairs_allocated--;
+        return gui_color_pairs[8][8];
+    }
+
+    gui_color_pairs[bg == -1 ? 8 : bg][fg == -1 ? 8 : fg] = gui_color_pairs_allocated;
+   
+    return gui_color_pairs_allocated;
+}
+
+/*
  * gui_color_get_pair: get color pair with a WeeChat color number
  */
 
@@ -459,20 +519,13 @@
     int fg, bg;
     
     if ((num_color < 0) || (num_color > GUI_NUM_COLORS - 1))
-        return WEECHAT_COLOR_WHITE;
-    
-    fg = gui_color[num_color]->foreground;
-    bg = gui_color[num_color]->background;
-    
-    if (((fg == -1) || (fg == 99))
-        && ((bg == -1) || (bg == 99)))
-        return 63;
-    if ((fg == -1) || (fg == 99))
-        fg = WEECHAT_COLOR_WHITE;
-    if ((bg == -1) || (bg == 99))
-        bg = 0;
-    
-    return (bg * 8) + fg;
+    	fg = bg = -1;
+    else {
+        fg = gui_color[num_color]->foreground;
+        bg = gui_color[num_color]->background;
+    }
+   
+    return gui_color_get_pair_fgbg (fg, bg);
 }
 
 /*
@@ -482,21 +535,7 @@
 void
 gui_color_init_pairs ()
 {
-    int i;
-    char shift_colors[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-    
-    if (has_colors ())
-    {
-        for (i = 1; i < 64; i++)
-            init_pair (i, shift_colors[i % 8], (i < 8) ? -1 : shift_colors[i / 8]);
-        
-        /* disable white on white, replaced by black on white */
-        init_pair (63, -1, -1);
-        
-        /* white on default bg is default (-1) */
-        if (!cfg_col_real_white)
-            init_pair (WEECHAT_COLOR_WHITE, -1, -1);
-    }
+    /* In curses this function now also does nothing, just as in gtk+ :) */
 }
 
 /*
--- a/src/gui/curses/gui-curses.h	2009-03-14 23:42:49.000000000 +0200
+++ b/src/gui/curses/gui-curses.h	2009-05-22 20:39:11.000000000 +0300
@@ -78,6 +78,7 @@
 extern int gui_refresh_screen_needed;
 
 /* color functions */
+extern int gui_color_get_pair_fgbg (int, int);
 extern int gui_color_get_pair (int);
 extern void gui_color_init ();
 
--- a/src/gui/curses/gui-curses-input.c	2009-03-14 23:42:49.000000000 +0200
+++ b/src/gui/curses/gui-curses-input.c	2009-05-22 20:45:11.000000000 +0300
@@ -53,18 +53,8 @@
     irc_color %= GUI_NUM_IRC_COLORS;
     if (gui_irc_colors[irc_color][1] & A_BOLD)
         wattron (GUI_CURSES(window)->win_input, A_BOLD);
-    
-    if (((fg == -1) || (fg == 99))
-        && ((bg == -1) || (bg == 99)))
-        wattron (GUI_CURSES(window)->win_input, COLOR_PAIR(63));
-    else
-    {
-        if ((fg == -1) || (fg == 99))
-            fg = WEECHAT_COLOR_WHITE;
-        if ((bg == -1) || (bg == 99))
-            bg = 0;
-        wattron (GUI_CURSES(window)->win_input, COLOR_PAIR((bg * 8) + fg));
-    }
+   
+    wattron (GUI_CURSES(window)->win_input, COLOR_PAIR(gui_color_get_pair_fgbg (fg, bg)));
 }
 
 /*

Reply via email to