raster pushed a commit to branch master.

commit 3fc3ce4c79d555b4f4dca57861a13dcab1bb16ad
Author: Carsten Haitzler (Rasterman) <[email protected]>
Date:   Sat May 4 11:44:20 2013 +0900

    add whitepsace debug mode and termsave abstraction infra.
---
 src/bin/Makefile.am   |   1 +
 src/bin/termio.c      |  70 +++++++++++++++--
 src/bin/termio.h      |   1 +
 src/bin/termpty.c     | 204 +++++++++++++++++++++++++-------------------------
 src/bin/termpty.h     |   8 +-
 src/bin/termptyesc.c  |  24 +++---
 src/bin/termptyops.c  |   8 +-
 src/bin/termptysave.c |  82 ++++++++++++++++++++
 src/bin/termptysave.h |   8 ++
 9 files changed, 283 insertions(+), 123 deletions(-)

diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index ea63e6c..9763b74 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -36,6 +36,7 @@ termptyesc.c termptyesc.h \
 termptyops.c termptyops.h \
 termptygfx.c termptygfx.h \
 termptyext.c termptyext.h \
+termptysave.c termptysave.h \
 utf8.c utf8.h \
 win.c win.h \
 utils.c utils.h \
diff --git a/src/bin/termio.c b/src/bin/termio.c
index 9a7d7fc..4daf630 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -90,6 +90,7 @@ struct _Termio
    Eina_Bool top_left : 1;
    Eina_Bool boxsel : 1;
    Eina_Bool reset_sel : 1;
+   Eina_Bool debugwhite : 1;
 };
 
 static Evas_Smart *_smart = NULL;
@@ -1158,6 +1159,7 @@ _smart_apply(Evas_Object *obj)
         blk->active = EINA_FALSE;
      }
    inv = sd->pty->state.reverse;
+   termpty_cellcomp_freeze(sd->pty);
    for (y = 0; y < sd->grid.h; y++)
      {
         Termcell *cells;
@@ -1301,15 +1303,41 @@ _smart_apply(Evas_Object *obj)
                            (tc[x].fg_extended != fgext) ||
                            (tc[x].bg_extended != bgext) ||
                            (tc[x].underline != cells[j].att.underline) ||
-                           (tc[x].strikethrough != cells[j].att.strike))
+                           (tc[x].strikethrough != cells[j].att.strike) ||
+                           (sd->debugwhite))
                          {
                             if (ch1 < 0) ch1 = x;
                             ch2 = x;
                          }
                        tc[x].fg_extended = fgext;
                        tc[x].bg_extended = bgext;
-                       tc[x].underline = cells[j].att.underline;
-                       tc[x].strikethrough = cells[j].att.strike;
+                       if (sd->debugwhite)
+                         {
+                            if (cells[j].att.newline)
+                              tc[x].strikethrough = 1;
+                            else
+                              tc[x].strikethrough = 0;
+                            if (cells[j].att.autowrapped)
+                              tc[x].underline = 1;
+                            else
+                              tc[x].underline = 0;
+//                            if (cells[j].att.tab)
+//                              tc[x].underline = 1;
+//                            else
+//                              tc[x].underline = 0;
+                            if ((cells[j].att.newline) ||
+                                (cells[j].att.autowrapped))
+                              {
+                                 fg = 8;
+                                 bg = 4;
+                                 codepoint = '!';
+                              }
+                         }
+                       else
+                         {
+                            tc[x].underline = cells[j].att.underline;
+                            tc[x].strikethrough = cells[j].att.strike;
+                         }
                        tc[x].fg = fg;
                        tc[x].bg = bg;
                        tc[x].codepoint = codepoint;
@@ -1333,6 +1361,7 @@ _smart_apply(Evas_Object *obj)
           evas_object_textgrid_update_add(sd->grid.obj, ch1, y,
                                           ch2 - ch1 + 1, 1);
      }
+   termpty_cellcomp_thaw(sd->pty);
    
    EINA_LIST_FOREACH_SAFE(sd->pty->block.active, l, ln, blk)
      {
@@ -2210,8 +2239,13 @@ _sel_word(Evas_Object *obj, int cx, int cy)
    int x, w = 0;
    if (!sd) return;
 
+   termpty_cellcomp_freeze(sd->pty);
    cells = termpty_cellrow_get(sd->pty, cy, &w);
-   if (!cells) return;
+   if (!cells)
+     {
+        termpty_cellcomp_thaw(sd->pty);
+        return;
+     }
    sd->cur.sel = 1;
    sd->cur.makesel = 0;
    sd->cur.sel1.x = cx;
@@ -2243,6 +2277,7 @@ _sel_word(Evas_Object *obj, int cx, int cy)
         if (_codepoint_is_wordsep(sd->config, cells[x].codepoint)) break;
         sd->cur.sel2.x = x;
      }
