diff options
| -rw-r--r-- | st.c | 160 |
1 files changed, 87 insertions, 73 deletions
| @@ -1784,56 +1784,80 @@ tputtab(bool forward) { | |||
| 1784 | void | 1784 | void |
| 1785 | tputc(char *c, int len) { | 1785 | tputc(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 | ||
| 1974 | int | 1988 | int |
