Handle DECRQM (Request Mode) escape sequences
The DECRQM [1] escape sequence is a request to the terminal to query the state
of a mode. The terminal replies to this request with a DECRPM [2] escape
sequence, containing the status of the mode flag.
[1]
https://vt100.net/docs/vt510-rm/DECRQM.html
[2]
https://vt100.net/docs/vt510-rm/DECRPM.html
diff -rup st-0.8.4.orig/st.c st-0.8.4/st.c
--- st-0.8.4.orig/st.c 2020-06-19 11:29:45.000000000 +0200
+++ st-0.8.4/st.c 2020-11-27 01:33:28.572861355 +0100
_AT_@ -1476,17 +1476,17 @@ tsetmode(int priv, int set, int *args, i
if (priv) {
switch (*args) {
case 1: /* DECCKM -- Cursor key */
- xsetmode(set, MODE_APPCURSOR);
+ xdomode(priv, *args, set, MODE_APPCURSOR);
break;
case 5: /* DECSCNM -- Reverse video */
- xsetmode(set, MODE_REVERSE);
+ xdomode(priv, *args, set, MODE_REVERSE);
break;
case 6: /* DECOM -- Origin */
- MODBIT(term.c.state, set, CURSOR_ORIGIN);
+ DOBIT(priv, *args, term.c.state, set, CURSOR_ORIGIN);
tmoveato(0, 0);
break;
case 7: /* DECAWM -- Auto wrap */
- MODBIT(term.mode, set, MODE_WRAP);
+ DOBIT(priv, *args, term.mode, set, MODE_WRAP);
break;
case 0: /* Error (IGNORED) */
case 2: /* DECANM -- ANSI/VT52 (IGNORED) */
_AT_@ -1497,46 +1497,71 @@ tsetmode(int priv, int set, int *args, i
case 19: /* DECPEX -- Printer extent (IGNORED) */
case 42: /* DECNRCM -- National characters (IGNORED) */
case 12: /* att610 -- Start blinking cursor (IGNORED) */
+ if (set & 2) decrpm(priv, *args, 0);
break;
case 25: /* DECTCEM -- Text Cursor Enable Mode */
- xsetmode(!set, MODE_HIDE);
+ xdomode(priv, *args, set ^ 1, MODE_HIDE);
break;
case 9: /* X10 mouse compatibility mode */
+ if (set & 2) {
+ decrpm(priv, *args, 0);
+ break;
+ }
xsetpointermotion(0);
xsetmode(0, MODE_MOUSE);
xsetmode(set, MODE_MOUSEX10);
break;
case 1000: /* 1000: report button press */
+ if (set & 2) {
+ decrpm(priv, *args, 0);
+ break;
+ }
xsetpointermotion(0);
xsetmode(0, MODE_MOUSE);
xsetmode(set, MODE_MOUSEBTN);
break;
case 1002: /* 1002: report motion on button press */
+ if (set & 2) {
+ decrpm(priv, *args, 0);
+ break;
+ }
xsetpointermotion(0);
xsetmode(0, MODE_MOUSE);
xsetmode(set, MODE_MOUSEMOTION);
break;
case 1003: /* 1003: enable all mouse motions */
+ if (set & 2) {
+ decrpm(priv, *args, 0);
+ break;
+ }
xsetpointermotion(set);
xsetmode(0, MODE_MOUSE);
xsetmode(set, MODE_MOUSEMANY);
break;
case 1004: /* 1004: send focus events to tty */
- xsetmode(set, MODE_FOCUS);
+ xdomode(priv, *args, set, MODE_FOCUS);
break;
case 1006: /* 1006: extended reporting mode */
- xsetmode(set, MODE_MOUSESGR);
+ xdomode(priv, *args, set, MODE_MOUSESGR);
break;
case 1034:
- xsetmode(set, MODE_8BIT);
+ xdomode(priv, *args, set, MODE_8BIT);
break;
case 1049: /* swap screen & set/restore cursor as xterm */
+ if (set & 2) {
+ decrpm(priv, *args, !IS_SET(MODE_ALTSCREEN) + 1);
+ break;
+ }
if (!allowaltscreen)
break;
tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
/* FALLTHROUGH */
case 47: /* swap screen */
case 1047:
+ if (set & 2) {
+ decrpm(priv, *args, !IS_SET(MODE_ALTSCREEN) + 1);
+ break;
+ }
if (!allowaltscreen)
break;
alt = IS_SET(MODE_ALTSCREEN);
_AT_@ -1550,10 +1575,14 @@ tsetmode(int priv, int set, int *args, i
break;
/* FALLTHROUGH */
case 1048:
+ if (set & 2) {
+ decrpm(priv, *args, 0);
+ break;
+ }
tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
break;
case 2004: /* 2004: bracketed paste mode */
- xsetmode(set, MODE_BRCKTPASTE);
+ xdomode(priv, *args, set, MODE_BRCKTPASTE);
break;
/* Not implemented mouse modes. See comments there. */
case 1001: /* mouse highlight mode; can hang the
_AT_@ -1564,33 +1593,37 @@ tsetmode(int priv, int set, int *args, i
case 1015: /* urxvt mangled mouse mode; incompatible
and can be mistaken for other control
codes. */
+ if (set & 2) decrpm(priv, *args, 0);
break;
default:
fprintf(stderr,
"erresc: unknown private set/reset mode %d\n",
*args);
+ if (set & 2) decrpm(priv, *args, 0);
break;
}
} else {
switch (*args) {
case 0: /* Error (IGNORED) */
+ if (set & 2) decrpm(priv, *args, 0);
break;
case 2:
- xsetmode(set, MODE_KBDLOCK);
+ xdomode(priv, *args, set, MODE_KBDLOCK);
break;
case 4: /* IRM -- Insertion-replacement */
- MODBIT(term.mode, set, MODE_INSERT);
+ DOBIT(priv, *args, term.mode, set, MODE_INSERT);
break;
case 12: /* SRM -- Send/Receive */
- MODBIT(term.mode, !set, MODE_ECHO);
+ DOBIT(priv, *args, term.mode, set ^ 1, MODE_ECHO);
break;
case 20: /* LNM -- Linefeed/new line */
- MODBIT(term.mode, set, MODE_CRLF);
+ DOBIT(priv, *args, term.mode, set, MODE_CRLF);
break;
default:
fprintf(stderr,
"erresc: unknown set/reset mode %d\n",
*args);
+ if (set & 2) decrpm(priv, *args, 0);
break;
}
}
_AT_@ -1806,6 +1839,15 @@ csihandle(void)
goto unknown;
}
break;
+ case '$':
+ switch (csiescseq.mode[1]) {
+ case 'p': /* DECRQM -- Request Mode - Host To Terminal */
+ tsetmode(csiescseq.priv, 2, csiescseq.arg, csiescseq.narg);
+ break;
+ default:
+ goto unknown;
+ }
+ break;
}
}
_AT_@ -2595,3 +2637,17 @@ redraw(void)
tfulldirt();
draw();
}
+
+void
+decrpm(int priv, int mode, unsigned value)
+{
+ char buf[40], *ptr = buf;
+ int len;
+
+ *ptr++ = 033;
+ *ptr++ = '[';
+ if (priv) *ptr++ = '?';
+ len = snprintf(ptr, sizeof(buf) - (ptr - buf), "%d;%u$y", mode, value);
+ if (len < 0) return;
+ ttywrite(buf, len + 2 + (priv != 0), 0);
+}
diff -rup st-0.8.4.orig/st.h st-0.8.4/st.h
--- st-0.8.4.orig/st.h 2020-06-19 11:29:45.000000000 +0200
+++ st-0.8.4/st.h 2020-11-27 00:58:15.278976407 +0100
_AT_@ -16,6 +16,10 @@
#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \
(t1.tv_nsec-t2.tv_nsec)/1E6)
#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit)))
+#define DOBIT(priv, mode, x, set, bit) (((set) & 2) ? \
+ decrpm((priv), (mode), ((!((x) & (bit))) ^ ((set) & 1)) + 1) : \
+ ((void)MODBIT((x), (set), (bit))) \
+ )
#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b))
#define IS_TRUECOL(x) (1 << 24 & (x))
_AT_@ -111,6 +115,8 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(char *);
+void decrpm(int, int, unsigned int);
+
/* config.h globals */
extern char *utmp;
extern char *scroll;
diff -rup st-0.8.4.orig/win.h st-0.8.4/win.h
--- st-0.8.4.orig/win.h 2020-06-19 11:29:45.000000000 +0200
+++ st-0.8.4/win.h 2020-11-27 00:02:20.482159051 +0100
_AT_@ -33,6 +33,7 @@ int xsetcolorname(int, const char *);
void xsettitle(char *);
int xsetcursor(int);
void xsetmode(int, unsigned int);
+void xdomode(int, int, int, unsigned int);
void xsetpointermotion(int);
void xsetsel(char *);
int xstartdraw(void);
diff -rup st-0.8.4.orig/x.c st-0.8.4/x.c
--- st-0.8.4.orig/x.c 2020-06-19 11:29:45.000000000 +0200
+++ st-0.8.4/x.c 2020-11-27 00:34:55.913052592 +0100
_AT_@ -1687,6 +1687,21 @@ xsetmode(int set, unsigned int flags)
redraw();
}
+void
+xdomode(int priv, int mode, int set, unsigned int flags)
+{
+ switch (set) {
+ case 0:
+ case 1:
+ xsetmode(set, flags);
+ break;
+ case 2:
+ case 3:
+ DOBIT(priv, mode, win.mode, set, flags);
+ break;
+ }
+}
+
int
xsetcursor(int cursor)
{
Received on Fri Nov 27 2020 - 01:54:36 CET