From 335262df6c248aa875eec16f07643c9e244adce4 Mon Sep 17 00:00:00 2001 From: Nobuhiro Takasaki Date: Sun, 15 Apr 2018 21:27:40 +0900 Subject: [PATCH 1/4] 256 colors supported --- src/misc1.c | 2 +- src/option.c | 17 +++++++ src/os_win32.c | 83 ++++++++++++++++++++++++++++++-- src/term.c | 127 +++++++++++++++++++++++++++++++------------------ src/terminal.c | 4 ++ 5 files changed, 182 insertions(+), 51 deletions(-) diff --git a/src/misc1.c b/src/misc1.c index 135293dd2d6445..f57f10f12b005b 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -3714,7 +3714,7 @@ vim_beep( /* No restore color information, refresh the screen. */ if (has_vtp_working() != 0 # ifdef FEAT_TERMGUICOLORS - && p_tgc + && (p_tgc || (!p_tgc && t_colors >= 256)) # endif ) { diff --git a/src/option.c b/src/option.c index ea8c6af9bb4e17..aeddc3380ea2b4 100644 --- a/src/option.c +++ b/src/option.c @@ -6042,6 +6042,9 @@ did_set_string_option( int redraw_gui_only = FALSE; #endif int ft_changed = FALSE; +#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) + int did_swaptcap = FALSE; +#endif /* Get the global option to compare with, otherwise we would have to check * two values for all local options. */ @@ -6781,6 +6784,10 @@ did_set_string_option( vim_free(T_CCO); T_CCO = empty_option; } +#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) + swap_tcap(); + did_swaptcap = TRUE; +#endif /* We now have a different color setup, initialize it again. */ init_highlight(TRUE, FALSE); } @@ -7633,6 +7640,16 @@ did_set_string_option( #endif check_redraw(options[opt_idx].flags); +#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) + if (did_swaptcap) + { + if (t_colors < 256) + p_tgc = 0; + set_termname("win32"); + init_highlight(TRUE, FALSE); + } +#endif + return errmsg; } diff --git a/src/os_win32.c b/src/os_win32.c index 0cb311337d4b38..b05e47ef1c0999 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -214,7 +214,7 @@ static guicolor_T save_console_bg_rgb; static guicolor_T save_console_fg_rgb; # ifdef FEAT_TERMGUICOLORS -# define USE_VTP (vtp_working && p_tgc) +# define USE_VTP (vtp_working && (p_tgc || (!p_tgc && t_colors >= 256))) # else # define USE_VTP 0 # endif @@ -2630,7 +2630,6 @@ mch_init(void) /* set termcap codes to current text attributes */ update_tcap(g_attrCurrent); - swap_tcap(); GetConsoleCursorInfo(g_hConOut, &g_cci); GetConsoleMode(g_hConIn, &g_cmodein); @@ -5763,7 +5762,11 @@ clear_chars( if (!USE_VTP) FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, n, coord, &dwDummy); else - FillConsoleOutputAttribute(g_hConOut, 0, n, coord, &dwDummy); + { + set_console_color_rgb(); + gotoxy(coord.X + 1, coord.Y + 1); + vtp_printf("\033[%dX", n); + } } @@ -7653,6 +7656,64 @@ vtp_sgr_bulks( vtp_printf((char *)buf); } +static int ansitbl[] = { + 0, 0, 0, + 224, 0, 0, + 0, 224, 0, + 224, 224, 0, + 0, 0, 224, + 224, 0, 224, + 0, 224, 224, + 224, 224, 224, + 128, 128, 128, + 255, 64, 64, + 64, 255, 64, + 255, 255, 64, + 64, 64, 255, + 255, 64, 255, + 64, 255, 255, + 255, 255, 255 +}; + +static int cubetbl[] = { + 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff +}; + +static int greytbl[] = { + 0x08, 0x12, 0x1c, 0x26, 0x30, 0x3a, 0x44, 0x4e, 0x58, 0x62, 0x6c, 0x76, + 0x80, 0x8a, 0x94, 0x9e, 0xa8, 0xb2, 0xbc, 0xc6, 0xd0, 0xda, 0xe4, 0xee +}; + + static int +ctermtoxterm( + int cterm) +{ + int i, r, g, b; + + if (cterm < 16) + { + r = ansitbl[cterm * 3 + 0]; + g = ansitbl[cterm * 3 + 1]; + b = ansitbl[cterm * 3 + 2]; + } + else if (cterm < 232) + { + + i = cterm - 16; + r = cubetbl[i / 36 % 6]; + g = cubetbl[i / 6 % 6]; + b = cubetbl[i % 6]; + } + else if (cterm < 256) + { + i = cterm - 232; + r = greytbl[i]; + g = greytbl[i]; + b = greytbl[i]; + } + return (int)((r << 16) | (g << 8) | (b)); +} + static void set_console_color_rgb(void) { @@ -7661,6 +7722,8 @@ set_console_color_rgb(void) int id; guicolor_T fg = INVALCOLOR; guicolor_T bg = INVALCOLOR; + int ctermfg; + int ctermbg; if (!USE_VTP) return; @@ -7669,9 +7732,19 @@ set_console_color_rgb(void) if (id > 0) syn_id2colors(id, &fg, &bg); if (fg == INVALCOLOR) - fg = 0xc0c0c0; /* white text */ + { + ctermfg = -1; + if (id > 0) + syn_id2cterm_bg(id, &ctermfg, &ctermbg); + fg = ctermfg != -1 ? ctermtoxterm(ctermfg) : 0xc0c0c0; /* white */ + } if (bg == INVALCOLOR) - bg = 0x000000; /* black background */ + { + ctermbg = -1; + if (id > 0) + syn_id2cterm_bg(id, &ctermfg, &ctermbg); + bg = ctermbg != -1 ? ctermtoxterm(ctermbg) : 0x000000; /* black */ + } fg = (GetRValue(fg) << 16) | (GetGValue(fg) << 8) | GetBValue(fg); bg = (GetRValue(bg) << 16) | (GetGValue(bg) << 8) | GetBValue(bg); diff --git a/src/term.c b/src/term.c index 3a27fa691d77ca..ade79caeb86458 100644 --- a/src/term.c +++ b/src/term.c @@ -2011,11 +2011,6 @@ set_termname(char_u *term) may_req_termresponse(); #endif -#if defined(WIN3264) && !defined(FEAT_GUI) && defined(FEAT_TERMGUICOLORS) - if (STRCMP(term, "win32") == 0) - set_color_count((p_tgc) ? 256 : 16); -#endif - return OK; } @@ -2853,7 +2848,11 @@ term_color(char_u *s, int n) /* Also accept "\e[3%dm" for TERMINFO, it is sometimes used */ /* Also accept CSI instead of [ */ if (n >= 8 && t_colors >= 16 - && ((s[0] == ESC && s[1] == '[') || (s[0] == CSI && (i = 1) == 1)) + && ((s[0] == ESC && s[1] == '[') +#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) + || (s[0] == ESC && s[1] == '|') +#endif + || (s[0] == CSI && (i = 1) == 1)) && s[i] != NUL && (STRCMP(s + i + 1, "%p1%dm") == 0 || STRCMP(s + i + 1, "%dm") == 0) @@ -2865,7 +2864,11 @@ term_color(char_u *s, int n) char *format = "%s%s%%dm"; #endif sprintf(buf, format, - i == 2 ? IF_EB("\033[", ESC_STR "[") : "\233", + i == 2 ? +#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) + s[1] == '|' ? IF_EB("\033|", ESC_STR "|") : +#endif + IF_EB("\033[", ESC_STR "[") : "\233", s[i] == '3' ? (n >= 16 ? "38;5;" : "9") : (n >= 16 ? "48;5;" : "10")); OUT_STR(tgoto(buf, 0, n >= 16 ? n : n - 8)); @@ -6652,26 +6655,38 @@ update_tcap(int attr) } # ifdef FEAT_TERMGUICOLORS +# define KSSIZE 20 struct ks_tbl_s { - int code; /* value of KS_ */ - char *vtp; /* code in vtp mode */ - char *buf; /* buffer in non-vtp mode */ - char *vbuf; /* buffer in vtp mode */ + int code; /* value of KS_ */ + char *vtp; /* code in vtp mode */ + char *vtp2; /* code in vtp2 mode */ + char buf[KSSIZE]; /* save buffer in non-vtp mode */ + char vbuf[KSSIZE]; /* save buffer in vtp mode */ + char v2buf[KSSIZE]; /* save buffer in vtp2 mode */ + char arr[KSSIZE]; /* real buffer */ }; static struct ks_tbl_s ks_tbl[] = { - {(int)KS_ME, "\033|0m" }, /* normal */ - {(int)KS_MR, "\033|7m" }, /* reverse */ - {(int)KS_MD, "\033|1m" }, /* bold */ - {(int)KS_SO, "\033|91m"}, /* standout: bright red text */ - {(int)KS_SE, "\033|39m"}, /* standout end: default color */ - {(int)KS_CZH, "\033|95m"}, /* italic: bright magenta text */ - {(int)KS_CZR, "\033|0m",}, /* italic end */ - {(int)KS_US, "\033|4m",}, /* underscore */ - {(int)KS_UE, "\033|24m"}, /* underscore end */ - {(int)KS_NAME, NULL} + {(int)KS_ME, "\033|0m", "\033|0m"}, /* normal */ + {(int)KS_MR, "\033|7m", "\033|7m"}, /* reverse */ + {(int)KS_MD, "\033|1m", "\033|1m"}, /* bold */ + {(int)KS_SO, "\033|91m", "\033|91m"}, /* standout: bright red text */ + {(int)KS_SE, "\033|39m", "\033|39m"}, /* standout end: default color */ + {(int)KS_CZH, "\033|95m", "\033|95m"}, /* italic: bright magenta text */ + {(int)KS_CZR, "\033|0m", "\033|0m"}, /* italic end */ + {(int)KS_US, "\033|4m", "\033|4m"}, /* underscore */ + {(int)KS_UE, "\033|24m", "\033|24m"}, /* underscore end */ +# ifdef TERMINFO + {(int)KS_CAB, "\033|%p1%db", "\033|%p14%dm"}, /* set background color */ + {(int)KS_CAF, "\033|%p1%df", "\033|%p13%dm"}, /* set foreground color */ +# else + {(int)KS_CAB, "\033|%db", "\033|4%dm"}, /* set background color */ + {(int)KS_CAF, "\033|%df", "\033|3%dm"}, /* set foreground color */ +# endif + {(int)KS_CCO, "16", "256"}, /* colors */ + {(int)KS_NAME} /* terminator */ }; static struct builtin_term * @@ -6696,57 +6711,79 @@ swap_tcap(void) { # ifdef FEAT_TERMGUICOLORS static int init_done = FALSE; - static int last_tgc; + static int curr_mode; /* 0=index c, 1=24bit c, 2=256 c */ struct ks_tbl_s *ks; struct builtin_term *bt; + int mode; /* buffer initialization */ if (!init_done) { - for (ks = ks_tbl; ks->vtp != NULL; ks++) + for (ks = ks_tbl; ks->code != (int)KS_NAME; ks++) { bt = find_first_tcap(DEFAULT_TERM, ks->code); if (bt != NULL) { - ks->buf = bt->bt_string; - ks->vbuf = ks->vtp; + STRNCPY(ks->buf, bt->bt_string, KSSIZE); + STRNCPY(ks->vbuf, ks->vtp, KSSIZE); + STRNCPY(ks->v2buf, ks->vtp2, KSSIZE); + + STRNCPY(ks->arr, bt->bt_string, KSSIZE); + bt->bt_string = &ks->arr[0]; } } init_done = TRUE; - last_tgc = p_tgc; - return; + curr_mode = 0; } - if (last_tgc != p_tgc) + if (p_tgc) + mode = 1; + else if (t_colors >= 256) + mode = 2; + else + mode = 0; + + for (ks = ks_tbl; ks->code != (int)KS_NAME; ks++) { - if (p_tgc) + bt = find_first_tcap(DEFAULT_TERM, ks->code); + if (bt != NULL) { - /* switch to special character sequence */ - for (ks = ks_tbl; ks->vtp != NULL; ks++) + switch (curr_mode) { - bt = find_first_tcap(DEFAULT_TERM, ks->code); - if (bt != NULL) - { - ks->buf = bt->bt_string; - bt->bt_string = ks->vbuf; - } + case 0: /* index */ + STRNCPY(&ks->buf[0], bt->bt_string, KSSIZE); + break; + case 1: /* vtp */ + STRNCPY(&ks->vbuf[0], bt->bt_string, KSSIZE); + break; + default: /* vtp2 */ + STRNCPY(&ks->v2buf[0], bt->bt_string, KSSIZE); } } - else + } + + if (mode != curr_mode) + { + for (ks = ks_tbl; ks->code != (int)KS_NAME; ks++) { - /* switch to index color */ - for (ks = ks_tbl; ks->vtp != NULL; ks++) + bt = find_first_tcap(DEFAULT_TERM, ks->code); + if (bt != NULL) { - bt = find_first_tcap(DEFAULT_TERM, ks->code); - if (bt != NULL) + switch (mode) { - ks->vbuf = bt->bt_string; - bt->bt_string = ks->buf; + case 0: /* index */ + STRNCPY(bt->bt_string, &ks->buf[0], KSSIZE); + break; + case 1: /* vtp */ + STRNCPY(bt->bt_string, &ks->vbuf[0], KSSIZE); + break; + default: /* vtp2 */ + STRNCPY(bt->bt_string, &ks->v2buf[0], KSSIZE); } } } - last_tgc = p_tgc; + curr_mode = mode; } # endif } diff --git a/src/terminal.c b/src/terminal.c index 7f6e48db64741e..b5bd6458b0216c 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -3118,6 +3118,10 @@ init_default_colors(term_T *term) # endif # ifdef FEAT_TERMGUICOLORS || p_tgc +# ifdef FEAT_VTP + /* Finally get INVALCOLOR on this execution path */ + || (!p_tgc && t_colors >= 256) +# endif # endif ) { From 8a55350a1dc6ac052bff164d5ec66d7d376559ab Mon Sep 17 00:00:00 2001 From: Nobuhiro Takasaki Date: Fri, 20 Apr 2018 12:29:36 +0900 Subject: [PATCH 2/4] Move colors to globals.h --- src/globals.h | 17 +++++++++++++++++ src/os_win32.c | 30 ++++++++++-------------------- src/terminal.c | 9 --------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/globals.h b/src/globals.h index d5320d7272dd68..bce2c720b02950 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1657,6 +1657,23 @@ EXTERN int *eval_lavars_used INIT(= NULL); EXTERN int ctrl_break_was_pressed INIT(= FALSE); #endif +EXTERN int cube_value[] +#ifdef DO_INIT + = { + 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF +} +#endif +; + +extern int grey_ramp[] +#ifdef DO_INIT + = { + 0x08, 0x12, 0x1C, 0x26, 0x30, 0x3A, 0x44, 0x4E, 0x58, 0x62, 0x6C, 0x76, + 0x80, 0x8A, 0x94, 0x9E, 0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE +} +#endif +; + /* * Optional Farsi support. Include it here, so EXTERN and INIT are defined. */ diff --git a/src/os_win32.c b/src/os_win32.c index b05e47ef1c0999..62c0bbdb8e8974 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -7656,7 +7656,7 @@ vtp_sgr_bulks( vtp_printf((char *)buf); } -static int ansitbl[] = { +static int ansi_rgb_table[] = { 0, 0, 0, 224, 0, 0, 0, 224, 0, @@ -7675,15 +7675,6 @@ static int ansitbl[] = { 255, 255, 255 }; -static int cubetbl[] = { - 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff -}; - -static int greytbl[] = { - 0x08, 0x12, 0x1c, 0x26, 0x30, 0x3a, 0x44, 0x4e, 0x58, 0x62, 0x6c, 0x76, - 0x80, 0x8a, 0x94, 0x9e, 0xa8, 0xb2, 0xbc, 0xc6, 0xd0, 0xda, 0xe4, 0xee -}; - static int ctermtoxterm( int cterm) @@ -7692,24 +7683,23 @@ ctermtoxterm( if (cterm < 16) { - r = ansitbl[cterm * 3 + 0]; - g = ansitbl[cterm * 3 + 1]; - b = ansitbl[cterm * 3 + 2]; + r = ansi_rgb_table[cterm * 3 + 0]; + g = ansi_rgb_table[cterm * 3 + 1]; + b = ansi_rgb_table[cterm * 3 + 2]; } else if (cterm < 232) { - i = cterm - 16; - r = cubetbl[i / 36 % 6]; - g = cubetbl[i / 6 % 6]; - b = cubetbl[i % 6]; + r = cube_value[i / 36 % 6]; + g = cube_value[i / 6 % 6]; + b = cube_value[i % 6]; } else if (cterm < 256) { i = cterm - 232; - r = greytbl[i]; - g = greytbl[i]; - b = greytbl[i]; + r = grey_ramp[i]; + g = grey_ramp[i]; + b = grey_ramp[i]; } return (int)((r << 16) | (g << 8) | (b)); } diff --git a/src/terminal.c b/src/terminal.c index b5bd6458b0216c..4c2c3ec4c410e6 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -3034,15 +3034,6 @@ static VTermColor ansi_table[16] = { {255, 255, 255, 16}, /* white */ }; -static int cube_value[] = { - 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF -}; - -static int grey_ramp[] = { - 0x08, 0x12, 0x1C, 0x26, 0x30, 0x3A, 0x44, 0x4E, 0x58, 0x62, 0x6C, 0x76, - 0x80, 0x8A, 0x94, 0x9E, 0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE -}; - /* * Convert a cterm color number 0 - 255 to RGB. * This is compatible with xterm. From be2775e215cdde073a5f8547d479a3ae7a77e759 Mon Sep 17 00:00:00 2001 From: Nobuhiro Takasaki Date: Fri, 20 Apr 2018 12:34:48 +0900 Subject: [PATCH 3/4] Convert numbers to enum --- src/term.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/term.c b/src/term.c index ade79caeb86458..59add032ec9439 100644 --- a/src/term.c +++ b/src/term.c @@ -6715,6 +6715,12 @@ swap_tcap(void) struct ks_tbl_s *ks; struct builtin_term *bt; int mode; + enum + { + CMODEINDEX, + CMODE24, + CMODE256 + }; /* buffer initialization */ if (!init_done) @@ -6733,15 +6739,15 @@ swap_tcap(void) } } init_done = TRUE; - curr_mode = 0; + curr_mode = CMODEINDEX; } if (p_tgc) - mode = 1; + mode = CMODE24; else if (t_colors >= 256) - mode = 2; + mode = CMODE256; else - mode = 0; + mode = CMODEINDEX; for (ks = ks_tbl; ks->code != (int)KS_NAME; ks++) { @@ -6750,13 +6756,13 @@ swap_tcap(void) { switch (curr_mode) { - case 0: /* index */ + case CMODEINDEX: STRNCPY(&ks->buf[0], bt->bt_string, KSSIZE); break; - case 1: /* vtp */ + case CMODE24: STRNCPY(&ks->vbuf[0], bt->bt_string, KSSIZE); break; - default: /* vtp2 */ + default: STRNCPY(&ks->v2buf[0], bt->bt_string, KSSIZE); } } @@ -6771,13 +6777,13 @@ swap_tcap(void) { switch (mode) { - case 0: /* index */ + case CMODEINDEX: STRNCPY(bt->bt_string, &ks->buf[0], KSSIZE); break; - case 1: /* vtp */ + case CMODE24: STRNCPY(bt->bt_string, &ks->vbuf[0], KSSIZE); break; - default: /* vtp2 */ + default: STRNCPY(bt->bt_string, &ks->v2buf[0], KSSIZE); } } From c643ee661a6bd5529f1d0402fa49df89101f1860 Mon Sep 17 00:00:00 2001 From: Nobuhiro Takasaki Date: Fri, 20 Apr 2018 15:06:42 +0900 Subject: [PATCH 4/4] Fix important mistakes --- src/globals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals.h b/src/globals.h index bce2c720b02950..6414920f8ae17d 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1665,7 +1665,7 @@ EXTERN int cube_value[] #endif ; -extern int grey_ramp[] +EXTERN int grey_ramp[] #ifdef DO_INIT = { 0x08, 0x12, 0x1C, 0x26, 0x30, 0x3A, 0x44, 0x4E, 0x58, 0x62, 0x6C, 0x76,