aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--st.c160
1 files changed, 87 insertions, 73 deletions
diff --git a/st.c b/st.c
index ba6973a..23ed213 100644
--- a/st.c
+++ b/st.c
@@ -1784,56 +1784,80 @@ tputtab(bool forward) {
1784void 1784void
1785tputc(char *c, int len) { 1785tputc(char *c, int len) {
1786 uchar ascii = *c; 1786 uchar ascii = *c;
1787 bool control = ascii < '\x20' || ascii == 0177;
1787 1788
1788 if(iofd != -1) 1789 if(iofd != -1)
1789 write(iofd, c, len); 1790 write(iofd, c, len);
1790 1791 /*
1791 switch(ascii) { 1792 * STR sequences must be checked before of anything
1792 case '\t': /* HT */ 1793 * because it can use some control codes as part of the sequence
1793 tputtab(1); 1794 */
1794 return; 1795 if(term.esc & ESC_STR) {
1795 case '\b': /* BS */ 1796 switch(ascii) {
1796 tmoveto(term.c.x-1, term.c.y); 1797 case '\033':
1797 return; 1798 term.esc = ESC_START | ESC_STR_END;
1798 case '\r': /* CR */
1799 tmoveto(0, term.c.y);
1800 return;
1801 case '\f': /* LF */
1802 case '\v': /* VT */
1803 case '\n': /* LF */
1804 /* go to first col if the mode is set */
1805 tnewline(IS_SET(MODE_CRLF));
1806 return;
1807 case '\a': /* BEL */
1808 if(term.esc & ESC_STR)
1809 break; 1799 break;
1810 if(!(xw.state & WIN_FOCUSED)) 1800 case '\a': /* backwards compatibility to xterm */
1811 xseturgency(1); 1801 term.esc = 0;
1812 return; 1802 strhandle();
1813 case '\033': /* ESC */ 1803 break;
1814 csireset(); 1804 default:
1815 term.esc = ESC_START; 1805 strescseq.buf[strescseq.len++] = ascii;
1816 return; 1806 if(strescseq.len+1 >= STR_BUF_SIZ) {
1817 case '\016': /* SO */ 1807 term.esc = 0;
1818 term.c.attr.mode |= ATTR_GFX; 1808 strhandle();
1819 break; 1809 }
1820 case '\017': /* SI */ 1810 }
1821 term.c.attr.mode &= ~ATTR_GFX;
1822 return;
1823 case '\032': /* SUB */
1824 case '\030': /* CAN */
1825 csireset();
1826 return; 1811 return;
1827 default:
1828 /* case '\005': ENQ (IGNORED) */
1829 /* case '\000': NUL (IGNORED) */
1830 /* case '\021': XON (IGNORED) */
1831 /* case '\023': XOFF (IGNORED) */
1832 /* case 0177: DEL (IGNORED) */
1833 break;
1834 } 1812 }
1835 1813 /*
1836 if(term.esc & ESC_START) { 1814 * Actions of control codes must be performed as soon they arrive
1815 * because they can be embedded inside a control sequence, and
1816 * they must not cause conflicts with sequences.
1817 */
1818 if(control) {
1819 switch(ascii) {
1820 case '\t': /* HT */
1821 tputtab(1);
1822 return;
1823 case '\b': /* BS */
1824 tmoveto(term.c.x-1, term.c.y);
1825 return;
1826 case '\r': /* CR */
1827 tmoveto(0, term.c.y);
1828 return;
1829 case '\f': /* LF */
1830 case '\v': /* VT */
1831 case '\n': /* LF */
1832 /* go to first col if the mode is set */
1833 tnewline(IS_SET(MODE_CRLF));
1834 return;
1835 case '\a': /* BEL */
1836 if(!(xw.state & WIN_FOCUSED))
1837 xseturgency(1);
1838 return;
1839 case '\033': /* ESC */
1840 csireset();
1841 term.esc = ESC_START;
1842 return;
1843 case '\016': /* SO */
1844 term.c.attr.mode |= ATTR_GFX;
1845 return;
1846 case '\017': /* SI */
1847 term.c.attr.mode &= ~ATTR_GFX;
1848 return;
1849 case '\032': /* SUB */
1850 case '\030': /* CAN */
1851 csireset();
1852 return;
1853 case '\005': /* ENQ (IGNORED) */
1854 case '\000': /* NUL (IGNORED) */
1855 case '\021': /* XON (IGNORED) */
1856 case '\023': /* XOFF (IGNORED) */
1857 case 0177: /* DEL (IGNORED) */
1858 return;
1859 }
1860 } else if(term.esc & ESC_START) {
1837 if(term.esc & ESC_CSI) { 1861 if(term.esc & ESC_CSI) {
1838 csiescseq.buf[csiescseq.len++] = ascii; 1862 csiescseq.buf[csiescseq.len++] = ascii;
1839 if(BETWEEN(ascii, 0x40, 0x7E) 1863 if(BETWEEN(ascii, 0x40, 0x7E)
@@ -1841,22 +1865,6 @@ tputc(char *c, int len) {
1841 term.esc = 0; 1865 term.esc = 0;
1842 csiparse(), csihandle(); 1866 csiparse(), csihandle();
1843 } 1867 }
1844 } else if(term.esc & ESC_STR) {
1845 switch(ascii) {
1846 case '\033':
1847 term.esc = ESC_START | ESC_STR_END;
1848 break;
1849 case '\a': /* backwards compatibility to xterm */
1850 term.esc = 0;
1851 strhandle();
1852 break;
1853 default:
1854 strescseq.buf[strescseq.len++] = ascii;
1855 if(strescseq.len+1 >= STR_BUF_SIZ) {
1856 term.esc = 0;
1857 strhandle();
1858 }
1859 }
1860 } else if(term.esc & ESC_STR_END) { 1868 } else if(term.esc & ESC_STR_END) {
1861 term.esc = 0; 1869 term.esc = 0;
1862 if(ascii == '\\') 1870 if(ascii == '\\')
@@ -1955,20 +1963,26 @@ tputc(char *c, int len) {
1955 term.esc = 0; 1963 term.esc = 0;
1956 } 1964 }
1957 } 1965 }
1958 } else { 1966 /*
1959 if(sel.bx != -1 && BETWEEN(term.c.y, sel.by, sel.ey)) 1967 * All characters which forms part of a sequence are not
1960 sel.bx = -1; 1968 * printed
1961 if(ascii >= '\020' || term.c.attr.mode & ATTR_GFX) { 1969 */
1962 if(IS_SET(MODE_WRAP) && term.c.state & CURSOR_WRAPNEXT) 1970 return;
1963 tnewline(1); /* always go to first col */
1964 tsetchar(c);
1965 if(term.c.x+1 < term.col) {
1966 tmoveto(term.c.x+1, term.c.y);
1967 } else {
1968 term.c.state |= CURSOR_WRAPNEXT;
1969 }
1970 }
1971 } 1971 }
1972 /*
1973 * Display control codes only if we are in graphic mode
1974 */
1975 if(control && !(term.c.attr.mode & ATTR_GFX))
1976 return;
1977 if(sel.bx != -1 && BETWEEN(term.c.y, sel.by, sel.ey))
1978 sel.bx = -1;
1979 if(IS_SET(MODE_WRAP) && term.c.state & CURSOR_WRAPNEXT)
1980 tnewline(1); /* always go to first col */
1981 tsetchar(c);
1982 if(term.c.x+1 < term.col)
1983 tmoveto(term.c.x+1, term.c.y);
1984 else
1985 term.c.state |= CURSOR_WRAPNEXT;
1972} 1986}
1973 1987
1974int 1988int