aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorRoberto E. Vargas Caballero <roberto.vargas@igrid-td.com>2016-09-14 08:27:32 +0200
committerRoberto E. Vargas Caballero <roberto.vargas@igrid-td.com>2016-09-14 08:27:32 +0200
commitf7398434b8fa949af7bf43472caaefdd97eed0f3 (patch)
tree35056e61107d513b0a7ed32b27488f3b5134e2aa /st.c
parentf0e2d28732549690466df995981698173daf39c0 (diff)
downloadst-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.c68
1 files changed, 45 insertions, 23 deletions
diff --git a/st.c b/st.c
index ebbd7ca..6c16386 100644
--- a/st.c
+++ b/st.c
@@ -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 {
155enum escape_state { 156enum 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
165enum window_state { 167enum 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)
2754void 2757void
2755tstrsequence(uchar c) 2758tstrsequence(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
3039check_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