Fix bold/non-bold mismatch in 256 colour mode by adding an extra 8 bits (ick) onto the attributes and using two of them to mark the fg and bg as 256 colours when necessary. If only it was 255 colours we would have one value for default and wouln't need this :-/.

This commit is contained in:
Nicholas Marriott 2008-09-08 22:03:56 +00:00
parent cecd7c0cc8
commit 6674197e85
8 changed files with 136 additions and 95 deletions

23
input.c
View File

@ -1,4 +1,4 @@
/* $Id: input.c,v 1.55 2008-09-08 21:05:41 nicm Exp $ */
/* $Id: input.c,v 1.56 2008-09-08 22:03:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -493,7 +493,7 @@ void
input_handle_c0_control(u_char ch, struct input_ctx *ictx)
{
struct screen *s = ictx->ctx.s;
u_char attr;
u_short attr;
log_debug2("-- c0 %zu: %hhu", ictx->off, ch);
@ -1053,7 +1053,8 @@ input_handle_sequence_sgr(struct input_ctx *ictx)
struct screen *s = ictx->ctx.s;
u_int i, n;
uint16_t m, o;
u_char attr, fg, bg;
u_short attr;
u_char fg, bg;
attr = s->attr;
fg = s->fg;
@ -1075,19 +1076,11 @@ input_handle_sequence_sgr(struct input_ctx *ictx)
if (input_get_argument(ictx, 2, &m, 0) != 0)
return;
if (o == 38) {
if (m > 7 && m < 16) {
/* XXX this is not right; colours 8-15 are not the same as bold */
attr |= ATTR_BRIGHT;
m -= 8;
}
attr |= ATTR_FG256;
fg = m;
break;
} else if (o == 48) {
if (m > 7 && m < 16) {
/* XXX this is not right; colours 8-15 are not the same as bold */
attr |= ATTR_BRIGHT;
m -= 8;
}
attr |= ATTR_BG256;
bg = m;
break;
}
@ -1139,9 +1132,11 @@ input_handle_sequence_sgr(struct input_ctx *ictx)
case 35:
case 36:
case 37:
attr &= ~ATTR_FG256;
fg = m - 30;
break;
case 39:
attr &= ~ATTR_FG256;
fg = 8;
break;
case 40:
@ -1152,9 +1147,11 @@ input_handle_sequence_sgr(struct input_ctx *ictx)
case 45:
case 46:
case 47:
attr &= ~ATTR_BG256;
bg = m - 40;
break;
case 49:
attr &= ~ATTR_BG256;
bg = 8;
break;
}

View File