+   termpty_cellcomp_thaw(sd->pty);
 }
 
 static void
@@ -2253,8 +2288,13 @@ _sel_word_to(Evas_Object *obj, int cx, int cy)
    int x, w = 0;
    if (!sd) return;
 
+   termpty_cellcomp_freeze(sd->pty);
    cells = termpty_cellrow_get(sd->pty, cy, &w);
-   if (!cells) return;
+   if (!cells)
+     {
+        termpty_cellcomp_thaw(sd->pty);
+        return;
+     }
    if (sd->cur.sel1.x > cx || sd->cur.sel1.y > cy)
      {
         sd->cur.sel1.x = cx;
@@ -2290,6 +2330,7 @@ _sel_word_to(Evas_Object *obj, int cx, int cy)
              sd->cur.sel2.x = x;
           }
      }
+   termpty_cellcomp_thaw(sd->pty);
 }
 
 static Eina_Bool
@@ -2596,6 +2637,7 @@ _selection_dbl_fix(Evas_Object *obj)
    
    sd = evas_object_smart_data_get(obj);
    if (!sd) return;
+   termpty_cellcomp_freeze(sd->pty);
    cells = termpty_cellrow_get(sd->pty, sd->cur.sel2.y - sd->scroll, &w);
    if (cells)
      {
@@ -2648,6 +2690,7 @@ _selection_dbl_fix(Evas_Object *obj)
                }
           }
      }
+   termpty_cellcomp_thaw(sd->pty);
 }
 #endif
 
@@ -2752,6 +2795,12 @@ _smart_cb_mouse_down(void *data, Evas *e __UNUSED__, 
Evas_Object *obj __UNUSED__
         evas_object_smart_callback_call(data, "options", NULL);
         return;
      }
+   if ((ev->button == 3) && evas_key_modifier_is_set(ev->modifiers, "Shift"))
+     {
+        termio_debugwhite_set(data, !sd->debugwhite);
+        printf("debugwhite %i\n",  sd->debugwhite);
+        return;
+     }
    if (_rep_mouse_down(sd, ev, cx, cy)) return;
    if (ev->button == 1)
      {
@@ -4009,6 +4058,7 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, 
int c2x, int c2y)
 
    if (!sd) return NULL;
    sb = eina_strbuf_new();
+   termpty_cellcomp_freeze(sd->pty);
    for (y = c1y; y <= c2y; y++)
      {
         Termcell *cells;
@@ -4130,6 +4180,7 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, 
int c2x, int c2y)
              else eina_strbuf_append_char(sb, '\n');
           }
      }
+   termpty_cellcomp_thaw(sd->pty);
 
    s = eina_strbuf_string_steal(sb);
    eina_strbuf_free(sb);
@@ -4325,3 +4376,12 @@ termio_icon_name_get(Evas_Object *obj)
    if (!sd) return NULL;
    return sd->pty->prop.icon;
 }
+
+void
+termio_debugwhite_set(Evas_Object *obj, Eina_Bool dbg)
+{
+   Termio *sd = evas_object_smart_data_get(obj);
+   if (!sd) return;
+   sd->debugwhite = dbg;
+   _smart_apply(obj);
+}
diff --git a/src/bin/termio.h b/src/bin/termio.h
index 1dc07d3..946dc6d 100644
--- a/src/bin/termio.h
+++ b/src/bin/termio.h
@@ -25,5 +25,6 @@ Evas_Object *termio_textgrid_get(Evas_Object *obj);
 Evas_Object *termio_mirror_add(Evas_Object *obj);
 const char  *termio_title_get(Evas_Object *obj);
 const char  *termio_icon_name_get(Evas_Object *obj);
+void         termio_debugwhite_set(Evas_Object *obj, Eina_Bool dbg);
 
 #endif
diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index e03bae0..f3b3d50 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -3,6 +3,7 @@
 #include "termpty.h"
 #include "termptyesc.h"
 #include "termptyops.h"
