mirror of
https://github.com/weechat/weechat.git
synced 2026-06-29 06:16:40 +02:00
Add 256 colors support
Changes: - new section "palette" in weechat.conf - new API functions: list_search_pos and list_casesearch_pos
This commit is contained in:
@@ -248,19 +248,19 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window,
|
||||
case GUI_COLOR_BAR_FG_CHAR:
|
||||
/* bar foreground */
|
||||
gui_window_set_custom_color_fg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]));
|
||||
CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]));
|
||||
string += 2;
|
||||
break;
|
||||
case GUI_COLOR_BAR_DELIM_CHAR:
|
||||
/* bar delimiter */
|
||||
gui_window_set_custom_color_fg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_COLOR_DELIM]));
|
||||
CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_DELIM]));
|
||||
string += 2;
|
||||
break;
|
||||
case GUI_COLOR_BAR_BG_CHAR:
|
||||
/* bar background */
|
||||
gui_window_set_custom_color_bg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
|
||||
CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
|
||||
string += 2;
|
||||
break;
|
||||
case GUI_COLOR_BAR_START_INPUT_CHAR:
|
||||
@@ -301,9 +301,9 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window,
|
||||
break;
|
||||
case GUI_COLOR_RESET_CHAR:
|
||||
gui_window_set_custom_color_fg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]));
|
||||
CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_FG]));
|
||||
gui_window_set_custom_color_bg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
|
||||
CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
|
||||
gui_window_remove_color_style (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
A_BOLD | A_UNDERLINE | A_REVERSE);
|
||||
string++;
|
||||
@@ -672,7 +672,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window,
|
||||
y = 0;
|
||||
gui_window_set_custom_color_fg_bg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
CONFIG_COLOR(config_color_bar_more),
|
||||
CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
|
||||
CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
|
||||
mvwprintw (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
y, x, "--");
|
||||
}
|
||||
@@ -685,7 +685,7 @@ gui_bar_window_draw (struct t_gui_bar_window *bar_window,
|
||||
y = (bar_window->height > 1) ? bar_window->height - 1 : 0;
|
||||
gui_window_set_custom_color_fg_bg (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
CONFIG_COLOR(config_color_bar_more),
|
||||
CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
|
||||
CONFIG_COLOR(bar_window->bar->options[GUI_BAR_OPTION_COLOR_BG]));
|
||||
mvwprintw (GUI_BAR_WINDOW_OBJECTS(bar_window)->win_bar,
|
||||
y, x, "++");
|
||||
}
|
||||
|
||||
@@ -31,8 +31,11 @@
|
||||
|
||||
#include "../../core/weechat.h"
|
||||
#include "../../core/wee-config.h"
|
||||
#include "../../core/wee-hashtable.h"
|
||||
#include "../../core/wee-list.h"
|
||||
#include "../../core/wee-string.h"
|
||||
#include "../../core/wee-utf8.h"
|
||||
#include "../../plugins/plugin.h"
|
||||
#include "../gui-color.h"
|
||||
#include "../gui-chat.h"
|
||||
#include "gui-curses.h"
|
||||
@@ -84,6 +87,7 @@ gui_color_search (const char *color_name)
|
||||
|
||||
/*
|
||||
* gui_color_assign: assign a WeeChat color (read from config)
|
||||
* return 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
@@ -92,15 +96,26 @@ gui_color_assign (int *color, const char *color_name)
|
||||
int color_index, pair;
|
||||
char *error;
|
||||
|
||||
/* search for color alias */
|
||||
pair = gui_color_palette_get_alias (color_name);
|
||||
if (pair >= 0)
|
||||
{
|
||||
*color = GUI_COLOR_PAIR_FLAG | pair;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* is it pair number? */
|
||||
error = NULL;
|
||||
pair = (int)strtol (color_name, &error, 10);
|
||||
if (error && !error[0] && (pair >= 0))
|
||||
{
|
||||
*color = 0x10000 | pair;
|
||||
/* color_name is a number, use this pair number */
|
||||
*color = GUI_COLOR_PAIR_FLAG | pair;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* search for basic WeeChat color */
|
||||
color_index = gui_color_search (color_name);
|
||||
if (color_index >= 0)
|
||||
{
|
||||
@@ -113,6 +128,57 @@ gui_color_assign (int *color, const char *color_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_assign_by_diff: assign color by difference
|
||||
* It is called when a color option is
|
||||
* set with value ++X or --X, to search
|
||||
* another color (for example ++1 is
|
||||
* next color/alias in list)
|
||||
* return 1 if ok, 0 if error
|
||||
*/
|
||||
|
||||
int
|
||||
gui_color_assign_by_diff (int *color, const char *color_name, int diff)
|
||||
{
|
||||
int index, list_size;
|
||||
struct t_weelist_item *ptr_item;
|
||||
const char *name;
|
||||
|
||||
index = weelist_search_pos (gui_color_list_with_alias, color_name);
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
|
||||
list_size = weelist_size (gui_color_list_with_alias);
|
||||
|
||||
diff = diff % (list_size + 1);
|
||||
|
||||
if (diff > 0)
|
||||
{
|
||||
index = (index + diff) % (list_size + 1);
|
||||
while (index > list_size - 1)
|
||||
{
|
||||
index -= list_size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
index = (index + list_size + diff) % list_size;
|
||||
while (index < 0)
|
||||
{
|
||||
index += list_size;
|
||||
}
|
||||
}
|
||||
|
||||
ptr_item = weelist_get (gui_color_list_with_alias, index);
|
||||
if (!ptr_item)
|
||||
return 0;
|
||||
name = weelist_string (ptr_item);
|
||||
if (name)
|
||||
return gui_color_assign (color, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_get_number: get number of available colors
|
||||
*/
|
||||
@@ -132,13 +198,17 @@ gui_color_get_name (int num_color)
|
||||
{
|
||||
static char color[32][16];
|
||||
static int index_color = 0;
|
||||
struct t_gui_color_palette *ptr_color_palette;
|
||||
|
||||
if (num_color & 0x10000)
|
||||
if (num_color & GUI_COLOR_PAIR_FLAG)
|
||||
{
|
||||
ptr_color_palette = gui_color_palette_get (num_color & GUI_COLOR_PAIR_MASK);
|
||||
if (ptr_color_palette && ptr_color_palette->alias)
|
||||
return ptr_color_palette->alias;
|
||||
index_color = (index_color + 1) % 32;
|
||||
color[index_color][0] = '\0';
|
||||
snprintf (color[index_color], sizeof (color[index_color]),
|
||||
"%d", num_color & 0xFFFF);
|
||||
"%d", num_color & GUI_COLOR_PAIR_MASK);
|
||||
return color[index_color];
|
||||
}
|
||||
|
||||
@@ -163,7 +233,7 @@ gui_color_build (int number, int foreground, int background)
|
||||
gui_color[number]->string = malloc (4);
|
||||
}
|
||||
|
||||
if (foreground & 0x10000)
|
||||
if (foreground & GUI_COLOR_PAIR_FLAG)
|
||||
{
|
||||
gui_color[number]->foreground = foreground;
|
||||
gui_color[number]->background = 0;
|
||||
@@ -171,7 +241,7 @@ gui_color_build (int number, int foreground, int background)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (background & 0x10000)
|
||||
if (background & GUI_COLOR_PAIR_FLAG)
|
||||
background = 0;
|
||||
gui_color[number]->foreground = gui_weechat_colors[foreground].foreground;
|
||||
gui_color[number]->background = gui_weechat_colors[background].foreground;
|
||||
@@ -200,6 +270,9 @@ gui_color_get_pair (int num_color)
|
||||
fg = gui_color[num_color]->foreground;
|
||||
bg = gui_color[num_color]->background;
|
||||
|
||||
if ((fg > 0) && (fg & GUI_COLOR_PAIR_FLAG))
|
||||
return fg & GUI_COLOR_PAIR_MASK;
|
||||
|
||||
if (((fg == -1) || (fg == 99))
|
||||
&& ((bg == -1) || (bg == 99)))
|
||||
return gui_color_last_pair;
|
||||
@@ -211,6 +284,34 @@ gui_color_get_pair (int num_color)
|
||||
return (bg * gui_color_num_bg) + fg + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_init_pair: init a color pair
|
||||
*/
|
||||
|
||||
void
|
||||
gui_color_init_pair (int number)
|
||||
{
|
||||
struct t_gui_color_palette *ptr_color_palette;
|
||||
int fg, bg;
|
||||
|
||||
if ((number >= 1) && (number <= COLOR_PAIRS - 1))
|
||||
{
|
||||
ptr_color_palette = gui_color_palette_get (number);
|
||||
if (ptr_color_palette)
|
||||
{
|
||||
init_pair (number,
|
||||
ptr_color_palette->foreground,
|
||||
ptr_color_palette->background);
|
||||
}
|
||||
else
|
||||
{
|
||||
fg = (number - 1) % gui_color_num_bg;
|
||||
bg = ((number - 1) < gui_color_num_bg) ? -1 : (number - 1) / gui_color_num_bg;
|
||||
init_pair (number, fg, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_init_pairs: init color pairs
|
||||
*/
|
||||
@@ -218,7 +319,8 @@ gui_color_get_pair (int num_color)
|
||||
void
|
||||
gui_color_init_pairs ()
|
||||
{
|
||||
int i, fg, bg, num_colors;
|
||||
int i, num_colors;
|
||||
struct t_gui_color_palette *ptr_color_palette;
|
||||
|
||||
/*
|
||||
* depending on terminal and $TERM value, we can have for example:
|
||||
@@ -235,23 +337,29 @@ gui_color_init_pairs ()
|
||||
{
|
||||
gui_color_num_bg = (COLOR_PAIRS >= 256) ? 16 : 8;
|
||||
num_colors = (COLOR_PAIRS >= 256) ? 256 : COLOR_PAIRS;
|
||||
for (i = 1; i < num_colors; i++)
|
||||
{
|
||||
fg = (i - 1) % gui_color_num_bg;
|
||||
bg = ((i - 1) < gui_color_num_bg) ? -1 : (i - 1) / gui_color_num_bg;
|
||||
init_pair (i, fg, bg);
|
||||
}
|
||||
gui_color_last_pair = num_colors - 1;
|
||||
|
||||
/* WeeChat pairs */
|
||||
for (i = 1; i < num_colors; i++)
|
||||
{
|
||||
gui_color_init_pair (i);
|
||||
}
|
||||
|
||||
/* disable white on white, replaced by black on white */
|
||||
init_pair (gui_color_last_pair, -1, -1);
|
||||
ptr_color_palette = gui_color_palette_get (gui_color_last_pair);
|
||||
if (!ptr_color_palette)
|
||||
init_pair (gui_color_last_pair, -1, -1);
|
||||
|
||||
/*
|
||||
* white on default bg is default (-1) (for terminals with white/light
|
||||
* background)
|
||||
*/
|
||||
if (!CONFIG_BOOLEAN(config_look_color_real_white))
|
||||
init_pair (COLOR_WHITE + 1, -1, -1);
|
||||
{
|
||||
ptr_color_palette = gui_color_palette_get (COLOR_WHITE);
|
||||
if (!ptr_color_palette)
|
||||
init_pair (COLOR_WHITE + 1, -1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,6 +503,167 @@ gui_color_display_terminal_colors ()
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_palette_add_alias_cb: add an alias in hashtable with aliases
|
||||
*/
|
||||
|
||||
void
|
||||
gui_color_palette_add_alias_cb (void *data,
|
||||
struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
struct t_gui_color_palette *color_palette;
|
||||
char *error;
|
||||
int number;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) hashtable;
|
||||
|
||||
color_palette = (struct t_gui_color_palette *)value;
|
||||
|
||||
if (color_palette && color_palette->alias)
|
||||
{
|
||||
error = NULL;
|
||||
number = (int)strtol ((char *)key, &error, 10);
|
||||
if (error && !error[0])
|
||||
{
|
||||
hashtable_set (gui_color_hash_palette_alias,
|
||||
color_palette->alias,
|
||||
&number);
|
||||
}
|
||||
weelist_add (gui_color_list_with_alias, color_palette->alias,
|
||||
WEECHAT_LIST_POS_END, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_palette_build_aliases: build aliases for palette
|
||||
*/
|
||||
|
||||
void
|
||||
gui_color_palette_build_aliases ()
|
||||
{
|
||||
int i;
|
||||
|
||||
hashtable_remove_all (gui_color_hash_palette_alias);
|
||||
weelist_remove_all (gui_color_list_with_alias);
|
||||
for (i = 0; i < GUI_CURSES_NUM_WEECHAT_COLORS; i++)
|
||||
{
|
||||
weelist_add (gui_color_list_with_alias,
|
||||
gui_weechat_colors[i].string,
|
||||
WEECHAT_LIST_POS_END,
|
||||
NULL);
|
||||
}
|
||||
hashtable_map (gui_color_hash_palette_color,
|
||||
&gui_color_palette_add_alias_cb, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_palette_new: create a new color in palette
|
||||
*/
|
||||
|
||||
struct t_gui_color_palette *
|
||||
gui_color_palette_new (int number, const char *value)
|
||||
{
|
||||
struct t_gui_color_palette *new_color_palette;
|
||||
char **items, *pos, *pos2, *error1, *error2, *error3, str_number[64];
|
||||
int num_items, fg, bg, r, g, b;
|
||||
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
new_color_palette = malloc (sizeof (*new_color_palette));
|
||||
if (new_color_palette)
|
||||
{
|
||||
new_color_palette->alias = NULL;
|
||||
new_color_palette->foreground = number;
|
||||
new_color_palette->background = -1;
|
||||
new_color_palette->r = -1;
|
||||
new_color_palette->g = -1;
|
||||
new_color_palette->b = -1;
|
||||
items = string_split (value, ";", 0, 0, &num_items);
|
||||
if (items)
|
||||
{
|
||||
if ((num_items >= 1) && items[0][0])
|
||||
{
|
||||
new_color_palette->alias = strdup (items[0]);
|
||||
}
|
||||
if ((num_items >= 2) && items[1][0])
|
||||
{
|
||||
pos = strchr (items[1], ',');
|
||||
if (pos)
|
||||
{
|
||||
pos[0] = '\0';
|
||||
error1 = NULL;
|
||||
fg = (int)strtol (items[1], &error1, 10);
|
||||
error2 = NULL;
|
||||
bg = (int)strtol (pos + 1, &error2, 10);
|
||||
if (error1 && !error1[0] && error2 && !error2[0]
|
||||
&& (fg >= -1) && (bg >= -1))
|
||||
{
|
||||
new_color_palette->foreground = fg;
|
||||
new_color_palette->background = bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((num_items >= 3) && items[2][0])
|
||||
{
|
||||
pos = strchr (items[2], '/');
|
||||
if (pos)
|
||||
{
|
||||
pos[0] = '\0';
|
||||
pos2 = strchr (pos + 1, '/');
|
||||
if (pos2)
|
||||
{
|
||||
pos2[0] = '\0';
|
||||
error1 = NULL;
|
||||
r = (int)strtol (items[2], &error1, 10);
|
||||
error2 = NULL;
|
||||
g = (int)strtol (pos + 1, &error2, 10);
|
||||
error3 = NULL;
|
||||
b = (int)strtol (pos2 + 1, &error3, 10);
|
||||
if (error1 && !error1[0] && error2 && !error2[0]
|
||||
&& error3 && !error3[0]
|
||||
&& (r >= 0) && (r <= 1000)
|
||||
&& (g >= 0) && (g <= 1000)
|
||||
&& (b >= 0) && (b <= 1000))
|
||||
{
|
||||
new_color_palette->r = r;
|
||||
new_color_palette->g = g;
|
||||
new_color_palette->b = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
string_free_split (items);
|
||||
}
|
||||
if (!new_color_palette->alias)
|
||||
{
|
||||
snprintf (str_number, sizeof (str_number), "%d", number);
|
||||
new_color_palette->alias = strdup (str_number);
|
||||
}
|
||||
}
|
||||
|
||||
return new_color_palette;
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_palette_free: free a color in palette
|
||||
*/
|
||||
|
||||
void
|
||||
gui_color_palette_free (struct t_gui_color_palette *color_palette)
|
||||
{
|
||||
if (!color_palette)
|
||||
return;
|
||||
|
||||
if (color_palette->alias)
|
||||
free (color_palette->alias);
|
||||
|
||||
free (color_palette);
|
||||
}
|
||||
|
||||
/*
|
||||
* gui_color_end: end GUI colors
|
||||
*/
|
||||
|
||||
@@ -235,9 +235,9 @@ gui_window_reset_style (WINDOW *window, int num_color)
|
||||
window_current_style_attr = 0;
|
||||
window_current_color_attr = 0;
|
||||
|
||||
wattroff (window, A_BOLD | A_UNDERLINE | A_REVERSE);
|
||||
wattron (window, COLOR_PAIR(gui_color_get_pair (num_color)) |
|
||||
gui_color[num_color]->attributes);
|
||||
wattroff (window, A_BOLD | A_UNDERLINE | A_REVERSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -297,9 +297,9 @@ gui_window_set_weechat_color (WINDOW *window, int num_color)
|
||||
gui_window_reset_style (window, num_color);
|
||||
wattron (window, gui_color[num_color]->attributes);
|
||||
if ((gui_color[num_color]->foreground > 0)
|
||||
&& (gui_color[num_color]->foreground & 0x10000))
|
||||
&& (gui_color[num_color]->foreground & GUI_COLOR_PAIR_FLAG))
|
||||
{
|
||||
wattron (window, COLOR_PAIR(gui_color[num_color]->foreground & 0xFFFF));
|
||||
wattron (window, COLOR_PAIR(gui_color[num_color]->foreground & GUI_COLOR_PAIR_MASK));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -354,15 +354,22 @@ void
|
||||
gui_window_set_custom_color_fg (WINDOW *window, int fg)
|
||||
{
|
||||
int current_bg;
|
||||
|
||||
if ((fg >= 0) && (fg < GUI_CURSES_NUM_WEECHAT_COLORS))
|
||||
|
||||
if (fg >= 0)
|
||||
{
|
||||
current_bg = window_current_style_bg;
|
||||
gui_window_remove_color_style (window, A_BOLD);
|
||||
gui_window_set_color_style (window, gui_weechat_colors[fg].attributes);
|
||||
gui_window_set_color (window,
|
||||
gui_weechat_colors[fg].foreground,
|
||||
current_bg);
|
||||
if (fg & GUI_COLOR_PAIR_FLAG)
|
||||
{
|
||||
gui_window_set_custom_color_pair (window, fg & GUI_COLOR_PAIR_MASK);
|
||||
}
|
||||
else if (fg < GUI_CURSES_NUM_WEECHAT_COLORS)
|
||||
{
|
||||
current_bg = window_current_style_bg;
|
||||
gui_window_remove_color_style (window, A_BOLD);
|
||||
gui_window_set_color_style (window, gui_weechat_colors[fg].attributes);
|
||||
gui_window_set_color (window,
|
||||
gui_weechat_colors[fg].foreground,
|
||||
current_bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,14 +383,21 @@ gui_window_set_custom_color_bg (WINDOW *window, int bg)
|
||||
{
|
||||
int current_attr, current_fg;
|
||||
|
||||
if ((bg >= 0) && (bg < GUI_CURSES_NUM_WEECHAT_COLORS))
|
||||
if (bg >= 0)
|
||||
{
|
||||
current_attr = window_current_style_attr;
|
||||
current_fg = window_current_style_fg;
|
||||
gui_window_set_color_style (window, current_attr);
|
||||
gui_window_set_color (window, current_fg,
|
||||
(gui_color_num_bg > 8) ?
|
||||
gui_weechat_colors[bg].background : gui_weechat_colors[bg].foreground);
|
||||
if (bg & GUI_COLOR_PAIR_FLAG)
|
||||
{
|
||||
gui_window_set_custom_color_pair (window, bg & GUI_COLOR_PAIR_MASK);
|
||||
}
|
||||
else if (bg < GUI_CURSES_NUM_WEECHAT_COLORS)
|
||||
{
|
||||
current_attr = window_current_style_attr;
|
||||
current_fg = window_current_style_fg;
|
||||
gui_window_set_color_style (window, current_attr);
|
||||
gui_window_set_color (window, current_fg,
|
||||
(gui_color_num_bg > 8) ?
|
||||
gui_weechat_colors[bg].background : gui_weechat_colors[bg].foreground);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user