diff options
-rw-r--r-- | stream.h | 1 | ||||
-rw-r--r-- | term.c | 66 |
2 files changed, 48 insertions, 19 deletions
diff --git a/stream.h b/stream.h index 8726381..4610647 100644 --- a/stream.h +++ b/stream.h @@ -41,6 +41,7 @@ struct Cell { }; struct Display { + bool cursor; uint rows, cols; uint y, x; const struct Cell *cells; diff --git a/term.c b/term.c index df3c87f..22eb621 100644 --- a/term.c +++ b/term.c @@ -26,7 +26,7 @@ #include "stream.h" -enum { +enum C0 { NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, HT, NL, VT, NP, CR, SO, SI, DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, @@ -50,6 +50,7 @@ static const struct Style Default = { .bg = -1, .fg = -1 }; static uint rows, cols; static uint y, x; +static bool cursor = true; static bool insert; static struct { uint top, bot; @@ -114,7 +115,7 @@ static char updateNUL(wchar_t ch) { return NUL; } -enum { +enum C1 { CSI = '[', OSC = ']', ST = '\\', @@ -136,7 +137,7 @@ static char updateESC(wchar_t ch) { } } -enum { +enum SGR { Reset, SetBold, SetDim, @@ -212,9 +213,9 @@ static void updateSGR(uint ps[], uint n) { } // SGR toggling all attributes and setting both colors in 256 palette. -enum { PSCap = 5 + 2 * 3 }; +enum { CSIMax = 5 + 2 * 3 }; -enum { +enum CSI { DEC = '?', CUU = 'A', CUD, @@ -234,24 +235,29 @@ enum { RM = 'l', SGR, DECSTBM = 'r', + DECSET = DEC + SM, + DECRST = DEC + RM, }; -enum { - Insert = 4, +enum Mode { + IRM = 4, + DECCKM = 1, + DECAWM = 7, + DECTCEM = 25, }; static char updateCSI(wchar_t ch) { - static bool dec; + static char dec; if (ch == DEC) { - dec = true; + dec = DEC; return CSI; } - static uint n, p, ps[PSCap]; + static uint n, p, ps[CSIMax]; if (ch == ';') { n++; p++; - ps[p %= PSCap] = 0; + ps[p %= CSIMax] = 0; return CSI; } if (ch >= '0' && ch <= '9') { @@ -261,7 +267,7 @@ static char updateCSI(wchar_t ch) { return CSI; } - switch (ch) { + switch (dec + ch) { break; case CUU: y -= MIN((n ? ps[0] : 1), y); break; case CUD: y = MIN(y + (n ? ps[0] : 1), rows - 1); break; case CUF: x = MIN(x + (n ? ps[0] : 1), cols - 1); @@ -308,14 +314,14 @@ static char updateCSI(wchar_t ch) { break; case SM: { switch (ps[0]) { - break; case Insert: insert = true; - break; default: unhandled("SM %s%u", (dec ? "? " : ""), ps[0]); + break; case IRM: insert = true; + break; default: unhandled("SM %u", ps[0]); } } break; case RM: { switch (ps[0]) { - break; case Insert: insert = false; - break; default: unhandled("RM %s%u", (dec ? "? " : ""), ps[0]); + break; case IRM: insert = false; + break; default: unhandled("RM %u", ps[0]); } } @@ -326,11 +332,30 @@ static char updateCSI(wchar_t ch) { scroll.bot = (n > 1 ? ps[1] - 1 : rows - 1); } + break; case DECSET: { + switch (ps[0]) { + break; case DECCKM: // ignore + break; case DECAWM: // TODO + break; case 12: // ignore + break; case DECTCEM: cursor = true; + break; default: if (ps[0] < 1000) unhandled("DECSET %u", ps[0]); + } + } + break; case DECRST: { + switch (ps[0]) { + break; case DECCKM: // ignore + break; case DECAWM: // TODO + break; case 12: // ignore + break; case DECTCEM: cursor = false; + break; default: if (ps[0] < 1000) unhandled("DECRST %u", ps[0]); + } + } + break; case 't': // ignore break; default: unhandled("CSI %s%lc", (dec ? "? " : ""), ch); } - dec = false; + dec = 0; ps[n = p = 0] = 0; return NUL; } @@ -377,7 +402,7 @@ styleDiff(FILE *file, const struct Style *prev, const struct Style *next) { return fprintf(file, "%c%c%c", ESC, CSI, SGR); } - uint ps[PSCap]; + uint ps[CSIMax]; uint n = 0; enum Attr diff = prev->attr ^ next->attr; @@ -457,9 +482,11 @@ int termSnapshot(int _fd) { int n = fprintf( file, "%c%c%d%c" + "%c%c%c%d%c" "%c%c%u;%u%c" "%c%c%u;%u%c", - ESC, CSI, Insert, (insert ? SM : RM), + ESC, CSI, IRM, (insert ? SM : RM), + ESC, CSI, DEC, DECTCEM, (cursor ? DECSET : DECRST) - DEC, ESC, CSI, scroll.top, scroll.bot, DECSTBM, ESC, CSI, 1 + y, 1 + x, CUP ); @@ -474,6 +501,7 @@ fail: struct Display termDisplay(void) { return (struct Display) { + .cursor = cursor, .rows = rows, .cols = cols, .y = y, |