termpty: Tab markers are the same for each line. Ref 4992

This commit is contained in:
Boris Faure 2016-12-18 18:48:03 +01:00
parent 836baf5d63
commit f3dd6f62fb
6 changed files with 98 additions and 23 deletions

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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 { \

View File

@ -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

View File

@ -264,6 +264,15 @@ termpty_clear_line(Termpty *ty, Termpty_Clear mode, int limit)
termpty_cells_clear(ty, cells, n);
}
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)
{
@ -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

View File

@ -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