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