mirror of
https://github.com/irssi/irssi.git
synced 2025-01-03 14:56:47 -05:00
Merge pull request #48 from ailin-nemui/256-colour-history
256 colour support for Irssi
This commit is contained in:
commit
fd3676e407
2
AUTHORS
2
AUTHORS
@ -78,3 +78,5 @@ Other patches (grep for "patch" in ChangeLog) by:
|
||||
Ismael Luceno
|
||||
Thomas Karpiniec
|
||||
Svante Kvarnström
|
||||
Ailin Nemui (Nei)
|
||||
Tom Feist (shabble)
|
||||
|
16
configure.ac
16
configure.ac
@ -166,6 +166,15 @@ AC_ARG_ENABLE(dane,
|
||||
fi,
|
||||
want_dane=no)
|
||||
|
||||
AC_ARG_ENABLE(true-color,
|
||||
[ --enable-true-color Build with true color support in terminal],
|
||||
if test x$enableval = xno ; then
|
||||
want_truecolor=no
|
||||
else
|
||||
want_truecolor=yes
|
||||
fi,
|
||||
want_truecolor=no)
|
||||
|
||||
dnl **
|
||||
dnl ** SSL Library checks (OpenSSL)
|
||||
dnl **
|
||||
@ -643,6 +652,12 @@ if test "x$want_dane" = "xyes"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$want_truecolor" = "xyes" -a "x$want_termcap" != "xyes" -a "x$want_terminfo" = "xyes" ; then
|
||||
AC_DEFINE([TERM_TRUECOLOR], [], [true color support in terminal])
|
||||
else
|
||||
want_truecolor=no
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
@ -761,6 +776,7 @@ echo "Building with SSL support ........ : $have_openssl"
|
||||
echo "Building with 64bit DCC support .. : $offt_64bit"
|
||||
echo "Building with garbage collector .. : $have_gc"
|
||||
echo "Building with DANE support ....... : $have_dane"
|
||||
echo "Building with true color support.. : $want_truecolor"
|
||||
|
||||
echo
|
||||
echo "If there are any problems, read the INSTALL file."
|
||||
|
@ -27,6 +27,8 @@
|
||||
%| Marks the indentation position
|
||||
%# Monospace font on/off (useful with lists and GUI)
|
||||
%% A single %
|
||||
%XAB %xAB Color from extended plane (A=1-7, B=0-Z)
|
||||
%ZAABBCC %zAABBCC HTML color (in hex notation)
|
||||
|
||||
In .theme files %n works a bit differently. See default.theme
|
||||
for more information.
|
||||
|
@ -130,6 +130,7 @@ aliases = {
|
||||
CHAT = "dcc chat";
|
||||
RUN = "SCRIPT LOAD";
|
||||
CALC = "exec - if command -v bc >/dev/null 2>&1\\; then printf '%s=' '$*'\\; echo '$*' | bc -l\\; else echo bc was not found\\; fi";
|
||||
CUBES = "/script exec Irssi::active_win->print(\"%_bases\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { join '', map { \"%x0\\${_}0\\$_\" } '0'..'9','A'..'F' }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print(\"%_cubes\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { my \\$y = \\$_*6 \\; join '', map { my \\$x = \\$_ \\; map { \"%x\\$x\\$_\\$x\\$_\" } @{['0'..'9','A'..'Z']}[\\$y .. \\$y+5] } 1..6 }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) for 0..5 \\; Irssi::active_win->print(\"%_grays\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { join '', map { \"%x7\\${_}7\\$_\" } 'A'..'X' }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print(\"%_mIRC extended colours\", MSGLEVEL_CLIENTCRAP) \\; my \\$x \\; \\$x .= sprintf \"\00399,%02d%02d\",\\$_,\\$_ for 0..15 \\; Irssi::active_win->print(\\$x, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; for my \\$z (0..6) { my \\$x \\; \\$x .= sprintf \"\00399,%02d%02d\",\\$_,\\$_ for 16+(\\$z*12)..16+(\\$z*12)+11 \\; Irssi::active_win->print(\\$x, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) }";
|
||||
SBAR = "STATUSBAR";
|
||||
INVITELIST = "mode $C +I";
|
||||
Q = "QUERY";
|
||||
|
@ -588,6 +588,63 @@ static void window_print_daychange(WINDOW_REC *window, struct tm *tm)
|
||||
printtext_string_window(window, MSGLEVEL_NEVER, str);
|
||||
}
|
||||
|
||||
short color_24bit_256 (const unsigned char rgb[])
|
||||
{
|
||||
static const int cstep_size = 40;
|
||||
static const int cstep_start = 0x5f;
|
||||
|
||||
static const int gstep_size = 10;
|
||||
static const int gstep_start = 0x08;
|
||||
|
||||
int dist[3] = {0};
|
||||
int r[3], gr[3];
|
||||
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
const int n = rgb[i];
|
||||
gr[i] = -1;
|
||||
if (n < cstep_start /2) {
|
||||
r[i] = 0;
|
||||
dist[i] = -cstep_size/2;
|
||||
}
|
||||
else {
|
||||
r[i] = 1+((n-cstep_start + cstep_size /2)/cstep_size);
|
||||
dist[i] = ((n-cstep_start + cstep_size /2)%cstep_size - cstep_size/2);
|
||||
}
|
||||
if (n < gstep_start /2) {
|
||||
gr[i] = -1;
|
||||
}
|
||||
else {
|
||||
gr[i] = ((n-gstep_start + gstep_size /2)/gstep_size);
|
||||
}
|
||||
}
|
||||
if (r[0] == r[1] && r[1] == r[2] &&
|
||||
4*abs(dist[0]) < gstep_size && 4*abs(dist[1]) < gstep_size && 4*abs(dist[2]) < gstep_size) {
|
||||
/* skip gray detection */
|
||||
}
|
||||
else {
|
||||
const int j = r[1] == r[2] ? 0 : 1;
|
||||
if ((r[0] == r[1] || r[j] == r[2]) && abs(r[j]-r[(j+1)%3]) <= 1) {
|
||||
const int k = gr[1] == gr[2] ? 0 : 1;
|
||||
if ((gr[0] == gr[1] || gr[k] == gr[2]) && abs(gr[k]-gr[(k+1)%3]) <= 2) {
|
||||
if (gr[k] < 0) {
|
||||
r[0] = r[1] = r[2] = 0;
|
||||
}
|
||||
else if (gr[k] > 23) {
|
||||
r[0] = r[1] = r[2] = 5;
|
||||
}
|
||||
else {
|
||||
r[0] = 6;
|
||||
r[1] = (gr[k] / 6);
|
||||
r[2] = gr[k]%6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 16 + r[0]*36 + r[1] * 6 + r[2];
|
||||
}
|
||||
|
||||
static void sig_print_text(void)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
@ -97,4 +97,6 @@ void window_bind_remove_unsticky(WINDOW_REC *window);
|
||||
void windows_init(void);
|
||||
void windows_deinit(void);
|
||||
|
||||
short color_24bit_256(const unsigned char rgb[]);
|
||||
|
||||
#endif
|
||||
|
@ -101,10 +101,88 @@ static void format_expand_code(const char **format, GString *out, int *flags)
|
||||
}
|
||||
}
|
||||
|
||||
void format_ext_color(GString *out, int bg, int color)
|
||||
{
|
||||
g_string_append_c(out, 4);
|
||||
if (bg && color < 0x10)
|
||||
g_string_append_c(out, FORMAT_COLOR_NOCHANGE);
|
||||
if (color < 0x10)
|
||||
g_string_append_c(out, color+'0');
|
||||
else {
|
||||
if (color < 0x60)
|
||||
g_string_append_c(out, bg ? FORMAT_COLOR_EXT1_BG
|
||||
: FORMAT_COLOR_EXT1);
|
||||
else if (color < 0xb0)
|
||||
g_string_append_c(out, bg ? FORMAT_COLOR_EXT2_BG
|
||||
: FORMAT_COLOR_EXT2);
|
||||
else
|
||||
g_string_append_c(out, bg ? FORMAT_COLOR_EXT3_BG
|
||||
: FORMAT_COLOR_EXT3);
|
||||
g_string_append_c(out, FORMAT_COLOR_NOCHANGE + ((color-0x10)%0x50));
|
||||
}
|
||||
if (!bg && color < 0x10)
|
||||
g_string_append_c(out, FORMAT_COLOR_NOCHANGE);
|
||||
}
|
||||
|
||||
#ifdef TERM_TRUECOLOR
|
||||
void unformat_24bit_color(char **ptr, int off, int *fgcolor, int *bgcolor, int *flags)
|
||||
{
|
||||
unsigned int color;
|
||||
unsigned char rgbx[4];
|
||||
unsigned int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
rgbx[i] = (*ptr)[i + off];
|
||||
}
|
||||
rgbx[3] -= 0x20;
|
||||
*ptr += 4;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (rgbx[3] & (0x10 << i))
|
||||
rgbx[i] -= 0x20;
|
||||
}
|
||||
color = rgbx[0] << 16 | rgbx[1] << 8 | rgbx[2];
|
||||
if (rgbx[3] & 0x1) {
|
||||
*bgcolor = color;
|
||||
*flags |= GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
}
|
||||
else {
|
||||
*fgcolor = color;
|
||||
*flags |= GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void format_24bit_color(GString *out, int bg, unsigned int color)
|
||||
{
|
||||
unsigned char rgb[] = { color >> 16, color >> 8, color };
|
||||
#ifdef TERM_TRUECOLOR
|
||||
unsigned char x = bg ? 0x1 : 0;
|
||||
unsigned int i;
|
||||
g_string_append_c(out, 4);
|
||||
g_string_append_c(out, FORMAT_COLOR_24);
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (rgb[i] > 0x20)
|
||||
g_string_append_c(out, rgb[i]);
|
||||
else {
|
||||
g_string_append_c(out, 0x20 + rgb[i]);
|
||||
x |= 0x10 << i;
|
||||
}
|
||||
}
|
||||
g_string_append_c(out, 0x20 + x);
|
||||
#else /* !TERM_TRUECOLOR */
|
||||
format_ext_color(out, bg, color_24bit_256(rgb));
|
||||
#endif /* TERM_TRUECOLOR */
|
||||
}
|
||||
|
||||
int format_expand_styles(GString *out, const char **format, int *flags)
|
||||
{
|
||||
int retval = 1;
|
||||
|
||||
char *p, fmt;
|
||||
|
||||
/* storage for numerical parsing code for %x/X formats. */
|
||||
int tmp;
|
||||
unsigned int tmp2;
|
||||
|
||||
fmt = **format;
|
||||
switch (fmt) {
|
||||
case '{':
|
||||
@ -162,6 +240,62 @@ int format_expand_styles(GString *out, const char **format, int *flags)
|
||||
/* code */
|
||||
format_expand_code(format, out, flags);
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
if ((*format)[1] < '0' || (*format)[1] > '7')
|
||||
break;
|
||||
|
||||
tmp = 16 + ((*format)[1]-'0'-1)*36;
|
||||
if (tmp > 231) {
|
||||
if (!isalpha((*format)[2]))
|
||||
break;
|
||||
|
||||
tmp += (*format)[2] >= 'a' ? (*format)[2] - 'a' : (*format)[2] - 'A';
|
||||
|
||||
if (tmp > 255)
|
||||
break;
|
||||
}
|
||||
else if (tmp > 0) {
|
||||
if (!isalnum((*format)[2]))
|
||||
break;
|
||||
|
||||
if ((*format)[2] >= 'a')
|
||||
tmp += 10 + (*format)[2] - 'a';
|
||||
else if ((*format)[2] >= 'A')
|
||||
tmp += 10 + (*format)[2] - 'A';
|
||||
else
|
||||
tmp += (*format)[2] - '0';
|
||||
}
|
||||
else {
|
||||
if (!isxdigit((*format)[2]))
|
||||
break;
|
||||
|
||||
tmp = g_ascii_xdigit_value((*format)[2]);
|
||||
}
|
||||
|
||||
retval += 2;
|
||||
|
||||
format_ext_color(out, fmt == 'x', tmp);
|
||||
break;
|
||||
case 'z':
|
||||
case 'Z':
|
||||
tmp2 = 0;
|
||||
for (tmp = 1; tmp < 7; ++tmp) {
|
||||
if (!isxdigit((*format)[tmp])) {
|
||||
tmp2 = UINT_MAX;
|
||||
break;
|
||||
}
|
||||
tmp2 <<= 4;
|
||||
tmp2 |= g_ascii_xdigit_value((*format)[tmp]);
|
||||
}
|
||||
|
||||
if (tmp2 == UINT_MAX)
|
||||
break;
|
||||
|
||||
retval += 6;
|
||||
|
||||
format_24bit_color(out, fmt == 'z', tmp2);
|
||||
break;
|
||||
default:
|
||||
/* check if it's a background color */
|
||||
p = strchr(format_backs, fmt);
|
||||
@ -195,7 +329,7 @@ int format_expand_styles(GString *out, const char **format, int *flags)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return retval;
|
||||
}
|
||||
|
||||
void format_read_arglist(va_list va, FORMAT_REC *format,
|
||||
@ -303,6 +437,7 @@ int format_get_length(const char *str)
|
||||
GString *tmp;
|
||||
int len;
|
||||
gboolean utf8;
|
||||
int adv = 0;
|
||||
|
||||
g_return_val_if_fail(str != NULL, 0);
|
||||
|
||||
@ -313,9 +448,10 @@ int format_get_length(const char *str)
|
||||
while (*str != '\0') {
|
||||
if (*str == '%' && str[1] != '\0') {
|
||||
str++;
|
||||
if (*str != '%' &&
|
||||
format_expand_styles(tmp, &str, NULL)) {
|
||||
str++;
|
||||
if (*str != '%') {
|
||||
adv = format_expand_styles(tmp, &str, NULL);
|
||||
str += adv;
|
||||
if (adv)
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -340,7 +476,7 @@ int format_real_length(const char *str, int len)
|
||||
const char *start;
|
||||
const char *oldstr;
|
||||
gboolean utf8;
|
||||
|
||||
int adv = 0;
|
||||
g_return_val_if_fail(str != NULL, 0);
|
||||
g_return_val_if_fail(len >= 0, 0);
|
||||
|
||||
@ -351,9 +487,10 @@ int format_real_length(const char *str, int len)
|
||||
while (*str != '\0' && len > 0) {
|
||||
if (*str == '%' && str[1] != '\0') {
|
||||
str++;
|
||||
if (*str != '%' &&
|
||||
format_expand_styles(tmp, &str, NULL)) {
|
||||
str++;
|
||||
if (*str != '%') {
|
||||
adv = format_expand_styles(tmp, &str, NULL);
|
||||
str += adv;
|
||||
if (adv)
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -378,6 +515,7 @@ char *format_string_expand(const char *text, int *flags)
|
||||
{
|
||||
GString *out;
|
||||
char code, *ret;
|
||||
int adv;
|
||||
|
||||
g_return_val_if_fail(text != NULL, NULL);
|
||||
|
||||
@ -388,10 +526,13 @@ char *format_string_expand(const char *text, int *flags)
|
||||
while (*text != '\0') {
|
||||
if (code == '%') {
|
||||
/* color code */
|
||||
if (!format_expand_styles(out, &text, flags)) {
|
||||
adv = format_expand_styles(out, &text, flags);
|
||||
if (!adv) {
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, *text);
|
||||
} else {
|
||||
text += adv - 1;
|
||||
}
|
||||
code = 0;
|
||||
} else {
|
||||
@ -415,6 +556,7 @@ static char *format_get_text_args(TEXT_DEST_REC *dest,
|
||||
GString *out;
|
||||
char code, *ret;
|
||||
int need_free;
|
||||
int adv;
|
||||
|
||||
out = g_string_new(NULL);
|
||||
|
||||
@ -422,10 +564,13 @@ static char *format_get_text_args(TEXT_DEST_REC *dest,
|
||||
while (*text != '\0') {
|
||||
if (code == '%') {
|
||||
/* color code */
|
||||
if (!format_expand_styles(out, &text, &dest->flags)) {
|
||||
adv = format_expand_styles(out, &text, &dest->flags);
|
||||
if (!adv) {
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, *text);
|
||||
} else {
|
||||
text += adv - 1;
|
||||
}
|
||||
code = 0;
|
||||
} else if (code == '$') {
|
||||
@ -716,13 +861,22 @@ void format_newline(WINDOW_REC *window)
|
||||
"", NULL);
|
||||
}
|
||||
|
||||
#ifndef TERM_TRUECOLOR
|
||||
inline static int color_24bit_256_int(unsigned int color)
|
||||
{
|
||||
unsigned char rgb[] = { color >> 16, color >> 8, color };
|
||||
return color_24bit_256(rgb);
|
||||
}
|
||||
#endif /* !TERM_TRUECOLOR */
|
||||
|
||||
/* parse ANSI color string */
|
||||
static const char *get_ansi_color(THEME_REC *theme, const char *str,
|
||||
int *fg_ret, int *bg_ret, int *flags_ret)
|
||||
{
|
||||
static char ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
|
||||
const char *start;
|
||||
int fg, bg, flags, num;
|
||||
int fg, bg, flags, num, i;
|
||||
unsigned int num2;
|
||||
|
||||
if (*str != '[')
|
||||
return str;
|
||||
@ -749,28 +903,127 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str,
|
||||
/* reset colors back to default */
|
||||
fg = theme->default_color;
|
||||
bg = -1;
|
||||
flags &= ~GUI_PRINT_FLAG_INDENT;
|
||||
flags &= ~(GUI_PRINT_FLAG_COLOR_24_FG | GUI_PRINT_FLAG_COLOR_24_BG | GUI_PRINT_FLAG_INDENT);
|
||||
break;
|
||||
case 1:
|
||||
/* hilight */
|
||||
flags |= GUI_PRINT_FLAG_BOLD;
|
||||
break;
|
||||
case 22:
|
||||
/* normal */
|
||||
flags &= ~GUI_PRINT_FLAG_BOLD;
|
||||
break;
|
||||
case 4:
|
||||
/* underline */
|
||||
flags |= GUI_PRINT_FLAG_UNDERLINE;
|
||||
break;
|
||||
case 24:
|
||||
/* not underline */
|
||||
flags &= ~GUI_PRINT_FLAG_UNDERLINE;
|
||||
break;
|
||||
case 5:
|
||||
/* blink */
|
||||
flags |= GUI_PRINT_FLAG_BLINK;
|
||||
break;
|
||||
case 25:
|
||||
/* steady */
|
||||
flags &= ~GUI_PRINT_FLAG_BLINK;
|
||||
break;
|
||||
case 7:
|
||||
/* reverse */
|
||||
flags |= GUI_PRINT_FLAG_REVERSE;
|
||||
break;
|
||||
case 27:
|
||||
/* positive */
|
||||
flags &= ~GUI_PRINT_FLAG_REVERSE;
|
||||
break;
|
||||
case 39:
|
||||
/* reset fg */
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
fg = theme->default_color;
|
||||
break;
|
||||
case 49:
|
||||
/* reset bg */
|
||||
bg = -1;
|
||||
flags &= ~(GUI_PRINT_FLAG_COLOR_24_BG | GUI_PRINT_FLAG_INDENT);
|
||||
break;
|
||||
case 38:
|
||||
case 48:
|
||||
/* ANSI indexed color or RGB color */
|
||||
if (*str != ';') break;
|
||||
str++;
|
||||
for (num2 = 0; i_isdigit(*str); str++)
|
||||
num2 = num2*10 + (*str-'0');
|
||||
|
||||
switch (num2) {
|
||||
case 2:
|
||||
/* RGB */
|
||||
num2 = 0;
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
num2 <<= 8;
|
||||
|
||||
if (*str != ';' && *str != ':') {
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
str++;
|
||||
for (; i_isdigit(*str); str++)
|
||||
num2 = (num2&~0xff) |
|
||||
(((num2&0xff) * 10 + (*str-'0'))&0xff);
|
||||
}
|
||||
|
||||
if (i == -1) break;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
if (num == 38) {
|
||||
flags |= GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
fg = num2;
|
||||
} else if (num == 48) {
|
||||
flags |= GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
bg = num2;
|
||||
}
|
||||
#else /* !TERM_TRUECOLOR */
|
||||
if (num == 38) {
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
fg = color_24bit_256_int(num2);
|
||||
} else if (num == 48) {
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
bg = color_24bit_256_int(num2);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
case 5:
|
||||
/* indexed */
|
||||
if (*str != ';') break;
|
||||
str++;
|
||||
for (num2 = 0; i_isdigit(*str); str++)
|
||||
num2 = num2*10 + (*str-'0');
|
||||
|
||||
if (num == 38) {
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
fg = num2;
|
||||
} else if (num == 48) {
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
bg = num2;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (num >= 30 && num <= 37) {
|
||||
if (fg == -1) fg = 0;
|
||||
fg = (fg & 0xf8) | ansitab[num-30];
|
||||
}
|
||||
if (num >= 40 && num <= 47) {
|
||||
if (bg == -1) bg = 0;
|
||||
bg = (bg & 0xf8) | ansitab[num-40];
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
fg = ansitab[num-30];
|
||||
} else if (num >= 40 && num <= 47) {
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
bg = ansitab[num-40];
|
||||
} else if (num >= 90 && num <= 97) {
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
fg = 8 + ansitab[num-90];
|
||||
} else if (num >= 100 && num <= 107) {
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
bg = 8 + ansitab[num-100];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -858,6 +1111,20 @@ int strip_real_length(const char *str, int len,
|
||||
*last_color_len = (int) (str-mircstart);
|
||||
|
||||
} else if (*str == 4 && str[1] != '\0') {
|
||||
#ifdef TERM_TRUECOLOR
|
||||
if (str[1] == FORMAT_COLOR_24 && str[2] != '\0') {
|
||||
if (str[3] == '\0') str++;
|
||||
else if (str[4] == '\0') str += 2;
|
||||
else if (str[5] == '\0') str += 3;
|
||||
else {
|
||||
if (last_color_pos != NULL)
|
||||
*last_color_pos = (int) (str-start);
|
||||
if (last_color_len != NULL)
|
||||
*last_color_len = 6;
|
||||
str+=4;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (str[1] < FORMAT_STYLE_SPECIAL && str[2] != '\0') {
|
||||
if (last_color_pos != NULL)
|
||||
*last_color_pos = (int) (str-start);
|
||||
@ -907,6 +1174,14 @@ char *strip_codes(const char *input)
|
||||
|
||||
/* irssi color */
|
||||
if (p[2] != '\0') {
|
||||
#ifdef TERM_TRUECOLOR
|
||||
if (p[1] == FORMAT_COLOR_24) {
|
||||
if (p[3] == '\0') p += 2;
|
||||
else if (p[4] == '\0') p += 3;
|
||||
else if (p[5] == '\0') p += 4;
|
||||
else p += 5;
|
||||
} else
|
||||
#endif /* TERM_TRUECOLOR */
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
@ -1020,16 +1295,47 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
|
||||
break;
|
||||
case FORMAT_STYLE_CLRTOEOL:
|
||||
break;
|
||||
case FORMAT_COLOR_EXT1:
|
||||
fgcolor = 0x10 + *++ptr - FORMAT_COLOR_NOCHANGE;
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
break;
|
||||
case FORMAT_COLOR_EXT1_BG:
|
||||
bgcolor = 0x10 + *++ptr - FORMAT_COLOR_NOCHANGE;
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
break;
|
||||
case FORMAT_COLOR_EXT2:
|
||||
fgcolor = 0x60 + *++ptr - FORMAT_COLOR_NOCHANGE;
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
break;
|
||||
case FORMAT_COLOR_EXT2_BG:
|
||||
bgcolor = 0x60 + *++ptr - FORMAT_COLOR_NOCHANGE;
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
break;
|
||||
case FORMAT_COLOR_EXT3:
|
||||
fgcolor = 0xb0 + *++ptr - FORMAT_COLOR_NOCHANGE;
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
break;
|
||||
case FORMAT_COLOR_EXT3_BG:
|
||||
bgcolor = 0xb0 + *++ptr - FORMAT_COLOR_NOCHANGE;
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
break;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
case FORMAT_COLOR_24:
|
||||
unformat_24bit_color(&ptr, 1, &fgcolor, &bgcolor, &flags);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (*ptr != FORMAT_COLOR_NOCHANGE) {
|
||||
fgcolor = (unsigned char) *ptr-'0';
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
fgcolor = *ptr==(char)0xff ? -1 : (unsigned char) *ptr-'0';
|
||||
}
|
||||
if (ptr[1] == '\0')
|
||||
break;
|
||||
|
||||
ptr++;
|
||||
if (*ptr != FORMAT_COLOR_NOCHANGE) {
|
||||
bgcolor = *ptr-'0';
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
bgcolor = *ptr==(char)0xff ? -1 : *ptr-'0';
|
||||
}
|
||||
}
|
||||
ptr++;
|
||||
|
@ -13,6 +13,8 @@
|
||||
#define GUI_PRINT_FLAG_NEWLINE 0x0080
|
||||
#define GUI_PRINT_FLAG_CLRTOEOL 0x0100
|
||||
#define GUI_PRINT_FLAG_MONOSPACE 0x0200
|
||||
#define GUI_PRINT_FLAG_COLOR_24_FG 0x0400
|
||||
#define GUI_PRINT_FLAG_COLOR_24_BG 0x0800
|
||||
|
||||
#define MAX_FORMAT_PARAMS 10
|
||||
#define DEFAULT_FORMAT_ARGLIST_SIZE 200
|
||||
@ -121,6 +123,15 @@ char *strip_codes(const char *input);
|
||||
void format_send_to_gui(TEXT_DEST_REC *dest, const char *text);
|
||||
|
||||
#define FORMAT_COLOR_NOCHANGE ('0'-1) /* don't change this, at least hilighting depends this value */
|
||||
#define FORMAT_COLOR_EXT1 ('0'-2)
|
||||
#define FORMAT_COLOR_EXT2 ('0'-3)
|
||||
#define FORMAT_COLOR_EXT3 ('0'-4)
|
||||
#define FORMAT_COLOR_EXT1_BG ('0'-5)
|
||||
#define FORMAT_COLOR_EXT2_BG ('0'-9)
|
||||
#define FORMAT_COLOR_EXT3_BG ('0'-10)
|
||||
#ifdef TERM_TRUECOLOR
|
||||
#define FORMAT_COLOR_24 ('0'-13)
|
||||
#endif
|
||||
|
||||
#define FORMAT_STYLE_SPECIAL 0x60
|
||||
#define FORMAT_STYLE_BLINK (0x01 + FORMAT_STYLE_SPECIAL)
|
||||
@ -132,6 +143,8 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text);
|
||||
#define FORMAT_STYLE_CLRTOEOL (0x08 + FORMAT_STYLE_SPECIAL)
|
||||
#define FORMAT_STYLE_MONOSPACE (0x09 + FORMAT_STYLE_SPECIAL)
|
||||
int format_expand_styles(GString *out, const char **format, int *flags);
|
||||
void format_ext_color(GString *out, int bg, int color);
|
||||
void format_24bit_color(GString *out, int bg, unsigned int color);
|
||||
|
||||
void formats_init(void);
|
||||
void formats_deinit(void);
|
||||
|
@ -206,6 +206,7 @@ static char *printtext_get_args(TEXT_DEST_REC *dest, const char *str,
|
||||
{
|
||||
GString *out;
|
||||
char *ret;
|
||||
int adv;
|
||||
|
||||
out = g_string_new(NULL);
|
||||
for (; *str != '\0'; str++) {
|
||||
@ -255,9 +256,12 @@ static char *printtext_get_args(TEXT_DEST_REC *dest, const char *str,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (!format_expand_styles(out, &str, &dest->flags)) {
|
||||
adv = format_expand_styles(out, &str, &dest->flags);
|
||||
if (!adv) {
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, *str);
|
||||
} else {
|
||||
str += adv - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -272,6 +276,7 @@ static char *printtext_expand_formats(const char *str, int *flags)
|
||||
{
|
||||
GString *out;
|
||||
char *ret;
|
||||
int adv;
|
||||
|
||||
out = g_string_new(NULL);
|
||||
for (; *str != '\0'; str++) {
|
||||
@ -283,9 +288,12 @@ static char *printtext_expand_formats(const char *str, int *flags)
|
||||
if (*++str == '\0')
|
||||
break;
|
||||
|
||||
if (!format_expand_styles(out, &str, flags)) {
|
||||
adv = format_expand_styles(out, &str, flags);
|
||||
if (!adv) {
|
||||
g_string_append_c(out, '%');
|
||||
g_string_append_c(out, *str);
|
||||
} else {
|
||||
str += adv - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,8 +115,8 @@ void theme_destroy(THEME_REC *rec)
|
||||
}
|
||||
|
||||
static char *theme_replace_expand(THEME_REC *theme, int index,
|
||||
char default_fg, char default_bg,
|
||||
char *last_fg, char *last_bg,
|
||||
theme_rm_col default_fg, theme_rm_col default_bg,
|
||||
theme_rm_col *last_fg, theme_rm_col *last_bg,
|
||||
char chr, int flags)
|
||||
{
|
||||
GSList *rec;
|
||||
@ -168,15 +168,44 @@ static void theme_format_append_variable(GString *str, const char **format)
|
||||
g_free(value);
|
||||
}
|
||||
|
||||
static inline int chr_is_valid_rgb(const char format[])
|
||||
{
|
||||
int tmp;
|
||||
for (tmp = 1; tmp < 7; ++tmp) {
|
||||
if (!isxdigit(format[tmp]))
|
||||
return tmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int chr_is_valid_ext(const char format[])
|
||||
{
|
||||
if (format[1] < '0' || format[1] > '7')
|
||||
return 1;
|
||||
|
||||
if (format[1] == '7') {
|
||||
if (!isalpha(format[2]) || format[2] == 'y' || format[2] == 'Y'
|
||||
|| format[2] =='z' || format[2] == 'Z')
|
||||
return 2;
|
||||
} else if (format[1] == '0') {
|
||||
if (!isxdigit(format[2]))
|
||||
return 2;
|
||||
} else if (!isalnum(format[2]))
|
||||
return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* append next "item", either a character, $variable or %format */
|
||||
static void theme_format_append_next(THEME_REC *theme, GString *str,
|
||||
const char **format,
|
||||
char default_fg, char default_bg,
|
||||
char *last_fg, char *last_bg,
|
||||
theme_rm_col default_fg, theme_rm_col default_bg,
|
||||
theme_rm_col *last_fg, theme_rm_col *last_bg,
|
||||
int flags)
|
||||
{
|
||||
int index;
|
||||
unsigned char chr;
|
||||
char *t;
|
||||
|
||||
chr = **format;
|
||||
if ((chr == '$' || chr == '%') &&
|
||||
@ -203,22 +232,50 @@ static void theme_format_append_next(THEME_REC *theme, GString *str,
|
||||
/* %n = change to default color */
|
||||
g_string_append(str, "%n");
|
||||
|
||||
if (default_bg != 'n') {
|
||||
if (default_bg.m[0] != 'n') {
|
||||
g_string_append_c(str, '%');
|
||||
g_string_append_c(str, default_bg);
|
||||
g_string_append(str, default_bg.m);
|
||||
}
|
||||
if (default_fg != 'n') {
|
||||
if (default_fg.m[0] != 'n') {
|
||||
g_string_append_c(str, '%');
|
||||
g_string_append_c(str, default_fg);
|
||||
g_string_append(str, default_fg.m);
|
||||
}
|
||||
|
||||
*last_fg = default_fg;
|
||||
*last_bg = default_bg;
|
||||
} else if (chr == 'z' || chr == 'Z') {
|
||||
if (chr_is_valid_rgb(*format) == 0) {
|
||||
t = chr == 'z' ? (*last_bg).m : (*last_fg).m;
|
||||
strncpy(t, *format, 7);
|
||||
t[7] = '\0';
|
||||
g_string_append_c(str, '%');
|
||||
g_string_append(str, t);
|
||||
(*format)+=6;
|
||||
} else {
|
||||
g_string_append(str, "%%");
|
||||
g_string_append_c(str, **format);
|
||||
}
|
||||
} else if (chr == 'x' || chr == 'X') {
|
||||
if (chr_is_valid_ext(*format) == 0) {
|
||||
t = chr == 'x' ? (*last_bg).m : (*last_fg).m;
|
||||
strncpy(t, *format, 3);
|
||||
t[3] = '\0';
|
||||
g_string_append_c(str, '%');
|
||||
g_string_append(str, t);
|
||||
(*format)+=2;
|
||||
} else {
|
||||
g_string_append(str, "%%");
|
||||
g_string_append_c(str, **format);
|
||||
}
|
||||
} else {
|
||||
if (IS_FGCOLOR_FORMAT(chr))
|
||||
*last_fg = chr;
|
||||
if (IS_BGCOLOR_FORMAT(chr))
|
||||
*last_bg = chr;
|
||||
if (IS_FGCOLOR_FORMAT(chr)) {
|
||||
(*last_fg).m[0] = chr;
|
||||
(*last_fg).m[1] = '\0';
|
||||
}
|
||||
if (IS_BGCOLOR_FORMAT(chr)) {
|
||||
(*last_bg).m[0] = chr;
|
||||
(*last_bg).m[1] = '\0';
|
||||
}
|
||||
g_string_append_c(str, '%');
|
||||
g_string_append_c(str, chr);
|
||||
}
|
||||
@ -306,7 +363,10 @@ static int data_is_empty(const char **data)
|
||||
char *theme_format_expand_get(THEME_REC *theme, const char **format)
|
||||
{
|
||||
GString *str;
|
||||
char *ret, dummy;
|
||||
char *ret;
|
||||
theme_rm_col dummy, reset;
|
||||
dummy.m[0] = '\0';
|
||||
strcpy(reset.m, "n");
|
||||
int braces = 1; /* we start with one brace opened */
|
||||
|
||||
str = g_string_new(NULL);
|
||||
@ -321,7 +381,7 @@ char *theme_format_expand_get(THEME_REC *theme, const char **format)
|
||||
continue;
|
||||
} else {
|
||||
theme_format_append_next(theme, str, format,
|
||||
'n', 'n',
|
||||
reset, reset,
|
||||
&dummy, &dummy, 0);
|
||||
continue;
|
||||
}
|
||||
@ -343,15 +403,19 @@ char *theme_format_expand_get(THEME_REC *theme, const char **format)
|
||||
/* expand a single {abstract ...data... } */
|
||||
static char *theme_format_expand_abstract(THEME_REC *theme,
|
||||
const char **formatp,
|
||||
char default_fg, char default_bg,
|
||||
theme_rm_col *last_fg,
|
||||
theme_rm_col *last_bg,
|
||||
int flags)
|
||||
{
|
||||
GString *str;
|
||||
const char *p, *format;
|
||||
char *abstract, *data, *ret;
|
||||
theme_rm_col default_fg, default_bg;
|
||||
int len;
|
||||
|
||||
format = *formatp;
|
||||
default_fg = *last_fg;
|
||||
default_bg = *last_bg;
|
||||
|
||||
/* get abstract name first */
|
||||
p = format;
|
||||
@ -425,7 +489,7 @@ static char *theme_format_expand_abstract(THEME_REC *theme,
|
||||
/* abstract may itself contain abstracts or replaces */
|
||||
p = abstract;
|
||||
ret = theme_format_expand_data(theme, &p, default_fg, default_bg,
|
||||
&default_fg, &default_bg,
|
||||
last_fg, last_bg,
|
||||
flags | EXPAND_FLAG_LASTCOLOR_ARG);
|
||||
g_free(abstract);
|
||||
return ret;
|
||||
@ -433,13 +497,13 @@ static char *theme_format_expand_abstract(THEME_REC *theme,
|
||||
|
||||
/* expand the data part in {abstract data} */
|
||||
char *theme_format_expand_data(THEME_REC *theme, const char **format,
|
||||
char default_fg, char default_bg,
|
||||
char *save_last_fg, char *save_last_bg,
|
||||
theme_rm_col default_fg, theme_rm_col default_bg,
|
||||
theme_rm_col *save_last_fg, theme_rm_col *save_last_bg,
|
||||
int flags)
|
||||
{
|
||||
GString *str;
|
||||
char *ret, *abstract;
|
||||
char last_fg, last_bg;
|
||||
theme_rm_col last_fg, last_bg;
|
||||
int recurse_flags;
|
||||
|
||||
last_fg = default_fg;
|
||||
@ -482,7 +546,7 @@ char *theme_format_expand_data(THEME_REC *theme, const char **format,
|
||||
|
||||
/* get a single {...} */
|
||||
abstract = theme_format_expand_abstract(theme, format,
|
||||
last_fg, last_bg,
|
||||
&last_fg, &last_bg,
|
||||
recurse_flags);
|
||||
if (abstract != NULL) {
|
||||
g_string_append(str, abstract);
|
||||
@ -490,13 +554,11 @@ char *theme_format_expand_data(THEME_REC *theme, const char **format,
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & EXPAND_FLAG_LASTCOLOR_ARG) == 0) {
|
||||
/* save the last color */
|
||||
if (save_last_fg != NULL)
|
||||
*save_last_fg = last_fg;
|
||||
if (save_last_bg != NULL)
|
||||
*save_last_bg = last_bg;
|
||||
}
|
||||
|
||||
ret = str->str;
|
||||
g_string_free(str, FALSE);
|
||||
@ -510,7 +572,8 @@ char *theme_format_expand_data(THEME_REC *theme, const char **format,
|
||||
static char *theme_format_compress_colors(THEME_REC *theme, const char *format)
|
||||
{
|
||||
GString *str;
|
||||
char *ret, last_fg, last_bg;
|
||||
char *ret;
|
||||
char last_fg, last_bg;
|
||||
|
||||
str = g_string_new(NULL);
|
||||
|
||||
@ -543,8 +606,12 @@ static char *theme_format_compress_colors(THEME_REC *theme, const char *format)
|
||||
|
||||
if (IS_FGCOLOR_FORMAT(*format))
|
||||
last_fg = *format;
|
||||
else if (*format == 'Z' || *format == 'X')
|
||||
last_fg = '\0';
|
||||
if (IS_BGCOLOR_FORMAT(*format))
|
||||
last_bg = *format;
|
||||
else if (*format == 'z' || *format == 'x')
|
||||
last_bg = '\0';
|
||||
}
|
||||
format++;
|
||||
}
|
||||
@ -558,11 +625,13 @@ static char *theme_format_compress_colors(THEME_REC *theme, const char *format)
|
||||
char *theme_format_expand(THEME_REC *theme, const char *format)
|
||||
{
|
||||
char *data, *ret;
|
||||
theme_rm_col reset;
|
||||
strcpy(reset.m, "n");
|
||||
|
||||
g_return_val_if_fail(theme != NULL, NULL);
|
||||
g_return_val_if_fail(format != NULL, NULL);
|
||||
|
||||
data = theme_format_expand_data(theme, &format, 'n', 'n', NULL, NULL,
|
||||
data = theme_format_expand_data(theme, &format, reset, reset, NULL, NULL,
|
||||
EXPAND_FLAG_ROOT);
|
||||
ret = theme_format_compress_colors(theme, data);
|
||||
g_free(data);
|
||||
@ -944,10 +1013,6 @@ static int theme_read(THEME_REC *theme, const char *path)
|
||||
config_get_int(config, NULL, "default_color", -1);
|
||||
theme->info_eol = config_get_bool(config, NULL, "info_eol", FALSE);
|
||||
|
||||
/* FIXME: remove after 0.7.99 */
|
||||
if (theme->default_color == 0 &&
|
||||
config_get_int(config, NULL, "default_real_color", -1) != -1)
|
||||
theme->default_color = -1;
|
||||
theme_read_replaces(config, theme);
|
||||
|
||||
if (path != NULL)
|
||||
|
@ -57,10 +57,14 @@ void theme_set_default_abstract(const char *key, const char *value);
|
||||
#define EXPAND_FLAG_ROOT 0x10
|
||||
#define EXPAND_FLAG_LASTCOLOR_ARG 0x20
|
||||
|
||||
typedef struct {
|
||||
char m[8];
|
||||
} theme_rm_col;
|
||||
|
||||
char *theme_format_expand(THEME_REC *theme, const char *format);
|
||||
char *theme_format_expand_data(THEME_REC *theme, const char **format,
|
||||
char default_fg, char default_bg,
|
||||
char *save_last_fg, char *save_last_bg,
|
||||
theme_rm_col default_fg, theme_rm_col default_bg,
|
||||
theme_rm_col *save_last_fg, theme_rm_col *save_last_bg,
|
||||
int flags);
|
||||
|
||||
void themes_reload(void);
|
||||
|
@ -29,7 +29,14 @@
|
||||
#include "gui-printtext.h"
|
||||
#include "gui-windows.h"
|
||||
|
||||
int mirc_colors[] = { 15, 0, 1, 2, 12, 4, 5, 6, 14, 10, 3, 11, 9, 13, 8, 7 };
|
||||
int mirc_colors[] = { 15, 0, 1, 2, 12, 4, 5, 6, 14, 10, 3, 11, 9, 13, 8, 7,
|
||||
/* 16-27 */ 52, 94, 100, 58, 22, 29, 23, 24, 17, 54, 53, 89,
|
||||
/* 28-39 */ 88, 130, 142, 64, 28, 35, 30, 25, 18, 91, 90, 125,
|
||||
/* 40-51 */ 124, 166, 184, 106, 34, 49, 37, 33, 19, 129, 127, 161,
|
||||
/* 52-63 */ 196, 208, 226, 154, 46, 86, 51, 75, 21, 171, 201, 198,
|
||||
/* 64-75 */ 203, 215, 227, 191, 83, 122, 87, 111, 63, 177, 207, 205,
|
||||
/* 76-87 */ 217, 223, 229, 193, 157, 158, 159, 153, 147, 183, 219, 212,
|
||||
/* 88-98 */ 16, 233, 235, 237, 239, 241, 244, 247, 250, 254, 231, -1 };
|
||||
static int scrollback_lines, scrollback_time, scrollback_burst_remove;
|
||||
|
||||
static int next_xpos, next_ypos;
|
||||
@ -145,21 +152,39 @@ static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view)
|
||||
|
||||
static void get_colors(int flags, int *fg, int *bg, int *attr)
|
||||
{
|
||||
*attr = 0;
|
||||
if (flags & GUI_PRINT_FLAG_MIRC_COLOR) {
|
||||
/* mirc colors - real range is 0..15, but after 16
|
||||
colors wrap to 0, 1, ... */
|
||||
if (*bg >= 0) *bg = mirc_colors[*bg % 16];
|
||||
if (*fg >= 0) *fg = mirc_colors[*fg % 16];
|
||||
if (settings_get_bool("mirc_blink_fix"))
|
||||
*bg &= ~0x08;
|
||||
/* mirc colors - extended colours proposal */
|
||||
if (*bg >= 0) {
|
||||
*bg = mirc_colors[*bg % 100];
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_BG;
|
||||
if (settings_get_bool("mirc_blink_fix"))
|
||||
*bg = term_color256map[*bg&0xff] & ~0x08;
|
||||
}
|
||||
if (*fg >= 0) {
|
||||
*fg = mirc_colors[*fg % 100];
|
||||
flags &= ~GUI_PRINT_FLAG_COLOR_24_FG;
|
||||
}
|
||||
}
|
||||
|
||||
if (*fg < 0 || *fg > 15)
|
||||
if (flags & GUI_PRINT_FLAG_COLOR_24_FG)
|
||||
*attr |= ATTR_FGCOLOR24;
|
||||
else if (*fg < 0 || *fg > 255) {
|
||||
*fg = -1;
|
||||
if (*bg < 0 || *bg > 15)
|
||||
*bg = -1;
|
||||
*attr |= ATTR_RESETFG;
|
||||
}
|
||||
else
|
||||
*attr |= *fg;
|
||||
|
||||
if (flags & GUI_PRINT_FLAG_COLOR_24_BG)
|
||||
*attr |= ATTR_BGCOLOR24;
|
||||
else if (*bg < 0 || *bg > 255) {
|
||||
*bg = -1;
|
||||
*attr |= ATTR_RESETBG;
|
||||
}
|
||||
else
|
||||
*attr |= (*bg << BG_SHIFT);
|
||||
|
||||
*attr = 0;
|
||||
if (flags & GUI_PRINT_FLAG_REVERSE) *attr |= ATTR_REVERSE;
|
||||
if (flags & GUI_PRINT_FLAG_BOLD) *attr |= ATTR_BOLD;
|
||||
if (flags & GUI_PRINT_FLAG_UNDERLINE) *attr |= ATTR_UNDERLINE;
|
||||
@ -192,9 +217,7 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
|
||||
if (window == NULL) {
|
||||
g_return_if_fail(next_xpos != -1);
|
||||
|
||||
attr |= fg >= 0 ? fg : ATTR_RESETFG;
|
||||
attr |= bg >= 0 ? (bg << 4) : ATTR_RESETBG;
|
||||
term_set_color(root_window, attr);
|
||||
term_set_color2(root_window, attr, fg, bg);
|
||||
|
||||
term_move(root_window, next_xpos, next_ypos);
|
||||
if (flags & GUI_PRINT_FLAG_CLRTOEOL)
|
||||
|
@ -670,6 +670,8 @@ void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only,
|
||||
SERVER_REC *server;
|
||||
WI_ITEM_REC *wiitem;
|
||||
char *tmpstr, *tmpstr2;
|
||||
theme_rm_col reset;
|
||||
strcpy(reset.m, "n");
|
||||
int len;
|
||||
|
||||
if (str == NULL)
|
||||
@ -690,7 +692,7 @@ void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only,
|
||||
|
||||
/* expand templates */
|
||||
tmpstr = theme_format_expand_data(current_theme, &str,
|
||||
'n', 'n',
|
||||
reset, reset,
|
||||
NULL, NULL,
|
||||
EXPAND_FLAG_ROOT |
|
||||
EXPAND_FLAG_IGNORE_REPLACES |
|
||||
|
@ -275,21 +275,25 @@ static int get_attr(int color)
|
||||
{
|
||||
int attr;
|
||||
|
||||
if ((color & FG_MASK) >> 4)
|
||||
color = (color & ~FG_MASK) | term_color256map[color & FG_MASK];
|
||||
if ((color & BG_MASK) >> (BG_SHIFT + 4))
|
||||
color = (color & ~BG_MASK) | (term_color256map[(color & BG_MASK) >> BG_SHIFT] << BG_SHIFT);
|
||||
if (!term_use_colors)
|
||||
attr = (color & 0x70) ? A_REVERSE : 0;
|
||||
else if ((color & 0xff) == 8 || (color & (0xff | ATTR_RESETFG)) == 0)
|
||||
attr = (color & (0x7 << BG_SHIFT)) ? A_REVERSE : 0;
|
||||
else if ((color & ((0xf << BG_SHIFT) | 0xf)) == 8 || (color & (FG_MASK | BG_MASK | ATTR_RESETFG)) == 0)
|
||||
attr = COLOR_PAIR(63);
|
||||
else if ((color & 0x77) == 0)
|
||||
else if ((color & ((0x7 << BG_SHIFT) | 0x7)) == 0)
|
||||
attr = A_NORMAL;
|
||||
else {
|
||||
if (color & ATTR_RESETFG) {
|
||||
color &= ~0x0f;
|
||||
color &= ~FG_MASK;
|
||||
color |= settings_get_int("default_color");
|
||||
}
|
||||
attr = COLOR_PAIR((color&7) | ((color&0x70)>>1));
|
||||
attr = COLOR_PAIR((color&0x7) | ((color&(0x7<<BG_SHIFT))>>BG_SHIFT<<3));
|
||||
}
|
||||
|
||||
if ((color & 0x08) || (color & ATTR_BOLD)) attr |= A_BOLD;
|
||||
if ((color & 0x8) || (color & ATTR_BOLD)) attr |= A_BOLD;
|
||||
if (color & ATTR_BLINK) attr |= A_BLINK;
|
||||
|
||||
if (color & ATTR_UNDERLINE) attr |= A_UNDERLINE;
|
||||
@ -298,6 +302,11 @@ static int get_attr(int color)
|
||||
}
|
||||
|
||||
/* Change active color */
|
||||
void term_set_color2(TERM_WINDOW *window, int col, unsigned int fg_ignore, unsigned int bg_ignore)
|
||||
{
|
||||
term_set_color(window, col);
|
||||
}
|
||||
|
||||
void term_set_color(TERM_WINDOW *window, int col)
|
||||
{
|
||||
wattrset(window->win, get_attr(col));
|
||||
|
@ -22,9 +22,12 @@
|
||||
#include "signals.h"
|
||||
#include "term.h"
|
||||
#include "terminfo-core.h"
|
||||
#include "fe-windows.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* returns number of characters in the beginning of the buffer being a
|
||||
a single character, or -1 if more input is needed. The character will be
|
||||
@ -48,7 +51,8 @@ static int vcmove, vcx, vcy, curs_visible;
|
||||
static int crealx, crealy, cforcemove;
|
||||
static int curs_x, curs_y;
|
||||
|
||||
static int last_fg, last_bg, last_attrs;
|
||||
static unsigned int last_fg, last_bg;
|
||||
static int last_attrs;
|
||||
|
||||
static GSource *sigcont_source;
|
||||
static volatile sig_atomic_t got_sigcont;
|
||||
@ -293,15 +297,44 @@ void term_window_scroll(TERM_WINDOW *window, int count)
|
||||
term_lines_empty[window->y+y] = FALSE;
|
||||
}
|
||||
|
||||
inline static int term_putchar(int c)
|
||||
{
|
||||
return fputc(c, current_term->out);
|
||||
}
|
||||
|
||||
/* copied from terminfo-core.c */
|
||||
int tputs();
|
||||
|
||||
static int term_set_color_24bit(int bg, unsigned int lc)
|
||||
{
|
||||
static char buf[20];
|
||||
const unsigned char color[] = { lc >> 16, lc >> 8, lc };
|
||||
|
||||
if (!term_use_colors24) {
|
||||
if (bg)
|
||||
terminfo_set_bg(color_24bit_256(color));
|
||||
else
|
||||
terminfo_set_fg(color_24bit_256(color));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* \e[x8;2;...;...;...m */
|
||||
sprintf(buf, "\033[%d8;2;%d;%d;%dm", bg ? 4 : 3, color[0], color[1], color[2]);
|
||||
return tputs(buf, 0, term_putchar);
|
||||
}
|
||||
|
||||
#define COLOR_RESET UINT_MAX
|
||||
|
||||
/* Change active color */
|
||||
void term_set_color(TERM_WINDOW *window, int col)
|
||||
void term_set_color2(TERM_WINDOW *window, int col, unsigned int fgcol24, unsigned int bgcol24)
|
||||
{
|
||||
int set_normal;
|
||||
int fg = col & 0x0f;
|
||||
int bg = (col & 0xf0) >> 4;
|
||||
|
||||
set_normal = ((col & ATTR_RESETFG) && last_fg != -1) ||
|
||||
((col & ATTR_RESETBG) && last_bg != -1);
|
||||
unsigned int fg = (col & ATTR_FGCOLOR24) ? fgcol24 << 8 : (col & FG_MASK);
|
||||
unsigned int bg = (col & ATTR_BGCOLOR24) ? bgcol24 << 8 : ((col & BG_MASK) >> BG_SHIFT);
|
||||
|
||||
set_normal = ((col & ATTR_RESETFG) && last_fg != COLOR_RESET) ||
|
||||
((col & ATTR_RESETBG) && last_bg != COLOR_RESET);
|
||||
if (((last_attrs & ATTR_BOLD) && (col & ATTR_BOLD) == 0) ||
|
||||
((last_attrs & ATTR_BLINK) && (col & ATTR_BLINK) == 0)) {
|
||||
/* we'll need to get rid of bold/blink - this can only be
|
||||
@ -310,12 +343,12 @@ void term_set_color(TERM_WINDOW *window, int col)
|
||||
}
|
||||
|
||||
if (set_normal) {
|
||||
last_fg = last_bg = -1;
|
||||
last_fg = last_bg = COLOR_RESET;
|
||||
last_attrs = 0;
|
||||
terminfo_set_normal();
|
||||
}
|
||||
|
||||
if (!term_use_colors && (col & 0xf0) != 0)
|
||||
if (!term_use_colors && bg > 0)
|
||||
col |= ATTR_REVERSE;
|
||||
|
||||
/* reversed text (use standout) */
|
||||
@ -330,12 +363,15 @@ void term_set_color(TERM_WINDOW *window, int col)
|
||||
(fg != 0 || (col & ATTR_RESETFG) == 0)) {
|
||||
if (term_use_colors) {
|
||||
last_fg = fg;
|
||||
terminfo_set_fg(last_fg);
|
||||
if (!(fg & 0xff))
|
||||
term_set_color_24bit(0, last_fg >> 8);
|
||||
else
|
||||
terminfo_set_fg(last_fg);
|
||||
}
|
||||
}
|
||||
|
||||
/* set background color */
|
||||
if (col & 0x80 && window->term->TI_colors == 8)
|
||||
if (window && (term_color256map[bg&0xff]&8) == window->term->TI_colors)
|
||||
col |= ATTR_BLINK;
|
||||
if (col & ATTR_BLINK)
|
||||
current_term->set_blink(current_term);
|
||||
@ -344,12 +380,15 @@ void term_set_color(TERM_WINDOW *window, int col)
|
||||
(bg != 0 || (col & ATTR_RESETBG) == 0)) {
|
||||
if (term_use_colors) {
|
||||
last_bg = bg;
|
||||
terminfo_set_bg(last_bg);
|
||||
if (!(bg & 0xff))
|
||||
term_set_color_24bit(1, last_bg >> 8);
|
||||
else
|
||||
terminfo_set_bg(last_bg);
|
||||
}
|
||||
}
|
||||
|
||||
/* bold */
|
||||
if (col & 0x08 && window->term->TI_colors == 8)
|
||||
if (window && (term_color256map[fg&0xff]&8) == window->term->TI_colors)
|
||||
col |= ATTR_BOLD;
|
||||
if (col & ATTR_BOLD)
|
||||
terminfo_set_bold();
|
||||
@ -361,9 +400,16 @@ void term_set_color(TERM_WINDOW *window, int col)
|
||||
} else if (last_attrs & ATTR_UNDERLINE)
|
||||
terminfo_set_uline(FALSE);
|
||||
|
||||
last_attrs = col & ~0xff;
|
||||
/* update the new attribute settings whilst ignoring color values. */
|
||||
last_attrs = col & ~( BG_MASK | FG_MASK );
|
||||
}
|
||||
|
||||
void term_set_color(TERM_WINDOW *window, int col)
|
||||
{
|
||||
term_set_color2(window, col &~(ATTR_FGCOLOR24|ATTR_BGCOLOR24), UINT_MAX, UINT_MAX);
|
||||
}
|
||||
|
||||
|
||||
void term_move(TERM_WINDOW *window, int x, int y)
|
||||
{
|
||||
if (x >= 0 && y >= 0) {
|
||||
|
@ -37,6 +37,7 @@
|
||||
int term_width, term_height;
|
||||
|
||||
int term_use_colors;
|
||||
int term_use_colors24;
|
||||
int term_type;
|
||||
|
||||
static int force_colors;
|
||||
@ -106,10 +107,28 @@ static void cmd_redraw(void)
|
||||
irssi_redraw();
|
||||
}
|
||||
|
||||
int term_color256map[] = {
|
||||
0, 4, 2, 6, 1, 5, 3, 7, 8,12,10,14, 9,13,11,15,
|
||||
0, 0, 1, 1, 1, 1, 0, 0, 3, 1, 1, 9, 2, 2, 3, 3, 3, 3,
|
||||
2, 2, 3, 3, 3, 3, 2, 2, 3, 3, 3,11,10,10, 3, 3,11,11,
|
||||
0, 0, 5, 1, 1, 9, 0, 8, 8, 8, 9, 9, 2, 8, 8, 8, 9, 9,
|
||||
2, 8, 8, 8, 9, 9, 2, 8, 8, 3, 3,11,10,10, 3, 3,11,11,
|
||||
4, 4, 5, 5, 5, 5, 4, 8, 8, 8, 9, 9, 6, 8, 8, 8, 9, 9,
|
||||
6, 8, 8, 8, 8, 9, 6, 8, 8, 8, 7, 7, 6, 6, 8, 7, 7, 7,
|
||||
4, 4, 5, 5, 5, 5, 4, 8, 8, 8, 9, 9, 6, 8, 8, 8, 8, 9,
|
||||
6, 8, 8, 8, 7, 7, 6, 6, 8, 7, 7, 7, 6, 6, 7, 7, 7, 7,
|
||||
4, 4, 5, 5, 5,13, 4, 8, 8, 5, 5,13, 6, 8, 8, 8, 7, 7,
|
||||
6, 6, 8, 7, 7, 7, 6, 6, 7, 7, 7, 7,14,14, 7, 7, 7, 7,
|
||||
12,12, 5, 5,13,13,12,12, 5, 5,13,13, 6, 6, 8, 7, 7, 7,
|
||||
6, 6, 7, 7, 7, 7,14,14, 7, 7, 7, 7,14,14, 7, 7, 7,15,
|
||||
0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
7, 7, 7, 7, 7, 7, 0 };
|
||||
|
||||
static void read_settings(void)
|
||||
{
|
||||
const char *str;
|
||||
int old_colors = term_use_colors;
|
||||
int old_colors24 = term_use_colors24;
|
||||
int old_type = term_type;
|
||||
|
||||
/* set terminal type */
|
||||
@ -133,7 +152,14 @@ static void read_settings(void)
|
||||
term_use_colors = settings_get_bool("colors") &&
|
||||
(force_colors || term_has_colors());
|
||||
|
||||
if (term_use_colors != old_colors)
|
||||
#ifdef TERM_TRUECOLOR
|
||||
term_use_colors24 = settings_get_bool("colors_ansi_24bit") &&
|
||||
(force_colors || term_has_colors());
|
||||
#else
|
||||
term_use_colors24 = FALSE;
|
||||
#endif
|
||||
|
||||
if (term_use_colors != old_colors || term_use_colors24 != old_colors24)
|
||||
irssi_redraw();
|
||||
}
|
||||
|
||||
@ -149,6 +175,12 @@ void term_common_init(void)
|
||||
|
||||
force_colors = FALSE;
|
||||
term_use_colors = term_has_colors() && settings_get_bool("colors");
|
||||
#ifdef TERM_TRUECOLOR
|
||||
settings_add_bool("lookandfeel", "colors_ansi_24bit", FALSE);
|
||||
term_use_colors24 = term_has_colors() && settings_get_bool("colors_ansi_24bit");
|
||||
#else
|
||||
term_use_colors24 = FALSE;
|
||||
#endif
|
||||
read_settings();
|
||||
|
||||
if (g_get_charset(&dummy)) {
|
||||
|
@ -3,13 +3,19 @@
|
||||
|
||||
typedef struct _TERM_WINDOW TERM_WINDOW;
|
||||
|
||||
#define FG_MASK ( 0x00ff )
|
||||
#define BG_MASK ( 0xff00 )
|
||||
#define BG_SHIFT 8
|
||||
|
||||
/* text attributes */
|
||||
#define ATTR_RESETFG 0x0100
|
||||
#define ATTR_RESETBG 0x0200
|
||||
#define ATTR_BOLD 0x0400
|
||||
#define ATTR_BLINK 0x0800
|
||||
#define ATTR_UNDERLINE 0x1000
|
||||
#define ATTR_REVERSE 0x2000
|
||||
#define ATTR_RESETFG ( 0x010000 )
|
||||
#define ATTR_RESETBG ( 0x020000 )
|
||||
#define ATTR_BOLD ( 0x040000 )
|
||||
#define ATTR_BLINK ( 0x080000 )
|
||||
#define ATTR_UNDERLINE ( 0x100000 )
|
||||
#define ATTR_REVERSE ( 0x200000 )
|
||||
#define ATTR_FGCOLOR24 ( 0x400000 )
|
||||
#define ATTR_BGCOLOR24 ( 0x800000 )
|
||||
|
||||
#define ATTR_RESET (ATTR_RESETFG|ATTR_RESETBG)
|
||||
|
||||
@ -25,6 +31,8 @@ typedef guint32 unichar;
|
||||
extern TERM_WINDOW *root_window;
|
||||
extern int term_width, term_height;
|
||||
extern int term_use_colors, term_type;
|
||||
extern int term_use_colors24;
|
||||
extern int term_color256map[];
|
||||
|
||||
/* Initialize / deinitialize terminal */
|
||||
int term_init(void);
|
||||
@ -63,6 +71,7 @@ void term_window_clear(TERM_WINDOW *window);
|
||||
/* Scroll window up/down */
|
||||
void term_window_scroll(TERM_WINDOW *window, int count);
|
||||
|
||||
void term_set_color2(TERM_WINDOW *window, int col, unsigned int fgcol24, unsigned int bgcol24);
|
||||
void term_set_color(TERM_WINDOW *window, int col);
|
||||
|
||||
void term_move(TERM_WINDOW *window, int x, int y);
|
||||
|
@ -331,16 +331,29 @@ static void _set_standout(TERM_REC *term, int set)
|
||||
tput(tparm(set ? term->TI_smso : term->TI_rmso));
|
||||
}
|
||||
|
||||
inline static int color256(const TERM_REC *term, const int color) {
|
||||
if (color < term->TI_colors)
|
||||
return color;
|
||||
|
||||
if (color < 16)
|
||||
return color % term->TI_colors;
|
||||
|
||||
if (color < 256)
|
||||
return term_color256map[color] % term->TI_colors;
|
||||
|
||||
return color % term->TI_colors;
|
||||
}
|
||||
|
||||
/* Change foreground color */
|
||||
static void _set_fg(TERM_REC *term, int color)
|
||||
{
|
||||
tput(tparm(term->TI_fg[color % term->TI_colors]));
|
||||
tput(tparm(term->TI_fg[color256(term, color)]));
|
||||
}
|
||||
|
||||
/* Change background color */
|
||||
static void _set_bg(TERM_REC *term, int color)
|
||||
{
|
||||
tput(tparm(term->TI_bg[color % term->TI_colors]));
|
||||
tput(tparm(term->TI_bg[color256(term, color)]));
|
||||
}
|
||||
|
||||
/* Beep */
|
||||
|
@ -104,8 +104,8 @@ static void textbuffer_cache_unref(TEXT_BUFFER_CACHE_REC *cache)
|
||||
textbuffer_cache_destroy(cache);
|
||||
}
|
||||
|
||||
#define FGATTR (ATTR_NOCOLORS | ATTR_RESETFG | 0x0f)
|
||||
#define BGATTR (ATTR_NOCOLORS | ATTR_RESETBG | 0xf0)
|
||||
#define FGATTR (ATTR_NOCOLORS | ATTR_RESETFG | FG_MASK | ATTR_FGCOLOR24)
|
||||
#define BGATTR (ATTR_NOCOLORS | ATTR_RESETBG | BG_MASK | ATTR_BGCOLOR24)
|
||||
|
||||
static void update_cmd_color(unsigned char cmd, int *color)
|
||||
{
|
||||
@ -113,14 +113,16 @@ static void update_cmd_color(unsigned char cmd, int *color)
|
||||
if (cmd & LINE_COLOR_BG) {
|
||||
/* set background color */
|
||||
*color &= FGATTR;
|
||||
*color &= ~ATTR_FGCOLOR24;
|
||||
if ((cmd & LINE_COLOR_DEFAULT) == 0)
|
||||
*color |= (cmd & 0x0f) << 4;
|
||||
*color |= (cmd & 0x0f) << BG_SHIFT;
|
||||
else {
|
||||
*color = (*color & FGATTR) | ATTR_RESETBG;
|
||||
}
|
||||
} else {
|
||||
/* set foreground color */
|
||||
*color &= BGATTR;
|
||||
*color &= ~ATTR_BGCOLOR24;
|
||||
if ((cmd & LINE_COLOR_DEFAULT) == 0)
|
||||
*color |= cmd & 0x0f;
|
||||
else {
|
||||
@ -142,10 +144,38 @@ static void update_cmd_color(unsigned char cmd, int *color)
|
||||
break;
|
||||
case LINE_CMD_COLOR0:
|
||||
*color &= BGATTR;
|
||||
*color &= ~ATTR_FGCOLOR24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TERM_TRUECOLOR
|
||||
static void unformat_24bit_line_color(const unsigned char **ptr, int off, int *flags, int *fg, int *bg)
|
||||
{
|
||||
unsigned int color;
|
||||
unsigned char rgbx[4];
|
||||
unsigned int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
rgbx[i] = (*ptr)[i + off];
|
||||
}
|
||||
rgbx[3] -= 0x20;
|
||||
*ptr += 4;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (rgbx[3] & (0x10 << i))
|
||||
rgbx[i] -= 0x20;
|
||||
}
|
||||
color = rgbx[0] << 16 | rgbx[1] << 8 | rgbx[2];
|
||||
if (rgbx[3] & 0x1) {
|
||||
*flags = (*flags & FGATTR) | ATTR_BGCOLOR24;
|
||||
*bg = color;
|
||||
}
|
||||
else {
|
||||
*flags = (*flags & BGATTR) | ATTR_FGCOLOR24;
|
||||
*fg = color;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline unichar read_unichar(const unsigned char *data, const unsigned char **next, int *width)
|
||||
{
|
||||
unichar chr = g_utf8_get_char_validated(data, -1);
|
||||
@ -171,6 +201,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
unsigned char cmd;
|
||||
const unsigned char *ptr, *next_ptr, *last_space_ptr;
|
||||
int xpos, pos, indent_pos, last_space, last_color, color, linecount;
|
||||
int last_bg24, last_fg24, bg24, fg24;
|
||||
int char_width;
|
||||
|
||||
g_return_val_if_fail(line->text != NULL, NULL);
|
||||
@ -204,7 +235,18 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
/* set indentation position here - don't do
|
||||
it if we're too close to right border */
|
||||
if (xpos < view->width-5) indent_pos = xpos;
|
||||
} else
|
||||
} else if (cmd == LINE_COLOR_EXT) {
|
||||
color &= ~ATTR_FGCOLOR24;
|
||||
color = (color & BGATTR) | *ptr++;
|
||||
} else if (cmd == LINE_COLOR_EXT_BG) {
|
||||
color &= ~ATTR_BGCOLOR24;
|
||||
color = (color & FGATTR) | (*ptr++ << BG_SHIFT);
|
||||
}
|
||||
#ifdef TERM_TRUECOLOR
|
||||
else if (cmd == LINE_COLOR_24)
|
||||
unformat_24bit_line_color(&ptr, 0, &color, &fg24, &bg24);
|
||||
#endif
|
||||
else
|
||||
update_cmd_color(cmd, &color);
|
||||
continue;
|
||||
}
|
||||
@ -236,7 +278,7 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
sub = g_new0(LINE_CACHE_SUB_REC, 1);
|
||||
if (last_space > indent_pos && last_space > 10) {
|
||||
/* go back to last space */
|
||||
color = last_color;
|
||||
color = last_color; fg24 = last_fg24; bg24 = last_bg24;
|
||||
ptr = last_space_ptr;
|
||||
while (*ptr == ' ') ptr++;
|
||||
} else if (view->longword_noindent) {
|
||||
@ -249,6 +291,9 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
sub->indent = xpos;
|
||||
sub->indent_func = indent_func;
|
||||
sub->color = color;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
sub->fg24 = fg24; sub->bg24 = bg24;
|
||||
#endif
|
||||
|
||||
lines = g_slist_append(lines, sub);
|
||||
linecount++;
|
||||
@ -260,11 +305,11 @@ view_update_line_cache(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line)
|
||||
if (!view->utf8 && char_width > 1) {
|
||||
last_space = xpos;
|
||||
last_space_ptr = next_ptr;
|
||||
last_color = color;
|
||||
last_color = color; last_fg24 = fg24; last_bg24 = bg24;
|
||||
} else if (*ptr == ' ') {
|
||||
last_space = xpos;
|
||||
last_space_ptr = ptr;
|
||||
last_color = color;
|
||||
last_color = color; last_fg24 = fg24; last_bg24 = bg24;
|
||||
}
|
||||
|
||||
xpos += char_width;
|
||||
@ -342,7 +387,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
const unsigned char *text, *end, *text_newline;
|
||||
unsigned char *tmp;
|
||||
unichar chr;
|
||||
int xpos, color, drawcount, first, need_move, need_clrtoeol, char_width;
|
||||
int xpos, color, fg24, bg24, drawcount, first, need_move, need_clrtoeol, char_width;
|
||||
|
||||
if (view->dirty) /* don't bother drawing anything - redraw is coming */
|
||||
return 0;
|
||||
@ -377,6 +422,10 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
if (indent_func == NULL)
|
||||
xpos = cache->lines[subline-1].indent;
|
||||
color = cache->lines[subline-1].color;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
fg24 = cache->lines[subline-1].fg24;
|
||||
bg24 = cache->lines[subline-1].bg24;
|
||||
#endif
|
||||
} else {
|
||||
indent_func = NULL;
|
||||
}
|
||||
@ -397,7 +446,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
if (need_move || xpos > 0)
|
||||
term_move(view->window, xpos, ypos);
|
||||
|
||||
term_set_color(view->window, color);
|
||||
term_set_color2(view->window, color, fg24, bg24);
|
||||
|
||||
if (subline == cache->count-1) {
|
||||
text_newline = NULL;
|
||||
@ -423,8 +472,17 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
text = tmp;
|
||||
continue;
|
||||
} else {
|
||||
update_cmd_color(*text, &color);
|
||||
term_set_color(view->window, color);
|
||||
if (*text == LINE_COLOR_EXT)
|
||||
color = (color & BGATTR & ~ATTR_FGCOLOR24) | *++text;
|
||||
else if (*text == LINE_COLOR_EXT_BG)
|
||||
color = (color & FGATTR & ~ATTR_BGCOLOR24) | (*++text << BG_SHIFT);
|
||||
#ifdef TERM_TRUECOLOR
|
||||
else if (*text == LINE_COLOR_24)
|
||||
unformat_24bit_line_color(&text, 1, &color, &fg24, &bg24);
|
||||
#endif
|
||||
else
|
||||
update_cmd_color(*text, &color);
|
||||
term_set_color2(view->window, color, fg24, bg24);
|
||||
}
|
||||
text++;
|
||||
continue;
|
||||
@ -455,7 +513,7 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
|
||||
/* low-ascii */
|
||||
term_set_color(view->window, ATTR_RESET|ATTR_REVERSE);
|
||||
term_addch(view->window, (chr & 127)+'A'-1);
|
||||
term_set_color(view->window, color);
|
||||
term_set_color2(view->window, color, fg24, bg24);
|
||||
}
|
||||
}
|
||||
text = end;
|
||||
|
@ -15,6 +15,9 @@ typedef struct {
|
||||
int indent;
|
||||
INDENT_FUNC indent_func;
|
||||
int color;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
int fg24, bg24;
|
||||
#endif
|
||||
|
||||
/* first word in line belong to the end of the last word in
|
||||
previous line */
|
||||
|
@ -39,8 +39,8 @@ TEXT_BUFFER_REC *textbuffer_create(void)
|
||||
|
||||
buffer = g_slice_new0(TEXT_BUFFER_REC);
|
||||
buffer->last_eol = TRUE;
|
||||
buffer->last_fg = LINE_COLOR_DEFAULT;
|
||||
buffer->last_bg = LINE_COLOR_DEFAULT | LINE_COLOR_BG;
|
||||
buffer->last_fg = -1;
|
||||
buffer->last_bg = -1;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -148,6 +148,7 @@ static void text_chunk_append(TEXT_BUFFER_REC *buffer,
|
||||
{
|
||||
TEXT_CHUNK_REC *chunk;
|
||||
int left;
|
||||
int i;
|
||||
|
||||
if (len == 0)
|
||||
return;
|
||||
@ -166,8 +167,12 @@ static void text_chunk_append(TEXT_BUFFER_REC *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
if (left > 0 && data[left-1] == 0)
|
||||
left--; /* don't split the commands */
|
||||
for (i = 5; i > 0; --i) {
|
||||
if (left >= i && data[left-i] == 0) {
|
||||
left -= i; /* don't split the commands */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(chunk->buffer + chunk->pos, data, left);
|
||||
chunk->pos += left;
|
||||
@ -238,26 +243,67 @@ int textbuffer_line_exists_after(LINE_REC *line, LINE_REC *search)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef TERM_TRUECOLOR
|
||||
static void format_24bit_line_color(unsigned char *out, int *pos, int bg, unsigned int color)
|
||||
{
|
||||
unsigned char rgb[] = { color >> 16, color >> 8, color };
|
||||
unsigned char x = bg ? 0x1 : 0;
|
||||
unsigned int i;
|
||||
out[(*pos)++] = LINE_COLOR_24;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (rgb[i] > 0x20)
|
||||
out[(*pos)++] = rgb[i];
|
||||
else {
|
||||
out[(*pos)++] = 0x20 + rgb[i];
|
||||
x |= 0x10 << i;
|
||||
}
|
||||
}
|
||||
out[(*pos)++] = 0x20 + x;
|
||||
}
|
||||
#endif
|
||||
|
||||
void textbuffer_line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line,
|
||||
int fg, int bg, int flags)
|
||||
{
|
||||
unsigned char data[20];
|
||||
unsigned char data[22];
|
||||
int pos;
|
||||
|
||||
/* get the fg & bg command chars */
|
||||
fg = fg < 0 ? LINE_COLOR_DEFAULT : fg & 0x0f;
|
||||
bg = LINE_COLOR_BG | (bg < 0 ? LINE_COLOR_DEFAULT : bg & 0x0f);
|
||||
|
||||
pos = 0;
|
||||
if (fg != buffer->last_fg) {
|
||||
if (fg != buffer->last_fg
|
||||
|| (flags & GUI_PRINT_FLAG_COLOR_24_FG) != (buffer->last_flags & GUI_PRINT_FLAG_COLOR_24_FG)) {
|
||||
buffer->last_fg = fg;
|
||||
data[pos++] = 0;
|
||||
data[pos++] = fg == 0 ? LINE_CMD_COLOR0 : fg;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
if (flags & GUI_PRINT_FLAG_COLOR_24_FG)
|
||||
format_24bit_line_color(data, &pos, 0, fg);
|
||||
else
|
||||
#endif
|
||||
if (fg < 0)
|
||||
data[pos++] = LINE_COLOR_DEFAULT;
|
||||
else if (fg < 16)
|
||||
data[pos++] = fg == 0 ? LINE_CMD_COLOR0 : fg;
|
||||
else if (fg < 256) {
|
||||
data[pos++] = LINE_COLOR_EXT;
|
||||
data[pos++] = fg;
|
||||
}
|
||||
}
|
||||
if (bg != buffer->last_bg) {
|
||||
if (bg != buffer->last_bg
|
||||
|| (flags & GUI_PRINT_FLAG_COLOR_24_BG) != (buffer->last_flags & GUI_PRINT_FLAG_COLOR_24_BG)) {
|
||||
buffer->last_bg = bg;
|
||||
data[pos++] = 0;
|
||||
data[pos++] = bg;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
if (flags & GUI_PRINT_FLAG_COLOR_24_BG)
|
||||
format_24bit_line_color(data, &pos, 1, bg);
|
||||
else
|
||||
#endif
|
||||
if (bg < 0)
|
||||
data[pos++] = LINE_COLOR_BG | LINE_COLOR_DEFAULT;
|
||||
else if (bg < 16)
|
||||
data[pos++] = LINE_COLOR_BG | bg;
|
||||
else if (bg < 256) {
|
||||
data[pos++] = LINE_COLOR_EXT_BG;
|
||||
data[pos++] = bg;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & GUI_PRINT_FLAG_UNDERLINE) != (buffer->last_flags & GUI_PRINT_FLAG_UNDERLINE)) {
|
||||
@ -318,8 +364,8 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after,
|
||||
data[len-2] == 0 && data[len-1] == LINE_CMD_EOL;
|
||||
|
||||
if (buffer->last_eol) {
|
||||
buffer->last_fg = LINE_COLOR_DEFAULT;
|
||||
buffer->last_bg = LINE_COLOR_DEFAULT | LINE_COLOR_BG;
|
||||
buffer->last_fg = -1;
|
||||
buffer->last_bg = -1;
|
||||
buffer->last_flags = 0;
|
||||
}
|
||||
|
||||
@ -427,10 +473,17 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str)
|
||||
|
||||
if (!coloring) {
|
||||
/* no colors, skip coloring commands */
|
||||
if (cmd == LINE_COLOR_EXT || cmd == LINE_COLOR_EXT_BG)
|
||||
ptr++;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
else if (cmd == LINE_COLOR_24)
|
||||
ptr+=4;
|
||||
#endif
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cmd & 0x80) == 0) {
|
||||
if ((cmd & LINE_CMD_EOL) == 0) {
|
||||
/* set color */
|
||||
set_color(str, cmd);
|
||||
} else switch (cmd) {
|
||||
@ -456,6 +509,17 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str)
|
||||
g_string_append_printf(str, "\004%c",
|
||||
FORMAT_STYLE_INDENT);
|
||||
break;
|
||||
case LINE_COLOR_EXT:
|
||||
format_ext_color(str, 0, *ptr++);
|
||||
break;
|
||||
case LINE_COLOR_EXT_BG:
|
||||
format_ext_color(str, 1, *ptr++);
|
||||
break;
|
||||
#ifdef TERM_TRUECOLOR
|
||||
case LINE_COLOR_24:
|
||||
g_string_append_printf(str, "\004%c", FORMAT_COLOR_24);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,11 @@ enum {
|
||||
LINE_CMD_INDENT, /* if line is split, indent it at this position */
|
||||
LINE_CMD_BLINK, /* enable/disable blink */
|
||||
LINE_CMD_BOLD, /* enable/disable bold */
|
||||
LINE_COLOR_EXT, /* extended color */
|
||||
LINE_COLOR_EXT_BG, /* extended bg */
|
||||
#ifdef TERM_TRUECOLOR
|
||||
LINE_COLOR_24, /* 24bit color */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -241,8 +241,11 @@ PPCODE:
|
||||
if (flags == 0) {
|
||||
ret = theme_format_expand(theme, format);
|
||||
} else {
|
||||
ret = theme_format_expand_data(theme, (const char **) &format, 'n', 'n',
|
||||
NULL, NULL, EXPAND_FLAG_ROOT | flags);
|
||||
theme_rm_col reset;
|
||||
strcpy(reset.m, "n");
|
||||
ret = theme_format_expand_data(theme, (const char **) &format,
|
||||
reset, reset, NULL, NULL,
|
||||
EXPAND_FLAG_ROOT | flags);
|
||||
}
|
||||
XPUSHs(sv_2mortal(new_pv(ret)));
|
||||
g_free_not_null(ret);
|
||||
|
Loading…
Reference in New Issue
Block a user