diff options
author | Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com> | 2016-09-14 08:27:32 +0200 |
---|---|---|
committer | Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com> | 2016-09-14 08:27:32 +0200 |
commit | f7398434b8fa949af7bf43472caaefdd97eed0f3 (patch) | |
tree | 35056e61107d513b0a7ed32b27488f3b5134e2aa /st.c | |
parent | f0e2d28732549690466df995981698173daf39c0 (diff) | |
download | st-f7398434b8fa949af7bf43472caaefdd97eed0f3.tar.gz st-f7398434b8fa949af7bf43472caaefdd97eed0f3.zip |
Add parsing of DCS q sequences
These sequences are used to operate with sixels, but they are still
str sequences, so they are finished with \a, ST or with a C1 control
code. This patch also disables utf8 handling for the case of sixels.
Diffstat (limited to 'st.c')
-rw-r--r-- | st.c | 68 |
1 files changed, 45 insertions, 23 deletions
@@ -138,6 +138,7 @@ enum term_mode { | |||
138 | MODE_BRCKTPASTE = 1 << 19, | 138 | MODE_BRCKTPASTE = 1 << 19, |
139 | MODE_PRINT = 1 << 20, | 139 | MODE_PRINT = 1 << 20, |
140 | MODE_UTF8 = 1 << 21, | 140 | MODE_UTF8 = 1 << 21, |
141 | MODE_SIXEL = 1 << 22, | ||
141 | MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ | 142 | MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ |
142 | |MODE_MOUSEMANY, | 143 | |MODE_MOUSEMANY, |
143 | }; | 144 | }; |
@@ -155,11 +156,12 @@ enum charset { | |||
155 | enum escape_state { | 156 | enum escape_state { |
156 | ESC_START = 1, | 157 | ESC_START = 1, |
157 | ESC_CSI = 2, | 158 | ESC_CSI = 2, |
158 | ESC_STR = 4, /* DCS, OSC, PM, APC */ | 159 | ESC_STR = 4, /* OSC, PM, APC */ |
159 | ESC_ALTCHARSET = 8, | 160 | ESC_ALTCHARSET = 8, |
160 | ESC_STR_END = 16, /* a final string was encountered */ | 161 | ESC_STR_END = 16, /* a final string was encountered */ |
161 | ESC_TEST = 32, /* Enter in test mode */ | 162 | ESC_TEST = 32, /* Enter in test mode */ |
162 | ESC_UTF8 = 64, | 163 | ESC_UTF8 = 64, |
164 | ESC_DCS =128, | ||
163 | }; | 165 | }; |
164 | 166 | ||
165 | enum window_state { | 167 | enum window_state { |
@@ -1485,7 +1487,7 @@ ttyread(void) | |||
1485 | ptr = buf; | 1487 | ptr = buf; |
1486 | 1488 | ||
1487 | for (;;) { | 1489 | for (;;) { |
1488 | if (IS_SET(MODE_UTF8)) { | 1490 | if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { |
1489 | /* process a complete utf8 char */ | 1491 | /* process a complete utf8 char */ |
1490 | charsize = utf8decode(ptr, &unicodep, buflen); | 1492 | charsize = utf8decode(ptr, &unicodep, buflen); |
1491 | if (charsize == 0) | 1493 | if (charsize == 0) |
@@ -1578,7 +1580,7 @@ ttysend(char *s, size_t n) | |||
1578 | 1580 | ||
1579 | lim = &s[n]; | 1581 | lim = &s[n]; |
1580 | for (t = s; t < lim; t += len) { | 1582 | for (t = s; t < lim; t += len) { |
1581 | if (IS_SET(MODE_UTF8)) { | 1583 | if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { |
1582 | len = utf8decode(t, &u, n); | 1584 | len = utf8decode(t, &u, n); |
1583 | } else { | 1585 | } else { |
1584 | u = *t & 0xFF; | 1586 | u = *t & 0xFF; |
@@ -2548,6 +2550,7 @@ strhandle(void) | |||
2548 | xsettitle(strescseq.args[0]); | 2550 | xsettitle(strescseq.args[0]); |
2549 | return; | 2551 | return; |
2550 | case 'P': /* DCS -- Device Control String */ | 2552 | case 'P': /* DCS -- Device Control String */ |
2553 | term.mode |= ESC_DCS; | ||
2551 | case '_': /* APC -- Application Program Command */ | 2554 | case '_': /* APC -- Application Program Command */ |
2552 | case '^': /* PM -- Privacy Message */ | 2555 | case '^': /* PM -- Privacy Message */ |
2553 | return; | 2556 | return; |
@@ -2754,9 +2757,12 @@ tdectest(char c) | |||
2754 | void | 2757 | void |
2755 | tstrsequence(uchar c) | 2758 | tstrsequence(uchar c) |
2756 | { | 2759 | { |
2760 | strreset(); | ||
2761 | |||
2757 | switch (c) { | 2762 | switch (c) { |
2758 | case 0x90: /* DCS -- Device Control String */ | 2763 | case 0x90: /* DCS -- Device Control String */ |
2759 | c = 'P'; | 2764 | c = 'P'; |
2765 | term.esc |= ESC_DCS; | ||
2760 | break; | 2766 | break; |
2761 | case 0x9f: /* APC -- Application Program Command */ | 2767 | case 0x9f: /* APC -- Application Program Command */ |
2762 | c = '_'; | 2768 | c = '_'; |
@@ -2768,7 +2774,6 @@ tstrsequence(uchar c) | |||
2768 | c = ']'; | 2774 | c = ']'; |
2769 | break; | 2775 | break; |
2770 | } | 2776 | } |
2771 | strreset(); | ||
2772 | strescseq.type = c; | 2777 | strescseq.type = c; |
2773 | term.esc |= ESC_STR; | 2778 | term.esc |= ESC_STR; |
2774 | } | 2779 | } |
@@ -2968,7 +2973,7 @@ tputc(Rune u) | |||
2968 | Glyph *gp; | 2973 | Glyph *gp; |
2969 | 2974 | ||
2970 | control = ISCONTROL(u); | 2975 | control = ISCONTROL(u); |
2971 | if (!IS_SET(MODE_UTF8)) { | 2976 | if (!IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { |
2972 | c[0] = u; | 2977 | c[0] = u; |
2973 | width = len = 1; | 2978 | width = len = 1; |
2974 | } else { | 2979 | } else { |
@@ -2991,30 +2996,47 @@ tputc(Rune u) | |||
2991 | if (term.esc & ESC_STR) { | 2996 | if (term.esc & ESC_STR) { |
2992 | if (u == '\a' || u == 030 || u == 032 || u == 033 || | 2997 | if (u == '\a' || u == 030 || u == 032 || u == 033 || |
2993 | ISCONTROLC1(u)) { | 2998 | ISCONTROLC1(u)) { |
2994 | term.esc &= ~(ESC_START|ESC_STR); | 2999 | term.esc &= ~(ESC_START|ESC_STR|ESC_DCS); |
3000 | if (IS_SET(MODE_SIXEL)) { | ||
3001 | /* TODO: render sixel */; | ||
3002 | term.mode &= ~MODE_SIXEL; | ||
3003 | return; | ||
3004 | } | ||
2995 | term.esc |= ESC_STR_END; | 3005 | term.esc |= ESC_STR_END; |
2996 | } else if (strescseq.len + len < sizeof(strescseq.buf) - 1) { | 3006 | goto check_control_code; |
2997 | memmove(&strescseq.buf[strescseq.len], c, len); | 3007 | } |
2998 | strescseq.len += len; | 3008 | |
3009 | |||
3010 | if (IS_SET(MODE_SIXEL)) { | ||
3011 | /* TODO: implement sixel mode */ | ||
2999 | return; | 3012 | return; |
3000 | } else { | 3013 | } |
3001 | /* | 3014 | if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q') |
3002 | * Here is a bug in terminals. If the user never sends | 3015 | term.mode |= MODE_SIXEL; |
3003 | * some code to stop the str or esc command, then st | 3016 | |
3004 | * will stop responding. But this is better than | 3017 | if (strescseq.len+len >= sizeof(strescseq.buf)-1) { |
3005 | * silently failing with unknown characters. At least | 3018 | /* |
3006 | * then users will report back. | 3019 | * Here is a bug in terminals. If the user never sends |
3007 | * | 3020 | * some code to stop the str or esc command, then st |
3008 | * In the case users ever get fixed, here is the code: | 3021 | * will stop responding. But this is better than |
3009 | */ | 3022 | * silently failing with unknown characters. At least |
3010 | /* | 3023 | * then users will report back. |
3011 | * term.esc = 0; | 3024 | * |
3012 | * strhandle(); | 3025 | * In the case users ever get fixed, here is the code: |
3013 | */ | 3026 | */ |
3027 | /* | ||
3028 | * term.esc = 0; | ||
3029 | * strhandle(); | ||
3030 | */ | ||
3014 | return; | 3031 | return; |
3015 | } | 3032 | } |
3033 | |||
3034 | memmove(&strescseq.buf[strescseq.len], c, len); | ||
3035 | strescseq.len += len; | ||
3036 | return; | ||
3016 | } | 3037 | } |
3017 | 3038 | ||
3039 | check_control_code: | ||
3018 | /* | 3040 | /* |
3019 | * Actions of control codes must be performed as soon they arrive | 3041 | * Actions of control codes must be performed as soon they arrive |
3020 | * because they can be embedded inside a control sequence, and | 3042 | * because they can be embedded inside a control sequence, and |