billiob pushed a commit to branch master.

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

commit f3dd6f62fb21e777ce640d7d8433f4a7be7c695f
Author: Boris Faure <bill...@gmail.com>
Date:   Sun Dec 18 18:48:03 2016 +0100

    termpty: Tab markers are the same for each line. Ref 4992
---
 src/bin/termio.c     |  3 +--
 src/bin/termpty.c    | 40 ++++++++++++++++++++++++++++++++++++----
 src/bin/termpty.h    |  8 ++++----
 src/bin/termptyesc.c | 28 +++++++++++++++++++---------
 src/bin/termptyops.c | 23 +++++++++++++++++++----
 src/bin/termptyops.h | 19 +++++++++++++++++++
 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

-- 


Reply via email to