+#include "termptysave.h"
 #include <sys/types.h>
 #include <signal.h>
 #include <sys/wait.h>
@@ -395,6 +396,7 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const 
char *cd, int w, int h
    close(ty->slavefd);
    ty->slavefd = -1;
    _pty_size(ty);
+   termpty_save_register(ty);
    return ty;
 err:
    if (ty->screen) free(ty->screen);
@@ -409,7 +411,8 @@ void
 termpty_free(Termpty *ty)
 {
    Termexp *ex;
-   
+
+   termpty_save_unregister(ty);
    EINA_LIST_FREE(ty->block.expecting, ex) free(ex);
    if (ty->block.blocks) eina_hash_free(ty->block.blocks);
    if (ty->block.chid_map) eina_hash_free(ty->block.chid_map);
@@ -461,7 +464,7 @@ termpty_free(Termpty *ty)
 
         for (i = 0; i < ty->backmax; i++)
           {
-             if (ty->back[i]) free(ty->back[i]);
+             if (ty->back[i]) termpty_save_free(ty->back[i]);
           }
         free(ty->back);
      }
@@ -472,10 +475,22 @@ termpty_free(Termpty *ty)
    free(ty);
 }
 
+void
+termpty_cellcomp_freeze(Termpty *ty __UNUSED__)
+{
+   termpty_save_freeze();
+}
+
+void
+termpty_cellcomp_thaw(Termpty *ty __UNUSED__)
+{
+   termpty_save_thaw();
+}
+
 Termcell *
 termpty_cellrow_get(Termpty *ty, int y, int *wret)
 {
-   Termsave *ts;
+   Termsave *ts, **tssrc;
 
    if (y >= 0)
      {
@@ -485,8 +500,10 @@ termpty_cellrow_get(Termpty *ty, int y, int *wret)
         return &(TERMPTY_SCREEN(ty, 0, y));
      }
    if (y < -ty->backmax) return NULL;
-   ts = ty->back[(ty->backmax + ty->backpos + y) % ty->backmax];
+   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;
 }
@@ -529,26 +546,24 @@ _termpty_horizontally_expand(Termpty *ty, int old_w, int 
old_h,
        old_circular_offset = ty->circular_offset,
        x = 0,
        y = 0;
-
-   Termsave **new_back,
-            *new_ts = NULL;
+   Termsave **new_back, *new_ts = NULL;
    Eina_Bool rewrapping = EINA_FALSE;
 
-   if (!ty->backmax || !ty->back)
-     goto expand_screen;
-
-   new_back = calloc(sizeof(Termsave*), ty->backmax);
+   if ((!ty->backmax) || (!ty->back)) goto expand_screen;
 
+   new_back = calloc(sizeof(Termsave *), ty->backmax);
+   if (!new_back) return;
+   
+   termpty_save_freeze();
    for (i = 0; i < ty->backmax; i++)
      {
         Termsave *ts;
 
         if (ty->backscroll_num == ty->backmax - 1)
-          ts = ty->back[(ty->backpos + i) % ty->backmax];
+          ts = termpty_save_extract(ty->back[(ty->backpos + i) % ty->backmax]);
         else
-          ts = ty->back[i];
-        if (!ts)
-          break;
+          ts = termpty_save_extract(ty->back[i]);
+        if (!ts) break;
 
         if (!ts->w)
           {
@@ -581,8 +596,7 @@ _termpty_horizontally_expand(Termpty *ty, int old_w, int 
old_h,
                   len -= remaining_width;
                   cells += remaining_width;
 
-                  new_ts = calloc(1, sizeof(Termsave) +
-                                  (ty->w - 1) * sizeof(Termcell));
+                  new_ts = termpty_save_new(ty->w);
                   new_ts->w = 0;
                   new_back[new_back_pos++] = new_ts;
                }
@@ -593,31 +607,22 @@ _termpty_horizontally_expand(Termpty *ty, int old_w, int 
old_h,
                }
 
              rewrapping = ts->cell[ts->w - 1].att.autowrapped;
-             if (!rewrapping)
-               {
-                  new_ts = NULL;
-               }
-
-             free(ts);
+             if (!rewrapping) new_ts = NULL;
+             termpty_save_free(ts);
           }
         else
           {
              if (ts->cell[ts->w - 1].att.autowrapped)
                {
                   rewrapping = EINA_TRUE;
-                  new_ts = calloc(1, sizeof(Termsave) +
-                                  (ty->w - 1) * sizeof(Termcell));
-                  new_ts->w = ts->w;
+                  new_ts = termpty_save_new(ty->w);
                   termpty_cell_copy(ty, ts->cell, new_ts->cell, ts->w);
                   new_ts->cell[ts->w - 1].att.autowrapped = 0;
-
                   new_back[new_back_pos++] = new_ts;
-                  free(ts);
+                  termpty_save_free(ts);
                }
              else
-               {
-                  new_back[new_back_pos++] = ts;
-               }
+               new_back[new_back_pos++] = ts;
           }
      }
 
@@ -638,12 +643,13 @@ _termpty_horizontally_expand(Termpty *ty, int old_w, int 
old_h,
 expand_screen:
 
    if (ty->altbuf)
-     return;
+     {
+        termpty_save_thaw();
+        return;
+     }
 
    ty->circular_offset = 0;
-
    /* TODO double-width :) */
-
    for (old_y = 0; old_y < old_h; old_y++)
      {
         ssize_t cur_line_length;
@@ -666,7 +672,7 @@ expand_screen:
                        new_ts = NULL;
                        len = cur_line_length - remaining_width;
                        termpty_cell_copy(ty, cells, ty->screen + (y * ty->w),
-                              len);
+                                         len);
                        x += len;
                     }
 
@@ -683,7 +689,6 @@ expand_screen:
                       len = cur_line_length;
 
                   old_x = 0;
-
                   if (cur_line_length >= remaining_width)
                     {
                        termpty_cell_copy(ty,
@@ -706,8 +711,7 @@ expand_screen:
                        TERMPTY_SCREEN(ty, x - 1, y).att.autowrapped = 0;
                     }
                   rewrapping = OLD_SCREEN(old_w - 1, old_y).att.autowrapped;
-                  if (!rewrapping)
-                    y++;
+                  if (!rewrapping) y++;
                }
           }
         else
