version 1.198, 2016/01/19 15:59:12 |
version 1.199, 2016/01/29 11:13:56 |
|
|
void tty_read_callback(struct bufferevent *, void *); |
void tty_read_callback(struct bufferevent *, void *); |
void tty_error_callback(struct bufferevent *, short, void *); |
void tty_error_callback(struct bufferevent *, short, void *); |
|
|
|
static int tty_same_fg(const struct grid_cell *, const struct grid_cell *); |
|
static int tty_same_bg(const struct grid_cell *, const struct grid_cell *); |
|
static int tty_same_colours(const struct grid_cell *, const struct grid_cell *); |
|
static int tty_is_fg(const struct grid_cell *, int); |
|
static int tty_is_bg(const struct grid_cell *, int); |
|
|
void tty_set_italics(struct tty *); |
void tty_set_italics(struct tty *); |
int tty_try_256(struct tty *, u_char, const char *); |
int tty_try_256(struct tty *, u_char, const char *); |
|
int tty_try_rgb(struct tty *, const struct grid_cell_rgb *, const char *); |
|
|
void tty_colours(struct tty *, const struct grid_cell *); |
void tty_colours(struct tty *, const struct grid_cell *); |
void tty_check_fg(struct tty *, struct grid_cell *); |
void tty_check_fg(struct tty *, struct grid_cell *); |
|
|
#define tty_pane_full_width(tty, ctx) \ |
#define tty_pane_full_width(tty, ctx) \ |
((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) |
((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) |
|
|
|
static int |
|
tty_same_fg(const struct grid_cell *gc1, const struct grid_cell *gc2) |
|
{ |
|
int flags1, flags2; |
|
|
|
flags1 = (gc1->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB)); |
|
flags2 = (gc2->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB)); |
|
|
|
if (flags1 != flags2) |
|
return (0); |
|
|
|
if (flags1 & GRID_FLAG_FGRGB) { |
|
if (gc1->fg_rgb.r != gc2->fg_rgb.r) |
|
return (0); |
|
if (gc1->fg_rgb.g != gc2->fg_rgb.g) |
|
return (0); |
|
if (gc1->fg_rgb.b != gc2->fg_rgb.b) |
|
return (0); |
|
return (1); |
|
} |
|
return (gc1->fg == gc2->fg); |
|
} |
|
|
|
static int |
|
tty_same_bg(const struct grid_cell *gc1, const struct grid_cell *gc2) |
|
{ |
|
int flags1, flags2; |
|
|
|
flags1 = (gc1->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB)); |
|
flags2 = (gc2->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB)); |
|
|
|
if (flags1 != flags2) |
|
return (0); |
|
|
|
if (flags1 & GRID_FLAG_BGRGB) { |
|
if (gc1->bg_rgb.r != gc2->bg_rgb.r) |
|
return (0); |
|
if (gc1->bg_rgb.g != gc2->bg_rgb.g) |
|
return (0); |
|
if (gc1->bg_rgb.b != gc2->bg_rgb.b) |
|
return (0); |
|
return (1); |
|
} |
|
return (gc1->bg == gc2->bg); |
|
} |
|
|
|
static int |
|
tty_same_colours(const struct grid_cell *gc1, const struct grid_cell *gc2) |
|
{ |
|
return (tty_same_fg(gc1, gc2) && tty_same_bg(gc1, gc2)); |
|
} |
|
|
|
static int |
|
tty_is_fg(const struct grid_cell *gc, int c) |
|
{ |
|
if (gc->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB)) |
|
return (0); |
|
return (gc->fg == c); |
|
} |
|
|
|
static int |
|
tty_is_bg(const struct grid_cell *gc, int c) |
|
{ |
|
if (gc->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB)) |
|
return (0); |
|
return (gc->bg == c); |
|
} |
|
|
void |
void |
tty_create_log(void) |
tty_create_log(void) |
{ |
{ |
|
|
tty_colours(struct tty *tty, const struct grid_cell *gc) |
tty_colours(struct tty *tty, const struct grid_cell *gc) |
{ |
{ |
struct grid_cell *tc = &tty->cell; |
struct grid_cell *tc = &tty->cell; |
u_char fg = gc->fg, bg = gc->bg, flags = gc->flags; |
|
int have_ax, fg_default, bg_default; |
int have_ax, fg_default, bg_default; |
|
|
/* No changes? Nothing is necessary. */ |
/* No changes? Nothing is necessary. */ |
if (fg == tc->fg && bg == tc->bg && |
if (tty_same_colours(gc, tc)) |
((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0) |
|
return; |
return; |
|
|
/* |
/* |
|
|
* case if only one is default need to fall onward to set the other |
* case if only one is default need to fall onward to set the other |
* colour. |
* colour. |
*/ |
*/ |
fg_default = (fg == 8 && !(flags & GRID_FLAG_FG256)); |
fg_default = tty_is_fg(gc, 8); |
bg_default = (bg == 8 && !(flags & GRID_FLAG_BG256)); |
bg_default = tty_is_bg(gc, 8); |
if (fg_default || bg_default) { |
if (fg_default || bg_default) { |
/* |
/* |
* If don't have AX but do have op, send sgr0 (op can't |
* If don't have AX but do have op, send sgr0 (op can't |
|
|
if (!have_ax && tty_term_has(tty->term, TTYC_OP)) |
if (!have_ax && tty_term_has(tty->term, TTYC_OP)) |
tty_reset(tty); |
tty_reset(tty); |
else { |
else { |
if (fg_default && |
if (fg_default && !tty_is_fg(tc, 8)) { |
(tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) { |
|
if (have_ax) |
if (have_ax) |
tty_puts(tty, "\033[39m"); |
tty_puts(tty, "\033[39m"); |
else if (tc->fg != 7 || |
else if (!tty_is_fg(tc, 7)) |
tc->flags & GRID_FLAG_FG256) |
|
tty_putcode1(tty, TTYC_SETAF, 7); |
tty_putcode1(tty, TTYC_SETAF, 7); |
tc->fg = 8; |
tc->fg = 8; |
tc->flags &= ~GRID_FLAG_FG256; |
tc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB); |
} |
} |
if (bg_default && |
if (bg_default && !tty_is_bg(tc, 8)) { |
(tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) { |
|
if (have_ax) |
if (have_ax) |
tty_puts(tty, "\033[49m"); |
tty_puts(tty, "\033[49m"); |
else if (tc->bg != 0 || |
else if (!tty_is_bg(tc, 0)) |
tc->flags & GRID_FLAG_BG256) |
|
tty_putcode1(tty, TTYC_SETAB, 0); |
tty_putcode1(tty, TTYC_SETAB, 0); |
tc->bg = 8; |
tc->bg = 8; |
tc->flags &= ~GRID_FLAG_BG256; |
tc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB); |
} |
} |
} |
} |
} |
} |
|
|
/* Set the foreground colour. */ |
/* Set the foreground colour. */ |
if (!fg_default && (fg != tc->fg || |
if (!fg_default && !tty_same_fg(gc, tc)) |
((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)))) |
|
tty_colours_fg(tty, gc); |
tty_colours_fg(tty, gc); |
|
|
/* |
/* |
* Set the background colour. This must come after the foreground as |
* Set the background colour. This must come after the foreground as |
* tty_colour_fg() can call tty_reset(). |
* tty_colour_fg() can call tty_reset(). |
*/ |
*/ |
if (!bg_default && (bg != tc->bg || |
if (!bg_default && !tty_same_bg(gc, tc)) |
((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)))) |
|
tty_colours_bg(tty, gc); |
tty_colours_bg(tty, gc); |
} |
} |
|
|
void |
void |
tty_check_fg(struct tty *tty, struct grid_cell *gc) |
tty_check_fg(struct tty *tty, struct grid_cell *gc) |
{ |
{ |
u_int colours; |
struct grid_cell_rgb *rgb = &gc->fg_rgb; |
|
u_int colours; |
|
|
|
/* Is this a 24-bit colour? */ |
|
if (gc->flags & GRID_FLAG_FGRGB) { |
|
/* Not a 24-bit terminal? Translate to 256-colour palette. */ |
|
if (!tty_term_flag(tty->term, TTYC_TC)) { |
|
gc->flags &= ~GRID_FLAG_FGRGB; |
|
gc->flags |= GRID_FLAG_FG256; |
|
gc->fg = colour_find_rgb(rgb->r, rgb->g, rgb->b); |
|
} |
|
} |
colours = tty_term_number(tty->term, TTYC_COLORS); |
colours = tty_term_number(tty->term, TTYC_COLORS); |
|
|
/* Is this a 256-colour colour? */ |
/* Is this a 256-colour colour? */ |
|
|
void |
void |
tty_check_bg(struct tty *tty, struct grid_cell *gc) |
tty_check_bg(struct tty *tty, struct grid_cell *gc) |
{ |
{ |
u_int colours; |
struct grid_cell_rgb *rgb = &gc->bg_rgb; |
|
u_int colours; |
|
|
|
/* Is this a 24-bit colour? */ |
|
if (gc->flags & GRID_FLAG_BGRGB) { |
|
/* Not a 24-bit terminal? Translate to 256-colour palette. */ |
|
if (!tty_term_flag(tty->term, TTYC_TC)) { |
|
gc->flags &= ~GRID_FLAG_BGRGB; |
|
gc->flags |= GRID_FLAG_BG256; |
|
gc->bg = colour_find_rgb(rgb->r, rgb->g, rgb->b); |
|
} |
|
} |
colours = tty_term_number(tty->term, TTYC_COLORS); |
colours = tty_term_number(tty->term, TTYC_COLORS); |
|
|
/* Is this a 256-colour colour? */ |
/* Is this a 256-colour colour? */ |
|
|
u_char fg = gc->fg; |
u_char fg = gc->fg; |
char s[32]; |
char s[32]; |
|
|
|
tc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB); |
|
|
|
/* Is this a 24-bit colour? */ |
|
if (gc->flags & GRID_FLAG_FGRGB) { |
|
if (tty_try_rgb(tty, &gc->fg_rgb, "38") == 0) |
|
goto save_fg; |
|
/* Should not get here, already converted in tty_check_fg. */ |
|
return; |
|
} |
|
|
/* Is this a 256-colour colour? */ |
/* Is this a 256-colour colour? */ |
if (gc->flags & GRID_FLAG_FG256) { |
if (gc->flags & GRID_FLAG_FG256) { |
/* Try as 256 colours. */ |
|
if (tty_try_256(tty, fg, "38") == 0) |
if (tty_try_256(tty, fg, "38") == 0) |
goto save_fg; |
goto save_fg; |
/* Else already handled by tty_check_fg. */ |
/* Should not get here, already converted in tty_check_fg. */ |
return; |
return; |
} |
} |
|
|
|
|
|
|
save_fg: |
save_fg: |
/* Save the new values in the terminal current cell. */ |
/* Save the new values in the terminal current cell. */ |
tc->fg = fg; |
if (gc->flags & GRID_FLAG_FGRGB) |
tc->flags &= ~GRID_FLAG_FG256; |
memcpy(&tc->fg_rgb, &gc->fg_rgb, sizeof tc->fg_rgb); |
tc->flags |= gc->flags & GRID_FLAG_FG256; |
else |
|
tc->fg = fg; |
|
tc->flags &= ~(GRID_FLAG_FGRGB|GRID_FLAG_FG256); |
|
tc->flags |= (gc->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB)); |
} |
} |
|
|
void |
void |
|
|
u_char bg = gc->bg; |
u_char bg = gc->bg; |
char s[32]; |
char s[32]; |
|
|
|
/* Is this a 24-bit colour? */ |
|
if (gc->flags & GRID_FLAG_BGRGB) { |
|
if (tty_try_rgb(tty, &gc->bg_rgb, "48") == 0) |
|
goto save_bg; |
|
/* Should not get here, already converted in tty_check_bg. */ |
|
return; |
|
} |
|
|
/* Is this a 256-colour colour? */ |
/* Is this a 256-colour colour? */ |
if (gc->flags & GRID_FLAG_BG256) { |
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; |
goto save_bg; |
/* Else already handled by tty_check_bg. */ |
/* Should not get here, already converted in tty_check_bg. */ |
return; |
return; |
} |
} |
|
|
|
|
|
|
save_bg: |
save_bg: |
/* Save the new values in the terminal current cell. */ |
/* Save the new values in the terminal current cell. */ |
tc->bg = bg; |
if (gc->flags & GRID_FLAG_BGRGB) |
tc->flags &= ~GRID_FLAG_BG256; |
memcpy(&tc->bg_rgb, &gc->bg_rgb, sizeof tc->bg_rgb); |
tc->flags |= gc->flags & GRID_FLAG_BG256; |
else |
|
tc->bg = bg; |
|
tc->flags &= ~(GRID_FLAG_BGRGB|GRID_FLAG_BG256); |
|
tc->flags |= (gc->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB)); |
} |
} |
|
|
int |
int |
|
|
|
|
fallback: |
fallback: |
xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); |
xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); |
|
tty_puts(tty, s); |
|
return (0); |
|
} |
|
|
|
int |
|
tty_try_rgb(struct tty *tty, const struct grid_cell_rgb *rgb, const char *type) |
|
{ |
|
char s[32]; |
|
|
|
if (!tty_term_flag(tty->term, TTYC_TC)) |
|
return (-1); |
|
|
|
xsnprintf(s, sizeof s, "\033[%s;2;%hhu;%hhu;%hhum", type, rgb->r, |
|
rgb->g, rgb->b); |
tty_puts(tty, s); |
tty_puts(tty, s); |
return (0); |
return (0); |
} |
} |