billiob pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=34592ab5b3e01e473355c9cc0f370cee0731c40c

commit 34592ab5b3e01e473355c9cc0f370cee0731c40c
Author: Boris Faure <bill...@gmail.com>
Date:   Mon Apr 6 18:08:23 2015 +0200

    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     | 487 +++++++++++++++++++++++++++++---------------------
 src/bin/termpty.h     |  12 +-
 src/bin/termptyops.c  |  42 +----
 src/bin/termptysave.c |  66 +++++--
 src/bin/termptysave.h |   3 +-
 7 files changed, 360 insertions(+), 281 deletions(-)

diff --git a/src/bin/miniview.c b/src/bin/miniview.c
index 06dc287..90b3477 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 ffdd7e7..c964079 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 5e49ba4..9a0a143 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -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;
+};
+
+#define SCREEN_INFO_GET_CELLS(Tsi, X, Y) \
+  Tsi->screen[X + (((Y + Tsi->circular_offset) % Tsi->h) * Tsi->w)]
 
-   while (y_start > 0)
-     {
-        if (TERMPTY_SCREEN(ty, ty->w - 1, y_start - 1).att.autowrapped)
-          y_start--;
-        else
-          {
-             *top = y_start;
-             return 0;
-          }
-     }
-   while (-y_start < ty->backscroll_num)
+static void
+_check_screen_info(Termpty *ty, struct screen_info *si)
+{
+   if (si->y >= si->h)
      {
-        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;
-          }
+        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--;
      }
-   *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);
-     }
-   else
-     {
-        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;
-
-   while (y <= y_end)
-     {
-        if (y >= 0)
+        if (set_cursor)
           {
-             line = &TERMPTY_SCREEN(ty, 0, y);
+             si->cy = si->y;
+             si->cx = 0;
           }
-        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)
+        si->y++;
+        si->x = 0;
+        _check_screen_info(ty, si);
+        return;
+     }
+   while (len > 0)
+     {
+        int copy_width = MIN(len, si->w - si->x);
+
+        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)
           {
-             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;
-                    }
-               }
-             if (y == ty->cursor_state.cy)
-               {
-                  *new_cyp = new_y_start;
+                  si->cx = ty->cursor_state.cx;
+                  si->cy = si->y;
                }
-             if (new_line)
+             else
                {
-                  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;
-
-        y_end = y_start - 1;
-        new_y_end = new_y_start - 1;
+        Termcell *cells = &TERMPTY_SCREEN(ty, 0, old_y);
+        if (!termpty_line_is_empty(cells, old_w))
+          {
+             effective_old_h = old_y + 1;
+             break;
+          }
+     }
+
+   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 7aba97a..26c5de0 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 f4ef69d..0df51f8 100644
--- a/src/bin/termptyops.c
+++ b/src/bin/termptyops.c
@@ -33,34 +33,6 @@ termpty_cells_clear(Termpty *ty, Termcell *cells, int 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)
 {
    Termcell *cells = NULL, *cells2;
@@ -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 2c22200..3c5f1b7 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 ce430a5..4520fcc 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

-- 


Reply via email to