@ -1,4 +1,4 @@
/* $Id: screen-display.c,v 1.19 2008-09-08 17:40:50 nicm Exp $ */
/* $Id: screen-display.c,v 1.20 2008-09-08 22:03:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -25,7 +25,7 @@
/* Set a cell. */
void
screen_display_set_cell(struct screen *s,
u_int px, u_int py, u_char data, u_char attr, u_char fg, u_char bg)
u_int px, u_int py, u_char data, u_short attr, u_char fg, u_char bg)
{
screen_set_cell(
s, screen_x(s, px), screen_y(s, py), data, attr, fg, bg);
@ -75,7 +75,7 @@ screen_display_move_lines(struct screen *s, u_int dy, u_int py, u_int ny)
/* Fill a set of cells. */
void
screen_display_fill_area(struct screen *s, u_int px, u_int py,
u_int nx, u_int ny, u_char data, u_char attr, u_char fg, u_char bg)
u_int nx, u_int ny, u_char data, u_short attr, u_char fg, u_char bg)
{
if (nx == 0 || ny == 0) {
SCREEN_DEBUG4(s, px, py, nx, ny);
@ -378,10 +378,14 @@ screen_display_insert_characters(struct screen *s, u_int px, u_int py, u_int nx)
if (px + nx != screen_last_x(s)) {
mx = screen_last_x(s) - (px + nx);
memmove(&s->grid_data[py][px + nx], &s->grid_data[py][px], mx);
memmove(&s->grid_attr[py][px + nx], &s->grid_attr[py][px], mx);
memmove(&s->grid_fg[py][px + nx], &s->grid_fg[py][px], mx);
memmove(&s->grid_bg[py][px + nx], &s->grid_bg[py][px], mx);
memmove(&s->grid_data[py][px + nx],
&s->grid_data[py][px], mx * sizeof **s->grid_data);
memmove(&s->grid_attr[py][px + nx],
&s->grid_attr[py][px], mx * sizeof **s->grid_attr);
memmove(&s->grid_fg[py][px + nx],
&s->grid_fg[py][px], mx * sizeof **s->grid_fg);
memmove(&s->grid_bg[py][px + nx],
&s->grid_bg[py][px], mx * sizeof **s->grid_bg);
}
memset(&s->grid_data[py][px], ' ', nx);
@ -437,7 +441,8 @@ screen_display_copy_area(struct screen *dst, struct screen *src,
u_int px, u_int py, u_int nx, u_int ny, u_int ox, u_int oy)
{
u_int i, j;
u_char data, attr, fg, bg;
u_short attr;
u_char data, fg, bg;
if (nx == 0 || ny == 0) {
SCREEN_DEBUG4(dst, px, py, nx, ny);

View File

@ -1,4 +1,4 @@
/* $Id: screen-redraw.c,v 1.10 2008-09-08 17:40:51 nicm Exp $ */
/* $Id: screen-redraw.c,v 1.11 2008-09-08 22:03:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -23,7 +23,7 @@
#include "tmux.h"
void screen_redraw_get_cell(struct screen_redraw_ctx *,
u_int, u_int, u_char *, u_char *, u_char *, u_char *);
u_int, u_int, u_char *, u_short *, u_char *, u_char *);
/* Initialise redrawing with a window. */
void
@ -99,7 +99,7 @@ screen_redraw_stop(struct screen_redraw_ctx *ctx)
/* Get cell data. */
void
screen_redraw_get_cell(struct screen_redraw_ctx *ctx,
u_int px, u_int py, u_char *data, u_char *attr, u_char *fg, u_char *bg)
u_int px, u_int py, u_char *data, u_short *attr, u_char *fg, u_char *bg)
{
struct screen *s = ctx->s;
@ -121,7 +121,7 @@ screen_redraw_move_cursor(struct screen_redraw_ctx *ctx, u_int px, u_int py)
/* Set attributes. */
void
screen_redraw_set_attributes(
struct screen_redraw_ctx *ctx, u_char attr, u_char fg, u_char bg)
struct screen_redraw_ctx *ctx, u_short attr, u_char fg, u_char bg)
{
ctx->write(ctx->data, TTY_ATTRIBUTES, attr, fg, bg);
}
@ -151,7 +151,8 @@ screen_redraw_write_string(struct screen_redraw_ctx *ctx, const char *fmt, ...)
void
screen_redraw_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py)
{
u_char data, attr, fg, bg;
u_short attr;
u_char data, fg, bg;
screen_redraw_move_cursor(ctx, px, py);
screen_redraw_get_cell(ctx, px, py, &data, &attr, &fg, &bg);

View File

@ -1,4 +1,4 @@
/* $Id: screen-write.c,v 1.11 2008-09-08 17:40:51 nicm Exp $ */
/* $Id: screen-write.c,v 1.12 2008-09-08 22:03:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -172,7 +172,7 @@ screen_write_put_string(struct screen_write_ctx *ctx, const char *fmt, ...)
/* Set screen attributes. */
void
screen_write_set_attributes(
struct screen_write_ctx *ctx, u_char attr, u_char fg, u_char bg)
struct screen_write_ctx *ctx, u_short attr, u_char fg, u_char bg)
{
struct screen *s = ctx->s;

View File

@ -1,4 +1,4 @@
/* $Id: screen.c,v 1.67 2008-09-08 17:40:51 nicm Exp $ */
/* $Id: screen.c,v 1.68 2008-09-08 22:03:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -279,14 +279,18 @@ screen_expand_line(struct screen *s, u_int py, u_int nx)
ox = s->grid_size[py];
s->grid_size[py] = nx;
s->grid_data[py] = xrealloc(s->grid_data[py], 1, nx);
memset(&s->grid_data[py][ox], ' ', nx - ox);
s->grid_attr[py] = xrealloc(s->grid_attr[py], 1, nx);
memset(&s->grid_attr[py][ox], 0, nx - ox);
s->grid_fg[py] = xrealloc(s->grid_fg[py], 1, nx);
memset(&s->grid_fg[py][ox], 8, nx - ox);
s->grid_bg[py] = xrealloc(s->grid_bg[py], 1, nx);
memset(&s->grid_bg[py][ox], 8, nx - ox);
s->grid_data[py] = xrealloc(
s->grid_data[py], sizeof **s->grid_data, nx);
memset(&s->grid_data[py][ox], ' ', (nx - ox) * sizeof **s->grid_data);
s->grid_attr[py] = xrealloc(
s->grid_attr[py], sizeof **s->grid_attr, nx);
memset(&s->grid_attr[py][ox], 0, (nx - ox) * sizeof **s->grid_attr);
s->grid_fg[py] = xrealloc(
s->grid_fg[py], sizeof **s->grid_fg, nx);
memset(&s->grid_fg[py][ox], 8, (nx - ox) * sizeof **s->grid_fg);
s->grid_bg[py] = xrealloc(
s->grid_bg[py], sizeof **s->grid_bg, nx);
memset(&s->grid_bg[py][ox], 8, (nx - ox) * sizeof **s->grid_bg);
}
/* Reduce line. */
@ -295,16 +299,20 @@ screen_reduce_line(struct screen *s, u_int py, u_int nx)
{
s->grid_size[py] = nx;
s->grid_data[py] = xrealloc(s->grid_data[py], 1, nx);
s->grid_attr[py] = xrealloc(s->grid_attr[py], 1, nx);
s->grid_fg[py] = xrealloc(s->grid_fg[py], 1, nx);
s->grid_bg[py] = xrealloc(s->grid_bg[py], 1, nx);
s->grid_data[py] = xrealloc(
s->grid_data[py], sizeof **s->grid_data, nx);
s->grid_attr[py] = xrealloc(
s->grid_attr[py], sizeof **s->grid_attr, nx);
s->grid_fg[py] = xrealloc(
s->grid_fg[py], sizeof **s->grid_fg, nx);
s->grid_bg[py] = xrealloc(
s->grid_bg[py], sizeof **s->grid_bg, nx);
}
/* Get cell. */
void
screen_get_cell(struct screen *s,
u_int cx, u_int cy, u_char *data, u_char *attr, u_char *fg, u_char *bg)
u_int cx, u_int cy, u_char *data, u_short *attr, u_char *fg, u_char *bg)
{
if (cx >= s->grid_size[cy]) {
*data = ' ';
@ -325,7 +333,7 @@ screen_get_cell(struct screen *s,
/* Set a cell. */
void
screen_set_cell(struct screen *s,
u_int cx, u_int cy, u_char data, u_char attr, u_char fg, u_char bg)
u_int cx, u_int cy, u_char data, u_short attr, u_char fg, u_char bg)
{
if (cx >= s->grid_size[cy])
screen_expand_line(s, cy, cx + 1);
@ -406,7 +414,7 @@ screen_move_lines(struct screen *s, u_int dy, u_int py, u_int ny)
/* Fill an area. */
void
screen_fill_area(struct screen *s, u_int px, u_int py,
u_int nx, u_int ny, u_char data, u_char attr, u_char fg, u_char bg)
u_int nx, u_int ny, u_char data, u_short attr, u_char fg, u_char bg)
{
u_int i, j;

View File

@ -1,4 +1,4 @@
/* $Id: status.c,v 1.44 2008-09-08 17:40:51 nicm Exp $ */
/* $Id: status.c,v 1.45 2008-09-08 22:03:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -25,7 +25,7 @@
#include "tmux.h"
size_t status_width(struct winlink *);
char *status_print(struct session *, struct winlink *, u_char *);
char *status_print(struct session *, struct winlink *, u_short *);
/* Draw status for client on the last lines of given context. */
void
@ -38,7 +38,8 @@ status_redraw(struct client *c)
char lbuf[BUFSIZ], rbuf[BUFSIZ];
size_t llen, rlen, offset, xx, yy;
size_t size, start, width;
u_char attr, fg, bg;
u_short attr;
u_char fg, bg;
struct tm *tm;
time_t t;
int larrow, rarrow;
@ -275,7 +276,7 @@ status_width(struct winlink *wl)
}
char *
status_print(struct session *s, struct winlink *wl, u_char *attr)
status_print(struct session *s, struct winlink *wl, u_short *attr)
{
char *text, flag;

26
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.183 2008-09-08 17:40:51 nicm Exp $ */
/* $Id: tmux.h,v 1.184 2008-09-08 22:03:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -395,6 +395,8 @@ struct msg_resize_data {
#define ATTR_HIDDEN 0x20
#define ATTR_ITALICS 0x40
#define ATTR_CHARSET 0x80 /* alternative character set */
#define ATTR_FG256 0x100
#define ATTR_BG256 0x200
/* Modes. */
#define MODE_CURSOR 0x01
@ -420,7 +422,7 @@ struct screen {
char *title;
u_char **grid_data;
u_char **grid_attr;
u_short **grid_attr;
u_char **grid_fg;
u_char **grid_bg;
u_int *grid_size;
@ -436,13 +438,13 @@ struct screen {
u_int cx; /* cursor x */
u_int cy; /* cursor y */
u_char attr;
u_short attr;
u_char fg;
u_char bg;
u_int saved_cx;
u_int saved_cy;
u_char saved_attr;
u_short saved_attr;
u_char saved_fg;
u_char saved_bg;
@ -692,7 +694,7 @@ struct tty {
struct termios tio;
u_char attr;
u_short attr;
u_char fg;
u_char bg;
@ -1139,12 +1141,12 @@ void input_key(struct window *, int);
/* screen-display.c */
void screen_display_set_cell(
struct screen *, u_int, u_int, u_char, u_char, u_char, u_char);
struct screen *, u_int, u_int, u_char, u_short, u_char, u_char);
void screen_display_make_lines(struct screen *, u_int, u_int);
void screen_display_free_lines(struct screen *, u_int, u_int);
void screen_display_move_lines(struct screen *, u_int, u_int, u_int);
void screen_display_fill_area(struct screen *,
u_int, u_int, u_int, u_int, u_char, u_char, u_char, u_char);
u_int, u_int, u_int, u_int, u_char, u_short, u_char, u_char);
void screen_display_scroll_region_up(struct screen *);
void screen_display_scroll_region_down(struct screen *);
void screen_display_insert_lines(struct screen *, u_int, u_int);
@ -1171,7 +1173,7 @@ size_t printflike2 screen_write_put_string_rjust(
void printflike2 screen_write_put_string(
struct screen_write_ctx *, const char *, ...);
void screen_write_set_attributes(
struct screen_write_ctx *, u_char, u_char, u_char);
struct screen_write_ctx *, u_short, u_char, u_char);
void screen_write_set_region(struct screen_write_ctx *, u_int, u_int);
void screen_write_cursor_up_scroll(struct screen_write_ctx *);
void screen_write_cursor_down_scroll(struct screen_write_ctx *);
@ -1204,7 +1206,7 @@ void screen_redraw_start(struct screen_redraw_ctx *,
void screen_redraw_stop(struct screen_redraw_ctx *);
void screen_redraw_move_cursor(struct screen_redraw_ctx *, u_int, u_int);
void screen_redraw_set_attributes(
struct screen_redraw_ctx *, u_char, u_char, u_char);
struct screen_redraw_ctx *, u_short, u_char, u_char);
void printflike2 screen_redraw_write_string(
struct screen_redraw_ctx *, const char *, ...);
void screen_redraw_cell(struct screen_redraw_ctx *, u_int, u_int);
@ -1223,14 +1225,14 @@ void screen_resize(struct screen *, u_int, u_int);
void screen_expand_line(struct screen *, u_int, u_int);
void screen_reduce_line(struct screen *, u_int, u_int);
void screen_get_cell(struct screen *,
u_int, u_int, u_char *, u_char *, u_char *, u_char *);
u_int, u_int, u_char *, u_short *, u_char *, u_char *);
void screen_set_cell(
struct screen *, u_int, u_int, u_char, u_char, u_char, u_char);
struct screen *, u_int, u_int, u_char, u_short, u_char, u_char);
void screen_make_lines(struct screen *, u_int, u_int);
void screen_free_lines(struct screen *, u_int, u_int);
void screen_move_lines(struct screen *, u_int, u_int, u_int);
void screen_fill_area(struct screen *,
u_int, u_int, u_int, u_int, u_char, u_char, u_char, u_char);
u_int, u_int, u_int, u_int, u_char, u_short, u_char, u_char);
void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int);
void screen_clear_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int);

73
tty.c
View File

@ -1,4 +1,4 @@
/* $Id: tty.c,v 1.39 2008-09-08 21:04:59 nicm Exp $ */
/* $Id: tty.c,v 1.40 2008-09-08 22:03:56 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -39,7 +39,9 @@ void tty_raw(struct tty *, const char *);
void tty_puts(struct tty *, const char *);
void tty_putc(struct tty *, char);
void tty_attributes(struct tty *, u_char, u_char, u_char);
void tty_attributes(struct tty *, u_short, u_char, u_char);
u_char tty_attributes_fg(struct tty *, u_char);
u_char tty_attributes_bg(struct tty *, u_char);
char tty_translate(char);
TAILQ_HEAD(, tty_term) tty_terms = TAILQ_HEAD_INITIALIZER(tty_terms);
@ -602,17 +604,14 @@ tty_vwrite(struct tty *tty, struct screen *s, int cmd, va_list ap)
}
void
tty_attributes(struct tty *tty, u_char attr, u_char fg, u_char bg)
tty_attributes(struct tty *tty, u_short attr, u_char fg, u_char bg)
{
char s[32];
if (attr == tty->attr && fg == tty->fg && bg == tty->bg)
return;
/* If any bits are being cleared, reset everything. */
if (tty->attr & ~attr) {
if ((tty->attr & ATTR_CHARSET) &&
exit_alt_charset_mode != NULL)
if ((tty->attr & ATTR_CHARSET) && exit_alt_charset_mode != NULL)
tty_puts(tty, exit_alt_charset_mode);
tty_puts(tty, exit_attribute_mode);
tty->fg = 8;
@ -620,10 +619,11 @@ tty_attributes(struct tty *tty, u_char attr, u_char fg, u_char bg)
tty->attr = 0;
}
/* Filter out bits already set. */
/* Filter out attribute bits already set. */
attr &= ~tty->attr;
tty->attr |= attr;
/* Set the attributes. */
if ((attr & ATTR_BRIGHT) && enter_bold_mode != NULL)
tty_puts(tty, enter_bold_mode);
if ((attr & ATTR_DIM) && enter_dim_mode != NULL)
@ -641,38 +641,65 @@ tty_attributes(struct tty *tty, u_char attr, u_char fg, u_char bg)
if ((attr & ATTR_CHARSET) && enter_alt_charset_mode != NULL)
tty_puts(tty, enter_alt_charset_mode);
if (fg != tty->fg) {
if (fg > 15 && tty->term->flags & TERM_256COLOURS) {
/* Set foreground colour. */
if (fg != tty->fg || attr & ATTR_FG256)
tty->fg = tty_attributes_fg(tty, fg);
/* Set background colour. */
if (bg != tty->bg || attr & ATTR_BG256)
tty->bg = tty_attributes_bg(tty, bg);
}
u_char
tty_attributes_fg(struct tty *tty, u_char fg)
{
char s[32];
if (tty->attr & ATTR_FG256) {
if (tty->term->flags & TERM_256COLOURS) {
xsnprintf(s, sizeof s, "\033[38;5;%hhum", fg);
tty_puts(tty, s);
} else {
if (fg > 7)
return (fg);
}
if (fg > 15)
fg = 8;
else if (fg > 7)
fg -= 8;
}
if (fg == 8 && !(tty->term->flags & TERM_HASDEFAULTS))
fg = 7;
if (fg == 8)
tty_puts(tty, "\033[39m");
else if (set_a_foreground != NULL)
tty_puts(tty, tparm(set_a_foreground, fg));
}
}
return (fg);
}
if (bg != tty->bg) {
if (bg > 15 && tty->term->flags & TERM_256COLOURS) {
u_char
tty_attributes_bg(struct tty *tty, u_char bg)
{
char s[32];
if (tty->attr & ATTR_BG256) {
if (tty->term->flags & TERM_256COLOURS) {
xsnprintf(s, sizeof s, "\033[48;5;%hhum", bg);
tty_puts(tty, s);
} else {
if (bg > 7)
return (bg);
}
if (bg > 15)
bg = 8;
else if (bg > 7)
bg -= 8;
}
if (bg == 8 && !(tty->term->flags & TERM_HASDEFAULTS))
bg = 0;
if (bg == 8)
tty_puts(tty, "\033[49m");
else if (set_a_background != NULL)
tty_puts(tty, tparm(set_a_background, bg));
}
}
tty->fg = fg;
tty->bg = bg;
return (bg);
}