diff --git a/src/common.h b/src/common.h index bb246962..37fee02f 100644 --- a/src/common.h +++ b/src/common.h @@ -39,6 +39,10 @@ #endif #include + +/* TODO: wrap this in some autoconf macro bullocks? */ +#include + #ifdef HAVE_GMODULE # include #endif diff --git a/src/core/session.c b/src/core/session.c index b3002632..6fdaa186 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); - fprintf(stderr, "exec failed: %s: %s\n", + g_message( "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 dce6890e..4c5fbb84 100644 --- a/src/fe-common/core/fe-common-core.c +++ b/src/fe-common/core/fe-common-core.c @@ -55,6 +55,9 @@ 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); @@ -120,13 +123,26 @@ 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 }, + { "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" + }, + { NULL } }; @@ -143,6 +159,9 @@ 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"); @@ -243,6 +262,10 @@ 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, @@ -257,17 +280,24 @@ 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 (windows == NULL) - fprintf(stderr, "GLib %s: %s\n", reason, message); - else { - printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, - TXT_GLIB_ERROR, reason, message); + 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); } + /* 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 9249f432..98245a59 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); - fprintf(stderr, "Exec: /bin/sh: %s\n", g_strerror(errno)); + g_message( "Exec: /bin/sh: %s\n", g_strerror(errno)); } else { args = g_strsplit(cmd, " ", -1); execvp(args[0], args); - fprintf(stderr, "Exec: %s: %s\n", args[0], g_strerror(errno)); + g_message( "Exec: %s: %s\n", args[0], g_strerror(errno)); } _exit(-1); diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index f2a82030..2b331fa8 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -66,6 +66,8 @@ 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,9 +105,20 @@ static void format_expand_code(const char **format, GString *out, int *flags) 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. */ + unsigned char accum = 0; + int tmp, i; + + //memset(num_buf, 0, 4); + fmt = **format; + + g_message( "format_expand_styles: fmtchar: %c\n", fmt); + switch (fmt) { case '{': case '}': @@ -121,6 +134,7 @@ 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; @@ -162,6 +176,46 @@ int format_expand_styles(GString *out, const char **format, int *flags) /* code */ 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; + default: /* check if it's a background color */ p = strchr(format_backs, fmt); @@ -169,6 +223,8 @@ 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; } @@ -176,6 +232,7 @@ 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); @@ -187,15 +244,16 @@ 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 FALSE; + return 0; } - return TRUE; + return retval; } void format_read_arglist(va_list va, FORMAT_REC *format, @@ -303,6 +361,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,11 +372,13 @@ 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 > 1) { continue; } + } /* %% or unknown %code, written as-is */ if (*str != '%') @@ -340,7 +401,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,11 +412,13 @@ 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 > 1) { continue; } + } /* %% or unknown %code, written as-is */ if (*str != '%') { @@ -376,8 +439,11 @@ 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; g_return_val_if_fail(text != NULL, NULL); @@ -388,10 +454,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 +484,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 +492,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 == '$') { @@ -830,10 +903,14 @@ 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, @@ -936,7 +1013,10 @@ 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++) { @@ -958,12 +1038,17 @@ 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') { @@ -978,12 +1063,12 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) switch (type) { - case 2: + case MIRC_BOLD_MARKER: /* bold */ if (!hide_text_style) flags ^= GUI_PRINT_FLAG_BOLD; break; - case 3: + case MIRC_COLOR_MARKER: /* MIRC color */ get_mirc_color((const char **) &ptr, hide_colors ? NULL : &fgcolor, @@ -991,7 +1076,7 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) if (!hide_colors) flags |= GUI_PRINT_FLAG_MIRC_COLOR; break; - case 4: + case LINE_FORMAT_MARKER: /* user specific colors */ flags &= ~GUI_PRINT_FLAG_MIRC_COLOR; switch (*ptr) { @@ -1003,7 +1088,12 @@ 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; diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 6c55a068..56412937 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -4,6 +4,12 @@ #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 diff --git a/src/fe-common/core/printtext.c b/src/fe-common/core/printtext.c index d3653f90..1ac4e4de 100644 --- a/src/fe-common/core/printtext.c +++ b/src/fe-common/core/printtext.c @@ -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,7 +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++) { if (*str != '%') { @@ -283,9 +287,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; } } diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 76b116d8..556fae1b 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -146,24 +146,43 @@ static void remove_old_lines(TEXT_BUFFER_VIEW_REC *view) static void get_colors(int flags, int *fg, int *bg, int *attr) { 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; } - if (*fg < 0 || *fg > 15) + if (*fg < 0 || *fg > 255) { + g_message( "getcolor: fg %d outside range, setting to -1\n", *fg); *fg = -1; - if (*bg < 0 || *bg > 15) + } + if (*bg < 0 || *bg > 255) { + g_message( "getcolor: bf %d outside range, setting to -1\n", *bg); *bg = -1; + } *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; - if (flags & GUI_PRINT_FLAG_BLINK) *attr |= ATTR_BLINK; + 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"); + } } static void view_add_eol(TEXT_BUFFER_VIEW_REC *view, LINE_REC **line) @@ -184,16 +203,32 @@ 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 << 4) : ATTR_RESETBG; + 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_move(root_window, next_xpos, next_ypos); diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 9dfc0db4..0b27f452 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -293,75 +293,116 @@ void term_window_scroll(TERM_WINDOW *window, int count) term_lines_empty[window->y+y] = FALSE; } -/* Change active color */ void term_set_color(TERM_WINDOW *window, int col) { 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); - if (((last_attrs & ATTR_BOLD) && (col & ATTR_BOLD) == 0) || - ((last_attrs & ATTR_BLINK) && (col & ATTR_BLINK) == 0)) { + int fg = (col & FG_MASK); + int bg = (col & BG_MASK) >> 8; +// int attrs = (col & 0xff0000) >> 16; + + 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); + } + + set_normal = ((col & ATTR_RESETFG) && last_fg != ATTR_COLOR_UNDEFINED) || + ((col & ATTR_RESETBG) && last_bg != ATTR_COLOR_UNDEFINED); + + if (((last_attrs & ATTR_BOLD) && !(col & ATTR_BOLD)) || + ((last_attrs & ATTR_BLINK) && !(col & ATTR_BLINK))) { /* 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 = -1; + last_fg = last_bg = ATTR_COLOR_UNDEFINED; 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 (!term_use_colors && (col & 0xf0) != 0) + /* if colors are disabled, any background color setting enables + * reverse video mode + */ + + if (!term_use_colors && bg > 0) { col |= ATTR_REVERSE; + } /* reversed text (use standout) */ if (col & ATTR_REVERSE) { - if ((last_attrs & ATTR_REVERSE) == 0) + if ((last_attrs & ATTR_REVERSE) == 0) { + g_message( "setreverse: on\n"); terminfo_set_standout(TRUE); - } else if (last_attrs & ATTR_REVERSE) + } + } else if (last_attrs & ATTR_REVERSE) { + g_message( "setreverse: off\n"); 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); } } /* set background color */ - if (col & 0x80 && window->term->TI_colors == 8) + /* TODO: What magic numbers? - originally 0xf0 - 11110000 + * + */ + if (col & 0x8000 && window->term->TI_colors == 8) { + g_message( "0x080 match: setting attr_bold\n"); col |= ATTR_BLINK; - if (col & ATTR_BLINK) - current_term->set_blink(current_term); + } - if (bg != last_bg && - (bg != 0 || (col & ATTR_RESETBG) == 0)) { + if (col & ATTR_BLINK) { + g_message( "setblink\n"); + current_term->set_blink(current_term); + } + + 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); } } /* bold */ - if (col & 0x08 && window->term->TI_colors == 8) + + /* 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"); col |= ATTR_BOLD; - if (col & ATTR_BOLD) + } + + if (col & ATTR_BOLD) { + g_message("setbold\n"); 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); + } - last_attrs = col & ~0xff; + /* update the new attribute settings whilst ignoring color values. */ + last_attrs = col & ~( BG_MASK | FG_MASK ); } void term_move(TERM_WINDOW *window, int x, int y) diff --git a/src/fe-text/term.h b/src/fe-text/term.h index 27174c83..5a40d4b2 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -4,12 +4,29 @@ typedef struct _TERM_WINDOW TERM_WINDOW; /* 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 FG_MASK ( 0x00ff ) +#define BG_MASK ( 0xff00 ) + +#define ATTR_RESETFG ( 0x010000 ) +#define ATTR_RESETBG ( 0x020000 ) +#define ATTR_BOLD ( 0x040000 ) +#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_RESET (ATTR_RESETFG|ATTR_RESETBG) @@ -65,6 +82,8 @@ void term_window_scroll(TERM_WINDOW *window, int count); 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 bddc93e1..753cf928 100644 --- a/src/fe-text/terminfo-core.c +++ b/src/fe-text/terminfo-core.c @@ -519,19 +519,19 @@ static int term_setup(TERM_REC *term) term_env = getenv("TERM"); if (term_env == NULL) { - fprintf(stderr, "TERM environment not set\n"); + g_message( "TERM environment not set\n"); return 0; } #ifdef HAVE_TERMINFO if (setupterm(term_env, 1, &err) != 0) { - fprintf(stderr, "setupterm() failed for TERM=%s: %d\n", term_env, err); + g_message( "setupterm() failed for TERM=%s: %d\n", term_env, err); return 0; } #else if (tgetent(term->buffer1, term_env) < 1) { - fprintf(stderr, "Termcap not found for TERM=%s\n", term_env); + g_message( "Termcap not found for TERM=%s\n", term_env); return 0; } #endif @@ -544,7 +544,7 @@ static int term_setup(TERM_REC *term) else if (term->TI_hpa && term->TI_vpa) term->move = _move_pa; else { - fprintf(stderr, "Terminal doesn't support cursor movement\n"); + g_message( "Terminal doesn't support cursor movement\n"); return 0; } term->move_relative = _move_relative; @@ -561,7 +561,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) { - fprintf(stderr, "Terminal doesn't support scrolling\n"); + g_message( "Terminal doesn't support scrolling\n"); return 0; } @@ -578,7 +578,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 */ - fprintf(stderr, "Terminal doesn't support clearing screen\n"); + g_message( "Terminal doesn't support clearing screen\n"); return 0; } @@ -586,7 +586,7 @@ static int term_setup(TERM_REC *term) if (term->TI_el) term->clrtoeol = _clrtoeol; else { - fprintf(stderr, "Terminal doesn't support clearing to end of line\n"); + g_message( "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 9e2b76d5..cd851198 100644 --- a/src/fe-text/terminfo-core.h +++ b/src/fe-text/terminfo-core.h @@ -16,6 +16,8 @@ #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 c19b9af7..78509151 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -104,46 +104,63 @@ 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 | 0xff) +#define BGATTR (ATTR_NOCOLORS | ATTR_RESETBG | 0xff00) static void update_cmd_color(unsigned char cmd, int *color) { - if ((cmd & 0x80) == 0) { - if (cmd & LINE_COLOR_BG) { - /* set background color */ - *color &= FGATTR; - if ((cmd & LINE_COLOR_DEFAULT) == 0) - *color |= (cmd & 0x0f) << 4; - else { - *color = (*color & FGATTR) | ATTR_RESETBG; - } - } else { - /* set foreground color */ - *color &= BGATTR; - if ((cmd & LINE_COLOR_DEFAULT) == 0) - *color |= cmd & 0x0f; - else { - *color = (*color & BGATTR) | ATTR_RESETFG; - } - } - } else switch (cmd) { + 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) { + 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"); break; } + } else { + if (next_color_bg == 1) { + *color = cmd << 8; + } else { + *color = cmd; + } + } } static inline unichar read_unichar(const unsigned char *data, const unsigned char **next, int *width) @@ -356,6 +373,7 @@ 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) { @@ -394,9 +412,11 @@ 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); if (subline == cache->count-1) { @@ -424,6 +444,9 @@ static int view_line_draw(TEXT_BUFFER_VIEW_REC *view, LINE_REC *line, continue; } else { update_cmd_color(*text, &color); + g_message( "post update_cmd_color: 0x%08x\n", + color); + term_set_color(view->window, color); } text++; @@ -453,8 +476,12 @@ 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); } } diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index 69f5969c..35f52a16 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -242,47 +242,80 @@ void textbuffer_line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line, int fg, int bg, int flags) { unsigned char data[20]; - int pos; + memset(data, 0, 20); + int pos = 0; + int i = 0; /* 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); + /* 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); + + /* 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); - pos = 0; if (fg != buffer->last_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]); + } if (bg != buffer->last_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]); + } 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]); + } - if (pos > 0) + 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"); *line = textbuffer_insert(buffer, *line, data, pos, NULL); + } buffer->last_flags = flags; } @@ -323,6 +356,9 @@ LINE_REC *textbuffer_insert(TEXT_BUFFER_REC *buffer, LINE_REC *insert_after, buffer->last_flags = 0; } + g_message( "line created: '%s' %d\n", line->text, line->info.time); + g_message( "Buffer %p\n", buffer); + return line; } @@ -377,18 +413,22 @@ void textbuffer_remove_all_lines(TEXT_BUFFER_REC *buffer) static void set_color(GString *str, int cmd) { - int color = -1; + int color = ATTR_COLOR_UNDEFINED; if (!(cmd & LINE_COLOR_DEFAULT)) - color = (cmd & 0x0f)+'0'; + color = (cmd & 0xff) + '0'; + + g_message( "textbuffer.c:set_color color: %d (%02x)\n", color, color); if ((cmd & LINE_COLOR_BG) == 0) { /* change foreground color */ - g_string_append_printf(str, "\004%c%c", + g_string_append_printf(str, "%c%c%c", + LINE_FORMAT_MARKER, color, FORMAT_COLOR_NOCHANGE); } else { /* change background color */ - g_string_append_printf(str, "\004%c%c", + g_string_append_printf(str, "%c%c%c", + LINE_FORMAT_MARKER, FORMAT_COLOR_NOCHANGE, color); } } @@ -430,6 +470,9 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str) continue; } + /* these magic numbers correspond with some of IS_COLOR_CODE in + * formats.c:843 (31 and 22) */ + if ((cmd & 0x80) == 0) { /* set color */ set_color(str, cmd); diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index e5d78487..a94a06af 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -8,15 +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 + }; typedef struct { @@ -24,6 +29,7 @@ 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. @@ -38,6 +44,28 @@ 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;