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 */
int esc; /* escape state flags */
char title[ESC_TITLE_SIZ];
int titlelen;
+ bool *tabs;
} Term;
/* Purely graphic info */
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 */
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);
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();
}
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);
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]) {
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
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);
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++) {
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 */
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
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);
}
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];
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;