@@ -722,10 +726,7 @@ expand_screen:
                   TERMPTY_SCREEN(ty, old_w - 1, old_y).att.autowrapped = 0;
                   x = cur_line_length;
                }
-             else
-               {
-                  y++;
-               }
+             else y++;
           }
      }
    if (y < old_h)
@@ -733,19 +734,19 @@ expand_screen:
         ty->state.cy -= old_h - y;
         if (ty->state.cy < 0) ty->state.cy = 0;
      }
-   ty->circular_offset = 0;
+   termpty_save_thaw();
 }
 
 static void
 _termpty_vertically_expand(Termpty *ty, int old_w, int old_h,
                            Termcell *old_screen)
 {
-   int from_history = 0,
-       y;
-
+   int from_history = 0, y;
+   
+   termpty_save_freeze();
+   
    if (ty->backmax > 0)
      from_history = MIN(ty->h - old_h, ty->backscroll_num);
-
    if (old_screen)
      {
         int old_circular_offset = ty->circular_offset;
@@ -762,8 +763,11 @@ _termpty_vertically_expand(Termpty *ty, int old_w, int 
old_h,
           }
      }
 
-   if (from_history <= 0 || !ty->back)
-     return;
+   if ((from_history <= 0) || (!ty->back))
+     {
+        termpty_save_thaw();
+        return;
+     }
 
    /* display content from backlog */
    for (y = from_history - 1; y >= 0; y--)
@@ -774,13 +778,13 @@ _termpty_vertically_expand(Termpty *ty, int old_w, int 
old_h,
         ty->backpos--;
         if (ty->backpos < 0)
           ty->backpos = ty->backscroll_num - 1;
-        ts = ty->back[ty->backpos];
+        ts = termpty_save_extract(ty->back[ty->backpos]);
 
         src = ts->cell;
         dst = &(TERMPTY_SCREEN(ty, 0, ty->h - from_history + y));
         termpty_cell_copy(ty, src, dst, ts->w);
 
-        free(ts);
+        termpty_save_free(ts);
         ty->back[ty->backpos] = NULL;
         ty->backscroll_num--;
      }
@@ -788,6 +792,7 @@ _termpty_vertically_expand(Termpty *ty, int old_w, int 
old_h,
    ty->circular_offset = (ty->circular_offset + ty->h - from_history) % ty->h;
 
    ty->state.cy += from_history;
+   termpty_save_thaw();
 }
 
 
@@ -801,17 +806,15 @@ _termpty_vertically_shrink(Termpty *ty, int old_w, int 
old_h,
        y;
    Termcell *src, *dst;
 
+   termpty_save_freeze();
+   
    old_circular_offset = ty->circular_offset;
-
-
    for (y = old_h - 1; y >= 0; y--)
      {
         ssize_t screen_length = termpty_line_length(&OLD_SCREEN(0, y), old_w);
 
-        if (screen_length)
-          break;
-        else
-          real_h--;
+        if (screen_length) break;
+        else real_h--;
      }
 
    to_history = real_h - ty->h;
@@ -842,11 +845,11 @@ _termpty_vertically_shrink(Termpty *ty, int old_w, int 
old_h,
         /* in place */
         int len, pos, offset;
 
-        if (to_history <= 0)
-          return;
-
-        if (ty->circular_offset == 0)
-          return;
+        if ((to_history <= 0) || (ty->circular_offset == 0))
+          {
+             termpty_save_thaw();
+             return;
+          }
 
         ty->circular_offset = (ty->circular_offset + to_history) % old_h;
         len = real_h - to_history;
@@ -876,12 +879,11 @@ _termpty_vertically_shrink(Termpty *ty, int old_w, int 
old_h,
 
         len = ty->h - len;
         if (len)
-          {
-             termpty_cell_fill(ty, NULL,
-                               &old_screen[(old_h - len) * old_w],
-                               len * old_w);
-          }
+          termpty_cell_fill(ty, NULL,
+                            &old_screen[(old_h - len) * old_w],
+                            len * old_w);
      }
+   termpty_save_thaw();
 }
 
 
@@ -907,6 +909,8 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, int 
old_h,
              done = EINA_FALSE,
              cy_pushed_back = EINA_FALSE;
 
+   termpty_save_freeze();
+   
    if (!ty->backmax || !ty->back)
      goto shrink_screen;
 
@@ -919,15 +923,15 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, int 
old_h,
         int remaining_width;
 
         if (ty->backscroll_num == ty->backmax - 1)
-          ts = ty->back[(ty->backpos + i) % ty->backmax];
+          ts = termpty_save_extract(ty->back[(ty->backpos + i) % ty->backmax]);
         else
-          ts = ty->back[i];
+          ts = termpty_save_extract(ty->back[i]);
         if (!ts)
           break;
 
 #define PUSH_BACK_TS(_ts) do {           \
         if (new_back[new_back_pos])      \
-          free(new_back[new_back_pos]);  \
+          termpty_save_free(new_back[new_back_pos]); \
         new_back[new_back_pos++] = _ts;  \
         new_back_scroll_num++;           \
         if (new_back_pos >= ty->backmax) \
@@ -939,16 +943,12 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, int 
old_h,
              if (rewrapping)
                {
                   rewrapping = EINA_FALSE;
-                  new_ts = calloc(1, sizeof(Termsave) +
-                                  (old_ts->w - 1) * sizeof(Termcell));
-                  new_ts->w = old_ts->w;
+                  new_ts = termpty_save_new(old_ts->w);
                   termpty_cell_copy(ty, old_cells, new_ts->cell, old_ts->w);
-
                   PUSH_BACK_TS(new_ts);
-
-                  free(old_ts);
+                  termpty_save_free(old_ts);
                   old_ts = NULL;
-                  free(ts);
+                  termpty_save_free(ts);
                }
              else
                PUSH_BACK_TS(ts);
@@ -967,9 +967,7 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, int 
old_h,
           {
              int len = MIN(old_ts->w + ts->w, ty->w);
 
-             new_ts = calloc(1, sizeof(Termsave) +
-                             (len - 1) * sizeof(Termcell));
-             new_ts->w = len;
+             new_ts = termpty_save_new(len);
              termpty_cell_copy(ty, old_cells, new_ts->cell, old_ts->w);
 
              remaining_width = len - old_ts->w;
@@ -983,8 +981,8 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, int 
old_h,
 
              new_ts->cell[new_ts->w - 1].att.autowrapped =
                 rewrapping || ts->w > 0;
-
-             free(old_ts);
+             
+             termpty_save_free(old_ts);
              old_ts = NULL;
 
              PUSH_BACK_TS(new_ts);
@@ -992,9 +990,7 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, int 
old_h,
 
         while (ts->w >= ty->w)
           {
-             new_ts = calloc(1, sizeof(Termsave) +
-                             (ty->w - 1) * sizeof(Termcell));
-             new_ts->w = ty->w;
+             new_ts = termpty_save_new(ty->w);
              termpty_cell_copy(ty, cells, new_ts->cell, ty->w);
              rewrapping = ts->cell[ts->w - 1].att.autowrapped;
 
@@ -1011,7 +1007,7 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, int 
old_h,
         if (!ts->w)
           {
              old_cells = 0;
-             free(old_ts);
+             termpty_save_free(old_ts);
              old_ts = NULL;
              rewrapping = EINA_FALSE;
              continue;
@@ -1024,13 +1020,10 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, 
int old_h,
           }
         else
           {
-             new_ts = calloc(1, sizeof(Termsave) +
-                             (ts->w - 1) * sizeof(Termcell));
-             new_ts->w = ts->w;
+             new_ts = termpty_save_new(ts->w);
              termpty_cell_copy(ty, cells, new_ts->cell, ts->w);
-
              PUSH_BACK_TS(new_ts);
-             free(ts);
+             termpty_save_free(ts);
           }
      }
 #undef PUSH_BACK_TS
@@ -1039,14 +1032,16 @@ _termpty_horizontally_shrink(Termpty *ty, int old_w, 
int old_h,
    ty->backscroll_num = new_back_scroll_num;
    if (ty->backscroll_num >= ty->backmax)
      ty->backscroll_num = ty->backmax - 1;
-
    free(ty->back);
    ty->back = new_back;
 
 shrink_screen:
 
    if (ty->altbuf)
-     return;
+     {
+        termpty_save_thaw();
+        return;
+     }
 
    ty->circular_offset = 0;
 
@@ -1058,9 +1053,8 @@ shrink_screen:
      {
         termpty_cell_copy(ty, old_cells, ty->screen, old_ts->w);
         x = old_ts->w;
-        if (!rewrapping)
-          y++;
-        free(old_ts);
+        if (!rewrapping) y++;
+        termpty_save_free(old_ts);
         old_ts = NULL;
         old_cells = NULL;
      }
@@ -1079,8 +1073,7 @@ shrink_screen:
    for (old_y = 0; old_y < screen_height_used; old_y++)
      {
         ssize_t cur_line_length;
-        int remaining_width,
-            len;
+        int remaining_width, len;
 
         cur_line_length = screen_lengths[old_y];
 
@@ -1151,12 +1144,14 @@ shrink_screen:
           }
         while (cur_line_length > 0);
      }
-   if (ty->state.cy >= ty->h)
-     ty->state.cy = ty->h - 1;
-   else if (ty->state.cy < 0)
-     ty->state.cy = 0;
+   if (ty->state.cy >= ty->h) ty->state.cy = ty->h - 1;
+   else if (ty->state.cy < 0) ty->state.cy = 0;
+   
+   termpty_save_thaw();
 
    free(screen_lengths);
+
+   termpty_save_thaw();
 }
 #undef OLD_SCREEN
 
@@ -1230,12 +1225,14 @@ termpty_backscroll_set(Termpty *ty, int size)
    int i;
 
    if (ty->backmax == size) return;
+   
+   termpty_save_freeze();
 
    if (ty->back)
      {
         for (i = 0; i < ty->backmax; i++)
           {
-             if (ty->back[i]) free(ty->back[i]);
+             if (ty->back[i]) termpty_save_free(ty->back[i]);
           }
         free(ty->back);
      }
@@ -1246,6 +1243,7 @@ termpty_backscroll_set(Termpty *ty, int size)
    ty->backscroll_num = 0;
    ty->backpos = 0;
    ty->backmax = size;
+   termpty_save_thaw();
 }
 
 pid_t
diff --git a/src/bin/termpty.h b/src/bin/termpty.h
index 47d74dd..7d8eb62 100644
--- a/src/bin/termpty.h
+++ b/src/bin/termpty.h
@@ -123,9 +123,9 @@ struct _Termpty
    Termstate state, save, swap;
    int exit_code;
    pid_t pid;
-   unsigned int altbuf : 1;
+   unsigned int altbuf     : 1;
    unsigned int mouse_mode : 3;
-   unsigned int mouse_ext : 2;
+   unsigned int mouse_ext  : 2;
 };
 
 struct _Termcell
