From 34592ab5b3e01e473355c9cc0f370cee0731c40c Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Mon, 6 Apr 2015 18:08:23 +0200 Subject: [PATCH] new resize/backlog implementation. Closes T2461 idea: store full lines in the backlog. No need to change them on resize --- src/bin/miniview.c | 9 +- src/bin/termio.c | 22 +- src/bin/termpty.c | 483 ++++++++++++++++++++++++------------------ src/bin/termpty.h | 12 +- src/bin/termptyops.c | 42 +--- src/bin/termptysave.c | 66 ++++-- src/bin/termptysave.h | 3 +- 7 files changed, 358 insertions(+), 279 deletions(-) diff --git a/src/bin/miniview.c b/src/bin/miniview.c index 06dc2871..90b34779 100644 --- a/src/bin/miniview.c +++ b/src/bin/miniview.c @@ -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; diff --git a/src/bin/termio.c b/src/bin/termio.c index ffdd7e71..c9640793 100644 --- a/src/bin/termio.c +++ b/src/bin/termio.c @@ -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; diff --git a/src/bin/termpty.c b/src/bin/termpty.c index 5e49ba41..9a0a1438 100644 --- a/src/bin/termpty.c +++ b/src/bin/termpty.c @@ -19,6 +19,7 @@ #if defined (__sun) || defined (__sun__) # include #endif +#include /* 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); diff --git a/src/bin/termpty.h b/src/bin/termpty.h index 7aba97aa..26c5de05 100644 --- a/src/bin/termpty.h +++ b/src/bin/termpty.h @@ -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); diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c index f4ef69d8..0df51f89 100644 --- a/src/bin/termptyops.c +++ b/src/bin/termptyops.c @@ -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(); } diff --git a/src/bin/termptysave.c b/src/bin/termptysave.c index 2c222005..3c5f1b75 100644 --- a/src/bin/termptysave.c +++ b/src/bin/termptysave.c @@ -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); } diff --git a/src/bin/termptysave.h b/src/bin/termptysave.h index ce430a5c..4520fccd 100644 --- a/src/bin/termptysave.h +++ b/src/bin/termptysave.h @@ -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