--- st.c | 139 ++++++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 88 insertions(+), 51 deletions(-) diff --git a/st.c b/st.c index d2261e2..6cce36a 100644 --- a/st.c +++ b/st.c _AT_@ -399,6 +399,7 @@ static void ttyread(void); static void ttyresize(void); static void ttysend(char *, size_t); static void ttywrite(const char *, size_t); +static bool iscontrol(int c); static void xdraws(char *, Glyph, int, int, int, int); static void xhints(void); _AT_@ -2134,6 +2135,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_@ -2293,13 +2295,22 @@ tputtab(int n) { tmoveto(x, term.c.y); } +bool +iscontrol(int c) { + return c < 0x20 || c == 0177 || BETWEEN(c, 0x80, 0x9f); +} + 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 != '\n' && c != '\r' && c != '\t') { + if(iscontrol(c)) { /* control code */ + if(c & 0x80) { + c &= 0x7f; + tputc("^", 1); + tputc("[", 1); + } else if(c != '\n' && c != '\r' && c != '\t') { c ^= '\x40'; tputc("^", 1); } _AT_@ -2340,55 +2351,59 @@ tselcs(void) { void tputc(char *c, int len) { - uchar ascii = *c; - bool control = ascii < '\x20' || ascii == 0177; + uchar ascii; + bool control; + bool dcs = term.esc & ESC_STR; long unicodep; int width; + char s[UTF_SIZ] = "?"; if(len == 1) { width = 1; + ascii = *c; } else { utf8decode(c, &unicodep, UTF_SIZ); width = wcwidth(unicodep); + ascii = unicodep; } + control = iscontrol(ascii) && width == 1; if(IS_SET(MODE_PRINT)) tprinter(c, len); /* - * STR sequences must be checked before anything else - * because it can use some control codes as part of the sequence. + * STR sequence must be checked before anything else + * because it uses all following characters until it + * receives a ESC, a SUB, a ST or any other C1 control + * character. */ - if(term.esc & ESC_STR) { - switch(ascii) { - case '\033': - term.esc = ESC_START | ESC_STR_END; - break; - case '\a': /* backwards compatibility to xterm */ - term.esc = 0; - strhandle(); - break; - default: - if(strescseq.len + len < sizeof(strescseq.buf) - 1) { - memmove(&strescseq.buf[strescseq.len], c, len); - strescseq.len += len; - } else { - /* - * Here is a bug in terminals. If the user never sends - * some code to stop the str or esc command, then st - * will stop responding. But this is better than - * silently failing with unknown characters. At least - * then users will report back. - * - * In the case users ever get fixed, here is the code: - */ - /* - * term.esc = 0; - * strhandle(); - */ - } + if(dcs) { + if(width == 1 && + (ascii == '\a' || ascii == 030 || + ascii == 032 || ascii == 033 || + BETWEEN(ascii, 0x80, 0x9f))) { + term.esc &= ~ESC_STR; + term.esc |= ESC_STR_END; + } else if(strescseq.len + len < sizeof(strescseq.buf) - 1) { + memmove(&strescseq.buf[strescseq.len], c, len); + strescseq.len += len; + return; + } else { + /* + * Here is a bug in terminals. If the user never sends + * some code to stop the str or esc command, then st + * will stop responding. But this is better than + * silently failing with unknown characters. At least + * then users will report back. + * + * In the case users ever get fixed, here is the code: + */ + /* + * term.esc = 0; + * strhandle(); + */ + return; } - return; } /* _AT_@ -2400,48 +2415,70 @@ tputc(char *c, int len) { switch(ascii) { case '\t': /* HT */ tputtab(1); - return; + break; case '\b': /* BS */ tmoveto(term.c.x-1, term.c.y); - return; + break; case '\r': /* CR */ tmoveto(0, term.c.y); - return; + break; case '\f': /* LF */ case '\v': /* VT */ case '\n': /* LF */ /* go to first col if the mode is set */ tnewline(IS_SET(MODE_CRLF)); - return; + break; case '\a': /* BEL */ - if(!(xw.state & WIN_FOCUSED)) - xseturgency(1); - if (bellvolume) - XBell(xw.dpy, bellvolume); - return; + 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 '\033': /* ESC */ csireset(); - term.esc = ESC_START; + term.esc |= ESC_START; return; case '\016': /* SO */ term.charset = 0; tselcs(); - return; + break; case '\017': /* SI */ term.charset = 1; tselcs(); - return; + break; case '\032': /* SUB */ + tsetchar(s, &term.c.attr, term.c.x, term.c.y); case '\030': /* CAN */ csireset(); - return; + break; case '\005': /* ENQ (IGNORED) */ case '\000': /* NUL (IGNORED) */ case '\021': /* XON (IGNORED) */ case '\023': /* XOFF (IGNORED) */ case 0177: /* DEL (IGNORED) */ - return; + case 0x84: /* TODO: IND */ + case 0x85: /* TODO: NEL */ + case 0x88: /* TODO: HTS */ + case 0x8d: /* TODO: RI */ + case 0x8e: /* TODO: SS2 */ + case 0x8f: /* TODO: SS3 */ + case 0x90: /* TODO: DCS */ + case 0x98: /* TODO: SOS */ + case 0x9a: /* TODO: DECID */ + case 0x9b: /* TODO: CSI */ + case 0x9c: /* TODO: ST */ + case 0x9d: /* TODO: OSC */ + case 0x9e: /* TODO: PM */ + case 0x9f: /* TODO: APC */ + break; } + term.esc &= ~(ESC_STR_END|ESC_STR); + return; } else if(term.esc & ESC_START) { if(term.esc & ESC_CSI) { csiescseq.buf[csiescseq.len++] = ascii; _AT_@ -2458,12 +2495,12 @@ tputc(char *c, int len) { term.esc = 0; } else if(term.esc & ESC_TEST) { if(ascii == '8') { /* DEC screen alignment test. */ - char E[UTF_SIZ] = "E"; int x, y; + s[0] = 'E'; for(x = 0; x < term.col; ++x) { for(y = 0; y < term.row; ++y) - tsetchar(E, &term.c.attr, x, y); + tsetchar(s, &term.c.attr, x, y); } } term.esc = 0; -- 1.8.5.3Received on Sat Apr 26 2014 - 08:45:01 CEST
This archive was generated by hypermail 2.3.0 : Sat Apr 26 2014 - 08:48:06 CEST