@@ -136,7 +136,7 @@ struct _Termcell
 
 struct _Termsave
 {
-   int w;
+   int      w;
    Termcell cell[1];
 };
 
@@ -173,6 +173,8 @@ void       termpty_shutdown(void);
 
 Termpty   *termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd, 
int w, int h, int backscroll);
 void       termpty_free(Termpty *ty);
+void       termpty_cellcomp_freeze(Termpty *ty);
+void       termpty_cellcomp_thaw(Termpty *ty);
 Termcell  *termpty_cellrow_get(Termpty *ty, int y, int *wret);
 void       termpty_write(Termpty *ty, const char *input, int len);
 void       termpty_resize(Termpty *ty, int w, int h);
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index 5528351..590a5fa 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -1230,25 +1230,25 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, 
Eina_Unicode *ce)
              return 1;
  */
            case 0x07: // BEL '\a' (bell)
-             if (ty->cb.bell.func) ty->cb.bell.func(ty->cb.bell.data);
              ty->state.had_cr = 0;
+             if (ty->cb.bell.func) ty->cb.bell.func(ty->cb.bell.data);
              return 1;
            case 0x08: // BS  '\b' (backspace)
              DBG("->BS");
+             ty->state.had_cr = 0;
              ty->state.wrapnext = 0;
              ty->state.cx--;
              if (ty->state.cx < 0) ty->state.cx = 0;
