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.
This commit is contained in:
parent
f0e2d28732
commit
f7398434b8
44
st.c
44
st.c
|
@ -138,6 +138,7 @@ enum term_mode {
|
|||
MODE_BRCKTPASTE = 1 << 19,
|
||||
MODE_PRINT = 1 << 20,
|
||||
MODE_UTF8 = 1 << 21,
|
||||
MODE_SIXEL = 1 << 22,
|
||||
MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\
|
||||
|MODE_MOUSEMANY,
|
||||
};
|
||||
|
@ -155,11 +156,12 @@ enum charset {
|
|||
enum escape_state {
|
||||
ESC_START = 1,
|
||||
ESC_CSI = 2,
|
||||
ESC_STR = 4, /* DCS, OSC, PM, APC */
|
||||
ESC_STR = 4, /* OSC, PM, APC */
|
||||
ESC_ALTCHARSET = 8,
|
||||
ESC_STR_END = 16, /* a final string was encountered */
|
||||
ESC_TEST = 32, /* Enter in test mode */
|
||||
ESC_UTF8 = 64,
|
||||
ESC_DCS =128,
|
||||
};
|
||||
|
||||
enum window_state {
|
||||
|
@ -1485,7 +1487,7 @@ ttyread(void)
|
|||
ptr = buf;
|
||||
|
||||
for (;;) {
|
||||
if (IS_SET(MODE_UTF8)) {
|
||||
if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
|
||||
/* process a complete utf8 char */
|
||||
charsize = utf8decode(ptr, &unicodep, buflen);
|
||||
if (charsize == 0)
|
||||
|
@ -1578,7 +1580,7 @@ ttysend(char *s, size_t n)
|
|||
|
||||
lim = &s[n];
|
||||
for (t = s; t < lim; t += len) {
|
||||
if (IS_SET(MODE_UTF8)) {
|
||||
if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
|
||||
len = utf8decode(t, &u, n);
|
||||
} else {
|
||||
u = *t & 0xFF;
|
||||
|
@ -2548,6 +2550,7 @@ strhandle(void)
|
|||
xsettitle(strescseq.args[0]);
|
||||
return;
|
||||
case 'P': /* DCS -- Device Control String */
|
||||
term.mode |= ESC_DCS;
|
||||
case '_': /* APC -- Application Program Command */
|
||||
case '^': /* PM -- Privacy Message */
|
||||
return;
|
||||
|
@ -2754,9 +2757,12 @@ tdectest(char c)
|
|||
void
|
||||
tstrsequence(uchar c)
|
||||
{
|
||||
strreset();
|
||||
|
||||
switch (c) {
|
||||
case 0x90: /* DCS -- Device Control String */
|
||||
c = 'P';
|
||||
term.esc |= ESC_DCS;
|
||||
break;
|
||||
case 0x9f: /* APC -- Application Program Command */
|
||||
c = '_';
|
||||
|
@ -2768,7 +2774,6 @@ tstrsequence(uchar c)
|
|||
c = ']';
|
||||
break;
|
||||
}
|
||||
strreset();
|
||||
strescseq.type = c;
|
||||
term.esc |= ESC_STR;
|
||||
}
|
||||
|
@ -2968,7 +2973,7 @@ tputc(Rune u)
|
|||
Glyph *gp;
|
||||
|
||||
control = ISCONTROL(u);
|
||||
if (!IS_SET(MODE_UTF8)) {
|
||||
if (!IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
|
||||
c[0] = u;
|
||||
width = len = 1;
|
||||
} else {
|
||||
|
@ -2991,13 +2996,25 @@ tputc(Rune u)
|
|||
if (term.esc & ESC_STR) {
|
||||
if (u == '\a' || u == 030 || u == 032 || u == 033 ||
|
||||
ISCONTROLC1(u)) {
|
||||
term.esc &= ~(ESC_START|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;
|
||||
term.esc &= ~(ESC_START|ESC_STR|ESC_DCS);
|
||||
if (IS_SET(MODE_SIXEL)) {
|
||||
/* TODO: render sixel */;
|
||||
term.mode &= ~MODE_SIXEL;
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
term.esc |= ESC_STR_END;
|
||||
goto check_control_code;
|
||||
}
|
||||
|
||||
|
||||
if (IS_SET(MODE_SIXEL)) {
|
||||
/* TODO: implement sixel mode */
|
||||
return;
|
||||
}
|
||||
if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
|
||||
term.mode |= MODE_SIXEL;
|
||||
|
||||
if (strescseq.len+len >= sizeof(strescseq.buf)-1) {
|
||||
/*
|
||||
* Here is a bug in terminals. If the user never sends
|
||||
* some code to stop the str or esc command, then st
|
||||
|
@ -3013,8 +3030,13 @@ tputc(Rune u)
|
|||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
memmove(&strescseq.buf[strescseq.len], c, len);
|
||||
strescseq.len += len;
|
||||
return;
|
||||
}
|
||||
|
||||
check_control_code:
|
||||
/*
|
||||
* Actions of control codes must be performed as soon they arrive
|
||||
* because they can be embedded inside a control sequence, and
|
||||
|
|
Loading…
Reference in a new issue