new resize/backlog implementation. Closes T2461

idea: store full lines in the backlog. No need to change them on resize
This commit is contained in:
Boris Faure 2015-04-06 18:08:23 +02:00
parent 4378f87162
commit 34592ab5b3
7 changed files with 358 additions and 279 deletions

View File

@ -139,12 +139,12 @@ _draw_line(const Termpty *ty, unsigned int *pixels,
Eina_Bool
_is_top_bottom_reached(Miniview *mv)
{
Termpty *ty;
int history_len;
EINA_SAFETY_ON_NULL_RETURN_VAL(mv, EINA_FALSE);
ty = termio_pty_get(mv->termio);
history_len = ty->backscroll_num;
/* TODO: RESIZE */
history_len = 42; //termpty_backscroll_len_get(ty);
if (( (- mv->img_hist) > (int)(mv->img_h - mv->rows - (mv->rows / 2))) &&
( (- mv->img_hist) < (int)(history_len + (mv->rows / 2))))
@ -522,7 +522,8 @@ _deferred_renderer(void *data)
evas_object_geometry_get(mv->termio, &ox, &oy, &ow, &oh);
if ((ow == 0) || (oh == 0)) return EINA_TRUE;
history_len = ty->backscroll_num;
/* TODO: RESIZE */
history_len = 42; //termpty_backscroll_len_get(ty);
evas_object_image_size_set(mv->img, mv->cols, mv->img_h);
ow = mv->cols;

View File

@ -133,8 +133,6 @@ termio_scroll(Evas_Object *obj, int direction, int start_y, int end_y)
if (mv) miniview_position_offset(mv, direction, EINA_FALSE);
// adjust scroll position for added scrollback
sd->scroll -= direction;
if (sd->scroll > sd->pty->backscroll_num)
sd->scroll = sd->pty->backscroll_num;
}
ty = sd->pty;
if (ty->selection.is_active)
@ -347,15 +345,8 @@ termio_scroll_delta(Evas_Object *obj, int delta, int by_page)
delta *= by;
}
sd->scroll += delta;
if (delta > 0)
{
if (sd->scroll > sd->pty->backscroll_num)
sd->scroll = sd->pty->backscroll_num;
}
else
{
if (sd->scroll < 0) sd->scroll = 0;
}
if (delta <= 0 && sd->scroll < 0)
sd->scroll = 0;
_smart_update_queue(obj, sd);
miniview_position_offset(term_miniview_get(sd->term), -delta, EINA_TRUE);
}
@ -2050,6 +2041,7 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, int c2x, int c2y,
EINA_SAFETY_ON_NULL_RETURN_VAL(sd, NULL);
termpty_cellcomp_freeze(sd->pty);
/* TODO: RESIZE use/save the reference point */
for (y = c1y; y <= c2y; y++)
{
Termcell *cells;
@ -4127,8 +4119,6 @@ _mouse_selection_scroll(void *data)
if (cy == 0)
cy = -1;
sd->scroll -= cy;
if (sd->scroll > sd->pty->backscroll_num)
sd->scroll = sd->pty->backscroll_num;
sd->pty->selection.end.y = -sd->scroll;
_smart_update_queue(data, sd);
}
@ -4324,9 +4314,8 @@ _smart_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNU
else
{
sd->scroll -= (ev->z * 4);
if (sd->scroll > sd->pty->backscroll_num)
sd->scroll = sd->pty->backscroll_num;
else if (sd->scroll < 0) sd->scroll = 0;
if (sd->scroll < 0)
sd->scroll = 0;
_smart_update_queue(data, sd);
miniview_position_offset(term_miniview_get(sd->term),
ev->z * 4, EINA_TRUE);
@ -4520,6 +4509,7 @@ _smart_apply(Evas_Object *obj)
}
inv = sd->pty->termstate.reverse;
termpty_cellcomp_freeze(sd->pty);
termpty_backscroll_adjust(sd->pty, &sd->scroll);
for (y = 0; y < sd->grid.h; y++)
{
Termcell *cells;

View File

@ -19,6 +19,7 @@
#if defined (__sun) || defined (__sun__)
# include <stropts.h>
#endif
#include <assert.h>
/* specific log domain to help debug only terminal code parser */
int _termpty_log_dom = -1;
@ -298,7 +299,7 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
if (!ty) return NULL;
ty->w = w;
ty->h = h;
ty->backmax = backscroll;
ty->backsize = backscroll;
termpty_reset_state(ty);
@ -567,16 +568,9 @@ termpty_free(Termpty *ty)
{
int i;
for (i = 0; i < ty->backmax; i++)
{
if (ty->back[i])
{
termpty_save_free(ty->back[i]);
ty->back[i] = NULL;
}
}
for (i = 0; i < ty->backsize; i++)
termpty_save_free(&ty->back[i]);
free(ty->back);
ty->back = NULL;
}
free(ty->screen);
free(ty->screen2);
@ -596,6 +590,24 @@ termpty_cellcomp_thaw(Termpty *ty EINA_UNUSED)
termpty_save_thaw();
}
static Eina_Bool
termpty_line_is_empty(const Termcell *cells, ssize_t nb_cells)
{
ssize_t len = nb_cells;
for (len = nb_cells - 1; len >= 0; len--)
{
const Termcell *cell = cells + len;
if ((cell->codepoint != 0) &&
(cell->att.bg != COL_INVIS))
return EINA_FALSE;
}
return EINA_TRUE;
}
ssize_t
termpty_line_length(const Termcell *cells, ssize_t nb_cells)
{
@ -613,6 +625,48 @@ termpty_line_length(const Termcell *cells, ssize_t nb_cells)
return 0;
}
#define BACKLOG_ROW_GET(Ty, Y) \
(&Ty->back[(Ty->backsize + ty->backpos - (Y)) % Ty->backsize])
void
termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max)
{
Termsave *ts;
ssize_t w;
if (ty->backsize <= 0)
return;
assert(ty->back);
termpty_save_freeze();
w = termpty_line_length(cells, w_max);
if (ty->backsize >= 1)
{
ts = BACKLOG_ROW_GET(ty, 0);
if (!ts->cells)
goto add_new_ts;
/* TODO: RESIZE uncompress ? */
if (ts->w && ts->cells[ts->w - 1].att.autowrapped)
{
termpty_save_expand(ts, cells, w);
return;
}
}
add_new_ts:
ts = BACKLOG_ROW_GET(ty, -1);
ts = termpty_save_new(ts, w);
if (!ts)
return;
termpty_cell_copy(ty, cells, ts->cells, w);
ty->backpos++;
if (ty->backpos >= ty->backsize)
ty->backpos = 0;
termpty_save_thaw();
}
ssize_t
termpty_row_length(Termpty *ty, int y)
{
@ -629,38 +683,114 @@ termpty_row_length(Termpty *ty, int y)
cells = &(TERMPTY_SCREEN(ty, 0, y));
return termpty_line_length(cells, ty->w);
}
if ((y < -ty->backmax) || !ty->back)
if ((y < -ty->backsize) || !ty->back)
{
ERR("invalid row given");
return 0;
}
ts = ty->back[(ty->backmax + ty->backpos + y) % ty->backmax];
if (!ts) return 0;
ts = BACKLOG_ROW_GET(ty, y);
return ts->comp ? ((Termsavecomp*)ts)->wout : ts->w;
return ts->cells ? ts->w : 0;
}
/* TODO: RESIZE reference point */
void
termpty_backscroll_adjust(Termpty *ty, int *scroll)
{
Termsave *ts;
int y;
int screen_y;
if (!ty->backsize || *scroll <= 0)
{
*scroll = 0;
return;
}
ERR("ty->backsize:%d ty->backpos:%d *scroll:%d",
ty->backsize, ty->backpos, *scroll);
/* TODO: RESIZE have a reference point? */
y = ty->backsize;
do
{
y--;
ts = BACKLOG_ROW_GET(ty, y);
}
while (!ts->cells);
ERR("y:%d", y);
if (*scroll <= y)
return;
screen_y = 0;
while (y >= 0)
{
int nb_lines;
ts = BACKLOG_ROW_GET(ty, y);
assert(ts != NULL);
nb_lines = (ts->w + ty->w) / ty->w;
ERR("[%d] ts->w:%d ty->w:%d, nb_lines:%d",
y, ts->w, ty->w, nb_lines);
screen_y += nb_lines;
y--;
}
ERR("screen_y:%d", screen_y);
*scroll = screen_y;
}
Termcell *
termpty_cellrow_get(Termpty *ty, int y, int *wret)
termpty_cellrow_get(Termpty *ty, int y_requested, int *wret)
{
Termsave *ts, **tssrc;
int screen_y = 0;
int backlog_y = 0;
if (y >= 0)
//ERR("y_requested:%d", y_requested);
if (y_requested >= 0)
{
if (y >= ty->h) return NULL;
if (y_requested >= ty->h)
return NULL;
*wret = ty->w;
/* fprintf(stderr, "getting: %i (%i, %i)\n", y, ty->circular_offset, ty->h); */
return &(TERMPTY_SCREEN(ty, 0, y));
return &(TERMPTY_SCREEN(ty, 0, y_requested));
}
if ((y < -ty->backmax) || !ty->back) return NULL;
tssrc = &(ty->back[(ty->backmax + ty->backpos + y) % ty->backmax]);
ts = termpty_save_extract(*tssrc);
if (!ts) return NULL;
*tssrc = ts;
*wret = ts->w;
return ts->cell;
if (!ty->back)
return NULL;
y_requested = -y_requested;
while (backlog_y <= ty->backsize)
{
Termsave *ts;
int nb_lines;
ts = BACKLOG_ROW_GET(ty, backlog_y);
if (!ts->cells)
{
//ERR("went too far: y_requested:%d screen_y:%d backlog_y:%d",
// y_requested, screen_y, backlog_y);
return NULL;
}
nb_lines = (ts->w + ty->w) / ty->w;
/* TODO: uncompress */
/* TODO: optimize */
//ERR("y_requested:%d screen_y:%d nb_lines:%d backlog_y:%d",
// y_requested, screen_y, nb_lines, backlog_y);
if (screen_y + nb_lines >= y_requested)
{
int delta = screen_y + nb_lines - y_requested;
*wret = ts->w - delta * ty->w;
if (*wret > ts->w)
*wret = ts->w;
return &ts->cells[delta * ty->w];
}
screen_y += nb_lines;
backlog_y++;
}
return NULL;
}
void
termpty_write(Termpty *ty, const char *input, int len)
{
@ -670,170 +800,113 @@ termpty_write(Termpty *ty, const char *input, int len)
ty->fd, strerror(errno));
}
static int
termpty_line_find_top(Termpty *ty, int y_end, int *top)
struct screen_info
{
int y_start = y_end;
Termcell *screen;
int w;
int h;
int x;
int y;
int cy;
int cx;
int circular_offset;
};
while (y_start > 0)
#define SCREEN_INFO_GET_CELLS(Tsi, X, Y) \
Tsi->screen[X + (((Y + Tsi->circular_offset) % Tsi->h) * Tsi->w)]
static void
_check_screen_info(Termpty *ty, struct screen_info *si)
{
if (si->y >= si->h)
{
if (TERMPTY_SCREEN(ty, ty->w - 1, y_start - 1).att.autowrapped)
y_start--;
else
{
*top = y_start;
return 0;
}
Termcell *cells = &SCREEN_INFO_GET_CELLS(si, 0, 0);
ERR("adjusting");
si->y--;
termpty_text_save_top(ty, cells, si->w);
termpty_cells_clear(ty, cells, si->w);
si->circular_offset++;
if (si->circular_offset >= si->h)
si->circular_offset = 0;
si->cy--;
}
while (-y_start < ty->backscroll_num)
{
Termsave *ts = ty->back[(y_start + ty->backpos - 1 +
ty->backmax) % ty->backmax];
if (ts)
{
ts = termpty_save_extract(ts);
}
if (!ts)
return -1;
ty->back[(y_start + ty->backpos - 1 + ty->backmax) % ty->backmax] = ts;
if (ts->cell[ts->w - 1].att.autowrapped)
y_start--;
else
{
*top = y_start;
return 0;
}
}
*top = y_start;
return 0;
}
static int
termpty_line_rewrap(Termpty *ty, int y_start, int y_end,
Termcell *new_screen, Termsave **new_back,
int new_w, int new_y_end, int *new_y_startp,
int *new_cyp)
static void
_termpty_line_rewrap(Termpty *ty, Termcell *cells, int len,
struct screen_info *si,
Eina_Bool set_cursor)
{
/* variables prefixed by new_ are about the resized term being built up */
int x, y, new_x, new_y, new_y_start;
int len, len_last, len_remaining, copy_width, new_ts_width;
Termsave *ts, *new_ts;
Termcell *line, *new_line = NULL;
int autowrapped = cells[len-1].att.autowrapped;
if (y_end >= 0)
ERR("si->x:%d si->y:%d si->cx:%d si->cy:%d",
si->x, si->y, si->cx, si->cy);
if (len == 0)
{
len_last = termpty_line_length(&TERMPTY_SCREEN(ty, 0, y_end), ty->w);
if (set_cursor)
{
si->cy = si->y;
si->cx = 0;
}
si->y++;
si->x = 0;
_check_screen_info(ty, si);
return;
}
else
while (len > 0)
{
ts = termpty_save_extract(ty->back[(y_end + ty->backpos +
ty->backmax) % ty->backmax]);
if (!ts)
return -1;
ty->back[(y_end + ty->backpos + ty->backmax) % ty->backmax] = ts;
len_last = ts->w;
}
len_remaining = len_last + (y_end - y_start) * ty->w;
new_y_start = new_y_end;
if (len_remaining)
{
new_y_start -= (len_remaining + new_w - 1) / new_w - 1;
}
else
{
if (new_y_start < 0)
new_back[new_y_start + ty->backmax] = termpty_save_new(0);
*new_y_startp = new_y_start;
return 0;
}
if (-new_y_start > ty->backmax)
{
y_start += ((-new_y_start - ty->backmax) * new_w) / ty->w;
x = ((-new_y_start - ty->backmax) * new_w) % ty->w;
len_remaining -= (-new_y_start - ty->backmax) * new_w;
new_y_start = -ty->backmax;
}
else
{
x = 0;
}
y = y_start;
new_x = 0;
new_y = new_y_start;
int copy_width = MIN(len, si->w - si->x);
while (y <= y_end)
{
if (y >= 0)
ERR("len:%d copy_width:%d", len, copy_width);
termpty_cell_copy(ty,
/*src*/ cells,
/*dst*/&SCREEN_INFO_GET_CELLS(si, si->x, si->y),
copy_width);
if (set_cursor)
{
line = &TERMPTY_SCREEN(ty, 0, y);
}
else
{
ts = termpty_save_extract(ty->back[(y + ty->backpos +
ty->backmax) % ty->backmax]);
if (!ts)
return -1;
ty->back[(y + ty->backpos + ty->backmax) % ty->backmax] = ts;
line = ts->cell;
}
if (y == y_end)
len = len_last;
else
len = ty->w;
line[len - 1].att.autowrapped = 0;
while (x < len)
{
copy_width = MIN(len - x, new_w - new_x);
if (new_x == 0)
if (ty->cursor_state.cx <= copy_width)
{
if (new_y >= 0)
{
new_line = new_screen + (new_y * new_w);
}
else
{
new_ts_width = MIN(len_remaining, new_w);
new_ts = termpty_save_new(new_ts_width);
if (!new_ts)
return -1;
new_line = new_ts->cell;
new_back[new_y + ty->backmax] = new_ts;
}
si->cx = ty->cursor_state.cx;
si->cy = si->y;
}
if (y == ty->cursor_state.cy)
else
{
*new_cyp = new_y_start;
}
if (new_line)
{
termpty_cell_copy(ty, line + x, new_line + new_x, copy_width);
x += copy_width;
new_x += copy_width;
len_remaining -= copy_width;
if ((new_x == new_w) && (new_y != new_y_end))
{
new_line[new_x - 1].att.autowrapped = 1;
new_x = 0;
new_y++;
}
ty->cursor_state.cx -= copy_width;
}
}
x = 0;
y++;
len -= copy_width;
si->x += copy_width;
ERR("si->x:%d si->w:%d", si->x, si->w);
if (si->x >= si->w)
{
si->y++;
si->x = 0;
}
_check_screen_info(ty, si);
}
ERR("autowrapped:%d", autowrapped);
if (!autowrapped)
{
si->y++;
si->x = 0;
_check_screen_info(ty, si);
}
*new_y_startp = new_y_start;
return 0;
}
void
termpty_resize(Termpty *ty, int new_w, int new_h)
{
Termcell *new_screen = NULL;
Termsave **new_back = NULL;
int y_start = 0, y_end = 0, new_y_start = 0, new_y_end,
new_cy = ty->cursor_state.cy;
int i, altbuf = 0;
int old_y = 0,
old_w = ty->w,
old_h = ty->h,
effective_old_h;
int altbuf = 0;
struct screen_info new_si = {.screen = NULL};
if ((ty->w == new_w) && (ty->h == new_h)) return;
if ((new_w == new_h) && (new_w == 1)) return; // FIXME: something weird is
@ -854,47 +927,50 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
ty->screen2 = calloc(1, sizeof(Termcell) * new_w * new_h);
if (!ty->screen2)
goto bad;
new_back = calloc(sizeof(Termsave *), ty->backmax);
y_end = ty->cursor_state.cy;
new_y_end = new_h - 1;
/* For each "full line" in old buffers, rewrap.
* From most recent to oldest */
while ((y_end >= -ty->backscroll_num) && (new_y_end >= -ty->backmax))
new_si.screen = new_screen;
new_si.w = new_w;
new_si.h = new_h;
/* compute the effective height on the old screen */
effective_old_h = old_h;
for (old_y = old_h -1; old_y >= 0; old_y--)
{
if (termpty_line_find_top(ty, y_end, &y_start) < 0)
goto bad;
if (termpty_line_rewrap(ty, y_start, y_end,
new_screen, new_back,
new_w, new_y_end,
&new_y_start, &new_cy) < 0)
goto bad;
Termcell *cells = &TERMPTY_SCREEN(ty, 0, old_y);
if (!termpty_line_is_empty(cells, old_w))
{
effective_old_h = old_y + 1;
break;
}
}
y_end = y_start - 1;
new_y_end = new_y_start - 1;
for (old_y = 0; old_y < effective_old_h; old_y++)
{
/* for each line in the old screen, append it to the new screen */
Termcell *cells = &TERMPTY_SCREEN(ty, 0, old_y);
int len;
len = termpty_line_length(cells, old_w);
ERR("[%d] len:%d", old_y, len);
_termpty_line_rewrap(ty, cells, len, &new_si,
old_y == ty->cursor_state.cy);
}
free(ty->screen);
ty->screen = new_screen;
for (i = 1; i <= ty->backscroll_num; i++)
termpty_save_free(ty->back[(ty->backpos - i + ty->backmax) % ty->backmax]);
free(ty->back);
ty->back = new_back;
ty->cursor_state.cy = (new_si.cy >= 0) ? new_si.cy : 0;
ty->cursor_state.cx = (new_si.cx >= 0) ? new_si.cx : 0;
ty->circular_offset = new_si.circular_offset;
ty->w = new_w;
ty->h = new_h;
ty->circular_offset = MAX(new_y_start, 0);
ty->backpos = 0;
ty->backscroll_num = MAX(-new_y_start, 0);
ty->termstate.had_cr = 0;
ty->cursor_state.cy = (new_cy + new_h - ty->circular_offset) % new_h;
ty->termstate.wrapnext = 0;
if (altbuf)
termpty_screen_swap(ty);
ty->termstate.wrapnext = 0;
_limit_coord(ty);
_pty_size(ty);
@ -905,8 +981,6 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
bad:
termpty_save_thaw();
free(new_screen);
free(new_back);
}
void
@ -914,25 +988,24 @@ termpty_backscroll_set(Termpty *ty, int size)
{
int i;
if (ty->backmax == size) return;
if (ty->backsize == size)
return;
/* TODO: RESIZE: handle that case better: changing backscroll size */
termpty_save_freeze();
if (ty->back)
{
for (i = 0; i < ty->backmax; i++)
{
if (ty->back[i]) termpty_save_free(ty->back[i]);
}
for (i = 0; i < ty->backsize; i++)
termpty_save_free(&ty->back[i]);
free(ty->back);
}
if (size > 0)
ty->back = calloc(1, sizeof(Termsave *) * size);
ty->back = calloc(1, sizeof(Termsave) * size);
else
ty->back = NULL;
ty->backscroll_num = 0;
ty->backpos = 0;
ty->backmax = size;
ty->backsize = size;
termpty_save_thaw();
}
@ -1089,7 +1162,7 @@ void
termpty_cell_copy(Termpty *ty, Termcell *src, Termcell *dst, int n)
{
int i;
for (i = 0; i < n; i++)
{
_handle_block_codepoint_overwrite(ty, dst[i].codepoint, src[i].codepoint);

View File

@ -99,7 +99,7 @@ struct _Termpty
} prop;
const char *cur_cmd;
Termcell *screen, *screen2;
Termsave **back;
Termsave *back;
unsigned char oldbuf[4];
Eina_Unicode *buf;
size_t buflen;
@ -107,8 +107,7 @@ struct _Termpty
int fd, slavefd;
int circular_offset;
int circular_offset2;
int backmax, backpos;
int backscroll_num;
int backsize, backpos;
struct {
int curid;
Eina_Hash *blocks;
@ -178,9 +177,11 @@ struct _Termsave
unsigned int comp : 1;
unsigned int z : 1;
unsigned int w : 22;
Termcell cell[1];
/* TODO: union ? */
Termcell *cells;
};
/* TODO: RESIZE rewrite Termsavecomp */
struct _Termsavecomp
{
unsigned int gen : 8;
@ -232,8 +233,9 @@ void termpty_cellcomp_thaw(Termpty *ty);
Termcell *termpty_cellrow_get(Termpty *ty, int y, int *wret);
ssize_t termpty_row_length(Termpty *ty, int y);
void termpty_write(Termpty *ty, const char *input, int len);
void termpty_resize(Termpty *ty, int w, int h);
void termpty_resize(Termpty *ty, int new_w, int new_h);
void termpty_backscroll_set(Termpty *ty, int size);
void termpty_backscroll_adjust(Termpty *ty, int *scroll);
pid_t termpty_pid_get(const Termpty *ty);
void termpty_block_free(Termblock *tb);

View File

@ -32,34 +32,6 @@ termpty_cells_clear(Termpty *ty, Termcell *cells, int count)
termpty_cell_fill(ty, &src, cells, count);
}
void
termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max)
{
Termsave *ts;
ssize_t w;
if (ty->backmax <= 0) return;
termpty_save_freeze();
w = termpty_line_length(cells, w_max);
ts = termpty_save_new(w);
if (!ts)
return;
termpty_cell_copy(ty, cells, ts->cell, w);
if (!ty->back) ty->back = calloc(1, sizeof(Termsave *) * ty->backmax);
if (ty->back[ty->backpos])
{
termpty_save_free(ty->back[ty->backpos]);
ty->back[ty->backpos] = NULL;
}
ty->back[ty->backpos] = ts;
ty->backpos++;
if (ty->backpos >= ty->backmax) ty->backpos = 0;
ty->backscroll_num++;
if (ty->backscroll_num >= ty->backmax) ty->backscroll_num = ty->backmax;
termpty_save_thaw();
}
void
termpty_text_scroll(Termpty *ty, Eina_Bool clear)
{
@ -377,6 +349,8 @@ termpty_reset_att(Termatt *att)
void
termpty_reset_state(Termpty *ty)
{
int backsize;
ty->cursor_state.cx = 0;
ty->cursor_state.cy = 0;
ty->termstate.scroll_y1 = 0;
@ -411,17 +385,15 @@ termpty_reset_state(Termpty *ty)
if (ty->back)
{
int i;
for (i = 0; i < ty->backmax; i++)
{
if (ty->back[i]) termpty_save_free(ty->back[i]);
}
for (i = 0; i < ty->backsize; i++)
termpty_save_free(&ty->back[i]);
free(ty->back);
ty->back = NULL;
}
ty->backscroll_num = 0;
ty->backpos = 0;
if (ty->backmax)
ty->back = calloc(1, sizeof(Termsave *) * ty->backmax);
backsize = ty->backsize;
ty->backsize = 0;
termpty_backscroll_set(ty, backsize);
termpty_save_thaw();
}

View File

@ -27,10 +27,13 @@ struct _Alloc
unsigned char __pad;
};
#if 0
static uint64_t _allocated = 0;
#endif
static unsigned char cur_gen = 0;
static Alloc *alloc[MEM_BLOCKS] = { 0 };
#if 0
static int
roundup_block_size(int sz)
{
@ -122,21 +125,25 @@ _alloc_new(int size, unsigned char gen)
ptr += sizeof(Alloc);
return ptr;
}
#endif
static void *
_ts_new(int size)
{
void *ptr;
/* TODO: RESIZE rewrite that stuff */
//void *ptr;
if (!size) return NULL;
ptr = _alloc_new(size, cur_gen);
//ptr = _alloc_new(size, cur_gen);
return ptr;
return calloc(1, size);
}
static void
_ts_free(void *ptr)
{
free(ptr);
#if 0
Alloc *al;
unsigned int sz;
Termsavecomp *ts = ptr;
@ -165,6 +172,7 @@ _ts_free(void *ptr)
#else
munmap(al, al->size);
#endif
#endif
}
static void
@ -210,12 +218,15 @@ static Eina_List *ptys = NULL;
static Ecore_Idler *idler = NULL;
static Ecore_Timer *timer = NULL;
#if 0
static Termsave *
_save_comp(Termsave *ts)
{
Termsave *ts2;
Termsavecomp *tsc;
ERR("save comp");
// already compacted
if (ts->comp) return ts;
// make new allocation for new generation
@ -226,7 +237,7 @@ _save_comp(Termsave *ts)
char *buf;
buf = alloca(LZ4_compressBound(ts->w * sizeof(Termcell)));
bytes = LZ4_compress((char *)(&(ts->cell[0])), buf,
bytes = LZ4_compress((char *)(&(ts->cells[0])), buf,
ts->w * sizeof(Termcell));
tsc = _ts_new(sizeof(Termsavecomp) + bytes);
if (!tsc)
@ -262,6 +273,7 @@ done:
ts_compfreeze--;
return ts2;
}
#endif
static void
_walk_pty(Termpty *ty)
@ -270,18 +282,20 @@ _walk_pty(Termpty *ty)
// int c0 = 0, c1 = 0;
if (!ty->back) return;
for (i = 0; i < ty->backmax; i++)
for (i = 0; i < ty->backsize; i++)
{
Termsavecomp *tsc = (Termsavecomp *)ty->back[i];
Termsavecomp *tsc = (Termsavecomp *)&ty->back[i];
if (tsc)
{
ty->back[i] = _save_comp(ty->back[i]);
#if 0
ty->back[i] = _save_comp(tsc);
tsc = (Termsavecomp *)ty->back[i];
if (tsc->comp) ts_comp++;
else ts_uncomp++;
// c0 += tsc->w;
// c1 += tsc->wout * sizeof(Termcell);
#endif
}
}
// printf("compress ratio: %1.3f\n", (double)c0 / (double)c1);
@ -290,10 +304,14 @@ _walk_pty(Termpty *ty)
static Eina_Bool
_idler(void *data EINA_UNUSED)
{
/* TODO: RESIZE : re-enable compression */
return EINA_FALSE;
Eina_List *l;
Termpty *ty;
// double t0, t;
_mem_gen_next();
// t0 = ecore_time_get();
@ -326,6 +344,8 @@ _timer(void *data EINA_UNUSED)
static inline void
_check_compressor(Eina_Bool frozen)
{
/* TODO: RESIZE re-enable compressor */
return;
if (freeze) return;
if (idler) return;
if ((ts_uncomp > 256) || (ts_freeops > 256))
@ -395,11 +415,11 @@ termpty_save_extract(Termsave *ts)
ts2->gen = _mem_gen_get();
ts2->w = tsc->wout;
buf = ((char *)tsc) + sizeof(Termsavecomp);
bytes = LZ4_uncompress(buf, (char *)(&(ts2->cell[0])),
bytes = LZ4_uncompress(buf, (char *)(&(ts2->cells[0])),
tsc->wout * sizeof(Termcell));
if (bytes < 0)
{
memset(&(ts2->cell[0]), 0, tsc->wout * sizeof(Termcell));
memset(&(ts2->cells[0]), 0, tsc->wout * sizeof(Termcell));
// ERR("Decompress problem in row at byte %i", -bytes);
}
if (ts->comp) ts_comp--;
@ -417,10 +437,13 @@ termpty_save_extract(Termsave *ts)
}
Termsave *
termpty_save_new(int w)
termpty_save_new(Termsave *ts, int w)
{
Termsave *ts = _ts_new(sizeof(Termsave) + ((w - 1) * sizeof(Termcell)));
if (!ts) return NULL;
termpty_save_free(ts);
Termcell *cells = calloc(1, w * sizeof(Termcell));
if (!cells ) return NULL;
ts->cells = cells;
ts->gen = _mem_gen_get();
ts->w = w;
if (!ts_compfreeze) ts_uncomp++;
@ -428,6 +451,21 @@ termpty_save_new(int w)
return ts;
}
Termsave *
termpty_save_expand(Termsave *ts, Termcell *cells, ssize_t delta)
{
Termcell *newcells;
newcells = realloc(ts->cells, (ts->w + delta) * sizeof(Termcell));
if (!newcells)
return NULL;
newcells[ts->w - 1].att.autowrapped = 0;
memcpy(&newcells[ts->w], cells, delta * sizeof(Termcell));
ts->w += delta;
ts->cells = newcells;
return ts;
}
void
termpty_save_free(Termsave *ts)
{
@ -438,6 +476,8 @@ termpty_save_free(Termsave *ts)
else ts_uncomp--;
ts_freeops++;
}
_ts_free(ts);
_ts_free(ts->cells);
ts->cells = NULL;
ts->w = 0;
_check_compressor(EINA_FALSE);
}

View File

@ -6,7 +6,8 @@ void termpty_save_thaw(void);
void termpty_save_register(Termpty *ty);
void termpty_save_unregister(Termpty *ty);
Termsave *termpty_save_extract(Termsave *ts);
Termsave *termpty_save_new(int w);
Termsave *termpty_save_new(Termsave *ts, int w);
void termpty_save_free(Termsave *ts);
Termsave *termpty_save_expand(Termsave *ts, Termcell *cells, ssize_t delta);
#endif