-             ty->state.had_cr = 0;
              return 1;
            case 0x09: // HT  '\t' (horizontal tab)
              DBG("->HT");
+             ty->state.had_cr = 0;
             TERMPTY_SCREEN(ty, ty->state.cx, ty->state.cy).att.tab = 1;
              ty->state.wrapnext = 0;
              ty->state.cx += 8;
              ty->state.cx = (ty->state.cx / 8) * 8;
              if (ty->state.cx >= ty->w)
                ty->state.cx = ty->w - 1;
-             ty->state.had_cr = 0;
              return 1;
            case 0x0a: // LF  '\n' (new line)
            case 0x0b: // VT  '\v' (vertical tab)
@@ -1256,11 +1256,11 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, 
Eina_Unicode *ce)
              DBG("->LF");
              if (ty->state.had_cr)
                TERMPTY_SCREEN(ty, ty->state.had_cr_x, 
ty->state.had_cr_y).att.newline = 1;
+             ty->state.had_cr = 0;
              ty->state.wrapnext = 0;
              if (ty->state.crlf) ty->state.cx = 0;
              ty->state.cy++;
              _termpty_text_scroll_test(ty);
-             ty->state.had_cr = 0;
              return 1;
            case 0x0d: // CR  '\r' (carriage ret)
              DBG("->CR");
