diff --git a/CHANGES b/CHANGES index 0776468d..d53d065f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ 21 November 2007 +* Create every line as zero length and only expand it as data is written, + rather than creating at full size immediately. * Make command output (eg list-keys) go to a scrollable window similar to scroll mode. * Redo screen redrawing so it is a) readable b) split into utility functions @@ -247,4 +249,4 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.79 2007-11-21 19:44:04 nicm Exp $ +$Id: CHANGES,v 1.80 2007-11-21 22:20:44 nicm Exp $ diff --git a/cmd-list-windows.c b/cmd-list-windows.c index c2a5e09a..74840b84 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-windows.c,v 1.10 2007-11-21 13:11:41 nicm Exp $ */ +/* $Id: cmd-list-windows.c,v 1.11 2007-11-21 22:20:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -42,15 +42,28 @@ const struct cmd_entry cmd_list_windows_entry = { void cmd_list_windows_exec(unused void *ptr, struct cmd_ctx *ctx) { - struct winlink *wl; - struct window *w; + struct winlink *wl; + struct window *w; + u_int i, sy; + unsigned long long size; RB_FOREACH(wl, winlinks, &ctx->session->windows) { w = wl->window; - ctx->print(ctx, "%d: %s \"%s\" (%s) [%ux%u] [history %u]", + + sy = w->screen.hsize + w->screen.dy; + size = sizeof *w; + for (i = 0; i < sy; i++) + size += 4 + w->screen.grid_size[i] * 3; + size += sy * (sizeof *w->screen.grid_data); + size += sy * (sizeof *w->screen.grid_attr); + size += sy * (sizeof *w->screen.grid_colr); + size += sy * (sizeof *w->screen.grid_size); + + ctx->print(ctx, + "%d: %s \"%s\" (%s) [%ux%u] [history %u] [%llu bytes]", wl->idx, w->name, w->screen.title, ttyname(w->fd), screen_size_x(&w->screen), screen_size_y(&w->screen), - w->screen.hsize); + w->screen.hsize, size); } if (ctx->cmdclient != NULL) diff --git a/screen-display.c b/screen-display.c index 8aceb88c..e1c1bc60 100644 --- a/screen-display.c +++ b/screen-display.c @@ -1,4 +1,4 @@ -/* $Id: screen-display.c,v 1.4 2007-11-21 21:28:58 nicm Exp $ */ +/* $Id: screen-display.c,v 1.5 2007-11-21 22:20:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -139,9 +139,7 @@ screen_display_cursor_set(struct screen *s, u_char ch) px = screen_x(s, s->cx); py = screen_y(s, s->cy); - s->grid_data[py][px] = ch; - s->grid_attr[py][px] = s->attr; - s->grid_colr[py][px] = s->colr; + screen_set_cell(s, px, py, ch, s->attr, s->colr); } /* Move cursor up and scroll if necessary. */ @@ -405,11 +403,15 @@ screen_display_insert_characters(struct screen *s, u_int px, u_int py, u_int nx) py = screen_y(s, py); + /* XXX Cheat and make the line a full line. */ + if (s->grid_size[py] < screen_size_x(s)) + screen_expand_line(s, py, screen_size_x(s)); + /* * Inserting a range of nx at px. * * - Move sx - (px + nx) from px to px + nx. - * - Clear the range at px. + * - Clear the range at px to px + nx. */ if (px + nx != screen_last_x(s)) { @@ -418,6 +420,7 @@ screen_display_insert_characters(struct screen *s, u_int px, u_int py, u_int nx) 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); } + memset(&s->grid_data[py][px], SCREEN_DEFDATA, nx); memset(&s->grid_attr[py][px], SCREEN_DEFATTR, nx); memset(&s->grid_colr[py][px], SCREEN_DEFCOLR, nx); @@ -437,11 +440,15 @@ screen_display_delete_characters(struct screen *s, u_int px, u_int py, u_int nx) py = screen_y(s, py); + /* XXX Cheat and make the line a full line. */ + if (s->grid_size[py] < screen_size_x(s)) + screen_expand_line(s, py, screen_size_x(s)); + /* * Deleting the range from px to px + nx. * * - Move sx - (px + nx) from px + nx to px. - * - Clear the range from the last x - (rx - lx) to the last x. + * - Clear the range from sx - nx to sx. */ if (px + nx != screen_last_x(s)) { diff --git a/screen.c b/screen.c index ab130b4c..e7be2a0e 100644 --- a/screen.c +++ b/screen.c @@ -1,4 +1,4 @@ -/* $Id: screen.c,v 1.34 2007-11-21 21:28:58 nicm Exp $ */ +/* $Id: screen.c,v 1.35 2007-11-21 22:20:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -110,7 +110,7 @@ screen_create(struct screen *s, u_int dx, u_int dy) void screen_resize(struct screen *s, u_int sx, u_int sy) { - u_int i, ox, oy, ny, my; + u_int ox, oy, ny, my; if (sx < 1) sx = 1; @@ -126,23 +126,6 @@ screen_resize(struct screen *s, u_int sx, u_int sy) * X dimension. */ if (sx != ox) { - /* Resize on-screen lines. */ - for (i = s->hsize; i < s->hsize + oy; i++) { - if (sx > s->grid_size[i]) { - s->grid_data[i] = - xrealloc(s->grid_data[i], sx, 1); - s->grid_attr[i] = - xrealloc(s->grid_attr[i], sx, 1); - s->grid_colr[i] = - xrealloc(s->grid_colr[i], sx, 1); - s->grid_size[i] = sx; - } - if (sx > ox) { - screen_fill_cells(s, ox, i, sx - ox, - SCREEN_DEFDATA, SCREEN_DEFATTR, - SCREEN_DEFCOLR); - } - } if (s->cx >= sx) s->cx = sx - 1; s->dx = sx; @@ -201,6 +184,56 @@ screen_resize(struct screen *s, u_int sx, u_int sy) s->rlower = s->dy - 1; } +/* Expand line. */ +void +screen_expand_line(struct screen *s, u_int py, u_int nx) +{ + u_int ox; + + 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], SCREEN_DEFDATA, nx - ox); + s->grid_attr[py] = xrealloc(s->grid_attr[py], 1, nx); + memset(&s->grid_attr[py][ox], SCREEN_DEFATTR, nx - ox); + s->grid_colr[py] = xrealloc(s->grid_colr[py], 1, nx); + memset(&s->grid_colr[py][ox], SCREEN_DEFCOLR, nx - ox); +} + +/* Get cell. */ +void +screen_get_cell(struct screen *s, + u_int cx, u_int cy, u_char *data, u_char *attr, u_char *colr) +{ + if (cx >= s->grid_size[cy]) { + *data = SCREEN_DEFDATA; + *attr = SCREEN_DEFATTR; + *colr = SCREEN_DEFCOLR; + } else { + *data = s->grid_data[cy][cx]; + *attr = s->grid_attr[cy][cx]; + *colr = s->grid_colr[cy][cx]; + } +} + +/* 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) +{ + if (cx >= s->grid_size[cy]) { + if (data == SCREEN_DEFDATA && + attr == SCREEN_DEFATTR && colr == SCREEN_DEFCOLR) + return; + 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; +} + /* Destroy a screen. */ void screen_destroy(struct screen *s) @@ -235,6 +268,20 @@ screen_draw_start(struct screen_draw_ctx *ctx, input_store_zero(b, CODE_CURSOROFF); } +/* Get cell data during drawing. */ +void +screen_draw_get_cell(struct screen_draw_ctx *ctx, + u_int px, u_int py, u_char *data, u_char *attr, u_char *colr) +{ + struct screen *s = ctx->s; + u_int cx, cy; + + cx = ctx->ox + px; + cy = screen_y(s, py) - ctx->oy; + + screen_get_cell(s, cx, cy, data, attr, colr); +} + /* Finalise drawing. */ void screen_draw_stop(struct screen_draw_ctx *ctx) @@ -254,28 +301,6 @@ screen_draw_stop(struct screen_draw_ctx *ctx) input_store_zero(b, CODE_CURSORON); } -/* Get cell data. */ -void -screen_draw_get_cell(struct screen_draw_ctx *ctx, - u_int px, u_int py, u_char *data, u_char *attr, u_char *colr) -{ - struct screen *s = ctx->s; - u_int cx, cy; - - cx = ctx->ox + px; - cy = screen_y(s, py) - ctx->oy; - - if (cx >= s->grid_size[cy]) { - *data = SCREEN_DEFDATA; - *attr = SCREEN_DEFATTR; - *colr = SCREEN_DEFCOLR; - } else { - *data = s->grid_data[cy][cx]; - *attr = s->grid_attr[cy][cx]; - *colr = s->grid_colr[cy][cx]; - } -} - /* Move cursor. */ void screen_draw_move(struct screen_draw_ctx *ctx, u_int px, u_int py) @@ -372,16 +397,13 @@ screen_make_lines(struct screen *s, u_int py, u_int ny) u_int i; for (i = py; i < py + ny; i++) { - s->grid_data[i] = xmalloc(s->dx); - s->grid_attr[i] = xmalloc(s->dx); - s->grid_colr[i] = xmalloc(s->dx); - s->grid_size[i] = s->dx; + s->grid_data[i] = NULL; + s->grid_attr[i] = NULL; + s->grid_colr[i] = NULL; + s->grid_size[i] = 0; } - screen_fill_lines( - s, py, ny, SCREEN_DEFDATA, SCREEN_DEFATTR, SCREEN_DEFCOLR); } - /* Free a range of ny lines at py. */ void screen_free_lines(struct screen *s, u_int py, u_int ny) @@ -389,9 +411,15 @@ screen_free_lines(struct screen *s, u_int py, u_int ny) u_int i; for (i = py; i < py + ny; i++) { - xfree(s->grid_data[i]); - xfree(s->grid_attr[i]); - xfree(s->grid_colr[i]); + if (s->grid_data[i] != NULL) + xfree(s->grid_data[i]); + s->grid_data[i] = NULL; + 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; s->grid_size[i] = 0; } } @@ -426,7 +454,8 @@ void screen_fill_cells(struct screen *s, u_int px, u_int py, u_int nx, u_char data, u_char attr, u_char colr) { - memset(&s->grid_data[py][px], data, nx); - memset(&s->grid_attr[py][px], attr, nx); - memset(&s->grid_colr[py][px], colr, nx); + u_int i; + + for (i = px; i < px + nx; i++) + screen_set_cell(s, i, py, data, attr, colr); } diff --git a/tmux.h b/tmux.h index 54227e28..d7b5a02f 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.91 2007-11-21 20:04:37 nicm Exp $ */ +/* $Id: tmux.h,v 1.92 2007-11-21 22:20:44 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -61,7 +61,7 @@ extern char *__progname; #define TTY_NAME_MAX 32 #endif -#define MAXTITLELEN 192 +#define MAXTITLELEN 128 /* Fatal errors. */ #define fatal(msg) log_fatal("%s: %s", __func__, msg); @@ -764,6 +764,10 @@ u_char screen_stringcolour(const char *); void screen_create(struct screen *, u_int, u_int); 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_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_draw_start(struct screen_draw_ctx *, struct screen *, struct buffer *, u_int, u_int); void screen_draw_stop(struct screen_draw_ctx *);