diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2007-11-21 22:20:44 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2007-11-21 22:20:44 +0000 |
commit | c64cf68244dab6801342d45f78d67a64decc2cae (patch) | |
tree | 5be75be3fdb75eeb3b21eb437702e220ec7bd8df /screen.c | |
parent | 1e5cb8d2e4511be550a409baa9060bbd16f2de0e (diff) | |
download | rtmux-c64cf68244dab6801342d45f78d67a64decc2cae.tar.gz rtmux-c64cf68244dab6801342d45f78d67a64decc2cae.tar.bz2 rtmux-c64cf68244dab6801342d45f78d67a64decc2cae.zip |
Cut memory consumption by only allocating lines when there is actually data on them, and only as much as the right-most data. Everything else is filled in at runtime.
Diffstat (limited to 'screen.c')
-rw-r--r-- | screen.c | 137 |
1 files changed, 83 insertions, 54 deletions
@@ -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 <nicm@users.sourceforge.net> @@ -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); } |