From 7eb496c00c313c2f8ab8debe6d154d5ac0db277b Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 31 May 2017 08:43:44 +0000 Subject: [PATCH] Look for setrgbf and setrgbb terminfo extensions for RGB colour. This is the most reasonable of the various (some bizarre) suggestions for capabilities. --- tmux.h | 157 +++++++++++++++++++++++++++-------------------------- tty-term.c | 20 +++++++ tty.c | 30 +++++++--- 3 files changed, 122 insertions(+), 85 deletions(-) diff --git a/tmux.h b/tmux.h index eb63d11f..a3f9c352 100644 --- a/tmux.h +++ b/tmux.h @@ -204,67 +204,67 @@ enum { /* Termcap codes. */ enum tty_code_code { TTYC_AX = 0, - TTYC_ACSC, /* acs_chars, ac */ - TTYC_BCE, /* back_color_erase, ut */ - TTYC_BEL, /* bell, bl */ - TTYC_BLINK, /* enter_blink_mode, mb */ - TTYC_BOLD, /* enter_bold_mode, md */ - TTYC_CIVIS, /* cursor_invisible, vi */ - TTYC_CLEAR, /* clear_screen, cl */ - TTYC_CNORM, /* cursor_normal, ve */ - TTYC_COLORS, /* max_colors, Co */ - TTYC_CR, /* restore cursor colour, Cr */ - TTYC_CS, /* set cursor colour, Cs */ - TTYC_CSR, /* change_scroll_region, cs */ - TTYC_CUB, /* parm_left_cursor, LE */ - TTYC_CUB1, /* cursor_left, le */ - TTYC_CUD, /* parm_down_cursor, DO */ - TTYC_CUD1, /* cursor_down, do */ - TTYC_CUF, /* parm_right_cursor, RI */ - TTYC_CUF1, /* cursor_right, nd */ - TTYC_CUP, /* cursor_address, cm */ - TTYC_CUU, /* parm_up_cursor, UP */ - TTYC_CUU1, /* cursor_up, up */ - TTYC_CVVIS, /* cursor_visible, vs */ - TTYC_DCH, /* parm_dch, DC */ - TTYC_DCH1, /* delete_character, dc */ - TTYC_DIM, /* enter_dim_mode, mh */ - TTYC_DL, /* parm_delete_line, DL */ - TTYC_DL1, /* delete_line, dl */ + TTYC_ACSC, + TTYC_BCE, + TTYC_BEL, + TTYC_BLINK, + TTYC_BOLD, + TTYC_CIVIS, + TTYC_CLEAR, + TTYC_CNORM, + TTYC_COLORS, + TTYC_CR, + TTYC_CS, + TTYC_CSR, + TTYC_CUB, + TTYC_CUB1, + TTYC_CUD, + TTYC_CUD1, + TTYC_CUF, + TTYC_CUF1, + TTYC_CUP, + TTYC_CUU, + TTYC_CUU1, + TTYC_CVVIS, + TTYC_DCH, + TTYC_DCH1, + TTYC_DIM, + TTYC_DL, + TTYC_DL1, TTYC_E3, - TTYC_ECH, /* erase_chars, ec */ - TTYC_ED, /* clr_eos, cd */ - TTYC_EL, /* clr_eol, ce */ - TTYC_EL1, /* clr_bol, cb */ - TTYC_ENACS, /* ena_acs, eA */ - TTYC_FSL, /* from_status_line, fsl */ - TTYC_HOME, /* cursor_home, ho */ - TTYC_HPA, /* column_address, ch */ - TTYC_ICH, /* parm_ich, IC */ - TTYC_ICH1, /* insert_character, ic */ - TTYC_IL, /* parm_insert_line, IL */ - TTYC_IL1, /* insert_line, il */ - TTYC_INDN, /* parm_index, indn */ - TTYC_INVIS, /* enter_secure_mode, mk */ - TTYC_KCBT, /* key_btab, kB */ - TTYC_KCUB1, /* key_left, kl */ - TTYC_KCUD1, /* key_down, kd */ - TTYC_KCUF1, /* key_right, kr */ - TTYC_KCUU1, /* key_up, ku */ + TTYC_ECH, + TTYC_ED, + TTYC_EL, + TTYC_EL1, + TTYC_ENACS, + TTYC_FSL, + TTYC_HOME, + TTYC_HPA, + TTYC_ICH, + TTYC_ICH1, + TTYC_IL, + TTYC_IL1, + TTYC_INDN, + TTYC_INVIS, + TTYC_KCBT, + TTYC_KCUB1, + TTYC_KCUD1, + TTYC_KCUF1, + TTYC_KCUU1, TTYC_KDC2, TTYC_KDC3, TTYC_KDC4, TTYC_KDC5, TTYC_KDC6, TTYC_KDC7, - TTYC_KDCH1, /* key_dc, kD */ + TTYC_KDCH1, TTYC_KDN2, TTYC_KDN3, TTYC_KDN4, TTYC_KDN5, TTYC_KDN6, TTYC_KDN7, - TTYC_KEND, /* key_end, ke */ + TTYC_KEND, TTYC_KEND2, TTYC_KEND3, TTYC_KEND4, @@ -340,29 +340,29 @@ enum tty_code_code { TTYC_KHOM5, TTYC_KHOM6, TTYC_KHOM7, - TTYC_KHOME, /* key_home, kh */ + TTYC_KHOME, TTYC_KIC2, TTYC_KIC3, TTYC_KIC4, TTYC_KIC5, TTYC_KIC6, TTYC_KIC7, - TTYC_KICH1, /* key_ic, kI */ + TTYC_KICH1, TTYC_KLFT2, TTYC_KLFT3, TTYC_KLFT4, TTYC_KLFT5, TTYC_KLFT6, TTYC_KLFT7, - TTYC_KMOUS, /* key_mouse, Km */ - TTYC_KNP, /* key_npage, kN */ + TTYC_KMOUS, + TTYC_KNP, TTYC_KNXT2, TTYC_KNXT3, TTYC_KNXT4, TTYC_KNXT5, TTYC_KNXT6, TTYC_KNXT7, - TTYC_KPP, /* key_ppage, kP */ + TTYC_KPP, TTYC_KPRV2, TTYC_KPRV3, TTYC_KPRV4, @@ -381,31 +381,33 @@ enum tty_code_code { TTYC_KUP5, TTYC_KUP6, TTYC_KUP7, - TTYC_MS, /* modify xterm(1) selection */ - TTYC_OP, /* orig_pair, op */ - TTYC_REV, /* enter_reverse_mode, mr */ - TTYC_RI, /* scroll_reverse, sr */ - TTYC_RMACS, /* exit_alt_charset_mode */ - TTYC_RMCUP, /* exit_ca_mode, te */ - TTYC_RMKX, /* keypad_local, ke */ - TTYC_SE, /* reset cursor style, Se */ - TTYC_SETAB, /* set_a_background, AB */ - TTYC_SETAF, /* set_a_foreground, AF */ - TTYC_SGR0, /* exit_attribute_mode, me */ - TTYC_SITM, /* enter_italics_mode, it */ - TTYC_SMACS, /* enter_alt_charset_mode, as */ - TTYC_SMCUP, /* enter_ca_mode, ti */ - TTYC_SMKX, /* keypad_xmit, ks */ - TTYC_SMSO, /* enter_standout_mode, so */ - TTYC_SMUL, /* enter_underline_mode, us */ + TTYC_MS, + TTYC_OP, + TTYC_REV, + TTYC_RI, + TTYC_RMACS, + TTYC_RMCUP, + TTYC_RMKX, + TTYC_SE, + TTYC_SETAB, + TTYC_SETAF, + TTYC_SETRGBB, + TTYC_SETRGBF, + TTYC_SGR0, + TTYC_SITM, + TTYC_SMACS, + TTYC_SMCUP, + TTYC_SMKX, + TTYC_SMSO, + TTYC_SMUL, TTYC_SMXX, - TTYC_SS, /* set cursor style, Ss */ - TTYC_TC, /* 24-bit "true" colour, Tc */ - TTYC_TSL, /* to_status_line, tsl */ + TTYC_SS, + TTYC_TC, + TTYC_TSL, TTYC_U8, - TTYC_VPA, /* row_address, cv */ - TTYC_XENL, /* eat_newline_glitch, xn */ - TTYC_XT, /* xterm(1)-compatible title, XT */ + TTYC_VPA, + TTYC_XENL, + TTYC_XT, }; /* Message codes. */ @@ -1648,6 +1650,7 @@ void tty_cursor(struct tty *, u_int, u_int); void tty_putcode(struct tty *, enum tty_code_code); void tty_putcode1(struct tty *, enum tty_code_code, int); void tty_putcode2(struct tty *, enum tty_code_code, int, int); +void tty_putcode3(struct tty *, enum tty_code_code, int, int, int); void tty_putcode_ptr1(struct tty *, enum tty_code_code, const void *); void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, const void *); @@ -1702,6 +1705,8 @@ const char *tty_term_string(struct tty_term *, enum tty_code_code); const char *tty_term_string1(struct tty_term *, enum tty_code_code, int); const char *tty_term_string2(struct tty_term *, enum tty_code_code, int, int); +const char *tty_term_string3(struct tty_term *, enum tty_code_code, int, + int, int); const char *tty_term_ptr1(struct tty_term *, enum tty_code_code, const void *); const char *tty_term_ptr2(struct tty_term *, enum tty_code_code, diff --git a/tty-term.c b/tty-term.c index d1142ad2..38829bdd 100644 --- a/tty-term.c +++ b/tty-term.c @@ -242,6 +242,8 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_SE] = { TTYCODE_STRING, "Se" }, [TTYC_SETAB] = { TTYCODE_STRING, "setab" }, [TTYC_SETAF] = { TTYCODE_STRING, "setaf" }, + [TTYC_SETRGBB] = { TTYCODE_STRING, "setrgbb" }, + [TTYC_SETRGBF] = { TTYCODE_STRING, "setrgbf" }, [TTYC_SGR0] = { TTYCODE_STRING, "sgr0" }, [TTYC_SITM] = { TTYCODE_STRING, "sitm" }, [TTYC_SMACS] = { TTYCODE_STRING, "smacs" }, @@ -521,6 +523,18 @@ tty_term_find(char *name, int fd, char **cause) code->type = TTYCODE_STRING; } + /* On terminals with RGB colour (TC), fill in setrgbf and setrgbb. */ + if (tty_term_flag(term, TTYC_TC) && + !tty_term_has(term, TTYC_SETRGBF) && + !tty_term_has(term, TTYC_SETRGBB)) { + code = &term->codes[TTYC_SETRGBF]; + code->value.string = xstrdup("\033[38;2;%p1%d;%p2%d;%p3%dm"); + code->type = TTYCODE_STRING; + code = &term->codes[TTYC_SETRGBB]; + code->value.string = xstrdup("\033[48;2;%p1%d;%p2%d;%p3%dm"); + code->type = TTYCODE_STRING; + } + return (term); error: @@ -576,6 +590,12 @@ tty_term_string2(struct tty_term *term, enum tty_code_code code, int a, int b) return (tparm((char *) tty_term_string(term, code), a, b)); } +const char * +tty_term_string3(struct tty_term *term, enum tty_code_code code, int a, int b, int c) +{ + return (tparm((char *) tty_term_string(term, code), a, b, c)); +} + const char * tty_term_ptr1(struct tty_term *term, enum tty_code_code code, const void *a) { diff --git a/tty.c b/tty.c index d792c9c2..9de1f50a 100644 --- a/tty.c +++ b/tty.c @@ -472,6 +472,14 @@ tty_putcode2(struct tty *tty, enum tty_code_code code, int a, int b) tty_puts(tty, tty_term_string2(tty->term, code, a, b)); } +void +tty_putcode3(struct tty *tty, enum tty_code_code code, int a, int b, int c) +{ + if (a < 0 || b < 0 || c < 0) + return; + tty_puts(tty, tty_term_string3(tty->term, code, a, b, c)); +} + void tty_putcode_ptr1(struct tty *tty, enum tty_code_code code, const void *a) { @@ -1847,7 +1855,7 @@ tty_check_fg(struct tty *tty, const struct window_pane *wp, /* Is this a 24-bit colour? */ if (gc->fg & COLOUR_FLAG_RGB) { /* Not a 24-bit terminal? Translate to 256-colour palette. */ - if (!tty_term_flag(tty->term, TTYC_TC)) { + if (!tty_term_has(tty->term, TTYC_SETRGBF)) { colour_split_rgb(gc->fg, &r, &g, &b); gc->fg = colour_find_rgb(r, g, b); } else @@ -1900,7 +1908,7 @@ tty_check_bg(struct tty *tty, const struct window_pane *wp, /* Is this a 24-bit colour? */ if (gc->bg & COLOUR_FLAG_RGB) { /* Not a 24-bit terminal? Translate to 256-colour palette. */ - if (!tty_term_flag(tty->term, TTYC_TC)) { + if (!tty_term_has(tty->term, TTYC_SETRGBB)) { colour_split_rgb(gc->bg, &r, &g, &b); gc->bg = colour_find_rgb(r, g, b); } else @@ -2031,13 +2039,17 @@ tty_try_colour(struct tty *tty, int colour, const char *type) } if (colour & COLOUR_FLAG_RGB) { - if (!tty_term_flag(tty->term, TTYC_TC)) - return (-1); - - colour_split_rgb(colour & 0xffffff, &r, &g, &b); - xsnprintf(s, sizeof s, "\033[%s;2;%hhu;%hhu;%hhum", type, - r, g, b); - tty_puts(tty, s); + if (*type == '3') { + if (!tty_term_has(tty->term, TTYC_SETRGBF)) + return (-1); + colour_split_rgb(colour & 0xffffff, &r, &g, &b); + tty_putcode3(tty, TTYC_SETRGBF, r, g, b); + } else { + if (!tty_term_has(tty->term, TTYC_SETRGBB)) + return (-1); + colour_split_rgb(colour & 0xffffff, &r, &g, &b); + tty_putcode3(tty, TTYC_SETRGBB, r, g, b); + } return (0); }