X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=2945c1bad04d938350475e9b77fe0c28758659b9;hb=43d74ef362b7dc5da3232cdc9412981ea6386df6;hp=124c04702bd754533702c17f7c4ba003fa0f8463;hpb=aa35bbd7a16c6c210a7574a8c45bbe939d5b2922;p=st.git diff --git a/st.c b/st.c index 124c047..2945c1b 100644 --- a/st.c +++ b/st.c @@ -70,8 +70,9 @@ 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 ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f)) +#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) +#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) #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) @@ -393,6 +394,7 @@ static void tsetmode(bool, bool, int *, int); static void tfulldirt(void); static void techo(char *, int); static bool tcontrolcode(uchar ); +static void tdectest(char ); static int32_t tdefcolor(int *, int *, int); static void tselcs(void); static void tdeftran(char); @@ -402,7 +404,6 @@ 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); @@ -2300,17 +2301,12 @@ 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(iscontrol(c)) { /* control code */ + if(ISCONTROL(c)) { /* control code */ if(c & 0x80) { c &= 0x7f; tputc("^", 1); @@ -2431,6 +2427,19 @@ tcontrolcode(uchar ascii) { } void +tdectest(char c) { + static char E[UTF_SIZ] = "E"; + int x, y; + + if(c == '8') { /* DEC screen alignment test. */ + for(x = 0; x < term.col; ++x) { + for(y = 0; y < term.row; ++y) + tsetchar(E, &term.c.attr, x, y); + } + } +} + +void tputc(char *c, int len) { uchar ascii; bool control; @@ -2439,16 +2448,17 @@ tputc(char *c, int len) { if(len == 1) { width = 1; - ascii = *c; + unicodep = ascii = *c; } else { utf8decode(c, &unicodep, UTF_SIZ); width = wcwidth(unicodep); + control = ISCONTROLC1(unicodep); ascii = unicodep; } - control = iscontrol(ascii) && width == 1; if(IS_SET(MODE_PRINT)) tprinter(c, len); + control = ISCONTROL(unicodep); /* * STR sequence must be checked before anything else @@ -2460,7 +2470,7 @@ tputc(char *c, int len) { if(width == 1 && (ascii == '\a' || ascii == 030 || ascii == 032 || ascii == 033 || - ISCONTROLC1(ascii))) { + ISCONTROLC1(unicodep))) { term.esc &= ~ESC_STR; term.esc |= ESC_STR_END; } else if(strescseq.len + len < sizeof(strescseq.buf) - 1) { @@ -2503,29 +2513,20 @@ tputc(char *c, int len) { csiparse(); csihandle(); } + return; } else if(term.esc & ESC_ALTCHARSET) { tdeftran(ascii); tselcs(); - term.esc = 0; } else if(term.esc & ESC_TEST) { - if(ascii == '8') { /* DEC screen alignment test. */ - char E[UTF_SIZ] = "E"; - int x, y; - - for(x = 0; x < term.col; ++x) { - for(y = 0; y < term.row; ++y) - tsetchar(E, &term.c.attr, x, y); - } - } - term.esc = 0; + tdectest(ascii); } else { switch(ascii) { case '[': term.esc |= ESC_CSI; - break; + return; case '#': term.esc |= ESC_TEST; - break; + return; case 'P': /* DCS -- Device Control String */ case '_': /* APC -- Application Program Command */ case '^': /* PM -- Privacy Message */ @@ -2534,29 +2535,26 @@ tputc(char *c, int len) { strreset(); strescseq.type = ascii; term.esc |= ESC_STR; - break; + return; case '(': /* set primary charset G0 */ case ')': /* set secondary charset G1 */ case '*': /* set tertiary charset G2 */ case '+': /* set quaternary charset G3 */ term.icharset = ascii - '('; term.esc |= ESC_ALTCHARSET; - break; + return; case 'D': /* IND -- Linefeed */ if(term.c.y == term.bot) { tscrollup(term.top, 1); } else { tmoveto(term.c.x, term.c.y+1); } - term.esc = 0; break; case 'E': /* NEL -- Next line */ tnewline(1); /* always go to first col */ - term.esc = 0; break; case 'H': /* HTS -- Horizontal tab stop */ term.tabs[term.c.x] = 1; - term.esc = 0; break; case 'M': /* RI -- Reverse index */ if(term.c.y == term.top) { @@ -2564,46 +2562,38 @@ tputc(char *c, int len) { } else { tmoveto(term.c.x, term.c.y-1); } - term.esc = 0; break; case 'Z': /* DECID -- Identify Terminal */ ttywrite(VT102ID, sizeof(VT102ID) - 1); - term.esc = 0; break; case 'c': /* RIS -- Reset to inital state */ treset(); - term.esc = 0; xresettitle(); xloadcols(); break; case '=': /* DECPAM -- Application keypad */ term.mode |= MODE_APPKEYPAD; - term.esc = 0; break; case '>': /* DECPNM -- Normal keypad */ term.mode &= ~MODE_APPKEYPAD; - term.esc = 0; break; case '7': /* DECSC -- Save Cursor */ tcursor(CURSOR_SAVE); - term.esc = 0; break; case '8': /* DECRC -- Restore Cursor */ tcursor(CURSOR_LOAD); - term.esc = 0; break; case '\\': /* ST -- String Terminator */ if(term.esc & ESC_STR_END) strhandle(); - term.esc = 0; break; default: fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n", (uchar) ascii, isprint(ascii)? ascii:'.'); - term.esc = 0; break; } } + term.esc = 0; /* * All characters which form part of a sequence are not * printed