From 7f9ec9c8d747eeebb233e37584962ab36e172080 Mon Sep 17 00:00:00 2001
From: Mark Edgar <medgar123@gmail.com>
Date: Thu, 19 Sep 2013 23:07:37 +0200
Subject: [PATCH 2/2] Support multiple set/reset mode params, e.g.
 \E[?1;3;4;5;6l. Fix bug where CSI ? is ignored. Remove unsupported
 capabilities from dvtm.info (flash, smkx/rmkx). Fix typo in rs1 terminfo
 capability.

---
 dvtm.info |  5 +---
 vt.c      | 99 +++++++++++++++++++++++++++++++--------------------------------
 2 files changed, 49 insertions(+), 55 deletions(-)

diff --git a/dvtm.info b/dvtm.info
index 869d7e1..7d73476 100644
--- a/dvtm.info
+++ b/dvtm.info
@@ -34,7 +34,6 @@ dvtm|dynamic virtual terminal manager,
 	el=\E[K,
 	el1=\E[1K,
 	enacs=\E(B\E)0,
-	flash=\E[?5h\E[?5l,
 	home=\E[H,
 	hpa=\E[%i%p1%dG,
 	ht=^I,
@@ -108,10 +107,9 @@ dvtm|dynamic virtual terminal manager,
 	rmacs=^O,
 	rmcup=\E[2J\E[?47l\E8,
 	rmir=\E[4l,
-	rmkx=\E>,
 	rmso=\E[27m,
 	rmul=\E[24m,
-	rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H,
+	rs1=\E>\E[?1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H,
 	rs2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E>\E[?1000l\E[?25h,
 	s0ds=\E(B,
 	s1ds=\E(0,
@@ -123,7 +121,6 @@ dvtm|dynamic virtual terminal manager,
 	smacs=^N,
 	smcup=\E7\E[?47h,
 	smir=\E[4h,
-	smkx=\E=,
 	smso=\E[7m,
 	smul=\E[4m,
 	tbc=\E[3g,
diff --git a/vt.c b/vt.c
index da00d2c..15a9280 100644
--- a/vt.c
+++ b/vt.c
@@ -711,6 +711,42 @@ static void interpret_csi_decstbm(Vt *t, int param[], int pcount)
 	b->curs_col = 0;
 }
 
+static void interpret_csi_mode(Vt *t, int param[], int pcount, bool set)
+{
+	for (int i = 0; i < pcount; i++) {
+		switch (param[i]) {
+		case 4: /* insert/replace mode */
+			t->insert = set;
+			break;
+		}
+	}
+}
+
+static void interpret_csi_priv_mode(Vt *t, int param[], int pcount, bool set)
+{
+	for (int i = 0; i < pcount; i++) {
+		switch (param[i]) {
+		case 1: /* set application/normal cursor key mode (DECCKM) */
+			t->curskeymode = set;
+			break;
+		case 6: /* set origin to relative/absolute (DECOM) */
+			t->relposmode = set;
+			break;
+		case 25: /* make cursor visible/invisible (DECCM) */
+			t->curshid = !set;
+			break;
+		case 47: /* use alternate/normal screen buffer */
+			vt_copymode_leave(t);
+			t->buffer = set ? &t->buffer_alternate : &t->buffer_normal;
+			vt_dirty(t);
+			break;
+		case 1000: /* enable/disable normal mouse tracking */
+			t->mousetrack = set;
+			break;
+		}
+	}
+}
+
 static void interpret_csi(Vt *t)
 {
 	static int csiparam[BUFSIZ];
@@ -736,67 +772,29 @@ static void interpret_csi(Vt *t)
 	}
 
 	if (t->ebuf[1] == '?') {
-		if (verb == 'h') { /* DEC Private Mode Set (DECSET) */
-			switch (csiparam[0]) {
-			case 1: /* set ANSI cursor (application) key mode (DECCKM) */
-				t->curskeymode = true;
-				break;
-			case 6: /* set origin to relative (DECOM) */
-				t->relposmode = true;
-				break;
-			case 25: /* make cursor visible (DECCM) */
-				t->curshid = false;
-				break;
-			case 47: /* use alternate screen buffer */
-				vt_copymode_leave(t);
-				t->buffer = &t->buffer_alternate;
-				vt_dirty(t);
-				break;
-			case 1000: /* enable normal mouse tracking */
-				t->mousetrack = true;
-				break;
-			}
-		} else if (verb == 'l') { /* DEC Private Mode Reset (DECRST) */
-			switch (csiparam[0]) {
-			case 1: /* reset ANSI cursor (normal) key mode (DECCKM) */
-				t->curskeymode = false;
-				break;
-			case 6: /* set origin to absolute (DECOM) */
-				t->relposmode = false;
-				break;
-			case 25: /* make cursor visible (DECCM) */
-				t->curshid = true;
-				break;
-			case 47: /* use normal screen buffer */
-				vt_copymode_leave(t);
-				t->buffer = &t->buffer_normal;
-				vt_dirty(t);
-				break;
-			case 1000: /* disable normal mouse tracking */
-				t->mousetrack = false;
-				break;
-			}
+		switch (verb) {
+		case 'h':
+		case 'l': /* private set/reset mode */
+			interpret_csi_priv_mode(t, csiparam, param_count, verb == 'h');
+			break;
 		}
+		return;
 	}
 
 	/* delegate handling depending on command character (verb) */
 	switch (verb) {
 	case 'h':
-		if (param_count == 1 && csiparam[0] == 4) /* insert mode */
-			t->insert = true;
+	case 'l': /* set/reset mode */
+		interpret_csi_mode(t, csiparam, param_count, verb == 'h');
 		break;
-	case 'l':
-		if (param_count == 1 && csiparam[0] == 4) /* replace mode */
-			t->insert = false;
-		break;
-	case 'm': /* it's a 'set attribute' sequence */
+	case 'm': /* set attribute */
 		interpret_csi_sgr(t, csiparam, param_count);
 		break;
-	case 'J': /* it's an 'erase display' sequence */
+	case 'J': /* erase display */
 		interpret_csi_ed(t, csiparam, param_count);
 		break;
 	case 'H':
-	case 'f': /* it's a 'move cursor' sequence */
+	case 'f': /* move cursor */
 		interpret_csi_cup(t, csiparam, param_count);
 		break;
 	case 'A':
@@ -809,8 +807,7 @@ static void interpret_csi(Vt *t)
 	case 'e':
 	case 'a':
 	case 'd':
-	case '`':
-		/* it is a 'relative move' */
+	case '`': /* relative move */
 		interpret_csi_c(t, verb, csiparam, param_count);
 		break;
 	case 'K': /* erase line */
-- 
1.8.4

