On Fri, Nov 27, 2020 at 01:54:36AM +0100, François-Xavier Carton wrote: > 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 > @@ -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) */ > @@ -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); > @@ -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 > @@ -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; > } > } > @@ -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; > } > } > > @@ -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 > @@ -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)) > @@ -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 > @@ -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 > @@ -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) > { >
Hi Francois, First: thanks for the patch. Do you have maybe a practical use-case example why you'd like to request supporting this? In all st years it has not been requested before. I'd like to prevent obscure/non-tested features. Although maybe it's not so obscure and useful, in that case please say so :) -- Kind regards, Hiltjo