diff --git a/CHANGES b/CHANGES index f0b26990..6de5c7ab 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +08 September 2008 + +* 256 colour support. tmux attempts to autodetect the terminal by looking + both at what ncurses reports (usually wrong for xterm) and checking if + the TERM contains "256col". For xterm TERM=xterm-256color is needed (as + well as a build that support 256 colours); this seems to work for rxvt + as well. On non-256 colour terminals, high colours are translated to white + foreground and black background. + 28 August 2008 * Support OS X/Darwin thanks to bsd-poll.c from OpenSSH. Also convert @@ -646,4 +655,4 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.157 2008-08-28 17:45:23 nicm Exp $ +$Id: CHANGES,v 1.158 2008-09-08 17:40:50 nicm Exp $ diff --git a/TODO b/TODO index e681f214..da2d2645 100644 --- a/TODO +++ b/TODO @@ -14,7 +14,7 @@ - status-fg/status-bg should be able to set attributes: bold, etc - save/restore (DECSC/DECRC) are ugly. maybe a struct screen_attr and memcpy - force-default option: assume terminal supports default colours even if AX - is missing (like, eg, xterm-color in an aterm) + is missing (like, eg, xterm-color in an aterm). DITTO for 256 colours - refer to windows by name etc (duplicates? fnmatch?) - commands: command to run something without a window at all? @@ -38,10 +38,10 @@ - better mode features: search, back word, forward word, etc - flags to centre screen in window - better terminal emulation (identify, insert mode, some other bits) -- 256 colour terminal support -- For 0.5 -------------------------------------------------------------------- +21:09 < merdely> NicM: if I run 'tmux attach -t main' and there is no tmux session named main, start a new one. - commands: save-buffer -b number filename load-buffer -b number filename copy-buffer -s src-session -t dst-session @@ -61,3 +61,4 @@ - many more info() displays for various things - document mode-keys - vi half page scroll +- bugs with 256 colour test perl script... diff --git a/cmd-list-windows.c b/cmd-list-windows.c index ec839e14..8713ad7a 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-windows.c,v 1.21 2008-06-29 07:04:30 nicm Exp $ */ +/* $Id: cmd-list-windows.c,v 1.22 2008-09-08 17:40:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -63,7 +63,8 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx) size += w->base.grid_size[i] * 3; size += w->base.hsize * (sizeof *w->base.grid_data); size += w->base.hsize * (sizeof *w->base.grid_attr); - size += w->base.hsize * (sizeof *w->base.grid_colr); + size += w->base.hsize * (sizeof *w->base.grid_fg); + size += w->base.hsize * (sizeof *w->base.grid_bg); size += w->base.hsize * (sizeof *w->base.grid_size); if (w->fd != -1) diff --git a/input.c b/input.c index 663d7b76..0a9d829a 100644 --- a/input.c +++ b/input.c @@ -1,4 +1,4 @@ -/* $Id: input.c,v 1.52 2008-07-24 21:42:40 nicm Exp $ */ +/* $Id: input.c,v 1.53 2008-09-08 17:40:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -520,11 +520,11 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx) break; case '\016': /* SO */ attr = s->attr | ATTR_CHARSET; - screen_write_set_attributes(&ictx->ctx, attr, s->colr); + screen_write_set_attributes(&ictx->ctx, attr, s->fg, s->bg); break; case '\017': /* SI */ attr = s->attr & ~ATTR_CHARSET; - screen_write_set_attributes(&ictx->ctx, attr, s->colr); + screen_write_set_attributes(&ictx->ctx, attr, s->fg, s->bg); break; default: log_debug("unknown c0: %hhu", ch); @@ -567,14 +567,15 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx) s->saved_cx = s->cx; s->saved_cy = s->cy; s->saved_attr = s->attr; - s->saved_colr = s->colr; + s->saved_fg = s->fg; + s->saved_bg = s->bg; s->mode |= MODE_SAVED; break; case '8': /* DECRC */ if (!(s->mode & MODE_SAVED)) break; screen_write_set_attributes( - &ictx->ctx, s->saved_attr, s->saved_colr); + &ictx->ctx, s->saved_attr, s->saved_fg, s->saved_bg); screen_write_move_cursor(&ictx->ctx, s->saved_cx, s->saved_cy); break; default: @@ -1049,16 +1050,45 @@ input_handle_sequence_sgr(struct input_ctx *ictx) { struct screen *s = ictx->ctx.s; u_int i, n; - uint16_t m; - u_char attr, colr; + uint16_t m, o; + u_char attr, fg, bg; + + attr = s->attr; + fg = s->fg; + bg = s->bg; n = ARRAY_LENGTH(&ictx->args); - if (n == 0) { + switch (n) { + case 0: attr = 0; - colr = 0x88; - } else { - attr = s->attr; - colr = s->colr; + fg = 8; + bg = 8; + break; + case 3: + if (input_get_argument(ictx, 1, &m, 0) != 0) + return; + if (m == 5) { + if (input_get_argument(ictx, 0, &o, 0) != 0) + return; + if (input_get_argument(ictx, 2, &m, 0) != 0) + return; + if (o == 38) { + if (m > 7 && m < 16) { + attr |= ATTR_BRIGHT; + m -= 7; + } + fg = m; + break; + } else if (o == 48) { + if (m > 7 && m < 16) { + attr |= ATTR_BRIGHT; + m -= 7; + } + bg = m; + break; + } + } + default: for (i = 0; i < n; i++) { if (input_get_argument(ictx, i, &m, 0) != 0) return; @@ -1066,7 +1096,8 @@ input_handle_sequence_sgr(struct input_ctx *ictx) case 0: case 10: attr &= ATTR_CHARSET; - colr = 0x88; + fg = 8; + bg = 8; break; case 1: attr |= ATTR_BRIGHT; @@ -1103,12 +1134,10 @@ input_handle_sequence_sgr(struct input_ctx *ictx) case 35: case 36: case 37: - colr &= 0x0f; - colr |= (m - 30) << 4; + fg = m - 30; break; case 39: - colr &= 0x0f; - colr |= 0x80; + fg = 8; break; case 40: case 41: @@ -1118,15 +1147,13 @@ input_handle_sequence_sgr(struct input_ctx *ictx) case 45: case 46: case 47: - colr &= 0xf0; - colr |= m - 40; + bg = m - 40; break; case 49: - colr &= 0xf0; - colr |= 0x08; + bg = 8; break; } } } - screen_write_set_attributes(&ictx->ctx, attr, colr); + screen_write_set_attributes(&ictx->ctx, attr, fg, bg); } diff --git a/screen-display.c b/screen-display.c index 147597c5..06ec6caf 100644 --- a/screen-display.c +++ b/screen-display.c @@ -1,4 +1,4 @@ -/* $Id: screen-display.c,v 1.18 2008-07-24 21:42:40 nicm Exp $ */ +/* $Id: screen-display.c,v 1.19 2008-09-08 17:40:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -24,10 +24,11 @@ /* 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 colr) +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) { - screen_set_cell(s, screen_x(s, px), screen_y(s, py), data, attr, colr); + screen_set_cell( + s, screen_x(s, px), screen_y(s, py), data, attr, fg, bg); } /* Create a region of lines. */ @@ -39,9 +40,9 @@ screen_display_make_lines(struct screen *s, u_int py, u_int ny) return; } screen_make_lines(s, screen_y(s, py), ny); - if (s->attr != 0 || s->colr != 0x88) { - screen_display_fill_area(s, 0, py, - screen_size_x(s), ny, ' ', s->attr, s->colr); + if (s->attr != 0 || s->fg != 8 || s->bg != 8) { + screen_display_fill_area( + s, 0, py, screen_size_x(s), ny, ' ', s->attr, s->fg, s->bg); } } @@ -74,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 colr) + u_int nx, u_int ny, u_char data, u_char attr, u_char fg, u_char bg) { if (nx == 0 || ny == 0) { SCREEN_DEBUG4(s, px, py, nx, ny); @@ -89,7 +90,7 @@ screen_display_fill_area(struct screen *s, u_int px, u_int py, return; } screen_fill_area( - s, screen_x(s, px), screen_y(s, py), nx, ny, data, attr, colr); + s, screen_x(s, px), screen_y(s, py), nx, ny, data, attr, fg, bg); } /* Scroll region up. */ @@ -121,7 +122,8 @@ screen_display_scroll_region_up(struct screen *s) sy = screen_size_y(s) + s->hsize; s->grid_data = xrealloc(s->grid_data, sy, sizeof *s->grid_data); s->grid_attr = xrealloc(s->grid_attr, sy, sizeof *s->grid_attr); - s->grid_colr = xrealloc(s->grid_colr, sy, sizeof *s->grid_colr); + s->grid_fg = xrealloc(s->grid_fg, sy, sizeof *s->grid_fg); + s->grid_bg = xrealloc(s->grid_bg, sy, sizeof *s->grid_fg); s->grid_size = xrealloc(s->grid_size, sy, sizeof *s->grid_size); screen_display_make_lines(s, screen_last_y(s), 1); return; @@ -378,12 +380,14 @@ screen_display_insert_characters(struct screen *s, u_int px, u_int py, u_int nx) 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_colr[py][px + nx], &s->grid_colr[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); } memset(&s->grid_data[py][px], ' ', nx); memset(&s->grid_attr[py][px], s->attr, nx); - memset(&s->grid_colr[py][px], s->colr, nx); + memset(&s->grid_fg[py][px], s->fg, nx); + memset(&s->grid_bg[py][px], s->bg, nx); } /* Delete characters. */ @@ -417,12 +421,14 @@ screen_display_delete_characters(struct screen *s, u_int px, u_int py, u_int nx) mx = screen_last_x(s) - (px + nx); memmove(&s->grid_data[py][px], &s->grid_data[py][px + nx], mx); memmove(&s->grid_attr[py][px], &s->grid_attr[py][px + nx], mx); - memmove(&s->grid_colr[py][px], &s->grid_colr[py][px + nx], mx); + memmove(&s->grid_fg[py][px], &s->grid_fg[py][px + nx], mx); + memmove(&s->grid_bg[py][px], &s->grid_bg[py][px + nx], mx); } memset(&s->grid_data[py][screen_size_x(s) - nx], ' ', nx); memset(&s->grid_attr[py][screen_size_x(s) - nx], s->attr, nx); - memset(&s->grid_colr[py][screen_size_x(s) - nx], s->colr, nx); + memset(&s->grid_fg[py][screen_size_x(s) - nx], s->fg, nx); + memset(&s->grid_bg[py][screen_size_x(s) - nx], s->bg, nx); } /* Fill cells from another screen, with an offset. */ @@ -431,7 +437,7 @@ 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, colr; + u_char data, attr, fg, bg; if (nx == 0 || ny == 0) { SCREEN_DEBUG4(dst, px, py, nx, ny); @@ -450,8 +456,8 @@ screen_display_copy_area(struct screen *dst, struct screen *src, for (j = px; j < px + nx; j++) { screen_get_cell(src, screen_x(src, j) + ox, screen_y(src, i) - oy, - &data, &attr, &colr); - screen_display_set_cell(dst, j, i, data, attr, colr); + &data, &attr, &fg, &bg); + screen_display_set_cell(dst, j, i, data, attr, fg, bg); } } } diff --git a/screen-redraw.c b/screen-redraw.c index 9fd47352..39687664 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -1,4 +1,4 @@ -/* $Id: screen-redraw.c,v 1.9 2008-06-18 16:35:06 nicm Exp $ */ +/* $Id: screen-redraw.c,v 1.10 2008-09-08 17:40:51 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_int, u_int, u_char *, u_char *, u_char *, u_char *); /* Initialise redrawing with a window. */ void @@ -71,7 +71,7 @@ screen_redraw_start(struct screen_redraw_ctx *ctx, ctx->saved_cx = s->cx; ctx->saved_cy = s->cy; - ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->colr); + ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->fg, s->bg); ctx->write(ctx->data, TTY_SCROLLREGION, 0, screen_last_y(s)); ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx); ctx->write(ctx->data, TTY_CURSOROFF); @@ -87,7 +87,7 @@ screen_redraw_stop(struct screen_redraw_ctx *ctx) s->cx = ctx->saved_cx; s->cy = ctx->saved_cy; - ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->colr); + ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->fg, s->bg); ctx->write(ctx->data, TTY_SCROLLREGION, s->rupper, s->rlower); ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx); if (s->mode & MODE_CURSOR) @@ -99,11 +99,12 @@ 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 *colr) + u_int px, u_int py, u_char *data, u_char *attr, u_char *fg, u_char *bg) { struct screen *s = ctx->s; - screen_get_cell(s, screen_x(s, px), screen_y(s, py), data, attr, colr); + screen_get_cell( + s, screen_x(s, px), screen_y(s, py), data, attr, fg, bg); } /* Move cursor. */ @@ -120,9 +121,9 @@ 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_int attr, u_int colr) + struct screen_redraw_ctx *ctx, u_char attr, u_char fg, u_char bg) { - ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr); + ctx->write(ctx->data, TTY_ATTRIBUTES, attr, fg, bg); } /* Write string. */ @@ -150,12 +151,12 @@ 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, colr; + u_char data, attr, fg, bg; screen_redraw_move_cursor(ctx, px, py); - screen_redraw_get_cell(ctx, px, py, &data, &attr, &colr); + screen_redraw_get_cell(ctx, px, py, &data, &attr, &fg, &bg); - ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr); + ctx->write(ctx->data, TTY_ATTRIBUTES, attr, fg, bg); ctx->write(ctx->data, TTY_CHARACTER, data); ctx->s->cx++; diff --git a/screen-write.c b/screen-write.c index aff2dc98..ddcaff6c 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1,4 +1,4 @@ -/* $Id: screen-write.c,v 1.10 2008-07-24 21:42:40 nicm Exp $ */ +/* $Id: screen-write.c,v 1.11 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -110,7 +110,7 @@ screen_write_put_character(struct screen_write_ctx *ctx, u_char ch) return; } - screen_display_set_cell(s, s->cx, s->cy, ch, s->attr, s->colr); + screen_display_set_cell(s, s->cx, s->cy, ch, s->attr, s->fg, s->bg); s->cx++; if (ctx->write != NULL) @@ -172,16 +172,17 @@ 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 colr) + struct screen_write_ctx *ctx, u_char attr, u_char fg, u_char bg) { struct screen *s = ctx->s; - if (s->attr != attr || s->colr != colr) { + if (s->attr != attr || s->fg != fg || s->bg != bg) { s->attr = attr; - s->colr = colr; + s->fg = fg; + s->bg = bg; if (ctx->write != NULL) - ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr); + ctx->write(ctx->data, TTY_ATTRIBUTES, attr, fg, bg); } } @@ -381,9 +382,9 @@ screen_write_fill_end_of_screen(struct screen_write_ctx *ctx) u_int i; screen_display_fill_area(s, s->cx, s->cy, - screen_right_x(s, s->cx), 1, ' ', s->attr, s->colr); + screen_right_x(s, s->cx), 1, ' ', s->attr, s->fg, s->bg); screen_display_fill_area(s, 0, s->cy + 1, screen_size_x(s), - screen_below_y(s, s->cy + 1), ' ', s->attr, s->colr); + screen_below_y(s, s->cy + 1), ' ', s->attr, s->fg, s->bg); if (ctx->write != NULL) { ctx->write(ctx->data, TTY_CLEARENDOFLINE); @@ -403,7 +404,7 @@ screen_write_fill_screen(struct screen_write_ctx *ctx) u_int i; screen_display_fill_area(s, 0, 0, - screen_size_x(s), screen_size_y(s), ' ', s->attr, s->colr); + screen_size_x(s), screen_size_y(s), ' ', s->attr, s->fg, s->bg); if (ctx->write != NULL) { for (i = 0; i < screen_size_y(s); i++) { @@ -421,7 +422,7 @@ screen_write_fill_end_of_line(struct screen_write_ctx *ctx) struct screen *s = ctx->s; screen_display_fill_area(s, s->cx, s->cy, - screen_right_x(s, s->cx), 1, ' ', s->attr, s->colr); + screen_right_x(s, s->cx), 1, ' ', s->attr, s->fg, s->bg); if (ctx->write != NULL) ctx->write(ctx->data, TTY_CLEARENDOFLINE); @@ -434,7 +435,7 @@ screen_write_fill_start_of_line(struct screen_write_ctx *ctx) struct screen *s = ctx->s; screen_display_fill_area(s, 0, s->cy, - screen_left_x(s, s->cx), 1, ' ', s->attr, s->colr); + screen_left_x(s, s->cx), 1, ' ', s->attr, s->fg, s->bg); if (ctx->write != NULL) ctx->write(ctx->data, TTY_CLEARSTARTOFLINE); @@ -446,8 +447,8 @@ screen_write_fill_line(struct screen_write_ctx *ctx) { struct screen *s = ctx->s; - screen_display_fill_area(s, 0, s->cy, - screen_size_x(s), s->cy, ' ', s->attr, s->colr); + screen_display_fill_area( + s, 0, s->cy, screen_size_x(s), s->cy, ' ', s->attr, s->fg, s->bg); if (ctx->write != NULL) ctx->write(ctx->data, TTY_CLEARLINE); diff --git a/screen.c b/screen.c index d1391025..d20e04aa 100644 --- a/screen.c +++ b/screen.c @@ -1,4 +1,4 @@ -/* $Id: screen.c,v 1.66 2008-07-24 21:42:40 nicm Exp $ */ +/* $Id: screen.c,v 1.67 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -142,14 +142,16 @@ screen_create(struct screen *s, u_int dx, u_int dy, u_int hlimit) s->hlimit = hlimit; s->attr = 0; - s->colr = 0x88; + s->fg = 8; + s->bg = 8; s->mode = MODE_CURSOR; s->title = xstrdup(""); s->grid_data = xmalloc(dy * (sizeof *s->grid_data)); s->grid_attr = xmalloc(dy * (sizeof *s->grid_attr)); - s->grid_colr = xmalloc(dy * (sizeof *s->grid_colr)); + s->grid_fg = xmalloc(dy * (sizeof *s->grid_fg)); + s->grid_bg = xmalloc(dy * (sizeof *s->grid_bg)); s->grid_size = xmalloc(dy * (sizeof *s->grid_size)); screen_make_lines(s, 0, dy); @@ -167,12 +169,13 @@ screen_reset(struct screen *s) s->rlower = s->dy - 1; s->attr = 0; - s->colr = 0x88; + s->fg = 8; + s->bg = 8; s->mode = MODE_CURSOR; screen_display_fill_area(s, 0, 0, - screen_size_x(s), screen_size_y(s), ' ', 0, 0x88); + screen_size_x(s), screen_size_y(s), ' ', 0, 8, 8); screen_clear_selection(s); } @@ -254,7 +257,8 @@ screen_resize(struct screen *s, u_int sx, u_int sy) ny = s->hsize + sy; s->grid_data = xrealloc(s->grid_data, ny, sizeof *s->grid_data); s->grid_attr = xrealloc(s->grid_attr, ny, sizeof *s->grid_attr); - s->grid_colr = xrealloc(s->grid_colr, ny, sizeof *s->grid_colr); + s->grid_fg = xrealloc(s->grid_fg, ny, sizeof *s->grid_fg); + s->grid_bg = xrealloc(s->grid_bg, ny, sizeof *s->grid_bg); s->grid_size = xrealloc(s->grid_size, ny, sizeof *s->grid_size); s->dy = sy; @@ -279,8 +283,10 @@ screen_expand_line(struct screen *s, u_int py, u_int 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_colr[py] = xrealloc(s->grid_colr[py], 1, nx); - memset(&s->grid_colr[py][ox], 0x88, 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); } /* Reduce line. */ @@ -291,22 +297,25 @@ screen_reduce_line(struct screen *s, u_int py, u_int 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_colr[py] = xrealloc(s->grid_colr[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); } /* Get cell. */ void screen_get_cell(struct screen *s, - u_int cx, u_int cy, u_char *data, u_char *attr, u_char *colr) + u_int cx, u_int cy, u_char *data, u_char *attr, u_char *fg, u_char *bg) { if (cx >= s->grid_size[cy]) { *data = ' '; *attr = 0; - *colr = 0x88; + *fg = 8; + *bg = 8; } else { *data = s->grid_data[cy][cx]; *attr = s->grid_attr[cy][cx]; - *colr = s->grid_colr[cy][cx]; + *fg = s->grid_fg[cy][cx]; + *bg = s->grid_bg[cy][cx]; } if (screen_check_selection(s, cx, cy)) @@ -316,14 +325,15 @@ 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 colr) + u_int cx, u_int cy, u_char data, u_char attr, u_char fg, u_char bg) { if (cx >= s->grid_size[cy]) screen_expand_line(s, cy, cx + 1); s->grid_data[cy][cx] = data; s->grid_attr[cy][cx] = attr; - s->grid_colr[cy][cx] = colr; + s->grid_fg[cy][cx] = fg; + s->grid_bg[cy][cx] = bg; } /* Destroy a screen. */ @@ -334,7 +344,8 @@ screen_destroy(struct screen *s) screen_free_lines(s, 0, s->dy + s->hsize); xfree(s->grid_data); xfree(s->grid_attr); - xfree(s->grid_colr); + xfree(s->grid_fg); + xfree(s->grid_bg); xfree(s->grid_size); } @@ -347,7 +358,8 @@ screen_make_lines(struct screen *s, u_int py, u_int ny) for (i = py; i < py + ny; i++) { s->grid_data[i] = NULL; s->grid_attr[i] = NULL; - s->grid_colr[i] = NULL; + s->grid_fg[i] = NULL; + s->grid_bg[i] = NULL; s->grid_size[i] = 0; } } @@ -365,9 +377,12 @@ screen_free_lines(struct screen *s, u_int py, u_int ny) if (s->grid_attr[i] != NULL) xfree(s->grid_attr[i]); s->grid_attr[i] = NULL; - if (s->grid_colr[i] != NULL) - xfree(s->grid_colr[i]); - s->grid_colr[i] = NULL; + if (s->grid_fg[i] != NULL) + xfree(s->grid_fg[i]); + s->grid_fg[i] = NULL; + if (s->grid_bg[i] != NULL) + xfree(s->grid_bg[i]); + s->grid_bg[i] = NULL; s->grid_size[i] = 0; } } @@ -381,7 +396,9 @@ screen_move_lines(struct screen *s, u_int dy, u_int py, u_int ny) memmove( &s->grid_attr[dy], &s->grid_attr[py], ny * (sizeof *s->grid_attr)); memmove( - &s->grid_colr[dy], &s->grid_colr[py], ny * (sizeof *s->grid_colr)); + &s->grid_fg[dy], &s->grid_fg[py], ny * (sizeof *s->grid_fg)); + memmove( + &s->grid_bg[dy], &s->grid_bg[py], ny * (sizeof *s->grid_bg)); memmove( &s->grid_size[dy], &s->grid_size[py], ny * (sizeof *s->grid_size)); } @@ -389,13 +406,13 @@ 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 colr) + u_int nx, u_int ny, u_char data, u_char attr, u_char fg, u_char bg) { u_int i, j; for (i = py; i < py + ny; i++) { for (j = px; j < px + nx; j++) - screen_set_cell(s, j, i, data, attr, colr); + screen_set_cell(s, j, i, data, attr, fg, bg); } } diff --git a/server.c b/server.c index e9ea3130..ed421922 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.78 2008-08-28 17:45:27 nicm Exp $ */ +/* $Id: server.c,v 1.79 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -344,8 +344,8 @@ server_check_redraw(struct client *c) if (sx < xx) screen_redraw_columns(&ctx, sx, xx - sx); if (sy < yy) { - screen_fill_area(&screen, - 0, sy, xx, 1, '-', 0, 0x88); + screen_fill_area( + &screen, 0, sy, xx, 1, '-', 0, 8, 8); screen_redraw_lines(&ctx, sy, yy - sy); } screen_redraw_stop(&ctx); diff --git a/status.c b/status.c index 7f2ed916..cca8a79a 100644 --- a/status.c +++ b/status.c @@ -1,4 +1,4 @@ -/* $Id: status.c,v 1.43 2008-08-28 17:45:27 nicm Exp $ */ +/* $Id: status.c,v 1.44 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -38,7 +38,7 @@ 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, colr; + u_char attr, fg, bg; struct tm *tm; time_t t; int larrow, rarrow; @@ -49,8 +49,8 @@ status_redraw(struct client *c) if (gettimeofday(&c->status_timer, NULL) != 0) fatal("gettimeofday"); - colr = options_get_number(&s->options, "status-bg") + - (options_get_number(&s->options, "status-fg") << 4); + fg = options_get_number(&s->options, "status-fg"); + bg = options_get_number(&s->options, "status-bg"); yy = c->sy - 1; if (yy == 0) @@ -137,7 +137,7 @@ draw: /* Begin drawing and move to the starting position. */ screen_redraw_start_client(&ctx, c); - screen_redraw_set_attributes(&ctx, 0, colr); + screen_redraw_set_attributes(&ctx, 0, fg, bg); if (llen != 0) { screen_redraw_move_cursor(&ctx, 0, yy); screen_redraw_write_string(&ctx, "%s ", lbuf); @@ -154,7 +154,7 @@ draw: offset = 0; RB_FOREACH(wl, winlinks, &s->windows) { text = status_print(s, wl, &attr); - screen_redraw_set_attributes(&ctx, attr, colr); + screen_redraw_set_attributes(&ctx, attr, fg, bg); if (larrow == 1 && offset < start) { if (session_alert_has(s, wl, WINDOW_ACTIVITY)) @@ -178,7 +178,7 @@ draw: if (offset < start + width) { if (offset >= start) { - screen_redraw_set_attributes(&ctx, 0, colr); + screen_redraw_set_attributes(&ctx, 0, fg, bg); ctx.write(ctx.data, TTY_CHARACTER, ' '); } offset++; @@ -188,7 +188,7 @@ draw: } /* Fill the remaining space if any. */ - screen_redraw_set_attributes(&ctx, 0, colr); + screen_redraw_set_attributes(&ctx, 0, fg, bg); while (offset++ < xx) ctx.write(ctx.data, TTY_CHARACTER, ' '); @@ -200,10 +200,11 @@ draw: /* Draw the arrows. */ if (larrow != 0) { - if (larrow == -1) - screen_redraw_set_attributes(&ctx, ATTR_REVERSE, colr); - else - screen_redraw_set_attributes(&ctx, 0, colr); + if (larrow == -1) { + screen_redraw_set_attributes( + &ctx, ATTR_REVERSE, fg, bg); + } else + screen_redraw_set_attributes(&ctx, 0, fg, bg); if (llen != 0) screen_redraw_move_cursor(&ctx, llen + 1, yy); else @@ -211,10 +212,11 @@ draw: ctx.write(ctx.data, TTY_CHARACTER, '<'); } if (rarrow != 0) { - if (rarrow == -1) - screen_redraw_set_attributes(&ctx, ATTR_REVERSE, colr); - else - screen_redraw_set_attributes(&ctx, 0, colr); + if (rarrow == -1) { + screen_redraw_set_attributes( + &ctx, ATTR_REVERSE, fg, bg); + } else + screen_redraw_set_attributes(&ctx, 0, fg, bg); if (rlen != 0) screen_redraw_move_cursor(&ctx, c->sx - rlen - 2, yy); else @@ -228,7 +230,7 @@ draw: blank: /* Just draw the whole line as blank. */ screen_redraw_start_client(&ctx, c); - screen_redraw_set_attributes(&ctx, 0, colr); + screen_redraw_set_attributes(&ctx, 0, fg, bg); screen_redraw_move_cursor(&ctx, 0, yy); for (offset = 0; offset < c->sx; offset++) ctx.write(ctx.data, TTY_CHARACTER, ' '); @@ -245,7 +247,7 @@ off: /* If the screen is too small, use blank. */ if (screen_size_y(c->session->curw->window->screen) < c->sy) { screen_redraw_move_cursor(&ctx, 0, c->sy - 1); - screen_redraw_set_attributes(&ctx, 0, 0x88); + screen_redraw_set_attributes(&ctx, 0, 8, 8); for (offset = 0; offset < c->sx; offset++) ctx.write(ctx.data, TTY_CHARACTER, ' '); } else @@ -313,7 +315,7 @@ status_message_redraw(struct client *c) yy = c->sy - 1; screen_redraw_start_client(&ctx, c); - screen_redraw_set_attributes(&ctx, ATTR_REVERSE, 0x88); + screen_redraw_set_attributes(&ctx, ATTR_REVERSE, 8, 8); screen_redraw_move_cursor(&ctx, 0, yy); screen_redraw_write_string(&ctx, "%.*s", (int) xx, c->message_string); @@ -342,7 +344,7 @@ status_prompt_redraw(struct client *c) yy = c->sy - 1; screen_redraw_start_client(&ctx, c); - screen_redraw_set_attributes(&ctx, ATTR_REVERSE, 0x88); + screen_redraw_set_attributes(&ctx, ATTR_REVERSE, 8, 8); screen_redraw_move_cursor(&ctx, 0, yy); screen_redraw_write_string(&ctx, "%.*s", (int) xx, c->prompt_string); @@ -367,7 +369,7 @@ status_prompt_redraw(struct client *c) } /* Draw a fake cursor. */ - screen_redraw_set_attributes(&ctx, 0, 0x88); + screen_redraw_set_attributes(&ctx, 0, 8, 8); screen_redraw_move_cursor(&ctx, xx + c->prompt_index - offset, yy); if (c->prompt_index == strlen(c->prompt_buffer)) ch = ' '; diff --git a/tmux.h b/tmux.h index ac8d3734..fa2a1b5f 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.182 2008-08-28 17:45:27 nicm Exp $ */ +/* $Id: tmux.h,v 1.183 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -421,7 +421,8 @@ struct screen { u_char **grid_data; u_char **grid_attr; - u_char **grid_colr; + u_char **grid_fg; + u_char **grid_bg; u_int *grid_size; u_int dx; /* display x size */ @@ -436,12 +437,14 @@ struct screen { u_int cx; /* cursor x */ u_int cy; /* cursor y */ u_char attr; - u_char colr; /* fg:bg */ + u_char fg; + u_char bg; u_int saved_cx; u_int saved_cy; u_char saved_attr; - u_char saved_colr; + u_char saved_fg; + u_char saved_bg; int mode; @@ -670,6 +673,10 @@ struct tty_term { TERMINAL *term; u_int references; +#define TERM_HASDEFAULTS 0x01 +#define TERM_256COLOURS 0x02 + int flags; + TAILQ_ENTRY(tty_term) entry; }; @@ -685,8 +692,9 @@ struct tty { struct termios tio; - u_int attr; - u_int colr; + u_char attr; + u_char fg; + u_char bg; u_char acs[UCHAR_MAX + 1]; @@ -1131,12 +1139,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); + struct screen *, u_int, u_int, u_char, u_char, 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_int, u_int, u_int, u_int, u_char, u_char, 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); @@ -1162,7 +1170,8 @@ size_t printflike2 screen_write_put_string_rjust( struct screen_write_ctx *, const char *, ...); 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); +void screen_write_set_attributes( + struct screen_write_ctx *, u_char, 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 *); @@ -1194,9 +1203,10 @@ void screen_redraw_start(struct screen_redraw_ctx *, struct screen *, void (*)(void *, int, ...), void *); 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_int, u_int); +void screen_redraw_set_attributes( + struct screen_redraw_ctx *, u_char, u_char, u_char); void printflike2 screen_redraw_write_string( - struct screen_redraw_ctx *, const char *, ...); + struct screen_redraw_ctx *, const char *, ...); void screen_redraw_cell(struct screen_redraw_ctx *, u_int, u_int); void screen_redraw_area( struct screen_redraw_ctx *, u_int, u_int, u_int, u_int); @@ -1212,14 +1222,15 @@ void screen_destroy(struct screen *); 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 *); -void screen_set_cell(struct screen *, u_int, u_int, u_char, u_char, u_char); +void screen_get_cell(struct screen *, + u_int, u_int, u_char *, u_char *, u_char *, u_char *); +void screen_set_cell( + struct screen *, u_int, u_int, u_char, u_char, 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_int, u_int, u_int, u_int, u_char, u_char, 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 5115205d..fae3bf59 100644 --- a/tty.c +++ b/tty.c @@ -1,4 +1,4 @@ -/* $Id: tty.c,v 1.37 2008-07-23 23:44:50 nicm Exp $ */ +/* $Id: tty.c,v 1.38 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -39,7 +39,7 @@ 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); +void tty_attributes(struct tty *, u_char, u_char, u_char); char tty_translate(char); TAILQ_HEAD(, tty_term) tty_terms = TAILQ_HEAD_INITIALIZER(tty_terms); @@ -78,7 +78,8 @@ tty_open(struct tty *tty, char **cause) tty->out = buffer_create(BUFSIZ); tty->attr = 0; - tty->colr = 0x88; + tty->fg = 8; + tty->bg = 8; tty->flags = 0; @@ -88,7 +89,8 @@ tty_open(struct tty *tty, char **cause) tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP); tio.c_iflag |= IGNBRK; tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET); - tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|ECHOPRT|ECHOKE|ECHOCTL|ISIG); + tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL| + ECHOPRT|ECHOKE|ECHOCTL|ISIG); tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; if (tcsetattr(tty->fd, TCSANOW, &tio) != 0) @@ -276,6 +278,17 @@ tty_find_term(char *name, int fd, char **cause) goto error; } + if (tigetflag("AX") == TRUE) + term->flags |= TERM_HASDEFAULTS; + + /* + * Try to figure out if we have 256 colours. The standard xterm + * definitions are broken (well, or the way they are parsed is: in + * any case they end up returning 8). So also do a hack. + */ + if (max_colors == 256 || strstr(name, "256col") != NULL) /* XXX HACK */ + term->flags |= TERM_256COLOURS; + return (term); error: @@ -396,7 +409,7 @@ void tty_vwrite(struct tty *tty, struct screen *s, int cmd, va_list ap) { char ch; - u_int i, ua, ub; + u_int i, ua, ub, uc; if (tty->flags & TTY_FREEZE) return; @@ -582,17 +595,18 @@ tty_vwrite(struct tty *tty, struct screen *s, int cmd, va_list ap) case TTY_ATTRIBUTES: ua = va_arg(ap, u_int); ub = va_arg(ap, u_int); - tty_attributes(tty, ua, ub); + uc = va_arg(ap, u_int); + tty_attributes(tty, ua, ub, uc); break; } } void -tty_attributes(struct tty *tty, u_char attr, u_char colr) +tty_attributes(struct tty *tty, u_char attr, u_char fg, u_char bg) { - u_char fg, bg; + char s[32]; - if (attr == tty->attr && colr == tty->colr) + if (attr == tty->attr && fg == tty->fg && bg == tty->bg) return; /* If any bits are being cleared, reset everything. */ @@ -601,7 +615,8 @@ tty_attributes(struct tty *tty, u_char attr, u_char colr) exit_alt_charset_mode != NULL) tty_puts(tty, exit_alt_charset_mode); tty_puts(tty, exit_attribute_mode); - tty->colr = 0x88; + tty->fg = 8; + tty->bg = 8; tty->attr = 0; } @@ -626,27 +641,38 @@ tty_attributes(struct tty *tty, u_char attr, u_char colr) if ((attr & ATTR_CHARSET) && enter_alt_charset_mode != NULL) tty_puts(tty, enter_alt_charset_mode); - fg = (colr >> 4) & 0xf; - if (fg != ((tty->colr >> 4) & 0xf)) { - if (tigetflag("AX") != TRUE && fg == 8) - fg = 7; - - if (fg == 8) - tty_puts(tty, "\033[39m"); - else if (set_a_foreground != NULL) - tty_puts(tty, tparm(set_a_foreground, fg)); + if (fg != tty->fg) { + if (fg > 15 && 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)); + } } - bg = colr & 0xf; - if (bg != (tty->colr & 0xf)) { - if (tigetflag("AX") != TRUE && bg == 8) - bg = 0; - - if (bg == 8) - tty_puts(tty, "\033[49m"); - else if (set_a_background != NULL) - tty_puts(tty, tparm(set_a_background, bg)); + if (bg != tty->bg) { + if (bg > 15 && 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)); + } } - tty->colr = colr; + tty->fg = fg; + tty->bg = bg; } diff --git a/window-copy.c b/window-copy.c index 869effa3..192f6a20 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1,4 +1,4 @@ -/* $Id: window-copy.c,v 1.28 2008-08-07 20:20:52 nicm Exp $ */ +/* $Id: window-copy.c,v 1.29 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -211,11 +211,11 @@ window_copy_write_line( if (py == 0) { screen_write_set_attributes( - ctx, ATTR_BRIGHT|ATTR_REVERSE, 0x88); + ctx, ATTR_BRIGHT|ATTR_REVERSE, 8, 8); screen_write_move_cursor(ctx, 0, 0); size = screen_write_put_string_rjust( ctx, "[%u,%u/%u]", data->ox, data->oy, w->base.hsize); - screen_write_set_attributes(ctx, 0, 0x88); + screen_write_set_attributes(ctx, 0, 8, 8); } else size = 0; screen_write_move_cursor(ctx, 0, py); diff --git a/window-more.c b/window-more.c index 362bb121..2a688497 100644 --- a/window-more.c +++ b/window-more.c @@ -1,4 +1,4 @@ -/* $Id: window-more.c,v 1.16 2008-07-24 21:42:40 nicm Exp $ */ +/* $Id: window-more.c,v 1.17 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -169,14 +169,14 @@ window_more_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py) if (py == 0) { screen_write_set_attributes( - ctx, ATTR_BRIGHT|ATTR_REVERSE, 0x88); + ctx, ATTR_BRIGHT|ATTR_REVERSE, 8, 8); screen_write_move_cursor(ctx, 0, 0); size = screen_write_put_string_rjust( ctx, "[%u/%u]", data->top, ARRAY_LENGTH(&data->list)); } else size = 0; - screen_write_set_attributes(ctx, 0, 0x88); + screen_write_set_attributes(ctx, 0, 8, 8); screen_write_move_cursor(ctx, 0, py); if (data->top + py < ARRAY_LENGTH(&data->list)) { msg = ARRAY_ITEM(&data->list, data->top + py); diff --git a/window-scroll.c b/window-scroll.c index c0387fd4..d76cf71c 100644 --- a/window-scroll.c +++ b/window-scroll.c @@ -1,4 +1,4 @@ -/* $Id: window-scroll.c,v 1.21 2008-07-02 21:22:57 nicm Exp $ */ +/* $Id: window-scroll.c,v 1.22 2008-09-08 17:40:51 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -149,7 +149,7 @@ window_scroll_write_line( if (py == 0) { screen_write_set_attributes( - ctx, ATTR_BRIGHT|ATTR_REVERSE, 0x88); + ctx, ATTR_BRIGHT|ATTR_REVERSE, 8, 8); screen_write_move_cursor(ctx, 0, 0); size = screen_write_put_string_rjust( ctx, "[%u,%u/%u]", data->ox, data->oy, w->base.hsize);