aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2016-12-18 18:48:03 +0100
committerBoris Faure <billiob@gmail.com>2016-12-18 18:48:03 +0100
commitf3dd6f62fb21e777ce640d7d8433f4a7be7c695f (patch)
tree4d8a9382aa644cdcb6f0b6acbf935cab2105f551
parentprivate: add macros ROUND_UP and DIV_ROUND_UP (diff)
downloadterminology-f3dd6f62fb21e777ce640d7d8433f4a7be7c695f.tar.gz
termpty: Tab markers are the same for each line. Ref 4992
-rw-r--r--src/bin/termio.c3
-rw-r--r--src/bin/termpty.c40
-rw-r--r--src/bin/termpty.h8
-rw-r--r--src/bin/termptyesc.c28
-rw-r--r--src/bin/termptyops.c23
-rw-r--r--src/bin/termptyops.h19
6 files changed, 98 insertions, 23 deletions
diff --git a/src/bin/termio.c b/src/bin/termio.c
index 743b9f0..f2dfaa9 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -2181,8 +2181,7 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, int c2x, int c2y,
}
if (((cells[x].codepoint != 0) &&
(cells[x].codepoint != ' ')) ||
- (cells[x].att.newline) ||
- (cells[x].att.tab))
+ (cells[x].att.newline))
{
have_more = EINA_TRUE;
break;
diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index f7449a8..338bf6c 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -347,6 +347,34 @@ _limit_coord(Termpty *ty)
TERMPTY_RESTRICT_FIELD(ty->cursor_save[1].cy, 0, ty->h);
}
+static void
+_termpty_resize_tabs(Termpty *ty, int new_w)
+{
+ unsigned int *new_tabs;
+ int i;
+ size_t nb_elems;
+
+ if (new_w == ty->w && ty->tabs)
+ return;
+
+ nb_elems = DIV_ROUND_UP(new_w, sizeof(unsigned int) * 8);
+ new_tabs = calloc(nb_elems, sizeof(unsigned int));
+ if (!new_tabs)
+ return;
+
+ if (ty->tabs)
+ {
+ memcpy(new_tabs, ty->tabs, nb_elems * sizeof(unsigned int));
+ free(ty->tabs);
+ }
+
+ ty->tabs = new_tabs;
+ for (i = ROUND_UP(ty->w, TAB_WIDTH); i < new_w; i += TAB_WIDTH)
+ {
+ TAB_SET(ty, i);
+ }
+}
+
Termpty *
termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
int w, int h, int backscroll, Eina_Bool xterm_256color,
@@ -367,8 +395,6 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
ty->h = h;
ty->backsize = backscroll;
- termpty_reset_state(ty);
-
ty->screen = calloc(1, sizeof(Termcell) * ty->w * ty->h);
if (!ty->screen)
{
@@ -384,6 +410,11 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
goto err;
}
+ ty->tabs = NULL;
+ _termpty_resize_tabs(ty, w);
+
+ termpty_reset_state(ty);
+
ty->circular_offset = 0;
#ifdef ENABLE_FUZZING
@@ -661,6 +692,7 @@ termpty_free(Termpty *ty)
free(ty->screen);
free(ty->screen2);
free(ty->buf);
+ free(ty->tabs);
free(ty);
}
@@ -1187,6 +1219,8 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
}
}
+ _termpty_resize_tabs(ty, new_w);
+
if (effective_old_h <= ty->cursor_state.cy)
effective_old_h = ty->cursor_state.cy + 1;
@@ -1507,10 +1541,8 @@ termpty_cell_codepoint_att_fill(Termpty *ty, Eina_Unicode codepoint,
for (i = 0; i < n; i++)
{
- int had_tabmarker = dst[i].att.tab;
_handle_block_codepoint_overwrite(ty, dst[i].codepoint, codepoint);
dst[i] = local;
- dst[i].att.tab = had_tabmarker;
}
}
diff --git a/src/bin/termpty.h b/src/bin/termpty.h
index 85413e5..26c55e2 100644
--- a/src/bin/termpty.h
+++ b/src/bin/termpty.h
@@ -63,13 +63,12 @@ struct _Termatt
// below used for working out text from selections
unsigned short autowrapped : 1;
unsigned short newline : 1;
- unsigned short tab : 1;
unsigned short fraktur : 1;
#if defined(SUPPORT_80_132_COLUMNS)
unsigned short is_80_132_mode_allowed : 1;
- unsigned short bit_padding : 13;
-#else
unsigned short bit_padding : 14;
+#else
+ unsigned short bit_padding : 15;
#endif
};
@@ -89,6 +88,7 @@ struct _Termpty
} prop;
const char *cur_cmd;
Termcell *screen, *screen2;
+ unsigned int *tabs;
int circular_offset;
int circular_offset2;
Eina_Unicode *buf;
@@ -264,7 +264,7 @@ extern int _termpty_log_dom;
#define TERMPTY_SCREEN(Tpty, X, Y) \
Tpty->screen[X + (((Y + Tpty->circular_offset) % Tpty->h) * Tpty->w)]
#define TERMPTY_FMTCLR(Tatt) \
- (Tatt).autowrapped = (Tatt).newline = (Tatt).tab = 0
+ (Tatt).autowrapped = (Tatt).newline = 0
#define TERMPTY_RESTRICT_FIELD(Field, Min, Max) \
do { \
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index 0149b0a..a293289 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -133,7 +133,7 @@ _handle_cursor_control(Termpty *ty, const Eina_Unicode *cc)
case 0x09: // HT '\t' (horizontal tab)
DBG("->HT");
ty->termstate.had_cr = 0;
- TERMPTY_SCREEN(ty, ty->cursor_state.cx, ty->cursor_state.cy).att.tab = 1;
+ //TERMPTY_SCREEN(ty, ty->cursor_state.cx, ty->cursor_state.cy).att.tab = 1;
ty->termstate.wrapnext = 0;
ty->cursor_state.cx += 8;
ty->cursor_state.cx = (ty->cursor_state.cx / 8) * 8;
@@ -1077,13 +1077,25 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
break;
*/
case 'g': // clear tabulation
- /* TODO: handle correctly */
arg = _csi_arg_get(&b);
- DBG("Tabulation Clear (TBC): %d", arg);
+ if (arg < 0) arg = 0;
+ if (arg == 0)
+ {
+ int cx = ty->cursor_state.cx;
+ TAB_UNSET(ty, cx);
+ }
+ else if (arg == 3)
+ {
+ termpty_clear_tabs_on_screen(ty);
+ }
+ else
+ {
+ ERR("Tabulation Clear (TBC) with invalid argument: %d", arg);
+ }
break;
case 'Z':
{
- int cx = ty->cursor_state.cx, cy = ty->cursor_state.cy;
+ int cx = ty->cursor_state.cx;
arg = _csi_arg_get(&b);
DBG("Cursor Backward Tabulation (CBT): %d", arg);
@@ -1095,8 +1107,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
{
cx--;
}
- while ((cx >= 0) &&
- ((!TERMPTY_SCREEN(ty, cx, cy).att.tab) && (cx % 8 != 0)));
+ while ((cx >= 0) && (!TAB_TEST(ty, cx)));
}
ty->cursor_state.cx = cx;
@@ -1747,9 +1758,8 @@ _handle_esc(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
termpty_cursor_copy(ty, EINA_FALSE);
return 1;
case 'H': // set tab at current column
- DBG("Character Tabulation Set (HTS) at x:%d y:%d",
- ty->cursor_state.cx, ty->cursor_state.cy);
- TERMPTY_SCREEN(ty, ty->cursor_state.cx, ty->cursor_state.cy).att.tab = 1;
+ DBG("Character Tabulation Set (HTS) at x:%d", ty->cursor_state.cx);
+ TAB_SET(ty, ty->cursor_state.cx);
return 1;
/*
case 'G': // query gfx mode
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c
index c7a1662..ff668cc 100644
--- a/src/bin/termptyops.c
+++ b/src/bin/termptyops.c
@@ -265,6 +265,15 @@ termpty_clear_line(Termpty *ty, Termpty_Clear mode, int limit)
}
void
+termpty_clear_tabs_on_screen(Termpty *ty)
+{
+ memset(ty->tabs, 0,
+ DIV_ROUND_UP(ty->w, sizeof(unsigned int) * 8u)
+ * sizeof(unsigned int));
+}
+
+
+void
termpty_clear_screen(Termpty *ty, Termpty_Clear mode)
{
Termcell *cells;
@@ -352,7 +361,6 @@ termpty_reset_att(Termatt *att)
att->bgintense = 0;
att->autowrapped = 0;
att->newline = 0;
- att->tab = 0;
att->fraktur = 0;
}
@@ -360,6 +368,7 @@ void
termpty_reset_state(Termpty *ty)
{
int backsize;
+ int i;
ty->cursor_state.cx = 0;
ty->cursor_state.cy = 0;
@@ -397,9 +406,9 @@ termpty_reset_state(Termpty *ty)
termpty_backlog_lock();
if (ty->back)
{
- size_t i;
- for (i = 0; i < ty->backsize; i++)
- termpty_save_free(&ty->back[i]);
+ size_t j;
+ for (j = 0; j < ty->backsize; j++)
+ termpty_save_free(&ty->back[j]);
free(ty->back);
ty->back = NULL;
}
@@ -408,6 +417,12 @@ termpty_reset_state(Termpty *ty)
ty->backsize = 0;
termpty_backlog_size_set(ty, backsize);
termpty_backlog_unlock();
+
+ termpty_clear_tabs_on_screen(ty);
+ for (i = 0; i < ty->w; i += TAB_WIDTH)
+ {
+ TAB_SET(ty, i);
+ }
}
void
diff --git a/src/bin/termptyops.h b/src/bin/termptyops.h
index 08de5ab..deaf204 100644
--- a/src/bin/termptyops.h
+++ b/src/bin/termptyops.h
@@ -22,7 +22,26 @@ void termpty_clear_all(Termpty *ty);
void termpty_reset_att(Termatt *att);
void termpty_reset_state(Termpty *ty);
void termpty_cursor_copy(Termpty *ty, Eina_Bool save);
+void termpty_clear_tabs_on_screen(Termpty *ty);
#define _term_txt_write(ty, txt) termpty_write(ty, txt, sizeof(txt) - 1)
+#define TAB_WIDTH 8u
+
+#define TAB_SET(ty, col) \
+ do { \
+ ty->tabs[col / sizeof(unsigned int) / 8] |= \
+ 1u << (col % (sizeof(unsigned int) * 8)); \
+ } while (0)
+
+#define TAB_UNSET(ty, col) \
+ do { \
+ ty->tabs[col / sizeof(unsigned int) / 8] &= \
+ ~(1u << (col % (sizeof(unsigned int) * 8))); \
+ } while (0)
+
+#define TAB_TEST(ty, col) \
+ (ty->tabs[col / sizeof(unsigned int) / 8] & \
+ (1u << (col % (sizeof(unsigned int) * 8))))
+
#endif