diff --git a/input.c b/input.c index 0ae1bc5c..475cf22a 100644 --- a/input.c +++ b/input.c @@ -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 @@ -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: @@ -1151,10 +1146,12 @@ input_handle_sequence_sgr(struct input_ctx *ictx) case 44: case 45: case 46: - case 47: + case 47: + attr &= ~ATTR_BG256; bg = m - 40; break; case 49: + attr &= ~ATTR_BG256; bg = 8; break; } diff --git a/screen-display.c b/screen-display.c index 06ec6caf..be8c8e93 100644 --- a/screen-display.c +++ b/screen-display.c @@ -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 @@ -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); diff --git a/screen-redraw.c b/screen-redraw.c index 39687664..a66aee45 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -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 @@ -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); diff --git a/screen-write.c b/screen-write.c index ddcaff6c..c4f3fef1 100644 --- a/screen-write.c +++ b/screen-write.c @@ -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 @@ -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; diff --git a/screen.c b/screen.c index d20e04aa..06d34083 100644 --- a/screen.c +++ b/screen.c @@ -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 @@ -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; diff --git a/status.c b/status.c index cca8a79a..6f2a534d 100644 --- a/status.c +++ b/status.c @@ -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 @@ -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; diff --git a/tmux.h b/tmux.h index fa2a1b5f..d9a19e89 100644 --- a/tmux.h +++ b/tmux.h @@ -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 @@ -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); diff --git a/tty.c b/tty.c index 955378ff..9f99cc61 100644 --- a/tty.c +++ b/tty.c @@ -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 @@ -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) - 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) { + 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); +} + +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) - 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)); + return (bg); } - } - tty->fg = fg; - tty->bg = 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)); + return (bg); }