JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Add TBC sequence
[st.git] / st.c
diff --git a/st.c b/st.c
index 0e82eaf..b7dfd55 100644 (file)
--- a/st.c
+++ b/st.c
@@ -164,7 +164,7 @@ typedef struct {
        int col;        /* nb col */
        Line* line;     /* screen */
        Line* alt;      /* alternate screen */
-       bool* dirty; /* dirtyness of lines */
+       bool* dirty;    /* dirtyness of lines */
        TCursor c;      /* cursor */
        int top;        /* top    scroll limit */
        int bot;        /* bottom scroll limit */
@@ -172,6 +172,7 @@ typedef struct {
        int esc;        /* escape state flags */
        char title[ESC_TITLE_SIZ];
        int titlelen;
+       bool *tabs;
 } Term;
 
 /* Purely graphic info */
@@ -186,8 +187,6 @@ typedef struct {
        int scr;
        int w;  /* window width */
        int h;  /* window height */
-       int bufw; /* pixmap width  */
-       int bufh; /* pixmap height */
        int ch; /* char height */
        int cw; /* char width  */
        char state; /* focus, redraw, visible */
@@ -849,12 +848,16 @@ tcursor(int mode) {
 
 void
 treset(void) {
+       unsigned i;
        term.c = (TCursor){{
                .mode = ATTR_NULL,
                .fg = DefaultFG,
                .bg = DefaultBG
        }, .x = 0, .y = 0, .state = CURSOR_DEFAULT};
-       
+
+       memset(term.tabs, 0, term.col * sizeof(*term.tabs));
+       for (i = TAB; i < term.col; i += TAB)
+               term.tabs[i] = 1;
        term.top = 0, term.bot = term.row - 1;
        term.mode = MODE_WRAP;
        tclearregion(0, 0, term.col-1, term.row-1);
@@ -867,12 +870,14 @@ tnew(int col, int row) {
        term.line = malloc(term.row * sizeof(Line));
        term.alt  = malloc(term.row * sizeof(Line));
        term.dirty = malloc(term.row * sizeof(*term.dirty));
+       term.tabs = malloc(term.col * sizeof(*term.tabs));
 
        for(row = 0; row < term.row; row++) {
                term.line[row] = malloc(term.col * sizeof(Glyph));
                term.alt [row] = malloc(term.col * sizeof(Glyph));
                term.dirty[row] = 0;
        }
+       memset(term.tabs, 0, term.col * sizeof(*term.tabs));
        /* setup screen */
        treset();
 }
@@ -1198,6 +1203,18 @@ csihandle(void) {
                DEFAULT(escseq.arg[0], 1);
                tmoveto(0, term.c.y-escseq.arg[0]);
                break;
+       case 'g': /* TBC -- Tabulation clear */
+               switch (escseq.arg[0]) {
+               case 0: /* clear current tab stop */
+                       term.tabs[term.c.x] = 0;
+                       break;
+               case 3: /* clear all the tabs */
+                       memset(term.tabs, 0, term.col * sizeof(*term.tabs));
+                       break;
+               default:
+                       goto unknown;
+               }
+               break;
        case 'G': /* CHA -- Move to <col> */
        case '`': /* XXX: HPA -- same? */
                DEFAULT(escseq.arg[0], 1);
@@ -1209,7 +1226,6 @@ csihandle(void) {
                DEFAULT(escseq.arg[1], 1);
                tmoveto(escseq.arg[1]-1, escseq.arg[0]-1);
                break;
-       /* XXX: (CSI n I) CHT -- Cursor Forward Tabulation <n> tab stops */
        case 'J': /* ED -- Clear screen */
                sel.bx = -1;
                switch(escseq.arg[0]) {
@@ -1424,8 +1440,11 @@ csireset(void) {
 
 void
 tputtab(void) {
-       int space = TAB - term.c.x % TAB;
-       tmoveto(term.c.x + space, term.c.y);
+       unsigned x;
+
+       for (x = term.c.x + 1; x < term.col && !term.tabs[x]; ++x)
+               /* nothing */ ;
+       tmoveto(x, term.c.y);
 }
 
 void
@@ -1486,6 +1505,10 @@ tputc(char *c) {
                                tnewline(1); /* always go to first col */
                                term.esc = 0;
                                break;
+                       case 'H': /* HTS -- Horizontal tab stop */
+                               term.tabs[term.c.x] = 1;
+                               term.esc = 0;
+                               break;
                        case 'M': /* RI -- Reverse index */
                                if(term.c.y == term.top)
                                        tscrolldown(term.top, 1);
@@ -1590,6 +1613,7 @@ tresize(int col, int row) {
        term.line = realloc(term.line, row * sizeof(Line));
        term.alt  = realloc(term.alt,  row * sizeof(Line));
        term.dirty = realloc(term.dirty, row * sizeof(*term.dirty));
+       term.tabs = realloc(term.tabs, col * sizeof(*term.tabs));
 
        /* resize each row to new width, zero-pad if needed */
        for(i = 0; i < minrow; i++) {
@@ -1608,7 +1632,15 @@ tresize(int col, int row) {
                term.line[i] = calloc(col, sizeof(Glyph));
                term.alt [i] = calloc(col, sizeof(Glyph));
        }
-       
+       if (col > term.col) {
+               bool *bp = term.tabs + term.col;
+
+               memset(bp, 0, sizeof(*term.tabs) * (col - term.col));
+               while (--bp > term.tabs && !*bp)
+                       /* nothing */ ;
+               for (bp += TAB; bp < term.tabs + col; bp += TAB)
+                       *bp = 1;
+       }
        /* update terminal size */
        term.col = col, term.row = row;
        /* make use of the LIMIT in tmoveto */
@@ -1621,8 +1653,8 @@ tresize(int col, int row) {
 
 void
 xresize(int col, int row) {
-       xw.bufw = MAX(1, col * xw.cw);
-       xw.bufh = MAX(1, row * xw.ch);
+       xw.w = MAX(1, 2*BORDER + col * xw.cw);
+       xw.h = MAX(1, 2*BORDER + row * xw.ch);
 }
 
 void
@@ -1671,7 +1703,7 @@ void
 xclear(int x1, int y1, int x2, int y2) {
        XSetForeground(xw.dpy, dc.gc, dc.col[IS_SET(MODE_REVERSE) ? DefaultFG : DefaultBG]);
        XFillRectangle(xw.dpy, xw.buf, dc.gc,
-                      x1 * xw.cw, y1 * xw.ch,
+                      BORDER + x1 * xw.cw, BORDER + y1 * xw.ch,
                       (x2-x1+1) * xw.cw, (y2-y1+1) * xw.ch);
 }
 
@@ -1757,10 +1789,8 @@ xinit(void) {
        xloadcols();
 
        /* window - default size */
-       xw.bufh = term.row * xw.ch;
-       xw.bufw = term.col * xw.cw;
-       xw.h = xw.bufh + 2*BORDER;
-       xw.w = xw.bufw + 2*BORDER;
+       xw.h = 2*BORDER + term.row * xw.ch;
+       xw.w = 2*BORDER + term.col * xw.cw;
 
        attrs.background_pixel = dc.col[DefaultBG];
        attrs.border_pixel = dc.col[DefaultBG];
@@ -1807,7 +1837,7 @@ xinit(void) {
 void
 xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
        int fg = base.fg, bg = base.bg, temp;
-       int winx = x*xw.cw, winy = y*xw.ch + dc.font.ascent, width = charlen*xw.cw;
+       int winx = BORDER+x*xw.cw, winy = BORDER+y*xw.ch + dc.font.ascent, width = charlen*xw.cw;
        XFontSet fontset = dc.font.set;
        int i;