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