diff --git a/src/bfu/style.c b/src/bfu/style.c index bc0434a4..bd853fde 100644 --- a/src/bfu/style.c +++ b/src/bfu/style.c @@ -38,7 +38,7 @@ get_bfu_color(struct terminal *term, const char *stylename) if (!term) return NULL; - color_mode = get_opt_int_tree(term->spec, "colors", NULL); + color_mode = get_color_mode(term->spec); if (!bfu_colors) { /* Initialize the style hash. */ diff --git a/src/config/options.c b/src/config/options.c index 721876f5..311d8366 100644 --- a/src/config/options.c +++ b/src/config/options.c @@ -38,6 +38,9 @@ #include "terminal/color.h" #include "terminal/screen.h" #include "terminal/terminal.h" +#ifdef CONFIG_TERMINFO +#include "terminal/terminfo.h" +#endif #include "util/color.h" #include "util/error.h" #include "util/memory.h" @@ -1421,3 +1424,44 @@ get_default_protocol(void) { return get_opt_str("protocol.default_protocol", NULL); } + +color_mode_T +get_color_mode(struct option *term_spec) +{ +#ifdef CONFIG_TERMINFO + if (get_cmd_opt_bool("terminfo")) { + int max_colors = terminfo_max_colors(); + color_mode_T color_mode = COLOR_MODE_16; + + switch (max_colors) { + case 88: +#ifdef CONFIG_88_COLORS + color_mode = COLOR_MODE_88; +#endif + break; + + case 256: +#ifdef CONFIG_256_COLORS + color_mode = COLOR_MODE_256; +#endif + break; + + case 16: + case 8: + break; + default: +#ifdef CONFIG_TRUE_COLOR + if (max_colors > 256) { + color_mode = COLOR_MODE_TRUE_COLOR; + } else +#endif + { + color_mode = COLOR_MODE_MONO; + } + break; + } + return color_mode; + } +#endif + return get_opt_int_tree(term_spec, "colors", NULL); +} diff --git a/src/config/options.h b/src/config/options.h index 5c7c8261..9ce063fe 100644 --- a/src/config/options.h +++ b/src/config/options.h @@ -2,6 +2,7 @@ #define EL__CONFIG_OPTIONS_H #include "main/object.h" +#include "terminal/color.h" #include "util/color.h" #include "util/lists.h" #include "util/memory.h" @@ -569,6 +570,8 @@ int get_https_by_default(void); const char *get_default_protocol(void); +color_mode_T get_color_mode(struct option *term_spec); + #ifdef __cplusplus } #endif diff --git a/src/document/renderer.cpp b/src/document/renderer.cpp index 29fa7d01..6010f531 100644 --- a/src/document/renderer.cpp +++ b/src/document/renderer.cpp @@ -501,8 +501,8 @@ render_document_frames(struct session *ses, int no_cache) if (ses->status.show_tabs_bar_at_top) doc_opts.box.y++; } - doc_opts.color_mode = get_opt_int_tree(ses->tab->term->spec, "colors", - NULL); + doc_opts.color_mode = get_color_mode(ses->tab->term->spec); + if (!get_opt_bool_tree(ses->tab->term->spec, "underline", NULL)) doc_opts.color_flags |= COLOR_ENHANCE_UNDERLINE; diff --git a/src/terminal/draw.c b/src/terminal/draw.c index 440be328..de4e6256 100644 --- a/src/terminal/draw.c +++ b/src/terminal/draw.c @@ -75,8 +75,7 @@ draw_border_cross(struct terminal *term, int x, int y, screen_char->data = BORDER_SCROSS; } - set_term_color(screen_char, color, 0, - get_opt_int_tree(term->spec, "colors", NULL)); + set_term_color(screen_char, color, 0, get_color_mode(term->spec)); } void @@ -89,8 +88,7 @@ draw_border_char(struct terminal *term, int x, int y, screen_char->data = (unsigned char) border; screen_char->attr = SCREEN_ATTR_FRAME; - set_term_color(screen_char, color, 0, - get_opt_int_tree(term->spec, "colors", NULL)); + set_term_color(screen_char, color, 0, get_color_mode(term->spec)); set_screen_dirty(term->screen, y, y); } @@ -101,8 +99,7 @@ draw_char_color(struct terminal *term, int x, int y, struct color_pair *color) if (!screen_char) return; - set_term_color(screen_char, color, 0, - get_opt_int_tree(term->spec, "colors", NULL)); + set_term_color(screen_char, color, 0, get_color_mode(term->spec)); set_screen_dirty(term->screen, y, y); } @@ -362,8 +359,7 @@ draw_char(struct terminal *term, int x, int y, screen_char->data = data; screen_char->attr = attr; - set_term_color(screen_char, color, 0, - get_opt_int_tree(term->spec, "colors", NULL)); + set_term_color(screen_char, color, 0, get_color_mode(term->spec)); set_screen_dirty(term->screen, y, y); } @@ -396,8 +392,7 @@ draw_box(struct terminal *term, struct el_box *box, end->attr = attr; end->data = data; if (color) { - set_term_color(end, color, 0, - get_opt_int_tree(term->spec, "colors", NULL)); + set_term_color(end, color, 0, get_color_mode(term->spec)); } else { clear_screen_char_color(end); } @@ -459,8 +454,7 @@ draw_text_utf8(struct terminal *term, int x, int y, start = get_char(term, x, y); if (color) { start->attr = attr; - set_term_color(start, color, 0, - get_opt_int_tree(term->spec, "colors", NULL)); + set_term_color(start, color, 0, get_color_mode(term->spec)); } if (start->data == UCS_NO_CHAR && x - 1 > 0) @@ -559,8 +553,7 @@ draw_text(struct terminal *term, int x, int y, if (color) { /* Use the last char as template. */ end->attr = attr; - set_term_color(end, color, 0, - get_opt_int_tree(term->spec, "colors", NULL)); + set_term_color(end, color, 0, get_color_mode(term->spec)); for (; pos < end && *text; text++, pos++) { end->data = *text; diff --git a/src/terminal/screen.c b/src/terminal/screen.c index 6c958017..31bac277 100644 --- a/src/terminal/screen.c +++ b/src/terminal/screen.c @@ -479,6 +479,8 @@ set_screen_dirty(struct terminal_screen *screen, int from, int to) screen->was_dirty = 1; } +#include + /** Set screen_driver.opt according to screen_driver.type and @a term_spec. * Other members of @a *driver need not have been initialized. * @@ -514,7 +516,8 @@ set_screen_driver_opt(struct screen_driver *driver, struct option *term_spec) } #endif /* CONFIG_UTF8 */ - driver->opt.color_mode = get_opt_int_tree(term_spec, "colors", NULL); + driver->opt.color_mode = get_color_mode(term_spec); + driver->opt.transparent = get_opt_bool_tree(term_spec, "transparency", NULL); @@ -585,45 +588,10 @@ set_screen_driver_opt(struct screen_driver *driver, struct option *term_spec) } } /* !utf8_io */ #ifdef CONFIG_TERMINFO - driver->opt.terminfo = get_cmd_opt_bool("terminfo"); - if (!driver->opt.terminfo) { - return; - } -#ifdef CONFIG_TRUE_COLOR - if (driver->opt.color_mode == COLOR_MODE_TRUE_COLOR) { - driver->opt.terminfo = 0; - return; - } -#endif if (driver->opt.color_mode == COLOR_MODE_MONO) { driver->opt.terminfo = 0; - return; - } - - switch (terminfo_max_colors()) { - case 88: -#ifdef CONFIG_88_COLORS - driver->opt.color_mode = COLOR_MODE_88; -#else - driver->opt.color_mode = COLOR_MODE_16; -#endif - break; - - case 256: -#ifdef CONFIG_256_COLORS - driver->opt.color_mode = COLOR_MODE_256; -#else - driver->opt.color_mode = COLOR_MODE_16; -#endif - break; - - case 16: - case 8: - driver->opt.color_mode = COLOR_MODE_16; - break; - default: - driver->opt.color_mode = COLOR_MODE_MONO; - break; + } else { + driver->opt.terminfo = get_cmd_opt_bool("terminfo"); } #endif } @@ -1290,23 +1258,46 @@ add_char_true(struct string *screen, struct screen_driver *driver, state->border = !!(ch->attr & SCREEN_ATTR_FRAME); add_term_string(screen, driver->opt.frame_seqs[state->border]); } +#ifdef CONFIG_TERMINFO + if (driver->opt.terminfo) { + if ((attr_delta & SCREEN_ATTR_ITALIC) && driver->opt.italic) { + state->italic = !!(ch->attr & SCREEN_ATTR_ITALIC); + add_to_string(screen, terminfo_set_italics(state->italic)); + } - if ((attr_delta & SCREEN_ATTR_ITALIC) && driver->opt.italic) { - state->italic = !!(ch->attr & SCREEN_ATTR_ITALIC); - add_term_string(screen, driver->opt.italic[state->italic]); - } + if ((attr_delta & SCREEN_ATTR_UNDERLINE) && driver->opt.underline) { + state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); + add_to_string(screen, terminfo_set_underline(state->underline)); + } - if ((attr_delta & SCREEN_ATTR_UNDERLINE) && driver->opt.underline) { - state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); - add_term_string(screen, driver->opt.underline[state->underline]); - } + if (attr_delta & SCREEN_ATTR_BOLD) { + if (ch->attr & SCREEN_ATTR_BOLD) { + add_to_string(screen, terminfo_set_bold(ch->attr & SCREEN_ATTR_BOLD)); + } else { + /* Force repainting of the other attributes. */ + state->color[0] = ch->c.color[0] + 1; + } + } + } else +#endif + { + if ((attr_delta & SCREEN_ATTR_ITALIC) && driver->opt.italic) { + state->italic = !!(ch->attr & SCREEN_ATTR_ITALIC); + add_term_string(screen, driver->opt.italic[state->italic]); + } - if (attr_delta & SCREEN_ATTR_BOLD) { - if (ch->attr & SCREEN_ATTR_BOLD) { - add_bytes_to_string(screen, "\033[1m", 4); - } else { - /* Force repainting of the other attributes. */ - state->color[0] = ch->c.color[0] + 1; + if ((attr_delta & SCREEN_ATTR_UNDERLINE) && driver->opt.underline) { + state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); + add_term_string(screen, driver->opt.underline[state->underline]); + } + + if (attr_delta & SCREEN_ATTR_BOLD) { + if (ch->attr & SCREEN_ATTR_BOLD) { + add_bytes_to_string(screen, "\033[1m", 4); + } else { + /* Force repainting of the other attributes. */ + state->color[0] = ch->c.color[0] + 1; + } } } @@ -1321,22 +1312,41 @@ add_char_true(struct string *screen, struct screen_driver *driver, ) { copy_color_true(state->color, ch->c.color); - add_true_foreground_color(screen, color_true_seqs, ch); - if (!driver->opt.transparent || !background_is_black(ch->c.color)) { - add_true_background_color(screen, color_true_seqs, ch); - } +#ifdef CONFIG_TERMINFO + if (driver->opt.terminfo) { + add_to_string(screen, terminfo_set_bold(ch->attr & SCREEN_ATTR_BOLD)); + add_to_string(screen, terminfo_set_foreground(ch->c.color[0] << 16 | ch->c.color[1] << 8 | ch->c.color[2])); + add_to_string(screen, terminfo_set_background(ch->c.color[3] << 16 | ch->c.color[4] << 8 | ch->c.color[5])); - if (ch->attr & SCREEN_ATTR_BOLD) - add_bytes_to_string(screen, "\033[1m", 4); + if (ch->attr & SCREEN_ATTR_ITALIC && driver->opt.italic) { + state->italic = !!(ch->attr & SCREEN_ATTR_ITALIC); + add_to_string(screen, terminfo_set_italics(state->italic)); + } - if (ch->attr & SCREEN_ATTR_ITALIC && driver->opt.italic) { - state->italic = !!(ch->attr & SCREEN_ATTR_ITALIC); - add_term_string(screen, driver->opt.italic[state->italic]); - } + if (ch->attr & SCREEN_ATTR_UNDERLINE && driver->opt.underline) { + state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); + add_to_string(screen, terminfo_set_underline(state->underline)); + } + } else +#endif + { + add_true_foreground_color(screen, color_true_seqs, ch); + if (!driver->opt.transparent || !background_is_black(ch->c.color)) { + add_true_background_color(screen, color_true_seqs, ch); + } - if (ch->attr & SCREEN_ATTR_UNDERLINE && driver->opt.underline) { - state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); - add_term_string(screen, driver->opt.underline[state->underline]); + if (ch->attr & SCREEN_ATTR_BOLD) + add_bytes_to_string(screen, "\033[1m", 4); + + if (ch->attr & SCREEN_ATTR_ITALIC && driver->opt.italic) { + state->italic = !!(ch->attr & SCREEN_ATTR_ITALIC); + add_term_string(screen, driver->opt.italic[state->italic]); + } + + if (ch->attr & SCREEN_ATTR_UNDERLINE && driver->opt.underline) { + state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE); + add_term_string(screen, driver->opt.underline[state->underline]); + } } }