mirror of
https://github.com/tmux/tmux.git
synced 2024-12-12 17:38:48 +00:00
Handle the RGB colour escape sequence (\033[38;2;<r>;<g>;<b>m and 48;2)
like xterm(1) does, by mapping to the nearest in the 256 colour palette.
This commit is contained in:
parent
1cb073d48e
commit
55b96a5bd5
34
colour.c
34
colour.c
@ -281,12 +281,11 @@ const struct colour_rgb colour_to_256[] = {
|
|||||||
{ 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
|
{ 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
|
||||||
};
|
};
|
||||||
|
|
||||||
int colour_rgb_cmp(const void *, const void *);
|
int colour_cmp_rgb(const void *, const void *);
|
||||||
int colour_rgb_find(struct colour_rgb *);
|
|
||||||
|
|
||||||
/* Compare function for bsearch(). */
|
/* Compare function for bsearch(). */
|
||||||
int
|
int
|
||||||
colour_rgb_cmp(const void *lhs0, const void *rhs0)
|
colour_cmp_rgb(const void *lhs0, const void *rhs0)
|
||||||
{
|
{
|
||||||
const struct colour_rgb *lhs = lhs0, *rhs = rhs0;
|
const struct colour_rgb *lhs = lhs0, *rhs = rhs0;
|
||||||
|
|
||||||
@ -310,23 +309,22 @@ colour_rgb_cmp(const void *lhs0, const void *rhs0)
|
|||||||
|
|
||||||
/* Work out the nearest colour from the 256 colour set. */
|
/* Work out the nearest colour from the 256 colour set. */
|
||||||
int
|
int
|
||||||
colour_rgb_find(struct colour_rgb *rgb)
|
colour_find_rgb(u_char r, u_char g, u_char b)
|
||||||
{
|
{
|
||||||
struct colour_rgb *found;
|
struct colour_rgb rgb = { .r = r, .g = g, .b = b }, *found;
|
||||||
u_int distance, lowest, colour, i;
|
u_int distance, lowest, colour, i;
|
||||||
int r, g, b;
|
|
||||||
|
|
||||||
found = bsearch(rgb, colour_to_256, nitems(colour_to_256),
|
found = bsearch(&rgb, colour_to_256, nitems(colour_to_256),
|
||||||
sizeof colour_to_256[0], colour_rgb_cmp);
|
sizeof colour_to_256[0], colour_cmp_rgb);
|
||||||
if (found != NULL)
|
if (found != NULL)
|
||||||
return (16 + found->i);
|
return (16 + found->i);
|
||||||
|
|
||||||
colour = 16;
|
colour = 16;
|
||||||
lowest = UINT_MAX;
|
lowest = UINT_MAX;
|
||||||
for (i = 0; i < 240; i++) {
|
for (i = 0; i < 240; i++) {
|
||||||
r = colour_from_256[i].r - rgb->r;
|
r = colour_from_256[i].r - rgb.r;
|
||||||
g = colour_from_256[i].g - rgb->g;
|
g = colour_from_256[i].g - rgb.g;
|
||||||
b = colour_from_256[i].b - rgb->b;
|
b = colour_from_256[i].b - rgb.b;
|
||||||
|
|
||||||
distance = r * r + g * g + b * b;
|
distance = r * r + g * g + b * b;
|
||||||
if (distance < lowest) {
|
if (distance < lowest) {
|
||||||
@ -409,20 +407,20 @@ colour_tostring(int c)
|
|||||||
int
|
int
|
||||||
colour_fromstring(const char *s)
|
colour_fromstring(const char *s)
|
||||||
{
|
{
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
const char *cp;
|
const char *cp;
|
||||||
struct colour_rgb rgb;
|
int n;
|
||||||
int n;
|
u_char r, g, b;
|
||||||
|
|
||||||
if (*s == '#' && strlen(s) == 7) {
|
if (*s == '#' && strlen(s) == 7) {
|
||||||
for (cp = s + 1; isxdigit((u_char) *cp); cp++)
|
for (cp = s + 1; isxdigit((u_char) *cp); cp++)
|
||||||
;
|
;
|
||||||
if (*cp != '\0')
|
if (*cp != '\0')
|
||||||
return (-1);
|
return (-1);
|
||||||
n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &rgb.r, &rgb.g, &rgb.b);
|
n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &r, &g, &b);
|
||||||
if (n != 3)
|
if (n != 3)
|
||||||
return (-1);
|
return (-1);
|
||||||
return (colour_rgb_find(&rgb) | 0x100);
|
return (colour_find_rgb(r, g, b) | 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
|
if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
|
||||||
|
91
input.c
91
input.c
@ -126,6 +126,8 @@ void input_csi_dispatch_rm_private(struct input_ctx *);
|
|||||||
void input_csi_dispatch_sm(struct input_ctx *);
|
void input_csi_dispatch_sm(struct input_ctx *);
|
||||||
void input_csi_dispatch_sm_private(struct input_ctx *);
|
void input_csi_dispatch_sm_private(struct input_ctx *);
|
||||||
void input_csi_dispatch_winops(struct input_ctx *);
|
void input_csi_dispatch_winops(struct input_ctx *);
|
||||||
|
void input_csi_dispatch_sgr_256(struct input_ctx *, int, u_int *);
|
||||||
|
void input_csi_dispatch_sgr_rgb(struct input_ctx *, int, u_int *);
|
||||||
void input_csi_dispatch_sgr(struct input_ctx *);
|
void input_csi_dispatch_sgr(struct input_ctx *);
|
||||||
int input_dcs_dispatch(struct input_ctx *);
|
int input_dcs_dispatch(struct input_ctx *);
|
||||||
int input_utf8_open(struct input_ctx *);
|
int input_utf8_open(struct input_ctx *);
|
||||||
@ -1609,13 +1611,71 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle CSI SGR for 256 colours. */
|
||||||
|
void
|
||||||
|
input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i)
|
||||||
|
{
|
||||||
|
struct grid_cell *gc = &ictx->cell.cell;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
(*i)++;
|
||||||
|
c = input_get(ictx, *i, 0, -1);
|
||||||
|
if (c == -1) {
|
||||||
|
if (fgbg == 38) {
|
||||||
|
gc->flags &= ~GRID_FLAG_FG256;
|
||||||
|
gc->fg = 8;
|
||||||
|
} else if (fgbg == 48) {
|
||||||
|
gc->flags &= ~GRID_FLAG_BG256;
|
||||||
|
gc->bg = 8;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fgbg == 38) {
|
||||||
|
gc->flags |= GRID_FLAG_FG256;
|
||||||
|
gc->fg = c;
|
||||||
|
} else if (fgbg == 48) {
|
||||||
|
gc->flags |= GRID_FLAG_BG256;
|
||||||
|
gc->bg = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle CSI SGR for RGB colours. */
|
||||||
|
void
|
||||||
|
input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
|
||||||
|
{
|
||||||
|
struct grid_cell *gc = &ictx->cell.cell;
|
||||||
|
int c, r, g, b;
|
||||||
|
|
||||||
|
(*i)++;
|
||||||
|
r = input_get(ictx, *i, 0, -1);
|
||||||
|
if (r == -1 || r > 255)
|
||||||
|
return;
|
||||||
|
(*i)++;
|
||||||
|
g = input_get(ictx, *i, 0, -1);
|
||||||
|
if (g == -1 || g > 255)
|
||||||
|
return;
|
||||||
|
(*i)++;
|
||||||
|
b = input_get(ictx, *i, 0, -1);
|
||||||
|
if (b == -1 || b > 255)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c = colour_find_rgb(r, g, b);
|
||||||
|
if (fgbg == 38) {
|
||||||
|
gc->flags |= GRID_FLAG_FG256;
|
||||||
|
gc->fg = c;
|
||||||
|
} else if (fgbg == 48) {
|
||||||
|
gc->flags |= GRID_FLAG_BG256;
|
||||||
|
gc->bg = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle CSI SGR. */
|
/* Handle CSI SGR. */
|
||||||
void
|
void
|
||||||
input_csi_dispatch_sgr(struct input_ctx *ictx)
|
input_csi_dispatch_sgr(struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
struct grid_cell *gc = &ictx->cell.cell;
|
struct grid_cell *gc = &ictx->cell.cell;
|
||||||
u_int i;
|
u_int i;
|
||||||
int n, m;
|
int n;
|
||||||
|
|
||||||
if (ictx->param_list_len == 0) {
|
if (ictx->param_list_len == 0) {
|
||||||
memcpy(gc, &grid_default_cell, sizeof *gc);
|
memcpy(gc, &grid_default_cell, sizeof *gc);
|
||||||
@ -1627,28 +1687,13 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
|||||||
|
|
||||||
if (n == 38 || n == 48) {
|
if (n == 38 || n == 48) {
|
||||||
i++;
|
i++;
|
||||||
if (input_get(ictx, i, 0, -1) != 5)
|
switch (input_get(ictx, i, 0, -1)) {
|
||||||
continue;
|
case 2:
|
||||||
|
input_csi_dispatch_sgr_rgb(ictx, n, &i);
|
||||||
i++;
|
break;
|
||||||
m = input_get(ictx, i, 0, -1);
|
case 5:
|
||||||
if (m == -1) {
|
input_csi_dispatch_sgr_256(ictx, n, &i);
|
||||||
if (n == 38) {
|
break;
|
||||||
gc->flags &= ~GRID_FLAG_FG256;
|
|
||||||
gc->fg = 8;
|
|
||||||
} else if (n == 48) {
|
|
||||||
gc->flags &= ~GRID_FLAG_BG256;
|
|
||||||
gc->bg = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (n == 38) {
|
|
||||||
gc->flags |= GRID_FLAG_FG256;
|
|
||||||
gc->fg = m;
|
|
||||||
} else if (n == 48) {
|
|
||||||
gc->flags |= GRID_FLAG_BG256;
|
|
||||||
gc->bg = m;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
1
tmux.h
1
tmux.h
@ -1953,6 +1953,7 @@ char *xterm_keys_lookup(int);
|
|||||||
int xterm_keys_find(const char *, size_t, size_t *, int *);
|
int xterm_keys_find(const char *, size_t, size_t *, int *);
|
||||||
|
|
||||||
/* colour.c */
|
/* colour.c */
|
||||||
|
int colour_find_rgb(u_char, u_char, u_char);
|
||||||
void colour_set_fg(struct grid_cell *, int);
|
void colour_set_fg(struct grid_cell *, int);
|
||||||
void colour_set_bg(struct grid_cell *, int);
|
void colour_set_bg(struct grid_cell *, int);
|
||||||
const char *colour_tostring(int);
|
const char *colour_tostring(int);
|
||||||
|
Loading…
Reference in New Issue
Block a user