summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-08-05 19:29:35 -0400
committerJune McEnroe <june@causal.agency>2019-08-05 19:29:35 -0400
commit6e9c4b5212f2bfc92051969711e74713604bee12 (patch)
tree95ca2194dcc291de4434bd29b27d7779c1d3665c
parentFix CUP coords in termSnapshot (diff)
downloadstream-6e9c4b5212f2bfc92051969711e74713604bee12.tar.gz
stream-6e9c4b5212f2bfc92051969711e74713604bee12.zip
Handle DECSET/DECRST for cursor
-rw-r--r--stream.h1
-rw-r--r--term.c66
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,