summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--configure.ac16
-rw-r--r--docs/formats.txt2
-rw-r--r--irssi.conf1
-rw-r--r--src/common.h4
-rw-r--r--src/core/session.c2
-rw-r--r--src/fe-common/core/fe-common-core.c52
-rw-r--r--src/fe-common/core/fe-exec.c4
-rw-r--r--src/fe-common/core/fe-windows.c57
-rw-r--r--src/fe-common/core/fe-windows.h2
-rw-r--r--src/fe-common/core/formats.c412
-rw-r--r--src/fe-common/core/formats.h19
-rw-r--r--src/fe-common/core/printtext.c11
-rw-r--r--src/fe-common/core/themes.c121
-rw-r--r--src/fe-common/core/themes.h8
-rw-r--r--src/fe-text/gui-printtext.c88
-rw-r--r--src/fe-text/statusbar.c4
-rw-r--r--src/fe-text/term-curses.c21
-rw-r--r--src/fe-text/term-terminfo.c135
-rw-r--r--src/fe-text/term.c34
-rw-r--r--src/fe-text/term.h26
-rw-r--r--src/fe-text/terminfo-core.c31
-rw-r--r--src/fe-text/terminfo-core.h2
-rw-r--r--src/fe-text/textbuffer-view.c147
-rw-r--r--src/fe-text/textbuffer-view.h3
-rw-r--r--src/fe-text/textbuffer.c153
-rw-r--r--src/fe-text/textbuffer.h33
-rw-r--r--src/perl/ui/Themes.xs7
28 files changed, 904 insertions, 493 deletions
diff --git a/AUTHORS b/AUTHORS
index 50f24ac4..aa4624c6 100644
--- a/AUTHORS
+++ b/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)
diff --git a/configure.ac b/configure.ac
index d409be36..04c50b4b 100644
--- a/configure.ac
+++ b/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."
diff --git a/docs/formats.txt b/docs/formats.txt
index 0ffef08f..2a507a04 100644
--- a/docs/formats.txt
+++ b/docs/formats.txt
@@ -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.
diff --git a/irssi.conf b/irssi.conf
index a92cdaff..c9817eae 100644
--- a/irssi.conf
+++ b/irssi.conf
@@ -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";
diff --git a/src/common.h b/src/common.h
index 37fee02f..bb246962 100644
--- a/src/common.h
+++ b/src/common.h
@@ -39,10 +39,6 @@
#endif
#include <glib.h>
-
-/* TODO: wrap this in some autoconf macro bullocks? */
-#include <glib/gstdio.h>
-
#ifdef HAVE_GMODULE
# include <gmodule.h>
#endif
diff --git a/src/core/session.c b/src/core/session.c
index 6fdaa186..b3002632 100644
--- a/src/core/session.c
+++ b/src/core/session.c
@@ -51,7 +51,7 @@ void session_upgrade(void)
return;
execv(session_args[0], session_args);
- g_message( "exec failed: %s: %s\n",
+ fprintf(stderr, "exec failed: %s: %s\n",
session_args[0], g_strerror(errno));
}
diff --git a/src/fe-common/core/fe-common-core.c b/src/fe-common/core/fe-common-core.c
index 4c5fbb84..dce6890e 100644
--- a/src/fe-common/core/fe-common-core.c
+++ b/src/fe-common/core/fe-common-core.c
@@ -55,9 +55,6 @@ static int no_autoconnect;
static char *cmdline_nick;
static char *cmdline_hostname;
-static char *irssi_logfile = NULL;
-static FILE * logfile_FILE = NULL;
-
void fe_core_log_init(void);
void fe_core_log_deinit(void);
@@ -123,26 +120,13 @@ static void sig_channel_destroyed(CHANNEL_REC *channel)
void fe_common_core_register_options(void)
{
- static GOptionEntry options[]
- = {
- { "connect", 'c', 0, G_OPTION_ARG_STRING, &autocon_server,
- "Automatically connect to server/network", "SERVER"
- },
- { "password", 'w', 0, G_OPTION_ARG_STRING, &autocon_password,
- "Autoconnect password", "PASSWORD"
- },
- { "port", 'p', 0, G_OPTION_ARG_INT, &autocon_port,
- "Autoconnect port", "PORT" },
- { "noconnect", '!', 0, G_OPTION_ARG_NONE, &no_autoconnect,
- "Disable autoconnecting", NULL },
+ static GOptionEntry options[] = {
+ { "connect", 'c', 0, G_OPTION_ARG_STRING, &autocon_server, "Automatically connect to server/network", "SERVER" },
+ { "password", 'w', 0, G_OPTION_ARG_STRING, &autocon_password, "Autoconnect password", "PASSWORD" },
+ { "port", 'p', 0, G_OPTION_ARG_INT, &autocon_port, "Autoconnect port", "PORT" },
+ { "noconnect", '!', 0, G_OPTION_ARG_NONE, &no_autoconnect, "Disable autoconnecting", NULL },
{ "nick", 'n', 0, G_OPTION_ARG_STRING, &cmdline_nick, "Specify nick to use", NULL },
- { "hostname", 'h', 0, G_OPTION_ARG_STRING, &cmdline_hostname,
- "Specify host name to use", NULL },
- { "logfile", 0, 0, G_OPTION_ARG_FILENAME, &irssi_logfile,
- "Logfile to write debugging data which would otherwise be printed " \
- "to STDERR or as Irssi internal messages", "PATH"
- },
-
+ { "hostname", 'h', 0, G_OPTION_ARG_STRING, &cmdline_hostname, "Specify host name to use", NULL },
{ NULL }
};
@@ -159,9 +143,6 @@ void fe_common_core_init(void)
{
const char *str;
- logfile_FILE = g_fopen(irssi_logfile, "a");
- if (logfile_FILE == NULL) irssi_logfile = NULL;
-
settings_add_bool("lookandfeel", "timestamps", TRUE);
settings_add_level("lookandfeel", "timestamp_level", "ALL");
settings_add_time("lookandfeel", "timestamp_timeout", "0");
@@ -262,10 +243,6 @@ void fe_common_core_deinit(void)
signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
signal_remove("channel created", (SIGNAL_FUNC) sig_channel_created);
signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
-
- if (irssi_logfile && logfile_FILE) {
- fclose(logfile_FILE);
- }
}
void glog_func(const char *log_domain, GLogLevelFlags log_level,
@@ -280,24 +257,17 @@ void glog_func(const char *log_domain, GLogLevelFlags log_level,
case G_LOG_LEVEL_CRITICAL:
reason = "critical";
break;
- case G_LOG_LEVEL_MESSAGE:
- reason = "msg";
- break;
default:
reason = "error";
break;
}
- if (irssi_logfile != NULL && logfile_FILE != NULL) {
- fprintf(logfile_FILE, "GLib: %s: %s", reason, message);
- fflush(logfile_FILE);
- } else { // if (windows == NULL)
- fprintf(stderr, "GLib %s: %s", reason, message);
+ if (windows == NULL)
+ fprintf(stderr, "GLib %s: %s\n", reason, message);
+ else {
+ printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
+ TXT_GLIB_ERROR, reason, message);
}
- /* else { */
- /* printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, */
- /* TXT_GLIB_ERROR, reason, message); */
- /* } */
}
#define MSGS_WINDOW_LEVELS (MSGLEVEL_MSGS|MSGLEVEL_ACTIONS|MSGLEVEL_DCCMSGS)
diff --git a/src/fe-common/core/fe-exec.c b/src/fe-common/core/fe-exec.c
index 98245a59..9249f432 100644
--- a/src/fe-common/core/fe-exec.c
+++ b/src/fe-common/core/fe-exec.c
@@ -348,12 +348,12 @@ static void process_exec(PROCESS_REC *rec, const char *cmd)
if (rec->shell) {
execvp(shell_args[0], (char **) shell_args);
- g_message( "Exec: /bin/sh: %s\n", g_strerror(errno));
+ fprintf(stderr, "Exec: /bin/sh: %s\n", g_strerror(errno));
} else {
args = g_strsplit(cmd, " ", -1);
execvp(args[0], args);
- g_message( "Exec: %s: %s\n", args[0], g_strerror(errno));
+ fprintf(stderr, "Exec: %s: %s\n", args[0], g_strerror(errno));
}
_exit(-1);
diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c
index aa5ea397..bf9d7154 100644
--- a/src/fe-common/core/fe-windows.c
+++ b/src/fe-common/core/fe-windows.c
@@ -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;
diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h
index 58c316ef..613f15f8 100644
--- a/src/fe-common/core/fe-windows.h
+++ b/src/fe-common/core/fe-windows.h
@@ -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
diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c
index 2b331fa8..770caaa1 100644
--- a/src/fe-common/core/formats.c
+++ b/src/fe-common/core/formats.c
@@ -66,8 +66,6 @@ static void format_expand_code(const char **format, GString *out, int *flags)
{
int set;
- g_message( "format_expand_codes()\n");
-
if (flags == NULL) {
/* flags are being ignored - skip the code */
while (**format != ']')
@@ -103,22 +101,89 @@ 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;
+ int retval = 1;
char *p, fmt;
/* storage for numerical parsing code for %x/X formats. */
- unsigned char accum = 0;
- int tmp, i;
-
- //memset(num_buf, 0, 4);
+ int tmp;
+ unsigned int tmp2;
fmt = **format;
-
- g_message( "format_expand_styles: fmtchar: %c\n", fmt);
-
switch (fmt) {
case '{':
case '}':
@@ -134,7 +199,6 @@ int format_expand_styles(GString *out, const char **format, int *flags)
case '9':
case '_':
/* bold on/off */
- g_message( "setting bold flag: %04x\n", FORMAT_STYLE_BOLD);
g_string_append_c(out, 4);
g_string_append_c(out, FORMAT_STYLE_BOLD);
break;
@@ -177,45 +241,61 @@ int format_expand_styles(GString *out, const char **format, int *flags)
format_expand_code(format, out, flags);
break;
case 'x':
- tmp = 0;
- accum = 0;
- for (i = 1; i < 3; i++) {
- char fmtchar = (*format)[i];
- g_message("Format X: code: %c\n", fmtchar);
- tmp = g_ascii_xdigit_value(fmtchar);
- if (tmp != -1) {
- accum = accum * 16 + tmp;
- }
- }
- retval += i - 1;
-
- g_string_append_c(out, 4);
- g_string_append_c(out, FORMAT_COLOR_NOCHANGE);
- g_string_append_c(out, accum);
-
- g_message("Format x: code: %d (0x%02x)\n", accum, accum);
-
- break;
case 'X':
- tmp = 0;
- accum = 0;
- for (i = 1; i < 3; i++) {
- char fmtchar = (*format)[i];
- g_message("Format X: code: %c\n", fmtchar);
- tmp = g_ascii_xdigit_value(fmtchar);
- if (tmp != -1) {
- accum = accum * 16 + tmp;
- }
- }
- g_string_append_c(out, 4);
- g_string_append_c(out, accum);
- g_string_append_c(out, FORMAT_COLOR_NOCHANGE);
- retval += i - 1;
-
- g_message("Format X: code: %d (0x%02x)\n", accum, accum);
-
- break;
+ 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);
@@ -223,8 +303,6 @@ int format_expand_styles(GString *out, const char **format, int *flags)
g_string_append_c(out, 4);
g_string_append_c(out, FORMAT_COLOR_NOCHANGE);
g_string_append_c(out, (char) ((int) (p-format_backs)+'0'));
- g_message( "BG: Printing: %d '%s'\n",
- ((int) (p-format_backs)+'0'), out->str);
break;
}
@@ -232,7 +310,6 @@ int format_expand_styles(GString *out, const char **format, int *flags)
if (fmt == 'p') fmt = 'm';
p = strchr(format_fores, fmt);
if (p != NULL) {
- /* color code indicator for format_send_to_gui */
g_string_append_c(out, 4);
g_string_append_c(out, (char) ((int) (p-format_fores)+'0'));
g_string_append_c(out, FORMAT_COLOR_NOCHANGE);
@@ -244,13 +321,12 @@ int format_expand_styles(GString *out, const char **format, int *flags)
p = strchr(format_boldfores, fmt);
if (p != NULL) {
g_string_append_c(out, 4);
- /* +8 selects bold version */
g_string_append_c(out, (char) (8+(int) (p-format_boldfores)+'0'));
g_string_append_c(out, FORMAT_COLOR_NOCHANGE);
break;
}
- return 0;
+ return FALSE;
}
return retval;
@@ -375,10 +451,9 @@ int format_get_length(const char *str)
if (*str != '%') {
adv = format_expand_styles(tmp, &str, NULL);
str += adv;
- if (adv > 1) {
+ if (adv)
continue;
}
- }
/* %% or unknown %code, written as-is */
if (*str != '%')
@@ -415,10 +490,9 @@ int format_real_length(const char *str, int len)
if (*str != '%') {
adv = format_expand_styles(tmp, &str, NULL);
str += adv;
- if (adv > 1) {
+ if (adv)
continue;
}
- }
/* %% or unknown %code, written as-is */
if (*str != '%') {
@@ -439,8 +513,6 @@ int format_real_length(const char *str, int len)
char *format_string_expand(const char *text, int *flags)
{
- g_message( "format_string_expand: flags: %04x\n", *flags);
-
GString *out;
char code, *ret;
int adv;
@@ -454,13 +526,13 @@ char *format_string_expand(const char *text, int *flags)
while (*text != '\0') {
if (code == '%') {
/* color code */
- adv = format_expand_styles(out, &text, flags);
- if (!adv) {
+ 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;
+ } else {
+ text += adv - 1;
}
code = 0;
} else {
@@ -492,13 +564,13 @@ static char *format_get_text_args(TEXT_DEST_REC *dest,
while (*text != '\0') {
if (code == '%') {
/* color code */
- adv = format_expand_styles(out, &text, &dest->flags);
- if (!adv) {
+ 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;
+ } else {
+ text += adv - 1;
}
code = 0;
} else if (code == '$') {
@@ -789,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;
@@ -822,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;
}
@@ -903,14 +1083,10 @@ static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret)
if (bg_ret) *bg_ret = bg;
}
-/* TODO: What are these magic numbers!?
- */
#define IS_COLOR_CODE(c) \
((c) == 2 || (c) == 3 || (c) == 4 || (c) == 6 || (c) == 7 || \
(c) == 15 || (c) == 22 || (c) == 27 || (c) == 31)
-//#define IS_COLOR_CODE(c) ((c) < 255)
-
/* Return how many characters in `str' must be skipped before `len'
characters of text is skipped. */
int strip_real_length(const char *str, int len,
@@ -935,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);
@@ -984,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;
}
@@ -1013,10 +1211,7 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
dup = str = g_strdup(text);
- flags = 0;
- fgcolor = theme->default_color;
- bgcolor = -1;
-
+ flags = 0; fgcolor = theme->default_color; bgcolor = -1;
while (*str != '\0') {
type = '\0';
for (ptr = str; *ptr != '\0'; ptr++) {
@@ -1038,17 +1233,12 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
if (*str != '\0' || (flags & GUI_PRINT_FLAG_CLRTOEOL)) {
/* send the text to gui handler */
- g_message("format_send_to_gui: sending: fg: 0x%04x, " \
- "bg: 0x%04x flags: 0x%04x\n", fgcolor, bgcolor, flags);
-
signal_emit_id(signal_gui_print_text, 6, dest->window,
GINT_TO_POINTER(fgcolor),
GINT_TO_POINTER(bgcolor),
GINT_TO_POINTER(flags), str,
dest);
-
flags &= ~(GUI_PRINT_FLAG_INDENT|GUI_PRINT_FLAG_CLRTOEOL);
- /* fprintf("format_send_to_gui: resetting flags: 0x%04x\n", flags); */
}
if (type == '\n') {
@@ -1063,12 +1253,12 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
switch (type)
{
- case MIRC_BOLD_MARKER:
+ case 2:
/* bold */
if (!hide_text_style)
flags ^= GUI_PRINT_FLAG_BOLD;
break;
- case MIRC_COLOR_MARKER:
+ case 3:
/* MIRC color */
get_mirc_color((const char **) &ptr,
hide_colors ? NULL : &fgcolor,
@@ -1076,7 +1266,7 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
if (!hide_colors)
flags |= GUI_PRINT_FLAG_MIRC_COLOR;
break;
- case LINE_FORMAT_MARKER:
+ case 4:
/* user specific colors */
flags &= ~GUI_PRINT_FLAG_MIRC_COLOR;
switch (*ptr) {
@@ -1088,12 +1278,7 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text)
break;
case FORMAT_STYLE_BOLD:
flags ^= GUI_PRINT_FLAG_BOLD;
- g_message(
- "format bold spotted, flags now: 0x%04x\n",
- flags);
-
break;
-
case FORMAT_STYLE_REVERSE:
flags ^= GUI_PRINT_FLAG_REVERSE;
break;
@@ -1110,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++;
diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h
index 56412937..037aa424 100644
--- a/src/fe-common/core/formats.h
+++ b/src/fe-common/core/formats.h
@@ -4,12 +4,6 @@
#include "themes.h"
#include "fe-windows.h"
-/* various types of colour codings possible. */
-#define MIRC_BOLD_MARKER ('\002')
-#define MIRC_COLOR_MARKER ('\003')
-#define LINE_FORMAT_MARKER ('\004')
-
-
#define GUI_PRINT_FLAG_BOLD 0x0001
#define GUI_PRINT_FLAG_REVERSE 0x0002
#define GUI_PRINT_FLAG_UNDERLINE 0x0004
@@ -19,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
@@ -127,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)
@@ -138,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);
diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c
index 1ac4e4de..a5eaa38f 100644
--- a/src/fe-common/core/printtext.c
+++ b/src/fe-common/core/printtext.c
@@ -256,12 +256,12 @@ static char *printtext_get_args(TEXT_DEST_REC *dest, const char *str,
break;
}
default:
- adv = format_expand_styles(out, &str, &dest->flags);
- if (!adv) {
+ 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;
+ } else {
+ str += adv - 1;
}
break;
}
@@ -277,6 +277,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++) {
if (*str != '%') {
@@ -292,7 +293,7 @@ static char *printtext_expand_formats(const char *str, int *flags)
g_string_append_c(out, '%');
g_string_append_c(out, *str);
} else {
- str += adv -1;
+ str += adv - 1;
}
}
diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c
index 548836ac..d92d23fe 100644
--- a/src/fe-common/core/themes.c
+++ b/src/fe-common/core/themes.c
@@ -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)
diff --git a/src/fe-common/core/themes.h b/src/fe-common/core/themes.h
index dcdea0fc..31cfe943 100644
--- a/src/fe-common/core/themes.h
+++ b/src/fe-common/core/themes.h
@@ -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);
diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c
index 556fae1b..380ca114 100644
--- a/src/fe-text/gui-printtext.c
+++ b/src/fe-text/gui-printtext.c
@@ -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,44 +152,43 @@ 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) {
- g_message( "getcolor: handling mirc colors\n");
-
- /* 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];
- /* TODO: What to do here? */
- 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 > 255) {
- g_message( "getcolor: fg %d outside range, setting to -1\n", *fg);
+ if (flags & GUI_PRINT_FLAG_COLOR_24_FG)
+ *attr |= ATTR_FGCOLOR24;
+ else if (*fg < 0 || *fg > 255) {
*fg = -1;
+ *attr |= ATTR_RESETFG;
}
- if (*bg < 0 || *bg > 255) {
- g_message( "getcolor: bf %d outside range, setting to -1\n", *bg);
+ 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;
- g_message( "getcolor: setting flag_reverse\n");
- }
- if (flags & GUI_PRINT_FLAG_BOLD) {
- *attr |= ATTR_BOLD;
- g_message( "getcolor: setting flag_bold\n");
- }
- if (flags & GUI_PRINT_FLAG_UNDERLINE) {
- *attr |= ATTR_UNDERLINE;
- g_message( "getcolor: setting flag_underline\n");
- }
- if (flags & GUI_PRINT_FLAG_BLINK) {
- *attr |= ATTR_BLINK;
- g_message( "getcolor: setting flag_blink\n");
- }
+ 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;
+ if (flags & GUI_PRINT_FLAG_BLINK) *attr |= ATTR_BLINK;
}
static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line)
@@ -203,33 +209,15 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
LINE_INFO_REC lineinfo;
int fg, bg, flags, attr;
- attr = 0;
-
flags = GPOINTER_TO_INT(pflags);
fg = GPOINTER_TO_INT(fgcolor);
bg = GPOINTER_TO_INT(bgcolor);
-
- g_message( "SGPT str: '%s'\n", str);
-
-
- g_message( "SGPT start: fg: %d (%02x), bg: %d (%02x) attr: %d (%04x), flags: %d (0x%04x)\n",
- fg, fg, bg, bg, attr, attr, flags, flags);
-
get_colors(flags, &fg, &bg, &attr);
- g_message( "SGPT getcol: fg: %d (%02x), bg: %d (%02x) attr: %d (%04x)\n",
- fg, fg, (bg << 8), (bg << 8), attr, attr);
-
if (window == NULL) {
g_return_if_fail(next_xpos != -1);
- attr |= fg >= 0 ? fg : ATTR_RESETFG;
- attr |= bg >= 0 ? (bg << 8) : ATTR_RESETBG;
- g_message(
- "SGPT nowin: fg: %d (%02x), bg: %d (%02x) attr: %d (%04x)\n",
- fg, fg, (bg << 8), (bg << 8), attr, attr);
-
- 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)
diff --git a/src/fe-text/statusbar.c b/src/fe-text/statusbar.c
index 68724293..5453c2d5 100644
--- a/src/fe-text/statusbar.c
+++ b/src/fe-text/statusbar.c
@@ -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 |
diff --git a/src/fe-text/term-curses.c b/src/fe-text/term-curses.c
index fc674fd3..f1ee3131 100644
--- a/src/fe-text/term-curses.c
+++ b/src/fe-text/term-curses.c
@@ -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));
diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c
index 0b27f452..2ca2f347 100644
--- a/src/fe-text/term-terminfo.c
+++ b/src/fe-text/term-terminfo.c
@@ -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,118 +297,119 @@ void term_window_scroll(TERM_WINDOW *window, int count)
term_lines_empty[window->y+y] = FALSE;
}
-void term_set_color(TERM_WINDOW *window, int col)
+inline static int term_putchar(int c)
{
- int set_normal;
+ 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);
+}
- int fg = (col & FG_MASK);
- int bg = (col & BG_MASK) >> 8;
-// int attrs = (col & 0xff0000) >> 16;
+#define COLOR_RESET UINT_MAX
- if (col != ATTR_RESET) {
- g_message( "T-TI: set color called with col: %d (%08x)\n", col, col);
- g_message( "T-TI: fg: %d (0x%02x), bg: %d (0x%02x)\n", fg, fg, bg, bg);
- } else {
- //g_message( "T-TI: set color called with col: %d (%08x)\n", col, col);
- }
+/* Change active color */
+void term_set_color2(TERM_WINDOW *window, int col, unsigned int fgcol24, unsigned int bgcol24)
+{
+ int set_normal;
- set_normal = ((col & ATTR_RESETFG) && last_fg != ATTR_COLOR_UNDEFINED) ||
- ((col & ATTR_RESETBG) && last_bg != ATTR_COLOR_UNDEFINED);
+ unsigned int fg = (col & ATTR_FGCOLOR24) ? fgcol24 << 8 : (col & FG_MASK);
+ unsigned int bg = (col & ATTR_BGCOLOR24) ? bgcol24 << 8 : ((col & BG_MASK) >> BG_SHIFT);
- if (((last_attrs & ATTR_BOLD) && !(col & ATTR_BOLD)) ||
- ((last_attrs & ATTR_BLINK) && !(col & ATTR_BLINK))) {
+ 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
done with setting the default color */
set_normal = TRUE;
}
if (set_normal) {
- last_fg = last_bg = ATTR_COLOR_UNDEFINED;
+ last_fg = last_bg = COLOR_RESET;
last_attrs = 0;
- g_message( "setnormal: setting last_* to 0%04x\n", last_fg);
terminfo_set_normal();
- /* terminfo_set_bg(123); */
- //terminfo_set_fg(47);
}
- /* if colors are disabled, any background color setting enables
- * reverse video mode
- */
-
- if (!term_use_colors && bg > 0) {
+ if (!term_use_colors && bg > 0)
col |= ATTR_REVERSE;
- }
/* reversed text (use standout) */
if (col & ATTR_REVERSE) {
- if ((last_attrs & ATTR_REVERSE) == 0) {
- g_message( "setreverse: on\n");
+ if ((last_attrs & ATTR_REVERSE) == 0)
terminfo_set_standout(TRUE);
- }
- } else if (last_attrs & ATTR_REVERSE) {
- g_message( "setreverse: off\n");
+ } else if (last_attrs & ATTR_REVERSE)
terminfo_set_standout(FALSE);
- }
/* set foreground color */
- if (fg != last_fg && (fg != 0 || (col & ATTR_RESETFG) == 0)) {
+ if (fg != last_fg &&
+ (fg != 0 || (col & ATTR_RESETFG) == 0)) {
if (term_use_colors) {
last_fg = fg;
- terminfo_set_fg(last_fg);
- g_message( "setfg: setting fg to %d (0x%04x)\n", fg, fg);
+ if (!(fg & 0xff))
+ term_set_color_24bit(0, last_fg >> 8);
+ else
+ terminfo_set_fg(last_fg);
}
}
/* set background color */
- /* TODO: What magic numbers? - originally 0xf0 - 11110000
- *
- */
- if (col & 0x8000 && window->term->TI_colors == 8) {
- g_message( "0x080 match: setting attr_bold\n");
+ if (window && (term_color256map[bg&0xff]&8) == window->term->TI_colors)
col |= ATTR_BLINK;
- }
-
- if (col & ATTR_BLINK) {
- g_message( "setblink\n");
+ if (col & ATTR_BLINK)
current_term->set_blink(current_term);
- }
- if (bg != last_bg && (bg != 0 || (col & ATTR_RESETBG) == 0)) {
+ if (bg != last_bg &&
+ (bg != 0 || (col & ATTR_RESETBG) == 0)) {
if (term_use_colors) {
last_bg = bg;
- terminfo_set_bg(last_bg);
- g_message( "setbg: setting bg to %d (0x%04x)\n", bg, bg);
+ if (!(bg & 0xff))
+ term_set_color_24bit(1, last_bg >> 8);
+ else
+ terminfo_set_bg(last_bg);
}
}
/* bold */
-
- /* TODO: maybe make this fg > 7, since that implies a bright
- * color,which bold can emulate.
- */
- if (fg > 0 && window->term->TI_colors == 8) {
- g_message( "0x080 match: setting attr_bold\n");
+ if (window && (term_color256map[fg&0xff]&8) == window->term->TI_colors)
col |= ATTR_BOLD;
- }
-
- if (col & ATTR_BOLD) {
- g_message("setbold\n");
+ if (col & ATTR_BOLD)
terminfo_set_bold();
- }
/* underline */
if (col & ATTR_UNDERLINE) {
- if ((last_attrs & ATTR_UNDERLINE) == 0) {
+ if ((last_attrs & ATTR_UNDERLINE) == 0)
terminfo_set_uline(TRUE);
- }
- } else if (last_attrs & ATTR_UNDERLINE) {
+ } else if (last_attrs & ATTR_UNDERLINE)
terminfo_set_uline(FALSE);
- }
- /* update the new attribute settings whilst ignoring color values. */
- last_attrs = col & ~( BG_MASK | FG_MASK );
+ /* 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) {
diff --git a/src/fe-text/term.c b/src/fe-text/term.c
index 38239016..4600f02e 100644
--- a/src/fe-text/term.c
+++ b/src/fe-text/term.c
@@ -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)) {
diff --git a/src/fe-text/term.h b/src/fe-text/term.h
index 5a40d4b2..e5f66644 100644
--- a/src/fe-text/term.h
+++ b/src/fe-text/term.h
@@ -3,30 +3,19 @@
typedef struct _TERM_WINDOW TERM_WINDOW;
-/* text attributes */
-
-
#define FG_MASK ( 0x00ff )
#define BG_MASK ( 0xff00 )
+#define BG_SHIFT 8
+/* text attributes */
#define ATTR_RESETFG ( 0x010000 )
#define ATTR_RESETBG ( 0x020000 )
#define ATTR_BOLD ( 0x040000 )
-#define ATTR_BLINK ( 0x080000 )
+#define ATTR_BLINK ( 0x080000 )
#define ATTR_UNDERLINE ( 0x100000 )
#define ATTR_REVERSE ( 0x200000 )
-
-/* can also mean default color, probably. */
-#define ATTR_COLOR_UNDEFINED ( -1 )
-
-#define EXT_COLOR_BLACK ( 0 )
-#define EXT_COLOR_RED ( 1 )
-#define EXT_COLOR_GREEN ( 2 )
-#define EXT_COLOR_YELLOW ( 3 )
-#define EXT_COLOR_BLUE ( 4 )
-#define EXT_COLOR_MAGENTA ( 5 )
-#define EXT_COLOR_CYAN ( 6 )
-#define EXT_COLOR_WHITE ( 7 )
+#define ATTR_FGCOLOR24 ( 0x400000 )
+#define ATTR_BGCOLOR24 ( 0x800000 )
#define ATTR_RESET (ATTR_RESETFG|ATTR_RESETBG)
@@ -42,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);
@@ -80,10 +71,9 @@ 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_set_extended_color(TERM_WINDOW *window, int fg, int bg);
-
void term_move(TERM_WINDOW *window, int x, int y);
void term_addch(TERM_WINDOW *window, char chr);
void term_add_unichar(TERM_WINDOW *window, unichar chr);
diff --git a/src/fe-text/terminfo-core.c b/src/fe-text/terminfo-core.c
index 753cf928..ba9256b4 100644
--- a/src/fe-text/terminfo-core.c
+++ b/src/fe-text/terminfo-core.c
@@ -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 */
@@ -519,19 +532,19 @@ static int term_setup(TERM_REC *term)
term_env = getenv("TERM");
if (term_env == NULL) {
- g_message( "TERM environment not set\n");
+ fprintf(stderr, "TERM environment not set\n");
return 0;
}
#ifdef HAVE_TERMINFO
if (setupterm(term_env, 1, &err) != 0) {
- g_message( "setupterm() failed for TERM=%s: %d\n", term_env, err);
+ fprintf(stderr, "setupterm() failed for TERM=%s: %d\n", term_env, err);
return 0;
}
#else
if (tgetent(term->buffer1, term_env) < 1)
{
- g_message( "Termcap not found for TERM=%s\n", term_env);
+ fprintf(stderr, "Termcap not found for TERM=%s\n", term_env);
return 0;
}
#endif
@@ -544,7 +557,7 @@ static int term_setup(TERM_REC *term)
else if (term->TI_hpa && term->TI_vpa)
term->move = _move_pa;
else {
- g_message( "Terminal doesn't support cursor movement\n");
+ fprintf(stderr, "Terminal doesn't support cursor movement\n");
return 0;
}
term->move_relative = _move_relative;
@@ -561,7 +574,7 @@ static int term_setup(TERM_REC *term)
else if (term->scroll == NULL && (term->TI_il1 && term->TI_dl1))
term->scroll = _scroll_line_1;
else if (term->scroll == NULL) {
- g_message( "Terminal doesn't support scrolling\n");
+ fprintf(stderr, "Terminal doesn't support scrolling\n");
return 0;
}
@@ -578,7 +591,7 @@ static int term_setup(TERM_REC *term)
/* we could do this by line inserts as well, but don't
bother - if some terminal has insert line it most probably
has delete line as well, if not a regular clear screen */
- g_message( "Terminal doesn't support clearing screen\n");
+ fprintf(stderr, "Terminal doesn't support clearing screen\n");
return 0;
}
@@ -586,7 +599,7 @@ static int term_setup(TERM_REC *term)
if (term->TI_el)
term->clrtoeol = _clrtoeol;
else {
- g_message( "Terminal doesn't support clearing to end of line\n");
+ fprintf(stderr, "Terminal doesn't support clearing to end of line\n");
return 0;
}
diff --git a/src/fe-text/terminfo-core.h b/src/fe-text/terminfo-core.h
index cd851198..9e2b76d5 100644
--- a/src/fe-text/terminfo-core.h
+++ b/src/fe-text/terminfo-core.h
@@ -16,8 +16,6 @@
#define terminfo_set_bold() current_term->set_bold(current_term)
#define terminfo_set_uline(set) current_term->set_uline(current_term, set)
#define terminfo_set_standout(set) current_term->set_standout(current_term, set)
-// new
-#define terminfo_set_blink() current_term->set_blink(current_term)
#define terminfo_is_colors_set(term) (term->TI_fg != NULL)
#define terminfo_beep(term) current_term->beep(current_term)
diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c
index 78509151..81deaf54 100644
--- a/src/fe-text/textbuffer-view.c
+++ b/src/fe-text/textbuffer-view.c
@@ -104,65 +104,78 @@ static void textbuffer_cache_unref(TEXT_BUFFER_CACHE_REC *cache)
textbuffer_cache_destroy(cache);
}
-#define FGATTR (ATTR_NOCOLORS | ATTR_RESETFG | 0xff)
-#define BGATTR (ATTR_NOCOLORS | ATTR_RESETBG | 0xff00)
+#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)
{
- static int next_color_bg = 0;
- g_message( "update_cmd_color() color: 0x%08x, cmd: 0x%08x\n", *color, cmd);
-
- if (cmd & 0x80) { /* cmd message */
- switch (cmd) {
-
+ if ((cmd & 0x80) == 0) {
+ if (cmd & LINE_COLOR_BG) {
+ /* set background color */
+ *color &= FGATTR;
+ *color &= ~ATTR_FGCOLOR24;
+ if ((cmd & LINE_COLOR_DEFAULT) == 0)
+ *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 {
+ *color = (*color & BGATTR) | ATTR_RESETFG;
+ }
+ }
+ } else switch (cmd) {
case LINE_CMD_UNDERLINE:
*color ^= ATTR_UNDERLINE;
- g_message( "update_cmd_color() toggle underline 0x%08d\n", *color);
-
break;
case LINE_CMD_REVERSE:
-
*color ^= ATTR_REVERSE;
- g_message( "update_cmd_color() toggle reverse 0x%08d\n", *color);
-
break;
case LINE_CMD_BLINK:
-
*color ^= ATTR_BLINK;
- g_message( "update_cmd_color() toggle blink 0x%08d\n", *color);
-
break;
case LINE_CMD_BOLD:
-
*color ^= ATTR_BOLD;
- g_message( "update_cmd_color() toggle bold 0x%08d\n", *color);
-
break;
case LINE_CMD_COLOR0:
*color &= BGATTR;
- g_message( "update_cmd_color() set BGATTR RESET 0x%08d\n", *color);
-
- break;
- case LINE_CMD_SELECT_FG:
- next_color_bg = 0;
- g_message( "update_cmd_color() Next color will be FG\n");
-
- break;
-
- case LINE_CMD_SELECT_BG:
- next_color_bg = 1;
- g_message( "update_cmd_color() Next color will be BG\n");
+ *color &= ~ATTR_FGCOLOR24;
break;
}
- } else {
- if (next_color_bg == 1) {
- *color = cmd << 8;
- } else {
- *color = cmd;
- }
- }
}
+#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);
@@ -188,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);
@@ -221,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;
}
@@ -253,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) {
@@ -266,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++;
@@ -277,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;
@@ -359,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;
@@ -373,7 +401,6 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
xpos = drawcount = 0; first = TRUE;
text_newline = text =
subline == 0 ? line->text : cache->lines[subline-1].start;
- g_message( "view_line_draw()\n");
for (;;) {
if (text == text_newline) {
if (need_clrtoeol && xpos < term_width) {
@@ -395,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;
}
@@ -412,12 +443,10 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
xpos = indent_func(view, line, ypos);
}
- if (need_move || xpos > 0) {
+ if (need_move || xpos > 0)
term_move(view->window, xpos, ypos);
- }
- g_message( "view_line_draw(): color: 0x%08x\n", color);
- term_set_color(view->window, color);
+ term_set_color2(view->window, color, fg24, bg24);
if (subline == cache->count-1) {
text_newline = NULL;
@@ -443,11 +472,17 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
text = tmp;
continue;
} else {
- update_cmd_color(*text, &color);
- g_message( "post update_cmd_color: 0x%08x\n",
- 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;
@@ -476,13 +511,9 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line,
term_addch(view->window, *text);
} else {
/* low-ascii */
- g_message( "printing inverse char %c\n",
- (chr & 127)+'A'-1);
term_set_color(view->window, ATTR_RESET|ATTR_REVERSE);
term_addch(view->window, (chr & 127)+'A'-1);
- g_message( "setting color back to: 0x%08x\n",
- color);
- term_set_color(view->window, color);
+ term_set_color2(view->window, color, fg24, bg24);
}
}
text = end;
diff --git a/src/fe-text/textbuffer-view.h b/src/fe-text/textbuffer-view.h
index 46da808e..48cba093 100644
--- a/src/fe-text/textbuffer-view.h
+++ b/src/fe-text/textbuffer-view.h
@@ -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 */
diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c
index 35f52a16..ad1b06f6 100644
--- a/src/fe-text/textbuffer.c
+++ b/src/fe-text/textbuffer.c
@@ -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,84 +243,92 @@ 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];
- memset(data, 0, 20);
-
- int pos = 0;
- int i = 0;
- /* get the fg & bg command chars */
- /* TODO: These things are adding additional data to colours. */
- g_message( "TBLAC1: fg: 0x%08x, bg: 0x%08x, flags: 0x%08x, last_flags: 0x%08x\n",
- fg, bg, flags, buffer->last_flags);
+ unsigned char data[22];
+ int pos;
- /* fg = fg < 0 ? LINE_COLOR_DEFAULT : fg & 0xff; */
- /* bg = LINE_COLOR_BG | (bg < 0 ? LINE_COLOR_DEFAULT : bg & 0xff); */
- g_message( "TBLAC2: fg: 0x%02x, bg: 0x%02x\n", fg, bg);
-
- if (fg != buffer->last_fg) {
+ pos = 0;
+ 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++] = LINE_CMD_SELECT_FG;
- data[pos++] = 0;
- data[pos++] = fg == 0 ? LINE_CMD_COLOR0 : fg;
- g_message( "TBLAC2: fg: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]);
-
+#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++] = LINE_CMD_SELECT_BG;
- data[pos++] = 0;
- data[pos++] = bg;
- g_message( "TBLAC2: bg: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]);
-
+#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)) {
data[pos++] = 0;
data[pos++] = LINE_CMD_UNDERLINE;
- g_message( "TBLAC2: underline: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]);
-
}
if ((flags & GUI_PRINT_FLAG_REVERSE) != (buffer->last_flags & GUI_PRINT_FLAG_REVERSE)) {
data[pos++] = 0;
data[pos++] = LINE_CMD_REVERSE;
- g_message( "TBLAC2: reverse: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]);
-
}
if ((flags & GUI_PRINT_FLAG_BLINK) != (buffer->last_flags & GUI_PRINT_FLAG_BLINK)) {
data[pos++] = 0;
data[pos++] = LINE_CMD_BLINK;
- g_message( "TBLAC2: blink: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]);
-
}
if ((flags & GUI_PRINT_FLAG_BOLD) != (buffer->last_flags & GUI_PRINT_FLAG_BOLD)) {
data[pos++] = 0;
data[pos++] = LINE_CMD_BOLD;
- g_message( "TBLAC2: bold: data[%d}=%d(0x%02x)\n", pos,data[pos-1],data[pos-1]);
-
}
if (flags & GUI_PRINT_FLAG_INDENT) {
data[pos++] = 0;
data[pos++] = LINE_CMD_INDENT;
- g_message( "TBLAC2: indent: data[%d}=%d(0x%02x)\n", pos-1,data[pos-1],data[pos-1]);
-
}
- g_message( "TBLAC data:\n");
-
- for (i=0; i < 20; i++) {
- g_message( "%02x\n", data[i]);
- }
- g_message( "\n");
-
- if (pos > 0) {
- g_message( "calling textbuffer_insert()\n");
+ if (pos > 0)
*line = textbuffer_insert(buffer, *line, data, pos, NULL);
- }
buffer->last_flags = flags;
}
@@ -351,14 +364,11 @@ 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;
}
- g_message( "line created: '%s' %d\n", line->text, line->info.time);
- g_message( "Buffer %p\n", buffer);
-
return line;
}
@@ -413,22 +423,18 @@ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer)
static void set_color(GString *str, int cmd)
{
- int color = ATTR_COLOR_UNDEFINED;
+ int color = -1;
if (!(cmd & LINE_COLOR_DEFAULT))
- color = (cmd & 0xff) + '0';
-
- g_message( "textbuffer.c:set_color color: %d (%02x)\n", color, color);
+ color = (cmd & 0x0f)+'0';
if ((cmd & LINE_COLOR_BG) == 0) {
/* change foreground color */
- g_string_append_printf(str, "%c%c%c",
- LINE_FORMAT_MARKER,
+ g_string_append_printf(str, "\004%c%c",
color, FORMAT_COLOR_NOCHANGE);
} else {
/* change background color */
- g_string_append_printf(str, "%c%c%c",
- LINE_FORMAT_MARKER,
+ g_string_append_printf(str, "\004%c%c",
FORMAT_COLOR_NOCHANGE, color);
}
}
@@ -467,13 +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;
}
- /* these magic numbers correspond with some of IS_COLOR_CODE in
- * formats.c:843 (31 and 22) */
-
- if ((cmd & 0x80) == 0) {
+ if ((cmd & LINE_CMD_EOL) == 0) {
/* set color */
set_color(str, cmd);
} else switch (cmd) {
@@ -499,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
}
}
}
diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h
index a94a06af..6123ba7a 100644
--- a/src/fe-text/textbuffer.h
+++ b/src/fe-text/textbuffer.h
@@ -8,20 +8,20 @@
#define LINE_COLOR_BG 0x20
#define LINE_COLOR_DEFAULT 0x10
-/* command values (see _LINE_REC protocol) */
enum {
LINE_CMD_EOL=0x80, /* line ends here */
LINE_CMD_CONTINUE, /* line continues in next block */
- /* TODO: no longer needed */
LINE_CMD_COLOR0, /* change to black, would be same as \0\0 but it breaks things.. */
LINE_CMD_UNDERLINE, /* enable/disable underlining */
LINE_CMD_REVERSE, /* enable/disable reversed text */
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_CMD_SELECT_FG,
- LINE_CMD_SELECT_BG
-
+ LINE_COLOR_EXT, /* extended color */
+ LINE_COLOR_EXT_BG, /* extended bg */
+#ifdef TERM_TRUECOLOR
+ LINE_COLOR_24, /* 24bit color */
+#endif
};
typedef struct {
@@ -29,7 +29,6 @@ typedef struct {
time_t time;
} LINE_INFO_REC;
-/* TODO: fixme. */
typedef struct _LINE_REC {
/* Text in the line. \0 means that the next char will be a
color or command.
@@ -44,28 +43,6 @@ typedef struct _LINE_REC {
DO NOT ADD BLACK WITH \0\0 - this will break things. Use
LINE_CMD_COLOR0 instead. */
-
-
- /* NEW COLOUR PROTOCOL:
-
- 0x00 - indicates command or colour.
- 0x01 - command follows (1 byte)
- -- following may be omitted if LINE_CMD_USE_DEFAULT_[FB}G is set.
- 0x02 - BG colour follows (1 byte)
- 0x04 - FG colour follows (1 byte)
-
-
- Things that will need to be fixed:
-
- * textbuffer-view.c:update_cmd_color()
- * textbuffer-view.c:view_line_draw()
- * textbuffer-view.c:view_update_line_cache()
-
- * textbuffer.c:textbuffer_line2text()
- * textbuffer.c:mark_temp_eol macro
-
- * gui-printtext.c ?
- */
struct _LINE_REC *prev, *next;
unsigned char *text;
diff --git a/src/perl/ui/Themes.xs b/src/perl/ui/Themes.xs
index dc5f6272..ab7c1909 100644
--- a/src/perl/ui/Themes.xs
+++ b/src/perl/ui/Themes.xs
@@ -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);