version 1.60, 2009/10/26 21:42:04 |
version 1.61, 2009/10/28 08:27:33 |
|
|
int tty_try_256(struct tty *, u_char, const char *); |
int tty_try_256(struct tty *, u_char, const char *); |
int tty_try_88(struct tty *, u_char, const char *); |
int tty_try_88(struct tty *, u_char, const char *); |
|
|
void tty_attributes_fg(struct tty *, const struct grid_cell *); |
void tty_colours(struct tty *, const struct grid_cell *, int *); |
void tty_attributes_bg(struct tty *, const struct grid_cell *); |
void tty_colours_fg(struct tty *, const struct grid_cell *, int *); |
|
void tty_colours_bg(struct tty *, const struct grid_cell *, int *); |
|
|
void tty_redraw_region(struct tty *, const struct tty_ctx *); |
void tty_redraw_region(struct tty *, const struct tty_ctx *); |
void tty_emulate_repeat( |
void tty_emulate_repeat( |
|
|
{ |
{ |
struct grid_cell *tc = &tty->cell; |
struct grid_cell *tc = &tty->cell; |
u_char changed; |
u_char changed; |
u_int fg, bg, attr; |
u_int fg = gc->fg, bg = gc->bg, attr = gc->attr; |
|
|
|
/* If any bits are being cleared, reset everything. */ |
|
if (tc->attr & ~attr) |
|
tty_reset(tty); |
|
|
/* |
/* |
|
* Set the colours. This may call tty_reset() (so it comes next) and |
|
* may add to the desired attributes in attr. |
|
*/ |
|
tty_colours(tty, gc, &attr); |
|
|
|
/* |
* If no setab, try to use the reverse attribute as a best-effort for a |
* If no setab, try to use the reverse attribute as a best-effort for a |
* non-default background. This is a bit of a hack but it doesn't do |
* non-default background. This is a bit of a hack but it doesn't do |
* any serious harm and makes a couple of applications happier. |
* any serious harm and makes a couple of applications happier. |
*/ |
*/ |
fg = gc->fg; bg = gc->bg; attr = gc->attr; |
|
if (!tty_term_has(tty->term, TTYC_SETAB)) { |
if (!tty_term_has(tty->term, TTYC_SETAB)) { |
if (attr & GRID_ATTR_REVERSE) { |
if (attr & GRID_ATTR_REVERSE) { |
if (fg != 7 && fg != 8) |
if (fg != 7 && fg != 8) |
|
|
} |
} |
} |
} |
|
|
/* If any bits are being cleared, reset everything. */ |
|
if (tc->attr & ~attr) |
|
tty_reset(tty); |
|
|
|
/* Filter out attribute bits already set. */ |
/* Filter out attribute bits already set. */ |
changed = attr & ~tc->attr; |
changed = attr & ~tc->attr; |
tc->attr = attr; |
tc->attr = attr; |
|
|
tty_putcode(tty, TTYC_INVIS); |
tty_putcode(tty, TTYC_INVIS); |
if (changed & GRID_ATTR_CHARSET) |
if (changed & GRID_ATTR_CHARSET) |
tty_putcode(tty, TTYC_SMACS); |
tty_putcode(tty, TTYC_SMACS); |
|
|
/* Set foreground colour. */ |
|
if (fg != tc->fg || |
|
(gc->flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)) { |
|
tty_attributes_fg(tty, gc); |
|
tc->fg = fg; |
|
tc->flags &= ~GRID_FLAG_FG256; |
|
tc->flags |= gc->flags & GRID_FLAG_FG256; |
|
} |
|
|
|
/* Set background colour. */ |
|
if (bg != tc->bg || |
|
(gc->flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)) { |
|
tty_attributes_bg(tty, gc); |
|
tc->bg = bg; |
|
tc->flags &= ~GRID_FLAG_BG256; |
|
tc->flags |= gc->flags & GRID_FLAG_BG256; |
|
} |
|
} |
} |
|
|
int |
void |
tty_try_256(struct tty *tty, u_char colour, const char *type) |
tty_colours(struct tty *tty, const struct grid_cell *gc, int *attr) |
{ |
{ |
char s[32]; |
struct grid_cell *tc = &tty->cell; |
|
u_char fg = gc->fg, bg = gc->bg; |
|
int flags, have_ax; |
|
int fg_default, bg_default; |
|
|
if (!(tty->term->flags & TERM_256COLOURS) && |
/* No changes? Nothing is necessary. */ |
!(tty->term_flags & TERM_256COLOURS)) |
flags = (gc->flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256); |
return (-1); |
if (fg == tc->fg && bg == tc->bg && flags == 0) |
|
return; |
|
|
xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); |
/* |
tty_puts(tty, s); |
* Is either the default colour? This is handled specially because the |
return (0); |
* best solution might be to reset both colours to default, in which |
} |
* case if only one is default need to fall onward to set the other |
|
* colour. |
|
*/ |
|
fg_default = (fg == 8 && !(gc->flags & GRID_FLAG_FG256)); |
|
bg_default = (bg == 8 && !(gc->flags & GRID_FLAG_BG256)); |
|
if (fg_default || bg_default) { |
|
/* |
|
* If don't have AX but do have op, send sgr0 (op can't |
|
* actually be used because it is sometimes the same as sgr0 |
|
* and sometimes isn't). This resets both colours to default. |
|
* |
|
* Otherwise, try to set the default colour only as needed. |
|
*/ |
|
have_ax = tty_term_has(tty->term, TTYC_AX); |
|
if (!have_ax && tty_term_has(tty->term, TTYC_OP)) |
|
tty_reset(tty); |
|
else { |
|
if (fg_default && |
|
fg != tc->fg && !(tc->flags & GRID_FLAG_FG256)) { |
|
if (have_ax) |
|
tty_puts(tty, "\033[39m"); |
|
else if (tc->fg != 7) |
|
tty_putcode1(tty, TTYC_SETAF, 7); |
|
tc->fg = 8; |
|
tc->flags &= ~GRID_FLAG_FG256; |
|
} |
|
if (bg_default && |
|
bg != tc->bg && !(tc->flags & GRID_FLAG_BG256)) { |
|
if (have_ax) |
|
tty_puts(tty, "\033[49m"); |
|
else if (tc->bg != 0) |
|
tty_putcode1(tty, TTYC_SETAB, 0); |
|
tc->bg = 8; |
|
tc->flags &= ~GRID_FLAG_BG256; |
|
} |
|
} |
|
} |
|
|
int |
/* Set the foreground colour. */ |
tty_try_88(struct tty *tty, u_char colour, const char *type) |
if (!fg_default && (fg != tc->fg || |
{ |
((gc->flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256)))) |
char s[32]; |
tty_colours_fg(tty, gc, attr); |
|
|
if (!(tty->term->flags & TERM_88COLOURS) && |
/* |
!(tty->term_flags & TERM_88COLOURS)) |
* Set the background colour. This must come after the foreground as |
return (-1); |
* tty_colour_fg() can call tty_reset(). |
colour = colour_256to88(colour); |
*/ |
|
if (!bg_default && (bg != tc->bg || |
xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); |
((gc->flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256)))) |
tty_puts(tty, s); |
tty_colours_bg(tty, gc, attr); |
return (0); |
|
} |
} |
|
|
void |
void |
tty_attributes_fg(struct tty *tty, const struct grid_cell *gc) |
tty_colours_fg(struct tty *tty, const struct grid_cell *gc, int *attr) |
{ |
{ |
u_char fg; |
struct grid_cell *tc = &tty->cell; |
|
u_char fg = gc->fg; |
|
|
fg = gc->fg; |
/* Is this a 256-colour colour? */ |
if (gc->flags & GRID_FLAG_FG256) { |
if (gc->flags & GRID_FLAG_FG256) { |
|
/* Try as 256 colours or translating to 88. */ |
if (tty_try_256(tty, fg, "38") == 0) |
if (tty_try_256(tty, fg, "38") == 0) |
return; |
goto save_fg; |
if (tty_try_88(tty, fg, "38") == 0) |
if (tty_try_88(tty, fg, "38") == 0) |
return; |
goto save_fg; |
|
|
|
/* Translate to 16-colour palette, updating bold if needed. */ |
fg = colour_256to16(fg); |
fg = colour_256to16(fg); |
if (fg & 8) { |
if (fg & 8) { |
fg &= 7; |
fg &= 7; |
tty_putcode(tty, TTYC_BOLD); |
(*attr) |= GRID_ATTR_BRIGHT; |
tty->cell.attr |= GRID_ATTR_BRIGHT; |
} else |
} else if (tty->cell.attr & GRID_ATTR_BRIGHT) |
tty_reset(tty); /* turn off bold */ |
tty_reset(tty); |
|
} |
} |
|
|
if (fg == 8) { |
/* Otherwise set the foreground colour. */ |
if (tty_term_has(tty->term, TTYC_AX)) { |
tty_putcode1(tty, TTYC_SETAF, fg); |
/* AX is an extension that means \033[39m works. */ |
|
tty_puts(tty, "\033[39m"); |
save_fg: |
} else if (tty_term_has(tty->term, TTYC_OP)) { |
/* Save the new values in the terminal current cell. */ |
/* |
tc->fg = fg; |
* op can be used to look for default colours but there |
tc->flags &= ~GRID_FLAG_FG256; |
* is no point in using it - with some terminals it |
tc->flags |= gc->flags & GRID_FLAG_FG256; |
* does SGR0 and others not, so SGR0 is needed anyway |
|
* to put the terminal into a known state. |
|
*/ |
|
tty_reset(tty); |
|
} else |
|
tty_putcode1(tty, TTYC_SETAF, 7); |
|
} else |
|
tty_putcode1(tty, TTYC_SETAF, fg); |
|
} |
} |
|
|
void |
void |
tty_attributes_bg(struct tty *tty, const struct grid_cell *gc) |
tty_colours_bg(struct tty *tty, const struct grid_cell *gc, unused int *attr) |
{ |
{ |
u_char bg; |
struct grid_cell *tc = &tty->cell; |
|
u_char bg = gc->bg; |
|
|
bg = gc->bg; |
/* Is this a 256-colour colour? */ |
if (gc->flags & GRID_FLAG_BG256) { |
if (gc->flags & GRID_FLAG_BG256) { |
|
/* Try as 256 colours or translating to 88. */ |
if (tty_try_256(tty, bg, "48") == 0) |
if (tty_try_256(tty, bg, "48") == 0) |
return; |
goto save_bg; |
if (tty_try_88(tty, bg, "48") == 0) |
if (tty_try_88(tty, bg, "48") == 0) |
return; |
goto save_bg; |
|
|
|
/* |
|
* Translate to 16-colour palette. Bold background doesn't |
|
* exist portably, so just discard the bold bit if set. |
|
*/ |
bg = colour_256to16(bg); |
bg = colour_256to16(bg); |
if (bg & 8) |
if (bg & 8) |
bg &= 7; |
bg &= 7; |
} |
} |
|
|
if (bg == 8) { |
/* Otherwise set the background colour. */ |
if (tty_term_has(tty->term, TTYC_AX)) { |
tty_putcode1(tty, TTYC_SETAB, bg); |
tty_puts(tty, "\033[49m"); |
|
} else if (tty_term_has(tty->term, TTYC_OP)) |
save_bg: |
tty_reset(tty); |
/* Save the new values in the terminal current cell. */ |
else |
tc->bg = bg; |
tty_putcode1(tty, TTYC_SETAB, 0); |
tc->flags &= ~GRID_FLAG_BG256; |
} else |
tc->flags |= gc->flags & GRID_FLAG_BG256; |
tty_putcode1(tty, TTYC_SETAB, bg); |
} |
|
|
|
int |
|
tty_try_256(struct tty *tty, u_char colour, 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); |
|
tty_puts(tty, s); |
|
return (0); |
|
} |
|
|
|
int |
|
tty_try_88(struct tty *tty, u_char colour, const char *type) |
|
{ |
|
char s[32]; |
|
|
|
if (!(tty->term->flags & TERM_88COLOURS) && |
|
!(tty->term_flags & TERM_88COLOURS)) |
|
return (-1); |
|
colour = colour_256to88(colour); |
|
|
|
xsnprintf(s, sizeof s, "\033[%s;5;%hhum", type, colour); |
|
tty_puts(tty, s); |
|
return (0); |
} |
} |