Initial 256 colour support, lightly tested.

This commit is contained in:
Nicholas Marriott 2008-09-08 17:40:51 +00:00
parent 33aa931541
commit 4235ddb4e8
15 changed files with 268 additions and 166 deletions

11
CHANGES
View File

@ -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 $

5
TODO
View File

@ -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...

View File

@ -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 <nicm@users.sourceforge.net>
@ -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)

71
input.c
View File

@ -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 <nicm@users.sourceforge.net>
@ -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);
}

View File

@ -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 <nicm@users.sourceforge.net>
@ -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);
}
}
}

View File

@ -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 <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_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++;

View File

@ -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 <nicm@users.sourceforge.net>
@ -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);

View File

@ -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 <nicm@users.sourceforge.net>
@ -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);
}
}

View File

@ -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 <nicm@users.sourceforge.net>
@ -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);

View File

@ -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 <nicm@users.sourceforge.net>
@ -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 = ' ';

41
tmux.h
View File

@ -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 <nicm@users.sourceforge.net>
@ -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);

84
tty.c
View File

@ -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 <nicm@users.sourceforge.net>
@ -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;
}

View File

@ -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 <nicm@users.sourceforge.net>
@ -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);

View File

@ -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 <nicm@users.sourceforge.net>
@ -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);

View File

@ -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 <nicm@users.sourceforge.net>
@ -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);