1
0
forked from aniani/vim

patch 8.0.1783: cannot use 256 colors in a MS-Windows console

Problem:    Cannot use 256 colors in a MS-Windows console.
Solution:   Add 256 color support. (Nobuhiro Takasaki, closes #2821)
This commit is contained in:
Bram Moolenaar
2018-05-01 15:47:38 +02:00
parent d76ce85266
commit c5cd88554f
8 changed files with 238 additions and 112 deletions

View File

@@ -2009,11 +2009,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;
}
@@ -2851,7 +2846,11 @@ term_color(char_u *s, int n)
/* Also accept "\e[3%dm" for TERMINFO, it is sometimes used */
/* Also accept CSI instead of <Esc>[ */
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)
@@ -2863,7 +2862,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));
@@ -6640,26 +6643,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 *
@@ -6684,57 +6699,85 @@ swap_tcap(void)
{
# ifdef FEAT_TERMGUICOLORS
static int init_done = FALSE;
static int last_tgc;
static int curr_mode;
struct ks_tbl_s *ks;
struct builtin_term *bt;
int mode;
enum
{
CMODEINDEX,
CMODE24,
CMODE256
};
/* 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 = CMODEINDEX;
}
if (last_tgc != p_tgc)
if (p_tgc)
mode = CMODE24;
else if (t_colors >= 256)
mode = CMODE256;
else
mode = CMODEINDEX;
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 CMODEINDEX:
STRNCPY(&ks->buf[0], bt->bt_string, KSSIZE);
break;
case CMODE24:
STRNCPY(&ks->vbuf[0], bt->bt_string, KSSIZE);
break;
default:
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 CMODEINDEX:
STRNCPY(bt->bt_string, &ks->buf[0], KSSIZE);
break;
case CMODE24:
STRNCPY(bt->bt_string, &ks->vbuf[0], KSSIZE);
break;
default:
STRNCPY(bt->bt_string, &ks->v2buf[0], KSSIZE);
}
}
}
last_tgc = p_tgc;
curr_mode = mode;
}
# endif
}
@@ -6920,3 +6963,79 @@ gui_get_rgb_color_cmn(int r, int g, int b)
return color;
}
#endif
#if (defined(WIN3264) && !defined(FEAT_GUI_W32)) || defined(FEAT_TERMINAL) \
|| defined(PROTO)
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
};
# ifdef FEAT_TERMINAL
# include "libvterm/include/vterm.h" // for VTERM_ANSI_INDEX_NONE
# endif
static uint8_t ansi_table[16][4] = {
// R G B idx
{ 0, 0, 0, 1}, // black
{224, 0, 0, 2}, // dark red
{ 0, 224, 0, 3}, // dark green
{224, 224, 0, 4}, // dark yellow / brown
{ 0, 0, 224, 5}, // dark blue
{224, 0, 224, 6}, // dark magenta
{ 0, 224, 224, 7}, // dark cyan
{224, 224, 224, 8}, // light grey
{128, 128, 128, 9}, // dark grey
{255, 64, 64, 10}, // light red
{ 64, 255, 64, 11}, // light green
{255, 255, 64, 12}, // yellow
{ 64, 64, 255, 13}, // light blue
{255, 64, 255, 14}, // light magenta
{ 64, 255, 255, 15}, // light cyan
{255, 255, 255, 16}, // white
};
void
cterm_color2rgb(int nr, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *ansi_idx)
{
int idx;
if (nr < 16)
{
*r = ansi_table[nr][0];
*g = ansi_table[nr][1];
*b = ansi_table[nr][2];
*ansi_idx = ansi_table[nr][3];
}
else if (nr < 232)
{
/* 216 color cube */
idx = nr - 16;
*r = cube_value[idx / 36 % 6];
*g = cube_value[idx / 6 % 6];
*b = cube_value[idx % 6];
*ansi_idx = VTERM_ANSI_INDEX_NONE;
}
else if (nr < 256)
{
/* 24 grey scale ramp */
idx = nr - 232;
*r = grey_ramp[idx];
*g = grey_ramp[idx];
*b = grey_ramp[idx];
*ansi_idx = VTERM_ANSI_INDEX_NONE;
}
else
{
*r = 0;
*g = 0;
*b = 0;
*ansi_idx = 0;
}
}
#endif