[hackers] [st] Cancel DCS with SUB, CAN, ESC or any CC1 code || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Mon, 28 Apr 2014 10:22:55 +0200

commit aa35bbd7a16c6c210a7574a8c45bbe939d5b2922
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
Date: Sat Apr 26 01:34:46 2014 +0200

    Cancel DCS with SUB, CAN, ESC or any CC1 code
    
    From http://www.vt100.net/docs/vt510-rm/chapter4:
    
            *The VT510 ignores all following characters until it receives a
             SUB, ST, or any other C1 control character.
    
    So OSC, PM and APC sequence ends with a SUB (it cancels the sequence
    and show a question mark as error), ST or any another C1 (8 bits)
    code, or their C0 (7 bits) equivalent sequences (at this moment we
    do not handle C1 codes, but we should). But it is also said that:
    
            Cancel CAN
            1/8 Immediately cancels an escape sequence, control sequence,
                    or device control string in progress. In this case, the
                    VT510 does not display any error character.
    
            Escape ESC
            1/11 Introduces an escape sequence. ESC also cancels any escape
                    sequence, control sequence, or device control string in
                    progress.

diff --git a/st.c b/st.c
index 49df792..124c047 100644
--- a/st.c
+++ b/st.c
_AT_@ -70,6 +70,8 @@ char *argv0;
 #define LEN(a) (sizeof(a) / sizeof(a)[0])
 #define DEFAULT(a, b) (a) = (a) ? (a) : (b)
 #define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b))
+#define ISCONTROLC0(c) (BETWEEN((uchar) (c), 0, 0x1f))
+#define ISCONTROLC1(c) (BETWEEN((uchar) (c), 0x80, 0x9f))
 #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)
 #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg)
 #define IS_SET(flag) ((term.mode & (flag)) != 0)
_AT_@ -390,6 +392,7 @@ static void tsetdirtattr(int);
 static void tsetmode(bool, bool, int *, int);
 static void tfulldirt(void);
 static void techo(char *, int);
+static bool tcontrolcode(uchar );
 static int32_t tdefcolor(int *, int *, int);
 static void tselcs(void);
 static void tdeftran(char);
_AT_@ -399,6 +402,7 @@ static void ttyread(void);
 static void ttyresize(void);
 static void ttysend(char *, size_t);
 static void ttywrite(const char *, size_t);
+static inline bool iscontrol(char);
 
 static void xdraws(char *, Glyph, int, int, int, int);
 static void xhints(void);
_AT_@ -2136,6 +2140,7 @@ strhandle(void) {
         char *p = NULL;
         int j, narg, par;
 
+ term.esc &= ~(ESC_STR_END|ESC_STR);
         strparse();
         narg = strescseq.narg;
         par = atoi(strescseq.args[0]);
_AT_@ -2295,13 +2300,22 @@ tputtab(int n) {
         tmoveto(x, term.c.y);
 }
 
+static inline bool
+iscontrol(char c) {
+ return ISCONTROLC0(c) || ISCONTROLC1(c);
+}
+
 void
 techo(char *buf, int len) {
         for(; len > 0; buf++, len--) {
                 char c = *buf;
 
- if(BETWEEN(c, 0x00, 0x1f) || c == 0x7f) { /* control code */
- if(c != '
' && c != ' ' && c != ' ') {
+ if(iscontrol(c)) { /* control code */
+ if(c & 0x80) {
+ c &= 0x7f;
+ tputc("^", 1);
+ tputc("[", 1);
+ } else if(c != '
' && c != ' ' && c != ' ') {
                                 c ^= '\x40';
                                 tputc("^", 1);
                         }
_AT_@ -2340,58 +2354,135 @@ tselcs(void) {
                ATTR_GFX);
 }
 
+bool
+tcontrolcode(uchar ascii) {
+ static char question[UTF_SIZ] = "?";
+
+ switch(ascii) {
+ case ' ': /* HT */
+ tputtab(1);
+ break;
+ case '': /* BS */
+ tmoveto(term.c.x-1, term.c.y);
+ break;
+ case ' ': /* CR */
+ tmoveto(0, term.c.y);
+ break;
+ case ' ': /* LF */
+ case ' ': /* VT */
+ case '
': /* LF */
+ /* go to first col if the mode is set */
+ tnewline(IS_SET(MODE_CRLF));
+ break;
+ case '': /* BEL */
+ if(term.esc & ESC_STR_END) {
+ /* backwards compatibility to xterm */
+ strhandle();
+ } else {
+ if(!(xw.state & WIN_FOCUSED))
+ xseturgency(1);
+ if (bellvolume)
+ XBell(xw.dpy, bellvolume);
+ }
+ break;
+ case '': /* ESC */
+ csireset();
+ term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST);
+ term.esc |= ESC_START;
+ return 1;
+ case '': /* SO */
+ term.charset = 0;
+ tselcs();
+ break;
+ case '': /* SI */
+ term.charset = 1;
+ tselcs();
+ break;
+ case '': /* SUB */
+ tsetchar(question, &term.c.attr, term.c.x, term.c.y);
+ case '': /* CAN */
+ csireset();
+ break;
+ case '': /* ENQ (IGNORED) */
+ case '
Received on Mon Apr 28 2014 - 10:22:55 CEST

This archive was generated by hypermail 2.3.0 : Mon Apr 28 2014 - 10:24:07 CEST