@@ -1271,15 +1271,17 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, 
Eina_Unicode *ce)
                }
              ty->state.wrapnext = 0;
              ty->state.cx = 0;
-             ty->state.had_cr = 1;
+//             ty->state.had_cr = 1;
              return 1;
 
            case 0x0e: // SO  (shift out) // Maps G1 character set into GL.
+             ty->state.had_cr = 0;
              ty->state.charset = 1;
              ty->state.charsetch = ty->state.chset[1];
              return 1;
            case 0x0f: // SI  (shift in) // Maps G0 character set into GL.
              ty->state.charset = 0;
+             ty->state.had_cr = 0;
              ty->state.charsetch = ty->state.chset[0];
              return 1;
 /*
@@ -1322,21 +1324,21 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, 
Eina_Unicode *ce)
              return 1;
  */
            default:
-             //ERR("unhandled char 0x%02x", c[0]);
              ty->state.had_cr = 0;
+             //ERR("unhandled char 0x%02x", c[0]);
              return 1;
           }
      }
    else if (c[0] == 0x7f) // DEL
      {
-        ERR("unhandled char 0x%02x [DEL]", c[0]);
         ty->state.had_cr = 0;
+        ERR("unhandled char 0x%02x [DEL]", c[0]);
         return 1;
      }
    else if (c[0] == 0x9b) // ANSI ESC!!!
      {
-        DBG("ANSI CSI!!!!!");
         ty->state.had_cr = 0;
+        DBG("ANSI CSI!!!!!");
         len = _handle_esc_csi(ty, c + 1, ce);
         if (len == 0) return 0;
         return 1 + len;
@@ -1346,6 +1348,7 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, 
Eina_Unicode *ce)
         Termexp *ex;
         Eina_List *l;
         
