JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Add DEC alignment test
[st.git] / st.c
diff --git a/st.c b/st.c
index 23ed213..693739e 100644 (file)
--- a/st.c
+++ b/st.c
@@ -72,6 +72,8 @@
 #define X2COL(x) (((x) - BORDER)/xw.cw)
 #define Y2ROW(y) (((y) - BORDER)/xw.ch)
 
+#define VT102ID "\033[?6c"
+
 enum glyph_attribute {
        ATTR_NULL      = 0,
        ATTR_REVERSE   = 1,
@@ -121,6 +123,7 @@ enum escape_state {
        ESC_STR = 4, /* DSC, OSC, PM, APC */
        ESC_ALTCHARSET = 8,
        ESC_STR_END    = 16, /* a final string was encountered */
+       ESC_TEST       = 32, /* Enter in test mode */
 };
 
 enum window_state {
@@ -287,7 +290,7 @@ static int tresize(int, int);
 static void tscrollup(int, int);
 static void tscrolldown(int, int);
 static void tsetattr(int*, int);
-static void tsetchar(char*);
+static void tsetchar(char *, Glyph *, int, int);
 static void tsetscroll(int, int);
 static void tswapscreen(void);
 static void tsetdirt(int, int);
@@ -1180,8 +1183,8 @@ tmoveto(int x, int y) {
 }
 
 void
-tsetchar(char *c) {
-       char *vt100_0[62] = { /* 0x41 - 0x7e */
+tsetchar(char *c, Glyph *attr, int x, int y) {
+       static char *vt100_0[62] = { /* 0x41 - 0x7e */
                "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
                0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
                0, 0, 0, 0, 0, 0, 0, 0, /* P - W */
@@ -1195,17 +1198,17 @@ tsetchar(char *c) {
        /*
         * The table is proudly stolen from rxvt.
         */
-       if(term.c.attr.mode & ATTR_GFX) {
+       if(attr->mode & ATTR_GFX) {
                if(c[0] >= 0x41 && c[0] <= 0x7e
                                && vt100_0[c[0] - 0x41]) {
                        c = vt100_0[c[0] - 0x41];
                }
        }
 
-       term.dirty[term.c.y] = 1;
-       term.line[term.c.y][term.c.x] = term.c.attr;
-       memcpy(term.line[term.c.y][term.c.x].c, c, UTF_SIZ);
-       term.line[term.c.y][term.c.x].state |= GLYPH_SET;
+       term.dirty[y] = 1;
+       term.line[y][x] = *attr;
+       memcpy(term.line[y][x].c, c, UTF_SIZ);
+       term.line[y][x].state |= GLYPH_SET;
 }
 
 void
@@ -1510,6 +1513,10 @@ csihandle(void) {
                DEFAULT(csiescseq.arg[0], 1);
                tmoveto(term.c.x, term.c.y+csiescseq.arg[0]);
                break;
+       case 'c': /* DA -- Device Attributes */
+               if(csiescseq.arg[0] == 0)
+                       ttywrite(VT102ID, sizeof(VT102ID) - 1);
+               break;
        case 'C': /* CUF -- Cursor <n> Forward */
        case 'a':
                DEFAULT(csiescseq.arg[0], 1);
@@ -1887,11 +1894,25 @@ tputc(char *c, int len) {
                                fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii);
                        }
                        term.esc = 0;
+               } else if(term.esc & ESC_TEST) {
+                       if(ascii == '8') { /* DEC screen alignment test. */
+                               char E[UTF_SIZ] = "E";
+                               int x, y;
+
+                               for(x = 0; x < term.col; ++x) {
+                                       for(y = 0; y < term.row; ++y)
+                                               tsetchar(E, &term.c.attr, x, y);
+                               }
+                       }
+                       term.esc = 0;
                } else {
                        switch(ascii) {
                        case '[':
                                term.esc |= ESC_CSI;
                                break;
+                       case '#':
+                               term.esc |= ESC_TEST;
+                               break;
                        case 'P': /* DCS -- Device Control String */
                        case '_': /* APC -- Application Program Command */
                        case '^': /* PM -- Privacy Message */
@@ -1933,6 +1954,10 @@ tputc(char *c, int len) {
                                }
                                term.esc = 0;
                                break;
+                       case 'Z': /* DECID -- Identify Terminal */
+                               ttywrite(VT102ID, sizeof(VT102ID) - 1);
+                               term.esc = 0;
+                               break;
                        case 'c': /* RIS -- Reset to inital state */
                                treset();
                                term.esc = 0;
@@ -1978,7 +2003,7 @@ tputc(char *c, int len) {
                sel.bx = -1;
        if(IS_SET(MODE_WRAP) && term.c.state & CURSOR_WRAPNEXT)
                tnewline(1); /* always go to first col */
-       tsetchar(c);
+       tsetchar(c, &term.c.attr, term.c.x, term.c.y);
        if(term.c.x+1 < term.col)
                tmoveto(term.c.x+1, term.c.y);
        else
@@ -2310,7 +2335,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
                 * Those ranges will not be brightened:
                 *      8 - 15 – bright system colors
                 *      196 - 231 – highest 256 color cube
-                *      252 - 255 – brightest colors in grescale
+                *      252 - 255 – brightest colors in greyscale
                 */
                font = &dc.bfont;
        }
@@ -2355,7 +2380,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
        }
        if(x + charlen >= term.col-1) {
                xclear(winx + width, (y == 0)? 0 : winy, xw.w,
-                       winy + xw.ch + (y == term.row-1)? xw.h : 0);
+                       (y == term.row-1)? xw.h : (winy + xw.ch));
        }
        if(y == 0)
                xclear(winx, 0, winx + width, BORDER);