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

Reply via email to