Skip to content

Instantly share code, notes, and snippets.

@zchee
Last active July 31, 2020 06:43

Revisions

  1. zchee revised this gist Aug 6, 2015. 1 changed file with 11 additions and 8 deletions.
    19 changes: 11 additions & 8 deletions tmux-truecolor.diff
    Original file line number Diff line number Diff line change
    @@ -718,7 +718,7 @@ index b9a663c..1b73244 100644
    void colour_set_bg(struct grid_cell *, int);
    const char *colour_tostring(int);
    diff --git a/tty.c b/tty.c
    index 374fb8c..b8f7b24 100644
    index 374fb8c..5e33301 100644
    --- a/tty.c
    +++ b/tty.c
    @@ -36,6 +36,7 @@ void tty_error_callback(struct bufferevent *, short, void *);
    @@ -763,7 +763,7 @@ index 374fb8c..b8f7b24 100644
    else {
    if (fg_default &&
    - (tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
    + (tc->fg != 8 || tc->flags & GRID_FLAG_FG256 || tc->flags & GRID_FLAG_FG24)) {
    + (tc->fg != 8 || tc->flags & GRID_FLAG_FG256 || tc->flags & GRID_FLAG_FG24)) {
    if (have_ax)
    tty_puts(tty, "\033[39m");
    else if (tc->fg != 7 ||
    @@ -776,7 +776,8 @@ index 374fb8c..b8f7b24 100644
    + tc->flags &= ~GRID_FLAG_FG24;
    }
    if (bg_default &&
    (tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) {
    - (tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) {
    + (tc->bg != 8 || tc->flags & GRID_FLAG_BG256 || tc->flags & GRID_FLAG_BG24)) {
    if (have_ax)
    tty_puts(tty, "\033[49m");
    else if (tc->bg != 0 ||
    @@ -917,7 +918,7 @@ index 374fb8c..b8f7b24 100644
    return;
    }

    @@ -1605,50 +1634,59 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    @@ -1605,50 +1634,60 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    if (fg >= 90 && fg <= 97) {
    xsnprintf(s, sizeof s, "\033[%dm", fg);
    tty_puts(tty, s);
    @@ -949,8 +950,8 @@ index 374fb8c..b8f7b24 100644
    +
    + /* Is this a 24-colour colour? */
    + if (gc->flags & GRID_FLAG_BG24) {
    + if (tty_try_256(tty, bg, "48") == 0){
    + tc->bg = bg;
    + if (tty_try_24(tty, rgb, "48") == 0){
    + tc->bg_rgb = rgb;
    + tc->flags |= gc->flags & GRID_FLAG_BG24;
    + }
    + return;
    @@ -959,11 +960,13 @@ index 374fb8c..b8f7b24 100644
    /* Is this a 256-colour colour? */
    if (gc->flags & GRID_FLAG_BG256) {
    - /* Try as 256 colours. */
    if (tty_try_256(tty, bg, "48") == 0)
    - if (tty_try_256(tty, bg, "48") == 0)
    - goto save_bg;
    - /* Else already handled by tty_check_bg. */
    + if (tty_try_256(tty, bg, "48") == 0){
    + tc->bg = bg;
    + tc->flags |= gc->flags & GRID_FLAG_BG256;
    + }
    return;
    }

    @@ -994,7 +997,7 @@ index 374fb8c..b8f7b24 100644
    }

    int
    @@ -1681,6 +1719,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    @@ -1681,6 +1720,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    return (-1);
    }

  2. zchee revised this gist Aug 6, 2015. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions tmux-truecolor.diff
    Original file line number Diff line number Diff line change
    @@ -718,7 +718,7 @@ index b9a663c..1b73244 100644
    void colour_set_bg(struct grid_cell *, int);
    const char *colour_tostring(int);
    diff --git a/tty.c b/tty.c
    index 374fb8c..96b008d 100644
    index 374fb8c..b8f7b24 100644
    --- a/tty.c
    +++ b/tty.c
    @@ -36,6 +36,7 @@ void tty_error_callback(struct bufferevent *, short, void *);
    @@ -917,7 +917,7 @@ index 374fb8c..96b008d 100644
    return;
    }

    @@ -1605,50 +1634,60 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    @@ -1605,50 +1634,59 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    if (fg >= 90 && fg <= 97) {
    xsnprintf(s, sizeof s, "\033[%dm", fg);
    tty_puts(tty, s);
    @@ -951,14 +951,14 @@ index 374fb8c..96b008d 100644
    + if (gc->flags & GRID_FLAG_BG24) {
    + if (tty_try_256(tty, bg, "48") == 0){
    + tc->bg = bg;
    + tc->flags |= gc->flags & GRID_FLAG_BG256;
    + tc->flags |= gc->flags & GRID_FLAG_BG24;
    + }
    + return;
    + }
    +
    /* Is this a 256-colour colour? */
    if (gc->flags & GRID_FLAG_BG256) {
    /* Try as 256 colours. */
    - /* Try as 256 colours. */
    if (tty_try_256(tty, bg, "48") == 0)
    - goto save_bg;
    - /* Else already handled by tty_check_bg. */
    @@ -994,7 +994,7 @@ index 374fb8c..96b008d 100644
    }

    int
    @@ -1681,6 +1720,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    @@ -1681,6 +1719,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    return (-1);
    }

  3. zchee revised this gist Aug 5, 2015. 1 changed file with 58 additions and 8 deletions.
    66 changes: 58 additions & 8 deletions tmux-truecolor.diff
    Original file line number Diff line number Diff line change
    @@ -718,7 +718,7 @@ index b9a663c..1b73244 100644
    void colour_set_bg(struct grid_cell *, int);
    const char *colour_tostring(int);
    diff --git a/tty.c b/tty.c
    index 374fb8c..536fbd9 100644
    index 374fb8c..96b008d 100644
    --- a/tty.c
    +++ b/tty.c
    @@ -36,6 +36,7 @@ void tty_error_callback(struct bufferevent *, short, void *);
    @@ -815,25 +815,75 @@ index 374fb8c..536fbd9 100644
    tty_colours_bg(tty, gc);
    }

    @@ -1528,7 +1548,7 @@ tty_check_fg(struct tty *tty, struct grid_cell *gc)
    colours = tty_term_number(tty->term, TTYC_COLORS);
    @@ -1525,20 +1545,15 @@ tty_check_fg(struct tty *tty, struct grid_cell *gc)
    {
    u_int colours;

    - colours = tty_term_number(tty->term, TTYC_COLORS);
    -
    /* Is this a 256-colour colour? */
    - if (gc->flags & GRID_FLAG_FG256) {
    + if (gc->flags & GRID_FLAG_FG256 && !(gc->flags & GRID_FLAG_BG24)) {
    /* And not a 256 colour mode? */
    if (!(tty->term->flags & TERM_256COLOURS) &&
    !(tty->term_flags & TERM_256COLOURS)) {
    @@ -1561,7 +1581,7 @@ tty_check_bg(struct tty *tty, struct grid_cell *gc)
    colours = tty_term_number(tty->term, TTYC_COLORS);
    gc->fg = colour_256to16(gc->fg);
    if (gc->fg & 8) {
    gc->fg &= 7;
    - if (colours >= 16)
    - gc->fg += 90;
    - else
    - gc->attr |= GRID_ATTR_BRIGHT;
    + gc->attr |= GRID_ATTR_BRIGHT;
    } else
    gc->attr &= ~GRID_ATTR_BRIGHT;
    gc->flags &= ~GRID_FLAG_FG256;
    @@ -1547,6 +1562,7 @@ tty_check_fg(struct tty *tty, struct grid_cell *gc)
    }

    /* Is this an aixterm colour? */
    + colours = tty_term_number(tty->term, TTYC_COLORS);
    if (gc->fg >= 90 && gc->fg <= 97 && colours < 16) {
    gc->fg -= 90;
    gc->attr |= GRID_ATTR_BRIGHT;
    @@ -1558,10 +1574,8 @@ tty_check_bg(struct tty *tty, struct grid_cell *gc)
    {
    u_int colours;

    - colours = tty_term_number(tty->term, TTYC_COLORS);
    -
    /* Is this a 256-colour colour? */
    - if (gc->flags & GRID_FLAG_BG256) {
    + if (gc->flags & GRID_FLAG_BG256 && !(gc->flags & GRID_FLAG_BG24)) {
    /*
    * And not a 256 colour mode? Translate to 16-colour
    * palette. Bold background doesn't exist portably, so just
    @@ -1589,15 +1609,29 @@ void
    @@ -1570,34 +1584,49 @@ tty_check_bg(struct tty *tty, struct grid_cell *gc)
    if (!(tty->term->flags & TERM_256COLOURS) &&
    !(tty->term_flags & TERM_256COLOURS)) {
    gc->bg = colour_256to16(gc->bg);
    - if (gc->bg & 8) {
    + if (gc->bg & 8)
    gc->bg &= 7;
    - if (colours >= 16)
    - gc->fg += 90;
    - }
    + gc->attr &= ~GRID_ATTR_BRIGHT;
    gc->flags &= ~GRID_FLAG_BG256;
    }
    return;
    }

    /* Is this an aixterm colour? */
    - if (gc->bg >= 90 && gc->bg <= 97 && colours < 16)
    + colours = tty_term_number(tty->term, TTYC_COLORS);
    + if (gc->bg >= 90 && gc->bg <= 97 && colours < 16) {
    gc->bg -= 90;
    + gc->attr |= GRID_ATTR_BRIGHT;
    + }
    }

    void
    tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    {
    struct grid_cell *tc = &tty->cell;
    @@ -867,7 +917,7 @@ index 374fb8c..536fbd9 100644
    return;
    }

    @@ -1605,50 +1639,60 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    @@ -1605,50 +1634,60 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    if (fg >= 90 && fg <= 97) {
    xsnprintf(s, sizeof s, "\033[%dm", fg);
    tty_puts(tty, s);
    @@ -944,7 +994,7 @@ index 374fb8c..536fbd9 100644
    }

    int
    @@ -1681,6 +1725,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    @@ -1681,6 +1720,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    return (-1);
    }

  4. zchee revised this gist Aug 5, 2015. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions tmux-truecolor.diff
    Original file line number Diff line number Diff line change
    @@ -718,7 +718,7 @@ index b9a663c..1b73244 100644
    void colour_set_bg(struct grid_cell *, int);
    const char *colour_tostring(int);
    diff --git a/tty.c b/tty.c
    index 374fb8c..b4def0a 100644
    index 374fb8c..536fbd9 100644
    --- a/tty.c
    +++ b/tty.c
    @@ -36,6 +36,7 @@ void tty_error_callback(struct bufferevent *, short, void *);
    @@ -867,7 +867,7 @@ index 374fb8c..b4def0a 100644
    return;
    }

    @@ -1605,50 +1639,59 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    @@ -1605,50 +1639,60 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    if (fg >= 90 && fg <= 97) {
    xsnprintf(s, sizeof s, "\033[%dm", fg);
    tty_puts(tty, s);
    @@ -881,7 +881,7 @@ index 374fb8c..b4def0a 100644
    -
    -save_fg:
    - /* Save the new values in the terminal current cell. */
    - tc->fg = fg;
    tc->fg = fg;
    - tc->flags &= ~GRID_FLAG_FG256;
    - tc->flags |= gc->flags & GRID_FLAG_FG256;
    }
    @@ -944,7 +944,7 @@ index 374fb8c..b4def0a 100644
    }

    int
    @@ -1681,6 +1724,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    @@ -1681,6 +1725,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    return (-1);
    }

  5. zchee revised this gist Aug 5, 2015. 1 changed file with 12 additions and 12 deletions.
    24 changes: 12 additions & 12 deletions tmux-truecolor.diff
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    diff --git a/tmux--git/colour.c b/tmux--git-24bit/colour.c
    diff --git a/colour.c b/colour.c
    index a56ddce..8098f83 100644
    --- a/tmux--git/colour.c
    +++ b/tmux--git-24bit/colour.c
    --- a/colour.c
    +++ b/colour.c
    @@ -29,305 +29,85 @@
    * of the 256 colour palette.
    */
    @@ -470,10 +470,10 @@ index a56ddce..8098f83 100644
    return (97);
    return (-1);
    }
    diff --git a/tmux--git/input.c b/tmux--git-24bit/input.c
    diff --git a/input.c b/input.c
    index 095816c..b74995f 100644
    --- a/tmux--git/input.c
    +++ b/tmux--git-24bit/input.c
    --- a/input.c
    +++ b/input.c
    @@ -127,8 +127,6 @@ void input_csi_dispatch_rm_private(struct input_ctx *);
    void input_csi_dispatch_sm(struct input_ctx *);
    void input_csi_dispatch_sm_private(struct input_ctx *);
    @@ -678,10 +678,10 @@ index 095816c..b74995f 100644
    gc->bg = n - 10;
    break;
    }
    diff --git a/tmux--git/tmux.h b/tmux--git-24bit/tmux.h
    diff --git a/tmux.h b/tmux.h
    index b9a663c..1b73244 100644
    --- a/tmux--git/tmux.h
    +++ b/tmux--git-24bit/tmux.h
    --- a/tmux.h
    +++ b/tmux.h
    @@ -631,9 +631,17 @@ struct utf8_data {
    #define GRID_FLAG_FG256 0x1
    #define GRID_FLAG_BG256 0x2
    @@ -717,10 +717,10 @@ index b9a663c..1b73244 100644
    void colour_set_fg(struct grid_cell *, int);
    void colour_set_bg(struct grid_cell *, int);
    const char *colour_tostring(int);
    diff --git a/tmux--git/tty.c b/tmux--git-24bit/tty.c
    diff --git a/tty.c b/tty.c
    index 374fb8c..b4def0a 100644
    --- a/tmux--git/tty.c
    +++ b/tmux--git-24bit/tty.c
    --- a/tty.c
    +++ b/tty.c
    @@ -36,6 +36,7 @@ void tty_error_callback(struct bufferevent *, short, void *);

    void tty_set_italics(struct tty *);
  6. zchee revised this gist Aug 5, 2015. 1 changed file with 0 additions and 3 deletions.
    3 changes: 0 additions & 3 deletions tmux-truecolor.diff
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,3 @@
    diff --git a/tmux--git/.git/index b/tmux--git-24bit/.git/index
    index 108c325..1861e3f 100644
    Binary files a/tmux--git/.git/index and b/tmux--git-24bit/.git/index differ
    diff --git a/tmux--git/colour.c b/tmux--git-24bit/colour.c
    index a56ddce..8098f83 100644
    --- a/tmux--git/colour.c
  7. zchee created this gist Aug 5, 2015.
    972 changes: 972 additions & 0 deletions tmux-truecolor.diff
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,972 @@
    diff --git a/tmux--git/.git/index b/tmux--git-24bit/.git/index
    index 108c325..1861e3f 100644
    Binary files a/tmux--git/.git/index and b/tmux--git-24bit/.git/index differ
    diff --git a/tmux--git/colour.c b/tmux--git-24bit/colour.c
    index a56ddce..8098f83 100644
    --- a/tmux--git/colour.c
    +++ b/tmux--git-24bit/colour.c
    @@ -29,305 +29,85 @@
    * of the 256 colour palette.
    */

    -struct colour_rgb {
    - u_char i;
    - u_char r;
    - u_char g;
    - u_char b;
    -};

    -const struct colour_rgb colour_from_256[] = {
    - { 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f },
    - { 2, 0x00, 0x00, 0x87 }, { 3, 0x00, 0x00, 0xaf },
    - { 4, 0x00, 0x00, 0xd7 }, { 5, 0x00, 0x00, 0xff },
    - { 6, 0x00, 0x5f, 0x00 }, { 7, 0x00, 0x5f, 0x5f },
    - { 8, 0x00, 0x5f, 0x87 }, { 9, 0x00, 0x5f, 0xaf },
    - { 10, 0x00, 0x5f, 0xd7 }, { 11, 0x00, 0x5f, 0xff },
    - { 12, 0x00, 0x87, 0x00 }, { 13, 0x00, 0x87, 0x5f },
    - { 14, 0x00, 0x87, 0x87 }, { 15, 0x00, 0x87, 0xaf },
    - { 16, 0x00, 0x87, 0xd7 }, { 17, 0x00, 0x87, 0xff },
    - { 18, 0x00, 0xaf, 0x00 }, { 19, 0x00, 0xaf, 0x5f },
    - { 20, 0x00, 0xaf, 0x87 }, { 21, 0x00, 0xaf, 0xaf },
    - { 22, 0x00, 0xaf, 0xd7 }, { 23, 0x00, 0xaf, 0xff },
    - { 24, 0x00, 0xd7, 0x00 }, { 25, 0x00, 0xd7, 0x5f },
    - { 26, 0x00, 0xd7, 0x87 }, { 27, 0x00, 0xd7, 0xaf },
    - { 28, 0x00, 0xd7, 0xd7 }, { 29, 0x00, 0xd7, 0xff },
    - { 30, 0x00, 0xff, 0x00 }, { 31, 0x00, 0xff, 0x5f },
    - { 32, 0x00, 0xff, 0x87 }, { 33, 0x00, 0xff, 0xaf },
    - { 34, 0x00, 0xff, 0xd7 }, { 35, 0x00, 0xff, 0xff },
    - { 36, 0x5f, 0x00, 0x00 }, { 37, 0x5f, 0x00, 0x5f },
    - { 38, 0x5f, 0x00, 0x87 }, { 39, 0x5f, 0x00, 0xaf },
    - { 40, 0x5f, 0x00, 0xd7 }, { 41, 0x5f, 0x00, 0xff },
    - { 42, 0x5f, 0x5f, 0x00 }, { 43, 0x5f, 0x5f, 0x5f },
    - { 44, 0x5f, 0x5f, 0x87 }, { 45, 0x5f, 0x5f, 0xaf },
    - { 46, 0x5f, 0x5f, 0xd7 }, { 47, 0x5f, 0x5f, 0xff },
    - { 48, 0x5f, 0x87, 0x00 }, { 49, 0x5f, 0x87, 0x5f },
    - { 50, 0x5f, 0x87, 0x87 }, { 51, 0x5f, 0x87, 0xaf },
    - { 52, 0x5f, 0x87, 0xd7 }, { 53, 0x5f, 0x87, 0xff },
    - { 54, 0x5f, 0xaf, 0x00 }, { 55, 0x5f, 0xaf, 0x5f },
    - { 56, 0x5f, 0xaf, 0x87 }, { 57, 0x5f, 0xaf, 0xaf },
    - { 58, 0x5f, 0xaf, 0xd7 }, { 59, 0x5f, 0xaf, 0xff },
    - { 60, 0x5f, 0xd7, 0x00 }, { 61, 0x5f, 0xd7, 0x5f },
    - { 62, 0x5f, 0xd7, 0x87 }, { 63, 0x5f, 0xd7, 0xaf },
    - { 64, 0x5f, 0xd7, 0xd7 }, { 65, 0x5f, 0xd7, 0xff },
    - { 66, 0x5f, 0xff, 0x00 }, { 67, 0x5f, 0xff, 0x5f },
    - { 68, 0x5f, 0xff, 0x87 }, { 69, 0x5f, 0xff, 0xaf },
    - { 70, 0x5f, 0xff, 0xd7 }, { 71, 0x5f, 0xff, 0xff },
    - { 72, 0x87, 0x00, 0x00 }, { 73, 0x87, 0x00, 0x5f },
    - { 74, 0x87, 0x00, 0x87 }, { 75, 0x87, 0x00, 0xaf },
    - { 76, 0x87, 0x00, 0xd7 }, { 77, 0x87, 0x00, 0xff },
    - { 78, 0x87, 0x5f, 0x00 }, { 79, 0x87, 0x5f, 0x5f },
    - { 80, 0x87, 0x5f, 0x87 }, { 81, 0x87, 0x5f, 0xaf },
    - { 82, 0x87, 0x5f, 0xd7 }, { 83, 0x87, 0x5f, 0xff },
    - { 84, 0x87, 0x87, 0x00 }, { 85, 0x87, 0x87, 0x5f },
    - { 86, 0x87, 0x87, 0x87 }, { 87, 0x87, 0x87, 0xaf },
    - { 88, 0x87, 0x87, 0xd7 }, { 89, 0x87, 0x87, 0xff },
    - { 90, 0x87, 0xaf, 0x00 }, { 91, 0x87, 0xaf, 0x5f },
    - { 92, 0x87, 0xaf, 0x87 }, { 93, 0x87, 0xaf, 0xaf },
    - { 94, 0x87, 0xaf, 0xd7 }, { 95, 0x87, 0xaf, 0xff },
    - { 96, 0x87, 0xd7, 0x00 }, { 97, 0x87, 0xd7, 0x5f },
    - { 98, 0x87, 0xd7, 0x87 }, { 99, 0x87, 0xd7, 0xaf },
    - { 100, 0x87, 0xd7, 0xd7 }, { 101, 0x87, 0xd7, 0xff },
    - { 102, 0x87, 0xff, 0x00 }, { 103, 0x87, 0xff, 0x5f },
    - { 104, 0x87, 0xff, 0x87 }, { 105, 0x87, 0xff, 0xaf },
    - { 106, 0x87, 0xff, 0xd7 }, { 107, 0x87, 0xff, 0xff },
    - { 108, 0xaf, 0x00, 0x00 }, { 109, 0xaf, 0x00, 0x5f },
    - { 110, 0xaf, 0x00, 0x87 }, { 111, 0xaf, 0x00, 0xaf },
    - { 112, 0xaf, 0x00, 0xd7 }, { 113, 0xaf, 0x00, 0xff },
    - { 114, 0xaf, 0x5f, 0x00 }, { 115, 0xaf, 0x5f, 0x5f },
    - { 116, 0xaf, 0x5f, 0x87 }, { 117, 0xaf, 0x5f, 0xaf },
    - { 118, 0xaf, 0x5f, 0xd7 }, { 119, 0xaf, 0x5f, 0xff },
    - { 120, 0xaf, 0x87, 0x00 }, { 121, 0xaf, 0x87, 0x5f },
    - { 122, 0xaf, 0x87, 0x87 }, { 123, 0xaf, 0x87, 0xaf },
    - { 124, 0xaf, 0x87, 0xd7 }, { 125, 0xaf, 0x87, 0xff },
    - { 126, 0xaf, 0xaf, 0x00 }, { 127, 0xaf, 0xaf, 0x5f },
    - { 128, 0xaf, 0xaf, 0x87 }, { 129, 0xaf, 0xaf, 0xaf },
    - { 130, 0xaf, 0xaf, 0xd7 }, { 131, 0xaf, 0xaf, 0xff },
    - { 132, 0xaf, 0xd7, 0x00 }, { 133, 0xaf, 0xd7, 0x5f },
    - { 134, 0xaf, 0xd7, 0x87 }, { 135, 0xaf, 0xd7, 0xaf },
    - { 136, 0xaf, 0xd7, 0xd7 }, { 137, 0xaf, 0xd7, 0xff },
    - { 138, 0xaf, 0xff, 0x00 }, { 139, 0xaf, 0xff, 0x5f },
    - { 140, 0xaf, 0xff, 0x87 }, { 141, 0xaf, 0xff, 0xaf },
    - { 142, 0xaf, 0xff, 0xd7 }, { 143, 0xaf, 0xff, 0xff },
    - { 144, 0xd7, 0x00, 0x00 }, { 145, 0xd7, 0x00, 0x5f },
    - { 146, 0xd7, 0x00, 0x87 }, { 147, 0xd7, 0x00, 0xaf },
    - { 148, 0xd7, 0x00, 0xd7 }, { 149, 0xd7, 0x00, 0xff },
    - { 150, 0xd7, 0x5f, 0x00 }, { 151, 0xd7, 0x5f, 0x5f },
    - { 152, 0xd7, 0x5f, 0x87 }, { 153, 0xd7, 0x5f, 0xaf },
    - { 154, 0xd7, 0x5f, 0xd7 }, { 155, 0xd7, 0x5f, 0xff },
    - { 156, 0xd7, 0x87, 0x00 }, { 157, 0xd7, 0x87, 0x5f },
    - { 158, 0xd7, 0x87, 0x87 }, { 159, 0xd7, 0x87, 0xaf },
    - { 160, 0xd7, 0x87, 0xd7 }, { 161, 0xd7, 0x87, 0xff },
    - { 162, 0xd7, 0xaf, 0x00 }, { 163, 0xd7, 0xaf, 0x5f },
    - { 164, 0xd7, 0xaf, 0x87 }, { 165, 0xd7, 0xaf, 0xaf },
    - { 166, 0xd7, 0xaf, 0xd7 }, { 167, 0xd7, 0xaf, 0xff },
    - { 168, 0xd7, 0xd7, 0x00 }, { 169, 0xd7, 0xd7, 0x5f },
    - { 170, 0xd7, 0xd7, 0x87 }, { 171, 0xd7, 0xd7, 0xaf },
    - { 172, 0xd7, 0xd7, 0xd7 }, { 173, 0xd7, 0xd7, 0xff },
    - { 174, 0xd7, 0xff, 0x00 }, { 175, 0xd7, 0xff, 0x5f },
    - { 176, 0xd7, 0xff, 0x87 }, { 177, 0xd7, 0xff, 0xaf },
    - { 178, 0xd7, 0xff, 0xd7 }, { 179, 0xd7, 0xff, 0xff },
    - { 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
    - { 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
    - { 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
    - { 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
    - { 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
    - { 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
    - { 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
    - { 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
    - { 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
    - { 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
    - { 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
    - { 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
    - { 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
    - { 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
    - { 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
    - { 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
    - { 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
    - { 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
    - { 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
    - { 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
    - { 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
    - { 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
    - { 224, 0x58, 0x58, 0x58 }, { 225, 0x62, 0x62, 0x62 },
    - { 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
    - { 228, 0x80, 0x80, 0x80 }, { 229, 0x8a, 0x8a, 0x8a },
    - { 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
    - { 232, 0xa8, 0xa8, 0xa8 }, { 233, 0xb2, 0xb2, 0xb2 },
    - { 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
    - { 236, 0xd0, 0xd0, 0xd0 }, { 237, 0xda, 0xda, 0xda },
    - { 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
    -};
    -const struct colour_rgb colour_to_256[] = {
    - { 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f },
    - { 2, 0x00, 0x00, 0x87 }, { 3, 0x00, 0x00, 0xaf },
    - { 4, 0x00, 0x00, 0xd7 }, { 5, 0x00, 0x00, 0xff },
    - { 6, 0x00, 0x5f, 0x00 }, { 7, 0x00, 0x5f, 0x5f },
    - { 8, 0x00, 0x5f, 0x87 }, { 9, 0x00, 0x5f, 0xaf },
    - { 10, 0x00, 0x5f, 0xd7 }, { 11, 0x00, 0x5f, 0xff },
    - { 12, 0x00, 0x87, 0x00 }, { 13, 0x00, 0x87, 0x5f },
    - { 14, 0x00, 0x87, 0x87 }, { 15, 0x00, 0x87, 0xaf },
    - { 16, 0x00, 0x87, 0xd7 }, { 17, 0x00, 0x87, 0xff },
    - { 18, 0x00, 0xaf, 0x00 }, { 19, 0x00, 0xaf, 0x5f },
    - { 20, 0x00, 0xaf, 0x87 }, { 21, 0x00, 0xaf, 0xaf },
    - { 22, 0x00, 0xaf, 0xd7 }, { 23, 0x00, 0xaf, 0xff },
    - { 24, 0x00, 0xd7, 0x00 }, { 25, 0x00, 0xd7, 0x5f },
    - { 26, 0x00, 0xd7, 0x87 }, { 27, 0x00, 0xd7, 0xaf },
    - { 28, 0x00, 0xd7, 0xd7 }, { 29, 0x00, 0xd7, 0xff },
    - { 30, 0x00, 0xff, 0x00 }, { 31, 0x00, 0xff, 0x5f },
    - { 32, 0x00, 0xff, 0x87 }, { 33, 0x00, 0xff, 0xaf },
    - { 34, 0x00, 0xff, 0xd7 }, { 35, 0x00, 0xff, 0xff },
    - { 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
    - { 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
    - { 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
    - { 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
    - { 224, 0x58, 0x58, 0x58 }, { 36, 0x5f, 0x00, 0x00 },
    - { 37, 0x5f, 0x00, 0x5f }, { 38, 0x5f, 0x00, 0x87 },
    - { 39, 0x5f, 0x00, 0xaf }, { 40, 0x5f, 0x00, 0xd7 },
    - { 41, 0x5f, 0x00, 0xff }, { 42, 0x5f, 0x5f, 0x00 },
    - { 43, 0x5f, 0x5f, 0x5f }, { 44, 0x5f, 0x5f, 0x87 },
    - { 45, 0x5f, 0x5f, 0xaf }, { 46, 0x5f, 0x5f, 0xd7 },
    - { 47, 0x5f, 0x5f, 0xff }, { 48, 0x5f, 0x87, 0x00 },
    - { 49, 0x5f, 0x87, 0x5f }, { 50, 0x5f, 0x87, 0x87 },
    - { 51, 0x5f, 0x87, 0xaf }, { 52, 0x5f, 0x87, 0xd7 },
    - { 53, 0x5f, 0x87, 0xff }, { 54, 0x5f, 0xaf, 0x00 },
    - { 55, 0x5f, 0xaf, 0x5f }, { 56, 0x5f, 0xaf, 0x87 },
    - { 57, 0x5f, 0xaf, 0xaf }, { 58, 0x5f, 0xaf, 0xd7 },
    - { 59, 0x5f, 0xaf, 0xff }, { 60, 0x5f, 0xd7, 0x00 },
    - { 61, 0x5f, 0xd7, 0x5f }, { 62, 0x5f, 0xd7, 0x87 },
    - { 63, 0x5f, 0xd7, 0xaf }, { 64, 0x5f, 0xd7, 0xd7 },
    - { 65, 0x5f, 0xd7, 0xff }, { 66, 0x5f, 0xff, 0x00 },
    - { 67, 0x5f, 0xff, 0x5f }, { 68, 0x5f, 0xff, 0x87 },
    - { 69, 0x5f, 0xff, 0xaf }, { 70, 0x5f, 0xff, 0xd7 },
    - { 71, 0x5f, 0xff, 0xff }, { 225, 0x62, 0x62, 0x62 },
    - { 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
    - { 228, 0x80, 0x80, 0x80 }, { 72, 0x87, 0x00, 0x00 },
    - { 73, 0x87, 0x00, 0x5f }, { 74, 0x87, 0x00, 0x87 },
    - { 75, 0x87, 0x00, 0xaf }, { 76, 0x87, 0x00, 0xd7 },
    - { 77, 0x87, 0x00, 0xff }, { 78, 0x87, 0x5f, 0x00 },
    - { 79, 0x87, 0x5f, 0x5f }, { 80, 0x87, 0x5f, 0x87 },
    - { 81, 0x87, 0x5f, 0xaf }, { 82, 0x87, 0x5f, 0xd7 },
    - { 83, 0x87, 0x5f, 0xff }, { 84, 0x87, 0x87, 0x00 },
    - { 85, 0x87, 0x87, 0x5f }, { 86, 0x87, 0x87, 0x87 },
    - { 87, 0x87, 0x87, 0xaf }, { 88, 0x87, 0x87, 0xd7 },
    - { 89, 0x87, 0x87, 0xff }, { 90, 0x87, 0xaf, 0x00 },
    - { 91, 0x87, 0xaf, 0x5f }, { 92, 0x87, 0xaf, 0x87 },
    - { 93, 0x87, 0xaf, 0xaf }, { 94, 0x87, 0xaf, 0xd7 },
    - { 95, 0x87, 0xaf, 0xff }, { 96, 0x87, 0xd7, 0x00 },
    - { 97, 0x87, 0xd7, 0x5f }, { 98, 0x87, 0xd7, 0x87 },
    - { 99, 0x87, 0xd7, 0xaf }, { 100, 0x87, 0xd7, 0xd7 },
    - { 101, 0x87, 0xd7, 0xff }, { 102, 0x87, 0xff, 0x00 },
    - { 103, 0x87, 0xff, 0x5f }, { 104, 0x87, 0xff, 0x87 },
    - { 105, 0x87, 0xff, 0xaf }, { 106, 0x87, 0xff, 0xd7 },
    - { 107, 0x87, 0xff, 0xff }, { 229, 0x8a, 0x8a, 0x8a },
    - { 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
    - { 232, 0xa8, 0xa8, 0xa8 }, { 108, 0xaf, 0x00, 0x00 },
    - { 109, 0xaf, 0x00, 0x5f }, { 110, 0xaf, 0x00, 0x87 },
    - { 111, 0xaf, 0x00, 0xaf }, { 112, 0xaf, 0x00, 0xd7 },
    - { 113, 0xaf, 0x00, 0xff }, { 114, 0xaf, 0x5f, 0x00 },
    - { 115, 0xaf, 0x5f, 0x5f }, { 116, 0xaf, 0x5f, 0x87 },
    - { 117, 0xaf, 0x5f, 0xaf }, { 118, 0xaf, 0x5f, 0xd7 },
    - { 119, 0xaf, 0x5f, 0xff }, { 120, 0xaf, 0x87, 0x00 },
    - { 121, 0xaf, 0x87, 0x5f }, { 122, 0xaf, 0x87, 0x87 },
    - { 123, 0xaf, 0x87, 0xaf }, { 124, 0xaf, 0x87, 0xd7 },
    - { 125, 0xaf, 0x87, 0xff }, { 126, 0xaf, 0xaf, 0x00 },
    - { 127, 0xaf, 0xaf, 0x5f }, { 128, 0xaf, 0xaf, 0x87 },
    - { 129, 0xaf, 0xaf, 0xaf }, { 130, 0xaf, 0xaf, 0xd7 },
    - { 131, 0xaf, 0xaf, 0xff }, { 132, 0xaf, 0xd7, 0x00 },
    - { 133, 0xaf, 0xd7, 0x5f }, { 134, 0xaf, 0xd7, 0x87 },
    - { 135, 0xaf, 0xd7, 0xaf }, { 136, 0xaf, 0xd7, 0xd7 },
    - { 137, 0xaf, 0xd7, 0xff }, { 138, 0xaf, 0xff, 0x00 },
    - { 139, 0xaf, 0xff, 0x5f }, { 140, 0xaf, 0xff, 0x87 },
    - { 141, 0xaf, 0xff, 0xaf }, { 142, 0xaf, 0xff, 0xd7 },
    - { 143, 0xaf, 0xff, 0xff }, { 233, 0xb2, 0xb2, 0xb2 },
    - { 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
    - { 236, 0xd0, 0xd0, 0xd0 }, { 144, 0xd7, 0x00, 0x00 },
    - { 145, 0xd7, 0x00, 0x5f }, { 146, 0xd7, 0x00, 0x87 },
    - { 147, 0xd7, 0x00, 0xaf }, { 148, 0xd7, 0x00, 0xd7 },
    - { 149, 0xd7, 0x00, 0xff }, { 150, 0xd7, 0x5f, 0x00 },
    - { 151, 0xd7, 0x5f, 0x5f }, { 152, 0xd7, 0x5f, 0x87 },
    - { 153, 0xd7, 0x5f, 0xaf }, { 154, 0xd7, 0x5f, 0xd7 },
    - { 155, 0xd7, 0x5f, 0xff }, { 156, 0xd7, 0x87, 0x00 },
    - { 157, 0xd7, 0x87, 0x5f }, { 158, 0xd7, 0x87, 0x87 },
    - { 159, 0xd7, 0x87, 0xaf }, { 160, 0xd7, 0x87, 0xd7 },
    - { 161, 0xd7, 0x87, 0xff }, { 162, 0xd7, 0xaf, 0x00 },
    - { 163, 0xd7, 0xaf, 0x5f }, { 164, 0xd7, 0xaf, 0x87 },
    - { 165, 0xd7, 0xaf, 0xaf }, { 166, 0xd7, 0xaf, 0xd7 },
    - { 167, 0xd7, 0xaf, 0xff }, { 168, 0xd7, 0xd7, 0x00 },
    - { 169, 0xd7, 0xd7, 0x5f }, { 170, 0xd7, 0xd7, 0x87 },
    - { 171, 0xd7, 0xd7, 0xaf }, { 172, 0xd7, 0xd7, 0xd7 },
    - { 173, 0xd7, 0xd7, 0xff }, { 174, 0xd7, 0xff, 0x00 },
    - { 175, 0xd7, 0xff, 0x5f }, { 176, 0xd7, 0xff, 0x87 },
    - { 177, 0xd7, 0xff, 0xaf }, { 178, 0xd7, 0xff, 0xd7 },
    - { 179, 0xd7, 0xff, 0xff }, { 237, 0xda, 0xda, 0xda },
    - { 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
    - { 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
    - { 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
    - { 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
    - { 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
    - { 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
    - { 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
    - { 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
    - { 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
    - { 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
    - { 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
    - { 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
    - { 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
    - { 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
    - { 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
    - { 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
    - { 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
    - { 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
    - { 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
    -};
    +/* 256 colour RGB table, generated on first use. */
    +struct colour_rgb *colour_rgb_256;

    -int colour_cmp_rgb(const void *, const void *);
    +void colour_rgb_generate256(void);
    +u_int colour_rgb_distance(struct colour_rgb *, struct colour_rgb *);
    +int colour_rgb_find(struct colour_rgb *);

    -/* Compare function for bsearch(). */
    -int
    -colour_cmp_rgb(const void *lhs0, const void *rhs0)
    +/* Generate 256 colour RGB table. */
    +void
    +colour_rgb_generate256(void)
    {
    - const struct colour_rgb *lhs = lhs0, *rhs = rhs0;
    + struct colour_rgb *rgb;
    + u_int i, r, g, b;

    - if (lhs->r < rhs->r)
    - return (-1);
    - if (lhs->r > rhs->r)
    - return (1);
    + /*
    + * Allocate the table. The first 16 colours are often changed by users
    + * and terminals so don't include them.
    + */
    + colour_rgb_256 = xcalloc(240, sizeof *colour_rgb_256);

    - if (lhs->g < rhs->g)
    - return (-1);
    - if (lhs->g > rhs->g)
    - return (1);
    + /* Add the colours first. */
    + r = g = b = 0;
    + for (i = 240; i > 24; i--) {
    + rgb = &colour_rgb_256[240 - i];

    - if (lhs->b < rhs->b)
    - return (-1);
    - if (lhs->b > rhs->b)
    - return (1);
    + if (r != 0)
    + rgb->r = (r * 40) + 55;
    + if (g != 0)
    + rgb->g = (g * 40) + 55;
    + if (b != 0)
    + rgb->b = (b * 40) + 55;
    +
    + b++;
    + if (b > 5) {
    + b = 0;
    + g++;
    + }
    + if (g > 5) {
    + g = 0;
    + r++;
    + }
    + }
    +
    + /* Then add the greys. */
    + for (i = 24; i > 0; i--) {
    + rgb = &colour_rgb_256[240 - i];
    +
    + rgb->r = 8 + (24 - i) * 10;
    + rgb->g = 8 + (24 - i) * 10;
    + rgb->b = 8 + (24 - i) * 10;
    + }
    +}
    +
    +/* Get colour RGB distance. */
    +u_int
    +colour_rgb_distance(struct colour_rgb *rgb1, struct colour_rgb *rgb2)
    +{
    + int r, g, b;

    - return (0);
    + r = rgb1->r - rgb2->r;
    + g = rgb1->g - rgb2->g;
    + b = rgb1->b - rgb2->b;
    + return (r * r + g * g + b * b);
    }

    /* Work out the nearest colour from the 256 colour set. */
    int
    -colour_find_rgb(u_char r, u_char g, u_char b)
    +colour_rgb_find(struct colour_rgb *rgb)
    {
    - struct colour_rgb rgb = { .r = r, .g = g, .b = b }, *found;
    - u_int distance, lowest, colour, i;
    - int dr, dg, db;
    + u_int distance, lowest, colour, i;

    - found = bsearch(&rgb, colour_to_256, nitems(colour_to_256),
    - sizeof colour_to_256[0], colour_cmp_rgb);
    - if (found != NULL)
    - return (16 + found->i);
    + if (colour_rgb_256 == NULL)
    + colour_rgb_generate256();

    colour = 16;
    lowest = UINT_MAX;
    for (i = 0; i < 240; i++) {
    - dr = (int)colour_from_256[i].r - r;
    - dg = (int)colour_from_256[i].g - g;
    - db = (int)colour_from_256[i].b - b;
    -
    - distance = dr * dr + dg * dg + db * db;
    + distance = colour_rgb_distance(&colour_rgb_256[i], rgb);
    if (distance < lowest) {
    lowest = distance;
    colour = 16 + i;
    @@ -361,7 +141,7 @@ colour_tostring(int c)
    static char s[32];

    if (c & 0x100) {
    - xsnprintf(s, sizeof s, "colour%d", c & ~0x100);
    + xsnprintf(s, sizeof s, "colour%u", c & ~0x100);
    return (s);
    }

    @@ -408,20 +188,20 @@ colour_tostring(int c)
    int
    colour_fromstring(const char *s)
    {
    - const char *errstr;
    - const char *cp;
    - int n;
    - u_char r, g, b;
    + const char *errstr;
    + const char *cp;
    + struct colour_rgb rgb;
    + int n;

    if (*s == '#' && strlen(s) == 7) {
    for (cp = s + 1; isxdigit((u_char) *cp); cp++)
    ;
    if (*cp != '\0')
    return (-1);
    - n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &r, &g, &b);
    + n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &rgb.r, &rgb.g, &rgb.b);
    if (n != 3)
    return (-1);
    - return (colour_find_rgb(r, g, b) | 0x100);
    + return (colour_rgb_find(&rgb) | 0x100);
    }

    if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
    @@ -431,39 +211,47 @@ colour_fromstring(const char *s)
    return (n | 0x100);
    }

    - if (strcasecmp(s, "black") == 0 || strcmp(s, "0") == 0)
    + if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0'))
    return (0);
    - if (strcasecmp(s, "red") == 0 || strcmp(s, "1") == 0)
    + if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0'))
    return (1);
    - if (strcasecmp(s, "green") == 0 || strcmp(s, "2") == 0)
    + if (strcasecmp(s, "green") == 0 || (s[0] == '2' && s[1] == '\0'))
    return (2);
    - if (strcasecmp(s, "yellow") == 0 || strcmp(s, "3") == 0)
    + if (strcasecmp(s, "yellow") == 0 || (s[0] == '3' && s[1] == '\0'))
    return (3);
    - if (strcasecmp(s, "blue") == 0 || strcmp(s, "4") == 0)
    + if (strcasecmp(s, "blue") == 0 || (s[0] == '4' && s[1] == '\0'))
    return (4);
    - if (strcasecmp(s, "magenta") == 0 || strcmp(s, "5") == 0)
    + if (strcasecmp(s, "magenta") == 0 || (s[0] == '5' && s[1] == '\0'))
    return (5);
    - if (strcasecmp(s, "cyan") == 0 || strcmp(s, "6") == 0)
    + if (strcasecmp(s, "cyan") == 0 || (s[0] == '6' && s[1] == '\0'))
    return (6);
    - if (strcasecmp(s, "white") == 0 || strcmp(s, "7") == 0)
    + if (strcasecmp(s, "white") == 0 || (s[0] == '7' && s[1] == '\0'))
    return (7);
    - if (strcasecmp(s, "default") == 0 || strcmp(s, "8") == 0)
    + if (strcasecmp(s, "default") == 0 || (s[0] == '8' && s[1] == '\0'))
    return (8);
    - if (strcasecmp(s, "brightblack") == 0 || strcmp(s, "90") == 0)
    + if (strcasecmp(s, "brightblack") == 0 ||
    + (s[0] == '9' && s[1] == '0' && s[2] == '\0'))
    return (90);
    - if (strcasecmp(s, "brightred") == 0 || strcmp(s, "91") == 0)
    + if (strcasecmp(s, "brightred") == 0 ||
    + (s[0] == '9' && s[1] == '1' && s[2] == '\0'))
    return (91);
    - if (strcasecmp(s, "brightgreen") == 0 || strcmp(s, "92") == 0)
    + if (strcasecmp(s, "brightgreen") == 0 ||
    + (s[0] == '9' && s[1] == '2' && s[2] == '\0'))
    return (92);
    - if (strcasecmp(s, "brightyellow") == 0 || strcmp(s, "93") == 0)
    + if (strcasecmp(s, "brightyellow") == 0 ||
    + (s[0] == '9' && s[1] == '3' && s[2] == '\0'))
    return (93);
    - if (strcasecmp(s, "brightblue") == 0 || strcmp(s, "94") == 0)
    + if (strcasecmp(s, "brightblue") == 0 ||
    + (s[0] == '9' && s[1] == '4' && s[2] == '\0'))
    return (94);
    - if (strcasecmp(s, "brightmagenta") == 0 || strcmp(s, "95") == 0)
    + if (strcasecmp(s, "brightmagenta") == 0 ||
    + (s[0] == '9' && s[1] == '5' && s[2] == '\0'))
    return (95);
    - if (strcasecmp(s, "brightcyan") == 0 || strcmp(s, "96") == 0)
    + if (strcasecmp(s, "brightcyan") == 0 ||
    + (s[0] == '9' && s[1] == '6' && s[2] == '\0'))
    return (96);
    - if (strcasecmp(s, "brightwhite") == 0 || strcmp(s, "97") == 0)
    + if (strcasecmp(s, "brightwhite") == 0 ||
    + (s[0] == '9' && s[1] == '7' && s[2] == '\0'))
    return (97);
    return (-1);
    }
    diff --git a/tmux--git/input.c b/tmux--git-24bit/input.c
    index 095816c..b74995f 100644
    --- a/tmux--git/input.c
    +++ b/tmux--git-24bit/input.c
    @@ -127,8 +127,6 @@ void input_csi_dispatch_rm_private(struct input_ctx *);
    void input_csi_dispatch_sm(struct input_ctx *);
    void input_csi_dispatch_sm_private(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 *);
    int input_dcs_dispatch(struct input_ctx *);
    int input_utf8_open(struct input_ctx *);
    @@ -505,8 +503,7 @@ const struct input_transition input_state_csi_enter_table[] = {
    { 0x1c, 0x1f, input_c0_dispatch, NULL },
    { 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate },
    { 0x30, 0x39, input_parameter, &input_state_csi_parameter },
    - { 0x3a, 0x3a, NULL, &input_state_csi_ignore },
    - { 0x3b, 0x3b, input_parameter, &input_state_csi_parameter },
    + { 0x3a, 0x3b, input_parameter, &input_state_csi_parameter },
    { 0x3c, 0x3f, input_intermediate, &input_state_csi_parameter },
    { 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
    { 0x7f, 0xff, NULL, NULL },
    @@ -523,8 +520,7 @@ const struct input_transition input_state_csi_parameter_table[] = {
    { 0x1c, 0x1f, input_c0_dispatch, NULL },
    { 0x20, 0x2f, input_intermediate, &input_state_csi_intermediate },
    { 0x30, 0x39, input_parameter, NULL },
    - { 0x3a, 0x3a, NULL, &input_state_csi_ignore },
    - { 0x3b, 0x3b, input_parameter, NULL },
    + { 0x3a, 0x3b, input_parameter, NULL },
    { 0x3c, 0x3f, NULL, &input_state_csi_ignore },
    { 0x40, 0x7e, input_csi_dispatch, &input_state_ground },
    { 0x7f, 0xff, NULL, NULL },
    @@ -918,7 +914,7 @@ input_split(struct input_ctx *ictx)
    return (0);

    ptr = ictx->param_buf;
    - while ((out = strsep(&ptr, ";")) != NULL) {
    + while ((out = strsep(&ptr, ":;")) != NULL) {
    if (*out == '\0')
    n = -1;
    else {
    @@ -1612,71 +1608,13 @@ 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. */
    void
    input_csi_dispatch_sgr(struct input_ctx *ictx)
    {
    struct grid_cell *gc = &ictx->cell.cell;
    u_int i;
    - int n;
    + int n, m;

    if (ictx->param_list_len == 0) {
    memcpy(gc, &grid_default_cell, sizeof *gc);
    @@ -1688,14 +1626,52 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)

    if (n == 38 || n == 48) {
    i++;
    - switch (input_get(ictx, i, 0, -1)) {
    - case 2:
    - input_csi_dispatch_sgr_rgb(ictx, n, &i);
    - break;
    - case 5:
    - input_csi_dispatch_sgr_256(ictx, n, &i);
    + m=input_get(ictx, i, 0, -1);
    + if (m == 2){ // 24bit?
    + u_char r, g, b;
    + r = input_get(ictx, i+1, 0, -1);
    + g = input_get(ictx, i+2, 0, -1);
    + b = input_get(ictx, i+3, 0, -1);
    + struct colour_rgb rgb = {.r=r, .g=g, .b=b};
    + if (n == 38){
    + gc->flags &= ~GRID_FLAG_FG256;
    + gc->flags |= GRID_FLAG_FG24;
    + gc->fg_rgb = rgb;
    + } else if (n == 48){
    + gc->flags &= ~GRID_FLAG_BG256;
    + gc->flags |= GRID_FLAG_BG24;
    + gc->bg_rgb = rgb;
    + }
    break;
    }
    +
    + if (m != 5)
    + continue;
    +
    + i++;
    + m = input_get(ictx, i, 0, -1);
    + if (m == -1) {
    + if (n == 38) {
    + gc->flags &= ~GRID_FLAG_FG256;
    + gc->flags &= ~GRID_FLAG_FG24;
    + gc->fg = 8;
    + } else if (n == 48) {
    + gc->flags &= ~GRID_FLAG_BG256;
    + gc->flags &= ~GRID_FLAG_BG24;
    + gc->bg = 8;
    + }
    +
    + } else {
    + if (n == 38) {
    + gc->flags |= GRID_FLAG_FG256;
    + gc->flags &= ~GRID_FLAG_FG24;
    + gc->fg = m;
    + } else if (n == 48) {
    + gc->flags |= GRID_FLAG_BG256;
    + gc->flags &= ~GRID_FLAG_BG24;
    + gc->bg = m;
    + }
    + }
    continue;
    }

    @@ -1749,10 +1725,12 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
    case 36:
    case 37:
    gc->flags &= ~GRID_FLAG_FG256;
    + gc->flags &= ~GRID_FLAG_FG24;
    gc->fg = n - 30;
    break;
    case 39:
    gc->flags &= ~GRID_FLAG_FG256;
    + gc->flags &= ~GRID_FLAG_FG24;
    gc->fg = 8;
    break;
    case 40:
    @@ -1764,10 +1742,12 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
    case 46:
    case 47:
    gc->flags &= ~GRID_FLAG_BG256;
    + gc->flags &= ~GRID_FLAG_BG24;
    gc->bg = n - 40;
    break;
    case 49:
    gc->flags &= ~GRID_FLAG_BG256;
    + gc->flags &= ~GRID_FLAG_BG24;
    gc->bg = 8;
    break;
    case 90:
    @@ -1790,6 +1770,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
    case 106:
    case 107:
    gc->flags &= ~GRID_FLAG_BG256;
    + gc->flags &= ~GRID_FLAG_BG24;
    gc->bg = n - 10;
    break;
    }
    diff --git a/tmux--git/tmux.h b/tmux--git-24bit/tmux.h
    index b9a663c..1b73244 100644
    --- a/tmux--git/tmux.h
    +++ b/tmux--git-24bit/tmux.h
    @@ -631,9 +631,17 @@ struct utf8_data {
    #define GRID_FLAG_FG256 0x1
    #define GRID_FLAG_BG256 0x2
    #define GRID_FLAG_PADDING 0x4
    +#define GRID_FLAG_FG24 0x8
    +#define GRID_FLAG_BG24 0x10

    /* Grid line flags. */
    #define GRID_LINE_WRAPPED 0x1
    +struct colour_rgb {
    + u_char r;
    + u_char g;
    + u_char b;
    +};
    +

    /* Grid cell data. */
    struct grid_cell {
    @@ -644,6 +652,8 @@ struct grid_cell {

    u_char xstate; /* top 4 bits width, bottom 4 bits size */
    u_char xdata[UTF8_SIZE];
    + struct colour_rgb fg_rgb;
    + struct colour_rgb bg_rgb;
    } __packed;

    /* Grid line. */
    @@ -1930,7 +1940,6 @@ char *xterm_keys_lookup(int);
    int xterm_keys_find(const char *, size_t, size_t *, int *);

    /* colour.c */
    -int colour_find_rgb(u_char, u_char, u_char);
    void colour_set_fg(struct grid_cell *, int);
    void colour_set_bg(struct grid_cell *, int);
    const char *colour_tostring(int);
    diff --git a/tmux--git/tty.c b/tmux--git-24bit/tty.c
    index 374fb8c..b4def0a 100644
    --- a/tmux--git/tty.c
    +++ b/tmux--git-24bit/tty.c
    @@ -36,6 +36,7 @@ void tty_error_callback(struct bufferevent *, short, void *);

    void tty_set_italics(struct tty *);
    int tty_try_256(struct tty *, u_char, const char *);
    +int tty_try_24(struct tty *, struct colour_rgb, const char *);

    void tty_colours(struct tty *, const struct grid_cell *);
    void tty_check_fg(struct tty *, struct grid_cell *);
    @@ -1460,7 +1461,16 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)

    /* No changes? Nothing is necessary. */
    if (fg == tc->fg && bg == tc->bg &&
    - ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0)
    + tc->fg_rgb.r == gc->fg_rgb.r &&
    + tc->fg_rgb.g == gc->fg_rgb.g &&
    + tc->fg_rgb.b == gc->fg_rgb.b &&
    +
    + tc->bg_rgb.r == gc->bg_rgb.r &&
    + tc->bg_rgb.g == gc->bg_rgb.g &&
    + tc->bg_rgb.b == gc->bg_rgb.b &&
    + ((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256|GRID_FLAG_FG24|GRID_FLAG_BG24)) == 0
    +
    + )
    return;

    /*
    @@ -1469,8 +1479,8 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
    * case if only one is default need to fall onward to set the other
    * colour.
    */
    - fg_default = (fg == 8 && !(flags & GRID_FLAG_FG256));
    - bg_default = (bg == 8 && !(flags & GRID_FLAG_BG256));
    + fg_default = (fg == 8 && !(flags & GRID_FLAG_FG256) && !(flags & GRID_FLAG_FG24));
    + bg_default = (bg == 8 && !(flags & GRID_FLAG_BG256) && !(flags & GRID_FLAG_BG24));
    if (fg_default || bg_default) {
    /*
    * If don't have AX but do have op, send sgr0 (op can't
    @@ -1484,39 +1494,49 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
    tty_reset(tty);
    else {
    if (fg_default &&
    - (tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
    + (tc->fg != 8 || tc->flags & GRID_FLAG_FG256 || tc->flags & GRID_FLAG_FG24)) {
    if (have_ax)
    tty_puts(tty, "\033[39m");
    else if (tc->fg != 7 ||
    - tc->flags & GRID_FLAG_FG256)
    + tc->flags & GRID_FLAG_FG256 ||
    + tc->flags & GRID_FLAG_FG24)
    tty_putcode1(tty, TTYC_SETAF, 7);
    tc->fg = 8;
    tc->flags &= ~GRID_FLAG_FG256;
    + tc->flags &= ~GRID_FLAG_FG24;
    }
    if (bg_default &&
    (tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) {
    if (have_ax)
    tty_puts(tty, "\033[49m");
    else if (tc->bg != 0 ||
    - tc->flags & GRID_FLAG_BG256)
    + tc->flags & GRID_FLAG_BG256 ||
    + tc->flags & GRID_FLAG_BG24)
    tty_putcode1(tty, TTYC_SETAB, 0);
    tc->bg = 8;
    tc->flags &= ~GRID_FLAG_BG256;
    + tc->flags &= ~GRID_FLAG_BG24;
    }
    }
    }

    /* Set the foreground colour. */
    - if (!fg_default && (fg != tc->fg ||
    - ((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256))))
    + if (!fg_default && (fg != tc->fg || ((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)) ||
    + (
    + ( tc->fg_rgb.r!=gc->fg_rgb.r || tc->fg_rgb.g!=gc->fg_rgb.g || tc->fg_rgb.b!=gc->fg_rgb.b ) ||
    + ((flags & GRID_FLAG_FG24) != (tc->flags & GRID_FLAG_FG24))
    + )))
    tty_colours_fg(tty, gc);

    /*
    * Set the background colour. This must come after the foreground as
    * tty_colour_fg() can call tty_reset().
    */
    - if (!bg_default && (bg != tc->bg ||
    - ((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256))))
    + if (!bg_default && (bg != tc->bg || ((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)) ||
    + (
    + ( tc->bg_rgb.r!=gc->bg_rgb.r || tc->bg_rgb.g!=gc->bg_rgb.g || tc->bg_rgb.b!=gc->bg_rgb.b ) ||
    + ((flags & GRID_FLAG_BG24) != (tc->flags & GRID_FLAG_BG24))
    + )))
    tty_colours_bg(tty, gc);
    }

    @@ -1528,7 +1548,7 @@ tty_check_fg(struct tty *tty, struct grid_cell *gc)
    colours = tty_term_number(tty->term, TTYC_COLORS);

    /* Is this a 256-colour colour? */
    - if (gc->flags & GRID_FLAG_FG256) {
    + if (gc->flags & GRID_FLAG_FG256 && !(gc->flags & GRID_FLAG_BG24)) {
    /* And not a 256 colour mode? */
    if (!(tty->term->flags & TERM_256COLOURS) &&
    !(tty->term_flags & TERM_256COLOURS)) {
    @@ -1561,7 +1581,7 @@ tty_check_bg(struct tty *tty, struct grid_cell *gc)
    colours = tty_term_number(tty->term, TTYC_COLORS);

    /* Is this a 256-colour colour? */
    - if (gc->flags & GRID_FLAG_BG256) {
    + if (gc->flags & GRID_FLAG_BG256 && !(gc->flags & GRID_FLAG_BG24)) {
    /*
    * And not a 256 colour mode? Translate to 16-colour
    * palette. Bold background doesn't exist portably, so just
    @@ -1589,15 +1609,29 @@ void
    tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    {
    struct grid_cell *tc = &tty->cell;
    + struct colour_rgb rgb= gc->fg_rgb;
    u_char fg = gc->fg;
    char s[32];

    + tc->flags &= ~GRID_FLAG_FG256;
    + tc->flags &= ~GRID_FLAG_FG24;
    +
    + /* Is this a 24-colour colour? */
    + if (gc->flags & GRID_FLAG_FG24) {
    +//log_debug("trying to output 24bit fg");
    + if (tty_try_24(tty, rgb, "38") == 0){
    + tc->fg_rgb = rgb;
    + tc->flags |= gc->flags & GRID_FLAG_FG24;
    + }
    + return;
    + }
    +
    /* Is this a 256-colour colour? */
    if (gc->flags & GRID_FLAG_FG256) {
    - /* Try as 256 colours. */
    - if (tty_try_256(tty, fg, "38") == 0)
    - goto save_fg;
    - /* Else already handled by tty_check_fg. */
    + if (tty_try_256(tty, fg, "38") == 0){
    + tc->fg = fg;
    + tc->flags |= gc->flags & GRID_FLAG_FG256;
    + }
    return;
    }

    @@ -1605,50 +1639,59 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
    if (fg >= 90 && fg <= 97) {
    xsnprintf(s, sizeof s, "\033[%dm", fg);
    tty_puts(tty, s);
    - goto save_fg;
    + tc->fg = fg;
    + return;
    }

    /* Otherwise set the foreground colour. */
    tty_putcode1(tty, TTYC_SETAF, fg);
    -
    -save_fg:
    - /* Save the new values in the terminal current cell. */
    - tc->fg = fg;
    - tc->flags &= ~GRID_FLAG_FG256;
    - tc->flags |= gc->flags & GRID_FLAG_FG256;
    }

    void
    tty_colours_bg(struct tty *tty, const struct grid_cell *gc)
    {
    struct grid_cell *tc = &tty->cell;
    + struct colour_rgb rgb= gc->bg_rgb;
    u_char bg = gc->bg;
    char s[32];

    + tc->flags &= ~GRID_FLAG_BG256;
    + tc->flags &= ~GRID_FLAG_BG24;
    +
    + /* Is this a 24-colour colour? */
    + if (gc->flags & GRID_FLAG_BG24) {
    + if (tty_try_256(tty, bg, "48") == 0){
    + tc->bg = bg;
    + tc->flags |= gc->flags & GRID_FLAG_BG256;
    + }
    + return;
    + }
    +
    /* Is this a 256-colour colour? */
    if (gc->flags & GRID_FLAG_BG256) {
    /* Try as 256 colours. */
    if (tty_try_256(tty, bg, "48") == 0)
    - goto save_bg;
    - /* Else already handled by tty_check_bg. */
    + tc->bg = bg;
    + tc->flags |= gc->flags & GRID_FLAG_BG256;
    return;
    }

    /* Is this an aixterm bright colour? */
    if (bg >= 90 && bg <= 97) {
    - xsnprintf(s, sizeof s, "\033[%dm", bg + 10);
    - tty_puts(tty, s);
    - goto save_bg;
    + /* 16 colour terminals or above only. */
    + if (tty_term_number(tty->term, TTYC_COLORS) >= 16) {
    + xsnprintf(s, sizeof s, "\033[%dm", bg + 10);
    + tty_puts(tty, s);
    + tc->bg = bg;
    + }
    + bg -= 90;
    + return;
    + /* no such thing as a bold background */
    }

    /* Otherwise set the background colour. */
    tty_putcode1(tty, TTYC_SETAB, bg);
    -
    -save_bg:
    - /* Save the new values in the terminal current cell. */
    tc->bg = bg;
    - tc->flags &= ~GRID_FLAG_BG256;
    - tc->flags |= gc->flags & GRID_FLAG_BG256;
    }

    int
    @@ -1681,6 +1724,22 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
    return (-1);
    }

    +int
    +tty_try_24(struct tty *tty, struct colour_rgb rgb, const char *type)
    +{
    + char s[32];
    +
    + //if (!(tty->term->flags & TERM_256COLOURS) &&
    + // !(tty->term_flags & TERM_256COLOURS))
    + // return (-1);
    +
    + //xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour);
    + xsnprintf(s, sizeof s, "\033[%s;2;%hhu;%hhu;%hhum", type, rgb.r, rgb.g, rgb.b);
    +//log_debug("24bit output: %s",s);
    + tty_puts(tty, s);
    + return (0);
    +}
    +
    void
    tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
    {