vte: extend SGR/color handling
This adds full xterm 256color support and improves SGR handling in general. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
ba59f62a26
commit
60527b2d64
244
src/vte.c
244
src/vte.c
@ -158,6 +158,8 @@ struct kmscon_vte {
|
||||
int csi_argv[CSI_ARG_MAX];
|
||||
unsigned int csi_flags;
|
||||
|
||||
unsigned int def_fcol;
|
||||
unsigned int def_bcol;
|
||||
struct font_char_attr cattr;
|
||||
unsigned int flags;
|
||||
|
||||
@ -173,6 +175,65 @@ struct kmscon_vte {
|
||||
struct vte_saved_state saved_state;
|
||||
};
|
||||
|
||||
enum vte_color {
|
||||
COLOR_BLACK,
|
||||
COLOR_RED,
|
||||
COLOR_GREEN,
|
||||
COLOR_YELLOW,
|
||||
COLOR_BLUE,
|
||||
COLOR_MAGENTA,
|
||||
COLOR_CYAN,
|
||||
COLOR_LIGHT_GREY,
|
||||
COLOR_DARK_GREY,
|
||||
COLOR_LIGHT_RED,
|
||||
COLOR_LIGHT_GREEN,
|
||||
COLOR_LIGHT_YELLOW,
|
||||
COLOR_LIGHT_BLUE,
|
||||
COLOR_LIGHT_MAGENTA,
|
||||
COLOR_LIGHT_CYAN,
|
||||
COLOR_WHITE,
|
||||
COLOR_NUM
|
||||
};
|
||||
|
||||
static uint8_t color_palette[COLOR_NUM][3] = {
|
||||
[COLOR_BLACK] = { 0, 0, 0 }, /* black */
|
||||
[COLOR_RED] = { 205, 0, 0 }, /* red */
|
||||
[COLOR_GREEN] = { 0, 205, 0 }, /* green */
|
||||
[COLOR_YELLOW] = { 205, 205, 0 }, /* yellow */
|
||||
[COLOR_BLUE] = { 0, 0, 238 }, /* blue */
|
||||
[COLOR_MAGENTA] = { 205, 0 , 205 }, /* magenta */
|
||||
[COLOR_CYAN] = { 0, 205, 205 }, /* cyan */
|
||||
[COLOR_LIGHT_GREY] = { 229, 229, 229 }, /* light grey */
|
||||
[COLOR_DARK_GREY] = { 127, 127, 127 }, /* dark grey */
|
||||
[COLOR_LIGHT_RED] = { 255, 0, 0 }, /* light red */
|
||||
[COLOR_LIGHT_GREEN] = { 0, 255, 0 }, /* light green */
|
||||
[COLOR_LIGHT_YELLOW] = { 255, 255, 0 }, /* light yellow */
|
||||
[COLOR_LIGHT_BLUE] = { 92, 92, 255 }, /* light blue */
|
||||
[COLOR_LIGHT_MAGENTA] = { 255, 0, 255 }, /* light magenta */
|
||||
[COLOR_LIGHT_CYAN] = { 0, 255, 255 }, /* light cyan */
|
||||
[COLOR_WHITE] = { 255, 255, 255 } /* white */
|
||||
};
|
||||
|
||||
static void set_fcolor(struct font_char_attr *attr, unsigned int color)
|
||||
{
|
||||
if (color >= COLOR_NUM)
|
||||
color = COLOR_WHITE;
|
||||
|
||||
attr->fr = color_palette[color][0];
|
||||
attr->fg = color_palette[color][1];
|
||||
attr->fb = color_palette[color][2];
|
||||
}
|
||||
|
||||
static void set_bcolor(struct font_char_attr *attr, unsigned int color)
|
||||
{
|
||||
if (color >= COLOR_NUM)
|
||||
color = COLOR_BLACK;
|
||||
|
||||
attr->br = color_palette[color][0];
|
||||
attr->bg = color_palette[color][1];
|
||||
attr->bb = color_palette[color][2];
|
||||
}
|
||||
|
||||
int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_console *con,
|
||||
kmscon_vte_write_cb write_cb, void *data)
|
||||
{
|
||||
@ -191,6 +252,8 @@ int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_console *con,
|
||||
vte->con = con;
|
||||
vte->write_cb = write_cb;
|
||||
vte->data = data;
|
||||
vte->def_fcol = COLOR_LIGHT_GREY;
|
||||
vte->def_bcol = COLOR_BLACK;
|
||||
|
||||
ret = kmscon_utf8_mach_new(&vte->mach);
|
||||
if (ret)
|
||||
@ -306,12 +369,8 @@ static void reset_state(struct kmscon_vte *vte)
|
||||
vte->gl = &kmscon_vte_unicode_lower;
|
||||
vte->gr = &kmscon_vte_unicode_upper;
|
||||
|
||||
vte->cattr.fr = 255;
|
||||
vte->cattr.fg = 255;
|
||||
vte->cattr.fb = 255;
|
||||
vte->cattr.br = 0;
|
||||
vte->cattr.bg = 0;
|
||||
vte->cattr.bb = 0;
|
||||
set_fcolor(&vte->cattr, vte->def_fcol);
|
||||
set_bcolor(&vte->cattr, vte->def_bcol);
|
||||
vte->cattr.bold = 0;
|
||||
vte->cattr.underline = 0;
|
||||
vte->cattr.inverse = 0;
|
||||
@ -777,19 +836,21 @@ static void do_esc(struct kmscon_vte *vte, uint32_t data)
|
||||
|
||||
static void csi_attribute(struct kmscon_vte *vte)
|
||||
{
|
||||
unsigned int i;
|
||||
static const uint8_t bval[6] = { 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff };
|
||||
unsigned int i, code;
|
||||
|
||||
if (vte->csi_argc <= 1 && vte->csi_argv[0] == -1) {
|
||||
vte->csi_argc = 1;
|
||||
vte->csi_argv[0] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < vte->csi_argc; ++i) {
|
||||
switch (vte->csi_argv[i]) {
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
vte->cattr.fr = 255;
|
||||
vte->cattr.fg = 255;
|
||||
vte->cattr.fb = 255;
|
||||
vte->cattr.br = 0;
|
||||
vte->cattr.bg = 0;
|
||||
vte->cattr.bb = 0;
|
||||
set_fcolor(&vte->cattr, vte->def_fcol);
|
||||
set_bcolor(&vte->cattr, vte->def_bcol);
|
||||
vte->cattr.bold = 0;
|
||||
vte->cattr.underline = 0;
|
||||
vte->cattr.inverse = 0;
|
||||
@ -813,44 +874,153 @@ static void csi_attribute(struct kmscon_vte *vte)
|
||||
vte->cattr.inverse = 0;
|
||||
break;
|
||||
case 30:
|
||||
vte->cattr.fr = 0;
|
||||
vte->cattr.fg = 0;
|
||||
vte->cattr.fb = 0;
|
||||
set_fcolor(&vte->cattr, COLOR_BLACK);
|
||||
break;
|
||||
case 31:
|
||||
vte->cattr.fr = 205;
|
||||
vte->cattr.fg = 0;
|
||||
vte->cattr.fb = 0;
|
||||
set_fcolor(&vte->cattr, COLOR_RED);
|
||||
break;
|
||||
case 32:
|
||||
vte->cattr.fr = 0;
|
||||
vte->cattr.fg = 205;
|
||||
vte->cattr.fb = 0;
|
||||
set_fcolor(&vte->cattr, COLOR_GREEN);
|
||||
break;
|
||||
case 33:
|
||||
vte->cattr.fr = 205;
|
||||
vte->cattr.fg = 205;
|
||||
vte->cattr.fb = 0;
|
||||
set_fcolor(&vte->cattr, COLOR_YELLOW);
|
||||
break;
|
||||
case 34:
|
||||
vte->cattr.fr = 0;
|
||||
vte->cattr.fg = 0;
|
||||
vte->cattr.fb = 238;
|
||||
set_fcolor(&vte->cattr, COLOR_BLUE);
|
||||
break;
|
||||
case 35:
|
||||
vte->cattr.fr = 205;
|
||||
vte->cattr.fg = 0;
|
||||
vte->cattr.fb = 205;
|
||||
set_fcolor(&vte->cattr, COLOR_MAGENTA);
|
||||
break;
|
||||
case 36:
|
||||
vte->cattr.fr = 0;
|
||||
vte->cattr.fg = 205;
|
||||
vte->cattr.fb = 205;
|
||||
set_fcolor(&vte->cattr, COLOR_CYAN);
|
||||
break;
|
||||
case 37:
|
||||
vte->cattr.fr = 255;
|
||||
vte->cattr.fg = 255;
|
||||
vte->cattr.fb = 255;
|
||||
set_fcolor(&vte->cattr, COLOR_LIGHT_GREY);
|
||||
break;
|
||||
case 39:
|
||||
set_fcolor(&vte->cattr, vte->def_fcol);
|
||||
break;
|
||||
case 40:
|
||||
set_bcolor(&vte->cattr, COLOR_BLACK);
|
||||
break;
|
||||
case 41:
|
||||
set_bcolor(&vte->cattr, COLOR_RED);
|
||||
break;
|
||||
case 42:
|
||||
set_bcolor(&vte->cattr, COLOR_GREEN);
|
||||
break;
|
||||
case 43:
|
||||
set_bcolor(&vte->cattr, COLOR_YELLOW);
|
||||
break;
|
||||
case 44:
|
||||
set_bcolor(&vte->cattr, COLOR_BLUE);
|
||||
break;
|
||||
case 45:
|
||||
set_bcolor(&vte->cattr, COLOR_MAGENTA);
|
||||
break;
|
||||
case 46:
|
||||
set_bcolor(&vte->cattr, COLOR_CYAN);
|
||||
break;
|
||||
case 47:
|
||||
set_bcolor(&vte->cattr, COLOR_LIGHT_GREY);
|
||||
break;
|
||||
case 49:
|
||||
set_bcolor(&vte->cattr, vte->def_bcol);
|
||||
break;
|
||||
case 90:
|
||||
set_fcolor(&vte->cattr, COLOR_DARK_GREY);
|
||||
break;
|
||||
case 91:
|
||||
set_fcolor(&vte->cattr, COLOR_LIGHT_RED);
|
||||
break;
|
||||
case 92:
|
||||
set_fcolor(&vte->cattr, COLOR_LIGHT_GREEN);
|
||||
break;
|
||||
case 93:
|
||||
set_fcolor(&vte->cattr, COLOR_LIGHT_YELLOW);
|
||||
break;
|
||||
case 94:
|
||||
set_fcolor(&vte->cattr, COLOR_LIGHT_BLUE);
|
||||
break;
|
||||
case 95:
|
||||
set_fcolor(&vte->cattr, COLOR_LIGHT_MAGENTA);
|
||||
break;
|
||||
case 96:
|
||||
set_fcolor(&vte->cattr, COLOR_LIGHT_CYAN);
|
||||
break;
|
||||
case 97:
|
||||
set_fcolor(&vte->cattr, COLOR_WHITE);
|
||||
break;
|
||||
case 100:
|
||||
set_bcolor(&vte->cattr, COLOR_DARK_GREY);
|
||||
break;
|
||||
case 101:
|
||||
set_bcolor(&vte->cattr, COLOR_LIGHT_RED);
|
||||
break;
|
||||
case 102:
|
||||
set_bcolor(&vte->cattr, COLOR_LIGHT_GREEN);
|
||||
break;
|
||||
case 103:
|
||||
set_bcolor(&vte->cattr, COLOR_LIGHT_YELLOW);
|
||||
break;
|
||||
case 104:
|
||||
set_bcolor(&vte->cattr, COLOR_LIGHT_BLUE);
|
||||
break;
|
||||
case 105:
|
||||
set_bcolor(&vte->cattr, COLOR_LIGHT_MAGENTA);
|
||||
break;
|
||||
case 106:
|
||||
set_bcolor(&vte->cattr, COLOR_LIGHT_CYAN);
|
||||
break;
|
||||
case 107:
|
||||
set_bcolor(&vte->cattr, COLOR_WHITE);
|
||||
break;
|
||||
case 38:
|
||||
/* fallthrough */
|
||||
case 48:
|
||||
if (i + 2 >= vte->csi_argc ||
|
||||
vte->csi_argv[i + 1] != 5 ||
|
||||
vte->csi_argv[i + 2] < 0) {
|
||||
log_debug("invalid 256color SGR");
|
||||
break;
|
||||
}
|
||||
|
||||
code = vte->csi_argv[i + 2];
|
||||
if (vte->csi_argv[i] == 38) {
|
||||
if (code < 16) {
|
||||
set_fcolor(&vte->cattr, code);
|
||||
} else if (code < 232) {
|
||||
code -= 16;
|
||||
vte->cattr.fb = bval[code % 6];
|
||||
code /= 6;
|
||||
vte->cattr.fg = bval[code % 6];
|
||||
code /= 6;
|
||||
vte->cattr.fr = bval[code % 6];
|
||||
} else {
|
||||
code = (code - 232) * 10 + 8;
|
||||
vte->cattr.fr = code;
|
||||
vte->cattr.fg = code;
|
||||
vte->cattr.fb = code;
|
||||
}
|
||||
} else {
|
||||
if (code < 16) {
|
||||
set_bcolor(&vte->cattr, code);
|
||||
} else if (code < 232) {
|
||||
code -= 16;
|
||||
vte->cattr.bb = bval[code % 6];
|
||||
code /= 6;
|
||||
vte->cattr.bg = bval[code % 6];
|
||||
code /= 6;
|
||||
vte->cattr.br = bval[code % 6];
|
||||
} else {
|
||||
code = (code - 232) * 10 + 8;
|
||||
vte->cattr.br = code;
|
||||
vte->cattr.bg = code;
|
||||
vte->cattr.bb = code;
|
||||
}
|
||||
}
|
||||
|
||||
i += 2;
|
||||
break;
|
||||
default:
|
||||
log_debug("unhandled SGR attr %i",
|
||||
|
Loading…
x
Reference in New Issue
Block a user