+        ty->state.had_cr = 0;
         EINA_LIST_FOREACH(ty->block.expecting, l, ex)
           {
              if (c[0] == ex->ch)
@@ -1375,9 +1378,12 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, 
Eina_Unicode *ce)
                }
           }
         _termpty_text_append(ty, c, 1);
-        ty->state.had_cr = 0;
         return 1;
      }
+   else
+     {
+        ty->state.had_cr = 0;
+     }
    cc = (int *)c;
    DBG("txt: [");
    while ((cc < ce) && (*cc >= 0x20) && (*cc != 0x7f))
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c
index 8c3f2b7..22abb9a 100644
--- a/src/bin/termptyops.c
+++ b/src/bin/termptyops.c
@@ -4,6 +4,7 @@
 #include "termptydbl.h"
 #include "termptyops.h"
 #include "termptygfx.h"
+#include "termptysave.h"
 
 #undef CRITICAL
 #undef ERR
@@ -36,22 +37,23 @@ termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t 
w_max)
 
    if (ty->backmax <= 0) return;
 
+   termpty_save_freeze();
    w = termpty_line_length(cells, w_max);
-   ts = calloc(1, sizeof(Termsave) + ((w - 1) * sizeof(Termcell)));
-   ts->w = w;
+   ts = termpty_save_new(w);
    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_cell_fill(ty, NULL, ty->back[ty->backpos]->cell,
                           ty->back[ty->backpos]->w);
-        free(ty->back[ty->backpos]);
+        termpty_save_free(ty->back[ty->backpos]);
      }
    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 - 1;
+   termpty_save_thaw();
 }
 
 void
diff --git a/src/bin/termptysave.c b/src/bin/termptysave.c
new file mode 100644
index 0000000..be1462c
--- /dev/null
+++ b/src/bin/termptysave.c
@@ -0,0 +1,82 @@
+#include "private.h"
+#include <Elementary.h>
+#include "termpty.h"
+#include "termptysave.h"
+
+static int ts_comp = 0;
+static int ts_uncomp = 0;
+static int freeze = 0;
+static Eina_List *ptys = NULL;
+
+static void
+_check_compressor(void)
+{
+   if (ts_uncomp > 1024)
+     {
+        // XXX: if no compressor start one if not frozen
+     }
+}
+
+void
+termpty_save_freeze(void)
+{
+   // XXX: suspend compressor
+   freeze++;
+}
+
+void
+termpty_save_thaw(void)
+{
+   // XXX: resume compressor
+   freeze--;
+   if (freeze <= 0) _check_compressor();
+}
+
+void
+termpty_save_register(Termpty *ty)
+{
+   termpty_save_freeze();
+   ptys = eina_list_append(ptys, ty);
+   termpty_save_thaw();
+}
+
+void
+termpty_save_unregister(Termpty *ty)
+{
+   termpty_save_freeze();
+   ptys = eina_list_remove(ptys, ty);
+   termpty_save_thaw();
+}
+
+Termsave *
+termpty_save_extract(Termsave *ts)
+{
+   // XXX: decompress a Termsave struct from our save store using input ptr as
+   // handle to find it
+   if (!ts) return NULL;
+   // XXX: if was compressed ts_comp--; ts_uncomp++;
+   _check_compressor();
+   return ts;
+}
+
+Termsave *
+termpty_save_new(int w)
+{
+   Termsave *ts = calloc(1, sizeof(Termsave) + (w - 1) * sizeof(Termcell));
+   if (!ts) return NULL;
+   ts->w = w;
+   ts_uncomp++;
+   _check_compressor();
+   return ts;
+}
+
+void
+termpty_save_free(Termsave *ts)
+{
+   if (!ts) return;
+   // XXX: if compressed mark region as free, if not then free ts
+   // XXX: if compresses ts_comp--; else ts_uncomp--;
+   ts_uncomp--;
+   _check_compressor();
+   free(ts);
+}
diff --git a/src/bin/termptysave.h b/src/bin/termptysave.h
new file mode 100644
index 0000000..108185d
--- /dev/null
+++ b/src/bin/termptysave.h
@@ -0,0 +1,8 @@
+void termpty_save_freeze(void);
+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);
+void termpty_save_free(Termsave *ts);
+    

-- 

------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2

Reply via email to