19b934d09SEd Schouten /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3fe267a55SPedro F. Giffuni *
49b934d09SEd Schouten * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
59b934d09SEd Schouten * All rights reserved.
69b934d09SEd Schouten *
79b934d09SEd Schouten * Redistribution and use in source and binary forms, with or without
89b934d09SEd Schouten * modification, are permitted provided that the following conditions
99b934d09SEd Schouten * are met:
109b934d09SEd Schouten * 1. Redistributions of source code must retain the above copyright
119b934d09SEd Schouten * notice, this list of conditions and the following disclaimer.
129b934d09SEd Schouten * 2. Redistributions in binary form must reproduce the above copyright
139b934d09SEd Schouten * notice, this list of conditions and the following disclaimer in the
149b934d09SEd Schouten * documentation and/or other materials provided with the distribution.
159b934d09SEd Schouten *
169b934d09SEd Schouten * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
179b934d09SEd Schouten * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
189b934d09SEd Schouten * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199b934d09SEd Schouten * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
209b934d09SEd Schouten * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
219b934d09SEd Schouten * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
229b934d09SEd Schouten * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
239b934d09SEd Schouten * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
249b934d09SEd Schouten * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
259b934d09SEd Schouten * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
269b934d09SEd Schouten * SUCH DAMAGE.
279b934d09SEd Schouten */
289b934d09SEd Schouten
299b934d09SEd Schouten static void teken_subr_cursor_up(teken_t *, unsigned int);
3092223bddSPoul-Henning Kamp static void teken_subr_erase_line(const teken_t *, unsigned int);
319b934d09SEd Schouten static void teken_subr_regular_character(teken_t *, teken_char_t);
329b934d09SEd Schouten static void teken_subr_reset_to_initial_state(teken_t *);
339b934d09SEd Schouten static void teken_subr_save_cursor(teken_t *);
349b934d09SEd Schouten
359b934d09SEd Schouten static inline int
teken_tab_isset(const teken_t * t,unsigned int col)3692223bddSPoul-Henning Kamp teken_tab_isset(const teken_t *t, unsigned int col)
379b934d09SEd Schouten {
389b934d09SEd Schouten unsigned int b, o;
399b934d09SEd Schouten
409b934d09SEd Schouten if (col >= T_NUMCOL)
419b934d09SEd Schouten return ((col % 8) == 0);
429b934d09SEd Schouten
439b934d09SEd Schouten b = col / (sizeof(unsigned int) * 8);
449b934d09SEd Schouten o = col % (sizeof(unsigned int) * 8);
459b934d09SEd Schouten
4692223bddSPoul-Henning Kamp return (t->t_tabstops[b] & (1U << o));
479b934d09SEd Schouten }
489b934d09SEd Schouten
499b934d09SEd Schouten static inline void
teken_tab_clear(teken_t * t,unsigned int col)509b934d09SEd Schouten teken_tab_clear(teken_t *t, unsigned int col)
519b934d09SEd Schouten {
529b934d09SEd Schouten unsigned int b, o;
539b934d09SEd Schouten
549b934d09SEd Schouten if (col >= T_NUMCOL)
559b934d09SEd Schouten return;
569b934d09SEd Schouten
579b934d09SEd Schouten b = col / (sizeof(unsigned int) * 8);
589b934d09SEd Schouten o = col % (sizeof(unsigned int) * 8);
599b934d09SEd Schouten
6092223bddSPoul-Henning Kamp t->t_tabstops[b] &= ~(1U << o);
619b934d09SEd Schouten }
629b934d09SEd Schouten
639b934d09SEd Schouten static inline void
teken_tab_set(teken_t * t,unsigned int col)649b934d09SEd Schouten teken_tab_set(teken_t *t, unsigned int col)
659b934d09SEd Schouten {
669b934d09SEd Schouten unsigned int b, o;
679b934d09SEd Schouten
689b934d09SEd Schouten if (col >= T_NUMCOL)
699b934d09SEd Schouten return;
709b934d09SEd Schouten
719b934d09SEd Schouten b = col / (sizeof(unsigned int) * 8);
729b934d09SEd Schouten o = col % (sizeof(unsigned int) * 8);
739b934d09SEd Schouten
7492223bddSPoul-Henning Kamp t->t_tabstops[b] |= 1U << o;
759b934d09SEd Schouten }
769b934d09SEd Schouten
779b934d09SEd Schouten static void
teken_tab_default(teken_t * t)789b934d09SEd Schouten teken_tab_default(teken_t *t)
799b934d09SEd Schouten {
809b934d09SEd Schouten unsigned int i;
819b934d09SEd Schouten
8292223bddSPoul-Henning Kamp memset(t->t_tabstops, 0, T_NUMCOL / 8);
839b934d09SEd Schouten
849b934d09SEd Schouten for (i = 8; i < T_NUMCOL; i += 8)
859b934d09SEd Schouten teken_tab_set(t, i);
869b934d09SEd Schouten }
879b934d09SEd Schouten
889b934d09SEd Schouten static void
teken_subr_do_scroll(const teken_t * t,int amount)8992223bddSPoul-Henning Kamp teken_subr_do_scroll(const teken_t *t, int amount)
909b934d09SEd Schouten {
919b934d09SEd Schouten teken_rect_t tr;
929b934d09SEd Schouten teken_pos_t tp;
939b934d09SEd Schouten
949b934d09SEd Schouten teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row);
959b934d09SEd Schouten teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row);
969b934d09SEd Schouten teken_assert(amount != 0);
979b934d09SEd Schouten
989b934d09SEd Schouten /* Copy existing data 1 line up. */
999b934d09SEd Schouten if (amount > 0) {
1009b934d09SEd Schouten /* Scroll down. */
1019b934d09SEd Schouten
1029b934d09SEd Schouten /* Copy existing data up. */
1039b934d09SEd Schouten if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
1049b934d09SEd Schouten tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount;
1059b934d09SEd Schouten tr.tr_begin.tp_col = 0;
1069b934d09SEd Schouten tr.tr_end.tp_row = t->t_scrollreg.ts_end;
1079b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
1089b934d09SEd Schouten tp.tp_row = t->t_scrollreg.ts_begin;
1099b934d09SEd Schouten tp.tp_col = 0;
1109b934d09SEd Schouten teken_funcs_copy(t, &tr, &tp);
1119b934d09SEd Schouten
1129b934d09SEd Schouten tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount;
1139b934d09SEd Schouten } else {
1149b934d09SEd Schouten tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
1159b934d09SEd Schouten }
1169b934d09SEd Schouten
1179b934d09SEd Schouten /* Clear the last lines. */
1189b934d09SEd Schouten tr.tr_begin.tp_col = 0;
1199b934d09SEd Schouten tr.tr_end.tp_row = t->t_scrollreg.ts_end;
1209b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
1219b934d09SEd Schouten teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
1229b934d09SEd Schouten } else {
1239b934d09SEd Schouten /* Scroll up. */
1249b934d09SEd Schouten amount = -amount;
1259b934d09SEd Schouten
1269b934d09SEd Schouten /* Copy existing data down. */
1279b934d09SEd Schouten if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
1289b934d09SEd Schouten tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
1299b934d09SEd Schouten tr.tr_begin.tp_col = 0;
1309b934d09SEd Schouten tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount;
1319b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
1329b934d09SEd Schouten tp.tp_row = t->t_scrollreg.ts_begin + amount;
1339b934d09SEd Schouten tp.tp_col = 0;
1349b934d09SEd Schouten teken_funcs_copy(t, &tr, &tp);
1359b934d09SEd Schouten
1369b934d09SEd Schouten tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount;
1379b934d09SEd Schouten } else {
1389b934d09SEd Schouten tr.tr_end.tp_row = t->t_scrollreg.ts_end;
1399b934d09SEd Schouten }
1409b934d09SEd Schouten
1419b934d09SEd Schouten /* Clear the first lines. */
1429b934d09SEd Schouten tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
1439b934d09SEd Schouten tr.tr_begin.tp_col = 0;
1449b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
1459b934d09SEd Schouten teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
1469b934d09SEd Schouten }
1479b934d09SEd Schouten }
1489b934d09SEd Schouten
1499b934d09SEd Schouten static ssize_t
teken_subr_do_cpr(const teken_t * t,unsigned int cmd,char response[16])15092223bddSPoul-Henning Kamp teken_subr_do_cpr(const teken_t *t, unsigned int cmd, char response[16])
1519b934d09SEd Schouten {
1529b934d09SEd Schouten
1539b934d09SEd Schouten switch (cmd) {
1549b934d09SEd Schouten case 5: /* Operating status. */
1559b934d09SEd Schouten strcpy(response, "0n");
1569b934d09SEd Schouten return (2);
1579b934d09SEd Schouten case 6: { /* Cursor position. */
1589b934d09SEd Schouten int len;
1599b934d09SEd Schouten
1609b934d09SEd Schouten len = snprintf(response, 16, "%u;%uR",
1619b934d09SEd Schouten (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1,
1629b934d09SEd Schouten t->t_cursor.tp_col + 1);
1639b934d09SEd Schouten
1649b934d09SEd Schouten if (len >= 16)
1659b934d09SEd Schouten return (-1);
1669b934d09SEd Schouten return (len);
1679b934d09SEd Schouten }
1689b934d09SEd Schouten case 15: /* Printer status. */
1699b934d09SEd Schouten strcpy(response, "13n");
1709b934d09SEd Schouten return (3);
1719b934d09SEd Schouten case 25: /* UDK status. */
1729b934d09SEd Schouten strcpy(response, "20n");
1739b934d09SEd Schouten return (3);
1749b934d09SEd Schouten case 26: /* Keyboard status. */
1759b934d09SEd Schouten strcpy(response, "27;1n");
1769b934d09SEd Schouten return (5);
1779b934d09SEd Schouten default:
1789b934d09SEd Schouten teken_printf("Unknown DSR\n");
1799b934d09SEd Schouten return (-1);
1809b934d09SEd Schouten }
1819b934d09SEd Schouten }
1829b934d09SEd Schouten
1839b934d09SEd Schouten static void
teken_subr_alignment_test(teken_t * t)1849b934d09SEd Schouten teken_subr_alignment_test(teken_t *t)
1859b934d09SEd Schouten {
1869b934d09SEd Schouten teken_rect_t tr;
1879b934d09SEd Schouten
188f311d560SEd Schouten t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
1899b934d09SEd Schouten t->t_scrollreg.ts_begin = 0;
1909b934d09SEd Schouten t->t_scrollreg.ts_end = t->t_winsize.tp_row;
191f311d560SEd Schouten t->t_originreg = t->t_scrollreg;
192f311d560SEd Schouten t->t_stateflags &= ~(TS_WRAPPED|TS_ORIGIN);
1939b934d09SEd Schouten teken_funcs_cursor(t);
1949b934d09SEd Schouten
1959b934d09SEd Schouten tr.tr_begin.tp_row = 0;
1969b934d09SEd Schouten tr.tr_begin.tp_col = 0;
1979b934d09SEd Schouten tr.tr_end = t->t_winsize;
1989b934d09SEd Schouten teken_funcs_fill(t, &tr, 'E', &t->t_defattr);
1999b934d09SEd Schouten }
2009b934d09SEd Schouten
2019b934d09SEd Schouten static void
teken_subr_backspace(teken_t * t)2029b934d09SEd Schouten teken_subr_backspace(teken_t *t)
2039b934d09SEd Schouten {
2049b934d09SEd Schouten
205eba77f5cSEd Schouten if (t->t_stateflags & TS_CONS25) {
2069b934d09SEd Schouten if (t->t_cursor.tp_col == 0) {
2079b934d09SEd Schouten if (t->t_cursor.tp_row == t->t_originreg.ts_begin)
2089b934d09SEd Schouten return;
2099b934d09SEd Schouten t->t_cursor.tp_row--;
2109b934d09SEd Schouten t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
2119b934d09SEd Schouten } else {
2129b934d09SEd Schouten t->t_cursor.tp_col--;
2139b934d09SEd Schouten }
214eba77f5cSEd Schouten } else {
215eba77f5cSEd Schouten if (t->t_cursor.tp_col == 0)
216eba77f5cSEd Schouten return;
217eba77f5cSEd Schouten
218eba77f5cSEd Schouten t->t_cursor.tp_col--;
219eba77f5cSEd Schouten t->t_stateflags &= ~TS_WRAPPED;
220eba77f5cSEd Schouten }
2219b934d09SEd Schouten
2229b934d09SEd Schouten teken_funcs_cursor(t);
2239b934d09SEd Schouten }
2249b934d09SEd Schouten
2259b934d09SEd Schouten static void
teken_subr_bell(const teken_t * t)22692223bddSPoul-Henning Kamp teken_subr_bell(const teken_t *t)
2279b934d09SEd Schouten {
2289b934d09SEd Schouten
2299b934d09SEd Schouten teken_funcs_bell(t);
2309b934d09SEd Schouten }
2319b934d09SEd Schouten
2329b934d09SEd Schouten static void
teken_subr_carriage_return(teken_t * t)2339b934d09SEd Schouten teken_subr_carriage_return(teken_t *t)
2349b934d09SEd Schouten {
2359b934d09SEd Schouten
2369b934d09SEd Schouten t->t_cursor.tp_col = 0;
2379b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
2389b934d09SEd Schouten teken_funcs_cursor(t);
2399b934d09SEd Schouten }
2409b934d09SEd Schouten
2419b934d09SEd Schouten static void
teken_subr_cursor_backward(teken_t * t,unsigned int ncols)2429b934d09SEd Schouten teken_subr_cursor_backward(teken_t *t, unsigned int ncols)
2439b934d09SEd Schouten {
2449b934d09SEd Schouten
2459b934d09SEd Schouten if (ncols > t->t_cursor.tp_col)
2469b934d09SEd Schouten t->t_cursor.tp_col = 0;
2479b934d09SEd Schouten else
2489b934d09SEd Schouten t->t_cursor.tp_col -= ncols;
2499b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
2509b934d09SEd Schouten teken_funcs_cursor(t);
2519b934d09SEd Schouten }
2529b934d09SEd Schouten
2539b934d09SEd Schouten static void
teken_subr_cursor_backward_tabulation(teken_t * t,unsigned int ntabs)2549b934d09SEd Schouten teken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs)
2559b934d09SEd Schouten {
2569b934d09SEd Schouten
2579b934d09SEd Schouten do {
2589b934d09SEd Schouten /* Stop when we've reached the beginning of the line. */
2599b934d09SEd Schouten if (t->t_cursor.tp_col == 0)
2609b934d09SEd Schouten break;
2619b934d09SEd Schouten
2629b934d09SEd Schouten t->t_cursor.tp_col--;
2639b934d09SEd Schouten
2649b934d09SEd Schouten /* Tab marker set. */
2659b934d09SEd Schouten if (teken_tab_isset(t, t->t_cursor.tp_col))
2669b934d09SEd Schouten ntabs--;
2679b934d09SEd Schouten } while (ntabs > 0);
2689b934d09SEd Schouten
2699b934d09SEd Schouten teken_funcs_cursor(t);
2709b934d09SEd Schouten }
2719b934d09SEd Schouten
2729b934d09SEd Schouten static void
teken_subr_cursor_down(teken_t * t,unsigned int nrows)2739b934d09SEd Schouten teken_subr_cursor_down(teken_t *t, unsigned int nrows)
2749b934d09SEd Schouten {
2759b934d09SEd Schouten
2769b934d09SEd Schouten if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end)
2779b934d09SEd Schouten t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
2789b934d09SEd Schouten else
2799b934d09SEd Schouten t->t_cursor.tp_row += nrows;
2809b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
2819b934d09SEd Schouten teken_funcs_cursor(t);
2829b934d09SEd Schouten }
2839b934d09SEd Schouten
2849b934d09SEd Schouten static void
teken_subr_cursor_forward(teken_t * t,unsigned int ncols)2859b934d09SEd Schouten teken_subr_cursor_forward(teken_t *t, unsigned int ncols)
2869b934d09SEd Schouten {
2879b934d09SEd Schouten
2889b934d09SEd Schouten if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
2899b934d09SEd Schouten t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
2909b934d09SEd Schouten else
2919b934d09SEd Schouten t->t_cursor.tp_col += ncols;
2929b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
2939b934d09SEd Schouten teken_funcs_cursor(t);
2949b934d09SEd Schouten }
2959b934d09SEd Schouten
2969b934d09SEd Schouten static void
teken_subr_cursor_forward_tabulation(teken_t * t,unsigned int ntabs)2979b934d09SEd Schouten teken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs)
2989b934d09SEd Schouten {
2999b934d09SEd Schouten
3009b934d09SEd Schouten do {
3019b934d09SEd Schouten /* Stop when we've reached the end of the line. */
3029b934d09SEd Schouten if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1)
3039b934d09SEd Schouten break;
3049b934d09SEd Schouten
3059b934d09SEd Schouten t->t_cursor.tp_col++;
3069b934d09SEd Schouten
3079b934d09SEd Schouten /* Tab marker set. */
3089b934d09SEd Schouten if (teken_tab_isset(t, t->t_cursor.tp_col))
3099b934d09SEd Schouten ntabs--;
3109b934d09SEd Schouten } while (ntabs > 0);
3119b934d09SEd Schouten
3129b934d09SEd Schouten teken_funcs_cursor(t);
3139b934d09SEd Schouten }
3149b934d09SEd Schouten
3159b934d09SEd Schouten static void
teken_subr_cursor_next_line(teken_t * t,unsigned int ncols)3169b934d09SEd Schouten teken_subr_cursor_next_line(teken_t *t, unsigned int ncols)
3179b934d09SEd Schouten {
3189b934d09SEd Schouten
3199b934d09SEd Schouten t->t_cursor.tp_col = 0;
3209b934d09SEd Schouten teken_subr_cursor_down(t, ncols);
3219b934d09SEd Schouten }
3229b934d09SEd Schouten
3239b934d09SEd Schouten static void
teken_subr_cursor_position(teken_t * t,unsigned int row,unsigned int col)3249b934d09SEd Schouten teken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col)
3259b934d09SEd Schouten {
3269b934d09SEd Schouten
32792223bddSPoul-Henning Kamp row = (row - 1) + t->t_originreg.ts_begin;
3289a71fa37SEd Schouten t->t_cursor.tp_row = row < t->t_originreg.ts_end ?
3299a71fa37SEd Schouten row : t->t_originreg.ts_end - 1;
3309b934d09SEd Schouten
3319a71fa37SEd Schouten col--;
3329a71fa37SEd Schouten t->t_cursor.tp_col = col < t->t_winsize.tp_col ?
3339a71fa37SEd Schouten col : t->t_winsize.tp_col - 1;
3349b934d09SEd Schouten
3359b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
3369b934d09SEd Schouten teken_funcs_cursor(t);
3379b934d09SEd Schouten }
3389b934d09SEd Schouten
3399b934d09SEd Schouten static void
teken_subr_cursor_position_report(const teken_t * t,unsigned int cmd)34092223bddSPoul-Henning Kamp teken_subr_cursor_position_report(const teken_t *t, unsigned int cmd)
3419b934d09SEd Schouten {
3429b934d09SEd Schouten char response[18] = "\x1B[";
3439b934d09SEd Schouten ssize_t len;
3449b934d09SEd Schouten
3459b934d09SEd Schouten len = teken_subr_do_cpr(t, cmd, response + 2);
3469b934d09SEd Schouten if (len < 0)
3479b934d09SEd Schouten return;
3489b934d09SEd Schouten
3499b934d09SEd Schouten teken_funcs_respond(t, response, len + 2);
3509b934d09SEd Schouten }
3519b934d09SEd Schouten
3529b934d09SEd Schouten static void
teken_subr_cursor_previous_line(teken_t * t,unsigned int ncols)3539b934d09SEd Schouten teken_subr_cursor_previous_line(teken_t *t, unsigned int ncols)
3549b934d09SEd Schouten {
3559b934d09SEd Schouten
3569b934d09SEd Schouten t->t_cursor.tp_col = 0;
3579b934d09SEd Schouten teken_subr_cursor_up(t, ncols);
3589b934d09SEd Schouten }
3599b934d09SEd Schouten
3609b934d09SEd Schouten static void
teken_subr_cursor_up(teken_t * t,unsigned int nrows)3619b934d09SEd Schouten teken_subr_cursor_up(teken_t *t, unsigned int nrows)
3629b934d09SEd Schouten {
3639b934d09SEd Schouten
3649b934d09SEd Schouten if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row)
3659b934d09SEd Schouten t->t_cursor.tp_row = t->t_scrollreg.ts_begin;
3669b934d09SEd Schouten else
3679b934d09SEd Schouten t->t_cursor.tp_row -= nrows;
3689b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
3699b934d09SEd Schouten teken_funcs_cursor(t);
3709b934d09SEd Schouten }
3719b934d09SEd Schouten
3729b934d09SEd Schouten static void
teken_subr_set_cursor_style(teken_t * t __unused,unsigned int style __unused)3737c27c925SEd Schouten teken_subr_set_cursor_style(teken_t *t __unused, unsigned int style __unused)
3748dcd2ed3SJean-Sébastien Pédron {
3758dcd2ed3SJean-Sébastien Pédron
3768dcd2ed3SJean-Sébastien Pédron /* TODO */
3778dcd2ed3SJean-Sébastien Pédron
3788dcd2ed3SJean-Sébastien Pédron /*
3798dcd2ed3SJean-Sébastien Pédron * CSI Ps SP q
3808dcd2ed3SJean-Sébastien Pédron * Set cursor style (DECSCUSR), VT520.
3818dcd2ed3SJean-Sébastien Pédron * Ps = 0 -> blinking block.
3828dcd2ed3SJean-Sébastien Pédron * Ps = 1 -> blinking block (default).
3838dcd2ed3SJean-Sébastien Pédron * Ps = 2 -> steady block.
3848dcd2ed3SJean-Sébastien Pédron * Ps = 3 -> blinking underline.
3858dcd2ed3SJean-Sébastien Pédron * Ps = 4 -> steady underline.
3868dcd2ed3SJean-Sébastien Pédron * Ps = 5 -> blinking bar (xterm).
3878dcd2ed3SJean-Sébastien Pédron * Ps = 6 -> steady bar (xterm).
3888dcd2ed3SJean-Sébastien Pédron */
3898dcd2ed3SJean-Sébastien Pédron }
3908dcd2ed3SJean-Sébastien Pédron
3918dcd2ed3SJean-Sébastien Pédron static void
teken_subr_delete_character(const teken_t * t,unsigned int ncols)39292223bddSPoul-Henning Kamp teken_subr_delete_character(const teken_t *t, unsigned int ncols)
3939b934d09SEd Schouten {
3949b934d09SEd Schouten teken_rect_t tr;
3959b934d09SEd Schouten
3969b934d09SEd Schouten tr.tr_begin.tp_row = t->t_cursor.tp_row;
3979b934d09SEd Schouten tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
3989b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
3999b934d09SEd Schouten
4009b934d09SEd Schouten if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
4019b934d09SEd Schouten tr.tr_begin.tp_col = t->t_cursor.tp_col;
4029b934d09SEd Schouten } else {
4039b934d09SEd Schouten /* Copy characters to the left. */
4049b934d09SEd Schouten tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols;
4059b934d09SEd Schouten teken_funcs_copy(t, &tr, &t->t_cursor);
4069b934d09SEd Schouten
4079b934d09SEd Schouten tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols;
4089b934d09SEd Schouten }
4099b934d09SEd Schouten
4109b934d09SEd Schouten /* Blank trailing columns. */
4119b934d09SEd Schouten teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
4129b934d09SEd Schouten }
4139b934d09SEd Schouten
4149b934d09SEd Schouten static void
teken_subr_delete_line(const teken_t * t,unsigned int nrows)41592223bddSPoul-Henning Kamp teken_subr_delete_line(const teken_t *t, unsigned int nrows)
4169b934d09SEd Schouten {
4179b934d09SEd Schouten teken_rect_t tr;
4189b934d09SEd Schouten
419c56bcdbbSEd Schouten /* Ignore if outside scrolling region. */
420c56bcdbbSEd Schouten if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin ||
421c56bcdbbSEd Schouten t->t_cursor.tp_row >= t->t_scrollreg.ts_end)
422c56bcdbbSEd Schouten return;
423c56bcdbbSEd Schouten
4249b934d09SEd Schouten tr.tr_begin.tp_col = 0;
4259b934d09SEd Schouten tr.tr_end.tp_row = t->t_scrollreg.ts_end;
4269b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
4279b934d09SEd Schouten
4289b934d09SEd Schouten if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
4299b934d09SEd Schouten tr.tr_begin.tp_row = t->t_cursor.tp_row;
4309b934d09SEd Schouten } else {
4319b934d09SEd Schouten teken_pos_t tp;
4329b934d09SEd Schouten
4339b934d09SEd Schouten /* Copy rows up. */
4349b934d09SEd Schouten tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows;
4359b934d09SEd Schouten tp.tp_row = t->t_cursor.tp_row;
4369b934d09SEd Schouten tp.tp_col = 0;
4379b934d09SEd Schouten teken_funcs_copy(t, &tr, &tp);
4389b934d09SEd Schouten
4399b934d09SEd Schouten tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows;
4409b934d09SEd Schouten }
4419b934d09SEd Schouten
4429b934d09SEd Schouten /* Blank trailing rows. */
4439b934d09SEd Schouten teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
4449b934d09SEd Schouten }
4459b934d09SEd Schouten
4469b934d09SEd Schouten static void
teken_subr_device_control_string(teken_t * t)4474a11e7f1SEd Schouten teken_subr_device_control_string(teken_t *t)
4489b934d09SEd Schouten {
4499b934d09SEd Schouten
4504a11e7f1SEd Schouten teken_printf("Unsupported device control string\n");
4514a11e7f1SEd Schouten t->t_stateflags |= TS_INSTRING;
4529b934d09SEd Schouten }
4539b934d09SEd Schouten
4549b934d09SEd Schouten static void
teken_subr_device_status_report(const teken_t * t,unsigned int cmd)45592223bddSPoul-Henning Kamp teken_subr_device_status_report(const teken_t *t, unsigned int cmd)
4569b934d09SEd Schouten {
4579b934d09SEd Schouten char response[19] = "\x1B[?";
4589b934d09SEd Schouten ssize_t len;
4599b934d09SEd Schouten
4609b934d09SEd Schouten len = teken_subr_do_cpr(t, cmd, response + 3);
4619b934d09SEd Schouten if (len < 0)
4629b934d09SEd Schouten return;
4639b934d09SEd Schouten
4649b934d09SEd Schouten teken_funcs_respond(t, response, len + 3);
4659b934d09SEd Schouten }
4669b934d09SEd Schouten
4679b934d09SEd Schouten static void
teken_subr_double_height_double_width_line_top(const teken_t * t)46892223bddSPoul-Henning Kamp teken_subr_double_height_double_width_line_top(const teken_t *t)
4699b934d09SEd Schouten {
4709b934d09SEd Schouten
47192223bddSPoul-Henning Kamp (void)t;
4729b934d09SEd Schouten teken_printf("double height double width top\n");
4739b934d09SEd Schouten }
4749b934d09SEd Schouten
4759b934d09SEd Schouten static void
teken_subr_double_height_double_width_line_bottom(const teken_t * t)47692223bddSPoul-Henning Kamp teken_subr_double_height_double_width_line_bottom(const teken_t *t)
4779b934d09SEd Schouten {
4789b934d09SEd Schouten
47992223bddSPoul-Henning Kamp (void)t;
4809b934d09SEd Schouten teken_printf("double height double width bottom\n");
4819b934d09SEd Schouten }
4829b934d09SEd Schouten
4839b934d09SEd Schouten static void
teken_subr_erase_character(const teken_t * t,unsigned int ncols)48492223bddSPoul-Henning Kamp teken_subr_erase_character(const teken_t *t, unsigned int ncols)
4859b934d09SEd Schouten {
4869b934d09SEd Schouten teken_rect_t tr;
4879b934d09SEd Schouten
4889b934d09SEd Schouten tr.tr_begin = t->t_cursor;
4899b934d09SEd Schouten tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
4909b934d09SEd Schouten
4919b934d09SEd Schouten if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
4929b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
4939b934d09SEd Schouten else
4949b934d09SEd Schouten tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
4959b934d09SEd Schouten
4969b934d09SEd Schouten teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
4979b934d09SEd Schouten }
4989b934d09SEd Schouten
4999b934d09SEd Schouten static void
teken_subr_erase_display(const teken_t * t,unsigned int mode)50092223bddSPoul-Henning Kamp teken_subr_erase_display(const teken_t *t, unsigned int mode)
5019b934d09SEd Schouten {
5029b934d09SEd Schouten teken_rect_t r;
5039b934d09SEd Schouten
5049b934d09SEd Schouten r.tr_begin.tp_col = 0;
5059b934d09SEd Schouten r.tr_end.tp_col = t->t_winsize.tp_col;
5069b934d09SEd Schouten
5079b934d09SEd Schouten switch (mode) {
5089b934d09SEd Schouten case 1: /* Erase from the top to the cursor. */
5099b934d09SEd Schouten teken_subr_erase_line(t, 1);
5109b934d09SEd Schouten
5119b934d09SEd Schouten /* Erase lines above. */
5129b934d09SEd Schouten if (t->t_cursor.tp_row == 0)
5139b934d09SEd Schouten return;
5149b934d09SEd Schouten r.tr_begin.tp_row = 0;
5159b934d09SEd Schouten r.tr_end.tp_row = t->t_cursor.tp_row;
5169b934d09SEd Schouten break;
5179b934d09SEd Schouten case 2: /* Erase entire display. */
5189b934d09SEd Schouten r.tr_begin.tp_row = 0;
5199b934d09SEd Schouten r.tr_end.tp_row = t->t_winsize.tp_row;
5209b934d09SEd Schouten break;
5219b934d09SEd Schouten default: /* Erase from cursor to the bottom. */
5229b934d09SEd Schouten teken_subr_erase_line(t, 0);
5239b934d09SEd Schouten
5249b934d09SEd Schouten /* Erase lines below. */
5259b934d09SEd Schouten if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1)
5269b934d09SEd Schouten return;
5279b934d09SEd Schouten r.tr_begin.tp_row = t->t_cursor.tp_row + 1;
5289b934d09SEd Schouten r.tr_end.tp_row = t->t_winsize.tp_row;
5299b934d09SEd Schouten break;
5309b934d09SEd Schouten }
5319b934d09SEd Schouten
5329b934d09SEd Schouten teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
5339b934d09SEd Schouten }
5349b934d09SEd Schouten
5359b934d09SEd Schouten static void
teken_subr_erase_line(const teken_t * t,unsigned int mode)53692223bddSPoul-Henning Kamp teken_subr_erase_line(const teken_t *t, unsigned int mode)
5379b934d09SEd Schouten {
5389b934d09SEd Schouten teken_rect_t r;
5399b934d09SEd Schouten
5409b934d09SEd Schouten r.tr_begin.tp_row = t->t_cursor.tp_row;
5419b934d09SEd Schouten r.tr_end.tp_row = t->t_cursor.tp_row + 1;
5429b934d09SEd Schouten
5439b934d09SEd Schouten switch (mode) {
5449b934d09SEd Schouten case 1: /* Erase from the beginning of the line to the cursor. */
5459b934d09SEd Schouten r.tr_begin.tp_col = 0;
5469b934d09SEd Schouten r.tr_end.tp_col = t->t_cursor.tp_col + 1;
5479b934d09SEd Schouten break;
5489b934d09SEd Schouten case 2: /* Erase entire line. */
5499b934d09SEd Schouten r.tr_begin.tp_col = 0;
5509b934d09SEd Schouten r.tr_end.tp_col = t->t_winsize.tp_col;
5519b934d09SEd Schouten break;
5529b934d09SEd Schouten default: /* Erase from cursor to the end of the line. */
5539b934d09SEd Schouten r.tr_begin.tp_col = t->t_cursor.tp_col;
5549b934d09SEd Schouten r.tr_end.tp_col = t->t_winsize.tp_col;
5559b934d09SEd Schouten break;
5569b934d09SEd Schouten }
5579b934d09SEd Schouten
5589b934d09SEd Schouten teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
5599b934d09SEd Schouten }
5609b934d09SEd Schouten
5619b934d09SEd Schouten static void
teken_subr_g0_scs_special_graphics(teken_t * t)56292223bddSPoul-Henning Kamp teken_subr_g0_scs_special_graphics(teken_t *t)
5639b934d09SEd Schouten {
5649b934d09SEd Schouten
565cd531e74SEd Schouten t->t_scs[0] = teken_scs_special_graphics;
5669b934d09SEd Schouten }
5679b934d09SEd Schouten
5689b934d09SEd Schouten static void
teken_subr_g0_scs_uk_national(teken_t * t)56992223bddSPoul-Henning Kamp teken_subr_g0_scs_uk_national(teken_t *t)
5709b934d09SEd Schouten {
5719b934d09SEd Schouten
572cd531e74SEd Schouten t->t_scs[0] = teken_scs_uk_national;
5739b934d09SEd Schouten }
5749b934d09SEd Schouten
5759b934d09SEd Schouten static void
teken_subr_g0_scs_us_ascii(teken_t * t)57692223bddSPoul-Henning Kamp teken_subr_g0_scs_us_ascii(teken_t *t)
5779b934d09SEd Schouten {
5789b934d09SEd Schouten
579cd531e74SEd Schouten t->t_scs[0] = teken_scs_us_ascii;
5809b934d09SEd Schouten }
5819b934d09SEd Schouten
5829b934d09SEd Schouten static void
teken_subr_g1_scs_special_graphics(teken_t * t)58392223bddSPoul-Henning Kamp teken_subr_g1_scs_special_graphics(teken_t *t)
5849b934d09SEd Schouten {
5859b934d09SEd Schouten
586cd531e74SEd Schouten t->t_scs[1] = teken_scs_special_graphics;
5879b934d09SEd Schouten }
5889b934d09SEd Schouten
5899b934d09SEd Schouten static void
teken_subr_g1_scs_uk_national(teken_t * t)59092223bddSPoul-Henning Kamp teken_subr_g1_scs_uk_national(teken_t *t)
5919b934d09SEd Schouten {
5929b934d09SEd Schouten
593cd531e74SEd Schouten t->t_scs[1] = teken_scs_uk_national;
5949b934d09SEd Schouten }
5959b934d09SEd Schouten
5969b934d09SEd Schouten static void
teken_subr_g1_scs_us_ascii(teken_t * t)59792223bddSPoul-Henning Kamp teken_subr_g1_scs_us_ascii(teken_t *t)
5989b934d09SEd Schouten {
5999b934d09SEd Schouten
600cd531e74SEd Schouten t->t_scs[1] = teken_scs_us_ascii;
6019b934d09SEd Schouten }
6029b934d09SEd Schouten
6039b934d09SEd Schouten static void
teken_subr_horizontal_position_absolute(teken_t * t,unsigned int col)6049b934d09SEd Schouten teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col)
6059b934d09SEd Schouten {
6069b934d09SEd Schouten
607b8d356b3SEd Schouten col--;
608b8d356b3SEd Schouten t->t_cursor.tp_col = col < t->t_winsize.tp_col ?
609b8d356b3SEd Schouten col : t->t_winsize.tp_col - 1;
6109b934d09SEd Schouten
6119b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
6129b934d09SEd Schouten teken_funcs_cursor(t);
6139b934d09SEd Schouten }
6149b934d09SEd Schouten
6159b934d09SEd Schouten static void
teken_subr_horizontal_tab(teken_t * t)6169b934d09SEd Schouten teken_subr_horizontal_tab(teken_t *t)
6179b934d09SEd Schouten {
618eba77f5cSEd Schouten
619eba77f5cSEd Schouten teken_subr_cursor_forward_tabulation(t, 1);
6209b934d09SEd Schouten }
6219b934d09SEd Schouten
6229b934d09SEd Schouten static void
teken_subr_horizontal_tab_set(teken_t * t)6239b934d09SEd Schouten teken_subr_horizontal_tab_set(teken_t *t)
6249b934d09SEd Schouten {
6259b934d09SEd Schouten
6269b934d09SEd Schouten teken_tab_set(t, t->t_cursor.tp_col);
6279b934d09SEd Schouten }
6289b934d09SEd Schouten
6299b934d09SEd Schouten static void
teken_subr_index(teken_t * t)6309b934d09SEd Schouten teken_subr_index(teken_t *t)
6319b934d09SEd Schouten {
6329b934d09SEd Schouten
6339b934d09SEd Schouten if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) {
6349b934d09SEd Schouten t->t_cursor.tp_row++;
6359b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
6369b934d09SEd Schouten teken_funcs_cursor(t);
6379b934d09SEd Schouten } else {
6389b934d09SEd Schouten teken_subr_do_scroll(t, 1);
6399b934d09SEd Schouten }
6409b934d09SEd Schouten }
6419b934d09SEd Schouten
6429b934d09SEd Schouten static void
teken_subr_insert_character(const teken_t * t,unsigned int ncols)64392223bddSPoul-Henning Kamp teken_subr_insert_character(const teken_t *t, unsigned int ncols)
6449b934d09SEd Schouten {
6459b934d09SEd Schouten teken_rect_t tr;
6469b934d09SEd Schouten
6479b934d09SEd Schouten tr.tr_begin = t->t_cursor;
6489b934d09SEd Schouten tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
6499b934d09SEd Schouten
6509b934d09SEd Schouten if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
6519b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
6529b934d09SEd Schouten } else {
6539b934d09SEd Schouten teken_pos_t tp;
6549b934d09SEd Schouten
6559b934d09SEd Schouten /* Copy characters to the right. */
6569b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col - ncols;
6579b934d09SEd Schouten tp.tp_row = t->t_cursor.tp_row;
6589b934d09SEd Schouten tp.tp_col = t->t_cursor.tp_col + ncols;
6599b934d09SEd Schouten teken_funcs_copy(t, &tr, &tp);
6609b934d09SEd Schouten
6619b934d09SEd Schouten tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
6629b934d09SEd Schouten }
6639b934d09SEd Schouten
6649b934d09SEd Schouten /* Blank current location. */
6659b934d09SEd Schouten teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
6669b934d09SEd Schouten }
6679b934d09SEd Schouten
6689b934d09SEd Schouten static void
teken_subr_insert_line(const teken_t * t,unsigned int nrows)66992223bddSPoul-Henning Kamp teken_subr_insert_line(const teken_t *t, unsigned int nrows)
6709b934d09SEd Schouten {
6719b934d09SEd Schouten teken_rect_t tr;
6729b934d09SEd Schouten
673c56bcdbbSEd Schouten /* Ignore if outside scrolling region. */
674c56bcdbbSEd Schouten if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin ||
675c56bcdbbSEd Schouten t->t_cursor.tp_row >= t->t_scrollreg.ts_end)
676c56bcdbbSEd Schouten return;
677c56bcdbbSEd Schouten
6789b934d09SEd Schouten tr.tr_begin.tp_row = t->t_cursor.tp_row;
6799b934d09SEd Schouten tr.tr_begin.tp_col = 0;
6809b934d09SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
6819b934d09SEd Schouten
6829b934d09SEd Schouten if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
6839b934d09SEd Schouten tr.tr_end.tp_row = t->t_scrollreg.ts_end;
6849b934d09SEd Schouten } else {
6859b934d09SEd Schouten teken_pos_t tp;
6869b934d09SEd Schouten
6879b934d09SEd Schouten /* Copy lines down. */
6889b934d09SEd Schouten tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows;
6899b934d09SEd Schouten tp.tp_row = t->t_cursor.tp_row + nrows;
6909b934d09SEd Schouten tp.tp_col = 0;
6919b934d09SEd Schouten teken_funcs_copy(t, &tr, &tp);
6929b934d09SEd Schouten
6939b934d09SEd Schouten tr.tr_end.tp_row = t->t_cursor.tp_row + nrows;
6949b934d09SEd Schouten }
6959b934d09SEd Schouten
6969b934d09SEd Schouten /* Blank current location. */
6979b934d09SEd Schouten teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
6989b934d09SEd Schouten }
6999b934d09SEd Schouten
7009b934d09SEd Schouten static void
teken_subr_keypad_application_mode(const teken_t * t)70192223bddSPoul-Henning Kamp teken_subr_keypad_application_mode(const teken_t *t)
7029b934d09SEd Schouten {
7039b934d09SEd Schouten
7049b934d09SEd Schouten teken_funcs_param(t, TP_KEYPADAPP, 1);
7059b934d09SEd Schouten }
7069b934d09SEd Schouten
7079b934d09SEd Schouten static void
teken_subr_keypad_numeric_mode(const teken_t * t)70892223bddSPoul-Henning Kamp teken_subr_keypad_numeric_mode(const teken_t *t)
7099b934d09SEd Schouten {
7109b934d09SEd Schouten
7119b934d09SEd Schouten teken_funcs_param(t, TP_KEYPADAPP, 0);
7129b934d09SEd Schouten }
7139b934d09SEd Schouten
7149b934d09SEd Schouten static void
teken_subr_newline(teken_t * t)7159b934d09SEd Schouten teken_subr_newline(teken_t *t)
7169b934d09SEd Schouten {
7179b934d09SEd Schouten
7189b934d09SEd Schouten t->t_cursor.tp_row++;
7199b934d09SEd Schouten
7209b934d09SEd Schouten if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) {
7219b934d09SEd Schouten teken_subr_do_scroll(t, 1);
7229b934d09SEd Schouten t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
7239b934d09SEd Schouten }
7249b934d09SEd Schouten
7259b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
7269b934d09SEd Schouten teken_funcs_cursor(t);
7279b934d09SEd Schouten }
7289b934d09SEd Schouten
7299b934d09SEd Schouten static void
teken_subr_newpage(teken_t * t)7309b934d09SEd Schouten teken_subr_newpage(teken_t *t)
7319b934d09SEd Schouten {
7329b934d09SEd Schouten
733eba77f5cSEd Schouten if (t->t_stateflags & TS_CONS25) {
7349b934d09SEd Schouten teken_rect_t tr;
7359b934d09SEd Schouten
7360abe3145SEd Schouten /* Clear screen. */
7370abe3145SEd Schouten tr.tr_begin.tp_row = t->t_originreg.ts_begin;
7380abe3145SEd Schouten tr.tr_begin.tp_col = 0;
7390abe3145SEd Schouten tr.tr_end.tp_row = t->t_originreg.ts_end;
7400abe3145SEd Schouten tr.tr_end.tp_col = t->t_winsize.tp_col;
7419b934d09SEd Schouten teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
7429b934d09SEd Schouten
7430abe3145SEd Schouten /* Cursor at top left. */
7440abe3145SEd Schouten t->t_cursor.tp_row = t->t_originreg.ts_begin;
7450abe3145SEd Schouten t->t_cursor.tp_col = 0;
7460abe3145SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
7479b934d09SEd Schouten teken_funcs_cursor(t);
748eba77f5cSEd Schouten } else {
749eba77f5cSEd Schouten teken_subr_newline(t);
750eba77f5cSEd Schouten }
7519b934d09SEd Schouten }
7529b934d09SEd Schouten
7539b934d09SEd Schouten static void
teken_subr_next_line(teken_t * t)7549b934d09SEd Schouten teken_subr_next_line(teken_t *t)
7559b934d09SEd Schouten {
7569b934d09SEd Schouten
7579b934d09SEd Schouten t->t_cursor.tp_col = 0;
7589b934d09SEd Schouten teken_subr_newline(t);
7599b934d09SEd Schouten }
7609b934d09SEd Schouten
7619b934d09SEd Schouten static void
teken_subr_operating_system_command(teken_t * t)7624a11e7f1SEd Schouten teken_subr_operating_system_command(teken_t *t)
7634a11e7f1SEd Schouten {
7644a11e7f1SEd Schouten
7654a11e7f1SEd Schouten teken_printf("Unsupported operating system command\n");
7664a11e7f1SEd Schouten t->t_stateflags |= TS_INSTRING;
7674a11e7f1SEd Schouten }
7684a11e7f1SEd Schouten
7694a11e7f1SEd Schouten static void
teken_subr_pan_down(const teken_t * t,unsigned int nrows)77092223bddSPoul-Henning Kamp teken_subr_pan_down(const teken_t *t, unsigned int nrows)
7719b934d09SEd Schouten {
7729b934d09SEd Schouten
7739b934d09SEd Schouten teken_subr_do_scroll(t, (int)nrows);
7749b934d09SEd Schouten }
7759b934d09SEd Schouten
7769b934d09SEd Schouten static void
teken_subr_pan_up(const teken_t * t,unsigned int nrows)77792223bddSPoul-Henning Kamp teken_subr_pan_up(const teken_t *t, unsigned int nrows)
7789b934d09SEd Schouten {
7799b934d09SEd Schouten
7809b934d09SEd Schouten teken_subr_do_scroll(t, -(int)nrows);
7819b934d09SEd Schouten }
7829b934d09SEd Schouten
7839b934d09SEd Schouten static void
teken_subr_primary_device_attributes(const teken_t * t,unsigned int request)78492223bddSPoul-Henning Kamp teken_subr_primary_device_attributes(const teken_t *t, unsigned int request)
7859b934d09SEd Schouten {
7869b934d09SEd Schouten
7879b934d09SEd Schouten if (request == 0) {
7889b934d09SEd Schouten const char response[] = "\x1B[?1;2c";
7899b934d09SEd Schouten
7909b934d09SEd Schouten teken_funcs_respond(t, response, sizeof response - 1);
7919b934d09SEd Schouten } else {
7929b934d09SEd Schouten teken_printf("Unknown DA1\n");
7939b934d09SEd Schouten }
7949b934d09SEd Schouten }
7959b934d09SEd Schouten
7969b934d09SEd Schouten static void
teken_subr_do_putchar(teken_t * t,const teken_pos_t * tp,teken_char_t c,int width)7973eb27bf0SPoul-Henning Kamp teken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c,
7989b934d09SEd Schouten int width)
7999b934d09SEd Schouten {
8009b934d09SEd Schouten
8013eb27bf0SPoul-Henning Kamp t->t_last = c;
8029b934d09SEd Schouten if (t->t_stateflags & TS_INSERT &&
8039b934d09SEd Schouten tp->tp_col < t->t_winsize.tp_col - width) {
8049b934d09SEd Schouten teken_rect_t ctr;
8059b934d09SEd Schouten teken_pos_t ctp;
8069b934d09SEd Schouten
8079b934d09SEd Schouten /* Insert mode. Move existing characters to the right. */
8089b934d09SEd Schouten ctr.tr_begin = *tp;
8099b934d09SEd Schouten ctr.tr_end.tp_row = tp->tp_row + 1;
8109b934d09SEd Schouten ctr.tr_end.tp_col = t->t_winsize.tp_col - width;
8119b934d09SEd Schouten ctp.tp_row = tp->tp_row;
8129b934d09SEd Schouten ctp.tp_col = tp->tp_col + width;
8139b934d09SEd Schouten teken_funcs_copy(t, &ctr, &ctp);
8149b934d09SEd Schouten }
8159b934d09SEd Schouten
816a6c26592SEd Schouten teken_funcs_putchar(t, tp, c, &t->t_curattr);
817a6c26592SEd Schouten
818eba77f5cSEd Schouten if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) {
819eba77f5cSEd Schouten teken_pos_t tp2;
820a6c26592SEd Schouten teken_attr_t attr;
821eba77f5cSEd Schouten
822a6c26592SEd Schouten /* Print second half of CJK fullwidth character. */
823eba77f5cSEd Schouten tp2.tp_row = tp->tp_row;
824eba77f5cSEd Schouten tp2.tp_col = tp->tp_col + 1;
825a6c26592SEd Schouten attr = t->t_curattr;
826a6c26592SEd Schouten attr.ta_format |= TF_CJK_RIGHT;
827a6c26592SEd Schouten teken_funcs_putchar(t, &tp2, c, &attr);
828eba77f5cSEd Schouten }
8299b934d09SEd Schouten }
8309b934d09SEd Schouten
8319b934d09SEd Schouten static void
teken_subr_regular_character(teken_t * t,teken_char_t c)8329b934d09SEd Schouten teken_subr_regular_character(teken_t *t, teken_char_t c)
8339b934d09SEd Schouten {
8349b934d09SEd Schouten int width;
8359b934d09SEd Schouten
836eba77f5cSEd Schouten if (t->t_stateflags & TS_8BIT) {
837fbcd1b6eSEd Schouten if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f))
838e06d84fcSEd Schouten return;
839fbcd1b6eSEd Schouten c = teken_scs_process(t, c);
840e06d84fcSEd Schouten width = 1;
841e06d84fcSEd Schouten } else {
8429b934d09SEd Schouten c = teken_scs_process(t, c);
8439b934d09SEd Schouten width = teken_wcwidth(c);
844e06d84fcSEd Schouten /* XXX: Don't process zero-width characters yet. */
8459b934d09SEd Schouten if (width <= 0)
8469b934d09SEd Schouten return;
847e06d84fcSEd Schouten }
8489b934d09SEd Schouten
849eba77f5cSEd Schouten if (t->t_stateflags & TS_CONS25) {
850eba77f5cSEd Schouten teken_subr_do_putchar(t, &t->t_cursor, c, width);
851eba77f5cSEd Schouten t->t_cursor.tp_col += width;
852eba77f5cSEd Schouten
853eba77f5cSEd Schouten if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
854eba77f5cSEd Schouten if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
855eba77f5cSEd Schouten /* Perform scrolling. */
856eba77f5cSEd Schouten teken_subr_do_scroll(t, 1);
857eba77f5cSEd Schouten } else {
858eba77f5cSEd Schouten /* No scrolling needed. */
859eba77f5cSEd Schouten if (t->t_cursor.tp_row <
860eba77f5cSEd Schouten t->t_winsize.tp_row - 1)
861eba77f5cSEd Schouten t->t_cursor.tp_row++;
862eba77f5cSEd Schouten }
863eba77f5cSEd Schouten t->t_cursor.tp_col = 0;
864eba77f5cSEd Schouten }
86567f2a03aSEd Schouten } else if (t->t_stateflags & TS_AUTOWRAP &&
86667f2a03aSEd Schouten ((t->t_stateflags & TS_WRAPPED &&
86767f2a03aSEd Schouten t->t_cursor.tp_col + 1 == t->t_winsize.tp_col) ||
86867f2a03aSEd Schouten t->t_cursor.tp_col + width > t->t_winsize.tp_col)) {
8699b934d09SEd Schouten teken_pos_t tp;
8709b934d09SEd Schouten
87167f2a03aSEd Schouten /*
87267f2a03aSEd Schouten * Perform line wrapping, if:
87367f2a03aSEd Schouten * - Autowrapping is enabled, and
87467f2a03aSEd Schouten * - We're in the wrapped state at the last column, or
87567f2a03aSEd Schouten * - The character to be printed does not fit anymore.
87667f2a03aSEd Schouten */
8779b934d09SEd Schouten if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
8789b934d09SEd Schouten /* Perform scrolling. */
8799b934d09SEd Schouten teken_subr_do_scroll(t, 1);
8809b934d09SEd Schouten tp.tp_row = t->t_scrollreg.ts_end - 1;
8819b934d09SEd Schouten } else {
8829b934d09SEd Schouten /* No scrolling needed. */
8839b934d09SEd Schouten tp.tp_row = t->t_cursor.tp_row + 1;
8849b934d09SEd Schouten if (tp.tp_row == t->t_winsize.tp_row) {
8859b934d09SEd Schouten /*
8869b934d09SEd Schouten * Corner case: regular character
8879b934d09SEd Schouten * outside scrolling region, but at the
8889b934d09SEd Schouten * bottom of the screen.
8899b934d09SEd Schouten */
8909b934d09SEd Schouten teken_subr_do_putchar(t, &t->t_cursor,
8919b934d09SEd Schouten c, width);
8929b934d09SEd Schouten return;
8939b934d09SEd Schouten }
8949b934d09SEd Schouten }
8959b934d09SEd Schouten
8969b934d09SEd Schouten tp.tp_col = 0;
8979b934d09SEd Schouten teken_subr_do_putchar(t, &tp, c, width);
8989b934d09SEd Schouten
8999b934d09SEd Schouten t->t_cursor.tp_row = tp.tp_row;
9009b934d09SEd Schouten t->t_cursor.tp_col = width;
9019b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
9029b934d09SEd Schouten } else {
9039b934d09SEd Schouten /* No line wrapping needed. */
9049b934d09SEd Schouten teken_subr_do_putchar(t, &t->t_cursor, c, width);
9059b934d09SEd Schouten t->t_cursor.tp_col += width;
9069b934d09SEd Schouten
9079b934d09SEd Schouten if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
9089b934d09SEd Schouten t->t_stateflags |= TS_WRAPPED;
9099b934d09SEd Schouten t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
9109b934d09SEd Schouten } else {
9119b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
9129b934d09SEd Schouten }
9139b934d09SEd Schouten }
9149b934d09SEd Schouten
9159b934d09SEd Schouten teken_funcs_cursor(t);
9169b934d09SEd Schouten }
9179b934d09SEd Schouten
9189b934d09SEd Schouten static void
teken_subr_reset_dec_mode(teken_t * t,unsigned int cmd)9199b934d09SEd Schouten teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd)
9209b934d09SEd Schouten {
9219b934d09SEd Schouten
9229b934d09SEd Schouten switch (cmd) {
9239b934d09SEd Schouten case 1: /* Cursor keys mode. */
9243a8a07eaSEd Schouten t->t_stateflags &= ~TS_CURSORKEYS;
9259b934d09SEd Schouten break;
9269b934d09SEd Schouten case 2: /* DECANM: ANSI/VT52 mode. */
9279b934d09SEd Schouten teken_printf("DECRST VT52\n");
9289b934d09SEd Schouten break;
9299b934d09SEd Schouten case 3: /* 132 column mode. */
9309b934d09SEd Schouten teken_funcs_param(t, TP_132COLS, 0);
9319b934d09SEd Schouten teken_subr_reset_to_initial_state(t);
9329b934d09SEd Schouten break;
9339b934d09SEd Schouten case 5: /* Inverse video. */
9349b934d09SEd Schouten teken_printf("DECRST inverse video\n");
9359b934d09SEd Schouten break;
9369b934d09SEd Schouten case 6: /* Origin mode. */
9379b934d09SEd Schouten t->t_stateflags &= ~TS_ORIGIN;
9389b934d09SEd Schouten t->t_originreg.ts_begin = 0;
9399b934d09SEd Schouten t->t_originreg.ts_end = t->t_winsize.tp_row;
9409b934d09SEd Schouten t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
9419b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
9429b934d09SEd Schouten teken_funcs_cursor(t);
9439b934d09SEd Schouten break;
9449b934d09SEd Schouten case 7: /* Autowrap mode. */
9459b934d09SEd Schouten t->t_stateflags &= ~TS_AUTOWRAP;
9469b934d09SEd Schouten break;
9479b934d09SEd Schouten case 8: /* Autorepeat mode. */
9489b934d09SEd Schouten teken_funcs_param(t, TP_AUTOREPEAT, 0);
9499b934d09SEd Schouten break;
9509b934d09SEd Schouten case 25: /* Hide cursor. */
9519b934d09SEd Schouten teken_funcs_param(t, TP_SHOWCURSOR, 0);
9529b934d09SEd Schouten break;
9539b934d09SEd Schouten case 40: /* Disallow 132 columns. */
9549b934d09SEd Schouten teken_printf("DECRST allow 132\n");
9559b934d09SEd Schouten break;
9569b934d09SEd Schouten case 45: /* Disable reverse wraparound. */
9579b934d09SEd Schouten teken_printf("DECRST reverse wraparound\n");
9589b934d09SEd Schouten break;
9599b934d09SEd Schouten case 47: /* Switch to alternate buffer. */
9609b934d09SEd Schouten teken_printf("Switch to alternate buffer\n");
9619b934d09SEd Schouten break;
96253e69c0cSEd Schouten case 1000: /* Mouse input. */
96353e69c0cSEd Schouten teken_funcs_param(t, TP_MOUSE, 0);
96453e69c0cSEd Schouten break;
9659b934d09SEd Schouten default:
9669b934d09SEd Schouten teken_printf("Unknown DECRST: %u\n", cmd);
9679b934d09SEd Schouten }
9689b934d09SEd Schouten }
9699b934d09SEd Schouten
9709b934d09SEd Schouten static void
teken_subr_reset_mode(teken_t * t,unsigned int cmd)9719b934d09SEd Schouten teken_subr_reset_mode(teken_t *t, unsigned int cmd)
9729b934d09SEd Schouten {
9739b934d09SEd Schouten
9749b934d09SEd Schouten switch (cmd) {
9759b934d09SEd Schouten case 4:
9769b934d09SEd Schouten t->t_stateflags &= ~TS_INSERT;
9779b934d09SEd Schouten break;
9789b934d09SEd Schouten default:
9799b934d09SEd Schouten teken_printf("Unknown reset mode: %u\n", cmd);
9809b934d09SEd Schouten }
9819b934d09SEd Schouten }
9829b934d09SEd Schouten
9839b934d09SEd Schouten static void
teken_subr_do_resize(teken_t * t)98427cf7d04SAleksandr Rybalko teken_subr_do_resize(teken_t *t)
98527cf7d04SAleksandr Rybalko {
98627cf7d04SAleksandr Rybalko
98727cf7d04SAleksandr Rybalko t->t_scrollreg.ts_begin = 0;
98827cf7d04SAleksandr Rybalko t->t_scrollreg.ts_end = t->t_winsize.tp_row;
98927cf7d04SAleksandr Rybalko t->t_originreg = t->t_scrollreg;
99027cf7d04SAleksandr Rybalko }
99127cf7d04SAleksandr Rybalko
99227cf7d04SAleksandr Rybalko static void
teken_subr_do_reset(teken_t * t)9939b934d09SEd Schouten teken_subr_do_reset(teken_t *t)
9949b934d09SEd Schouten {
9959b934d09SEd Schouten
9969b934d09SEd Schouten t->t_curattr = t->t_defattr;
9979b934d09SEd Schouten t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
998b03552b5SEd Schouten t->t_scrollreg.ts_begin = 0;
999b03552b5SEd Schouten t->t_scrollreg.ts_end = t->t_winsize.tp_row;
1000b03552b5SEd Schouten t->t_originreg = t->t_scrollreg;
1001577df3d6SBruce Evans t->t_stateflags &= TS_8BIT | TS_CONS25 | TS_CONS25KEYS;
1002eba77f5cSEd Schouten t->t_stateflags |= TS_AUTOWRAP;
10039b934d09SEd Schouten
1004cd531e74SEd Schouten t->t_scs[0] = teken_scs_us_ascii;
1005cd531e74SEd Schouten t->t_scs[1] = teken_scs_us_ascii;
1006cd531e74SEd Schouten t->t_curscs = 0;
10079b934d09SEd Schouten
10089b934d09SEd Schouten teken_subr_save_cursor(t);
10099b934d09SEd Schouten teken_tab_default(t);
10109b934d09SEd Schouten }
10119b934d09SEd Schouten
10129b934d09SEd Schouten static void
teken_subr_reset_to_initial_state(teken_t * t)10139b934d09SEd Schouten teken_subr_reset_to_initial_state(teken_t *t)
10149b934d09SEd Schouten {
10159b934d09SEd Schouten
10169b934d09SEd Schouten teken_subr_do_reset(t);
10179b934d09SEd Schouten teken_subr_erase_display(t, 2);
10189b934d09SEd Schouten teken_funcs_param(t, TP_SHOWCURSOR, 1);
10199b934d09SEd Schouten teken_funcs_cursor(t);
10209b934d09SEd Schouten }
10219b934d09SEd Schouten
10229b934d09SEd Schouten static void
teken_subr_restore_cursor(teken_t * t)10239b934d09SEd Schouten teken_subr_restore_cursor(teken_t *t)
10249b934d09SEd Schouten {
10259b934d09SEd Schouten
10269b934d09SEd Schouten t->t_cursor = t->t_saved_cursor;
10279b934d09SEd Schouten t->t_curattr = t->t_saved_curattr;
1028cd531e74SEd Schouten t->t_scs[t->t_curscs] = t->t_saved_curscs;
10299b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
1030f311d560SEd Schouten
1031f311d560SEd Schouten /* Get out of origin mode when the cursor is moved outside. */
1032f311d560SEd Schouten if (t->t_cursor.tp_row < t->t_originreg.ts_begin ||
1033f311d560SEd Schouten t->t_cursor.tp_row >= t->t_originreg.ts_end) {
1034f311d560SEd Schouten t->t_stateflags &= ~TS_ORIGIN;
1035f311d560SEd Schouten t->t_originreg.ts_begin = 0;
1036f311d560SEd Schouten t->t_originreg.ts_end = t->t_winsize.tp_row;
1037f311d560SEd Schouten }
1038f311d560SEd Schouten
10399b934d09SEd Schouten teken_funcs_cursor(t);
10409b934d09SEd Schouten }
10419b934d09SEd Schouten
10429b934d09SEd Schouten static void
teken_subr_reverse_index(teken_t * t)10439b934d09SEd Schouten teken_subr_reverse_index(teken_t *t)
10449b934d09SEd Schouten {
10459b934d09SEd Schouten
10469b934d09SEd Schouten if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) {
10479b934d09SEd Schouten t->t_cursor.tp_row--;
10489b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
10499b934d09SEd Schouten teken_funcs_cursor(t);
10509b934d09SEd Schouten } else {
10519b934d09SEd Schouten teken_subr_do_scroll(t, -1);
10529b934d09SEd Schouten }
10539b934d09SEd Schouten }
10549b934d09SEd Schouten
10559b934d09SEd Schouten static void
teken_subr_save_cursor(teken_t * t)10569b934d09SEd Schouten teken_subr_save_cursor(teken_t *t)
10579b934d09SEd Schouten {
10589b934d09SEd Schouten
10599b934d09SEd Schouten t->t_saved_cursor = t->t_cursor;
10609b934d09SEd Schouten t->t_saved_curattr = t->t_curattr;
1061cd531e74SEd Schouten t->t_saved_curscs = t->t_scs[t->t_curscs];
10629b934d09SEd Schouten }
10639b934d09SEd Schouten
10649b934d09SEd Schouten static void
teken_subr_secondary_device_attributes(const teken_t * t,unsigned int request)106592223bddSPoul-Henning Kamp teken_subr_secondary_device_attributes(const teken_t *t, unsigned int request)
10669b934d09SEd Schouten {
10679b934d09SEd Schouten
10689b934d09SEd Schouten if (request == 0) {
10699b934d09SEd Schouten const char response[] = "\x1B[>0;10;0c";
10709b934d09SEd Schouten teken_funcs_respond(t, response, sizeof response - 1);
10719b934d09SEd Schouten } else {
10729b934d09SEd Schouten teken_printf("Unknown DA2\n");
10739b934d09SEd Schouten }
10749b934d09SEd Schouten }
10759b934d09SEd Schouten
10769b934d09SEd Schouten static void
teken_subr_set_dec_mode(teken_t * t,unsigned int cmd)10779b934d09SEd Schouten teken_subr_set_dec_mode(teken_t *t, unsigned int cmd)
10789b934d09SEd Schouten {
10799b934d09SEd Schouten
10809b934d09SEd Schouten switch (cmd) {
10819b934d09SEd Schouten case 1: /* Cursor keys mode. */
10823a8a07eaSEd Schouten t->t_stateflags |= TS_CURSORKEYS;
10839b934d09SEd Schouten break;
10849b934d09SEd Schouten case 2: /* DECANM: ANSI/VT52 mode. */
10859b934d09SEd Schouten teken_printf("DECSET VT52\n");
10869b934d09SEd Schouten break;
10879b934d09SEd Schouten case 3: /* 132 column mode. */
10889b934d09SEd Schouten teken_funcs_param(t, TP_132COLS, 1);
10899b934d09SEd Schouten teken_subr_reset_to_initial_state(t);
10909b934d09SEd Schouten break;
10919b934d09SEd Schouten case 5: /* Inverse video. */
10929b934d09SEd Schouten teken_printf("DECSET inverse video\n");
10939b934d09SEd Schouten break;
10949b934d09SEd Schouten case 6: /* Origin mode. */
10959b934d09SEd Schouten t->t_stateflags |= TS_ORIGIN;
10969b934d09SEd Schouten t->t_originreg = t->t_scrollreg;
10979b934d09SEd Schouten t->t_cursor.tp_row = t->t_scrollreg.ts_begin;
10989b934d09SEd Schouten t->t_cursor.tp_col = 0;
10999b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
11009b934d09SEd Schouten teken_funcs_cursor(t);
11019b934d09SEd Schouten break;
11029b934d09SEd Schouten case 7: /* Autowrap mode. */
11039b934d09SEd Schouten t->t_stateflags |= TS_AUTOWRAP;
11049b934d09SEd Schouten break;
11059b934d09SEd Schouten case 8: /* Autorepeat mode. */
11069b934d09SEd Schouten teken_funcs_param(t, TP_AUTOREPEAT, 1);
11079b934d09SEd Schouten break;
11089b934d09SEd Schouten case 25: /* Display cursor. */
11099b934d09SEd Schouten teken_funcs_param(t, TP_SHOWCURSOR, 1);
11109b934d09SEd Schouten break;
11119b934d09SEd Schouten case 40: /* Allow 132 columns. */
11129b934d09SEd Schouten teken_printf("DECSET allow 132\n");
11139b934d09SEd Schouten break;
11149b934d09SEd Schouten case 45: /* Enable reverse wraparound. */
11159b934d09SEd Schouten teken_printf("DECSET reverse wraparound\n");
11169b934d09SEd Schouten break;
11179b934d09SEd Schouten case 47: /* Switch to alternate buffer. */
11189b934d09SEd Schouten teken_printf("Switch away from alternate buffer\n");
11199b934d09SEd Schouten break;
112053e69c0cSEd Schouten case 1000: /* Mouse input. */
112153e69c0cSEd Schouten teken_funcs_param(t, TP_MOUSE, 1);
112253e69c0cSEd Schouten break;
11239b934d09SEd Schouten default:
11249b934d09SEd Schouten teken_printf("Unknown DECSET: %u\n", cmd);
11259b934d09SEd Schouten }
11269b934d09SEd Schouten }
11279b934d09SEd Schouten
11289b934d09SEd Schouten static void
teken_subr_set_mode(teken_t * t,unsigned int cmd)11299b934d09SEd Schouten teken_subr_set_mode(teken_t *t, unsigned int cmd)
11309b934d09SEd Schouten {
11319b934d09SEd Schouten
11329b934d09SEd Schouten switch (cmd) {
11339b934d09SEd Schouten case 4:
11349b934d09SEd Schouten teken_printf("Insert mode\n");
11359b934d09SEd Schouten t->t_stateflags |= TS_INSERT;
11369b934d09SEd Schouten break;
11379b934d09SEd Schouten default:
11389b934d09SEd Schouten teken_printf("Unknown set mode: %u\n", cmd);
11399b934d09SEd Schouten }
11409b934d09SEd Schouten }
11419b934d09SEd Schouten
11429b934d09SEd Schouten static void
teken_subr_set_graphic_rendition(teken_t * t,unsigned int ncmds,const unsigned int cmds[])11439b934d09SEd Schouten teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds,
114492223bddSPoul-Henning Kamp const unsigned int cmds[])
11459b934d09SEd Schouten {
11469b934d09SEd Schouten unsigned int i, n;
11479b934d09SEd Schouten
11489b934d09SEd Schouten /* No attributes means reset. */
11499b934d09SEd Schouten if (ncmds == 0) {
11509b934d09SEd Schouten t->t_curattr = t->t_defattr;
11519b934d09SEd Schouten return;
11529b934d09SEd Schouten }
11539b934d09SEd Schouten
11549b934d09SEd Schouten for (i = 0; i < ncmds; i++) {
11559b934d09SEd Schouten n = cmds[i];
11569b934d09SEd Schouten
11579b934d09SEd Schouten switch (n) {
11589b934d09SEd Schouten case 0: /* Reset. */
11599b934d09SEd Schouten t->t_curattr = t->t_defattr;
11609b934d09SEd Schouten break;
11619b934d09SEd Schouten case 1: /* Bold. */
11629b934d09SEd Schouten t->t_curattr.ta_format |= TF_BOLD;
11639b934d09SEd Schouten break;
11649b934d09SEd Schouten case 4: /* Underline. */
11659b934d09SEd Schouten t->t_curattr.ta_format |= TF_UNDERLINE;
11669b934d09SEd Schouten break;
11679b934d09SEd Schouten case 5: /* Blink. */
11689b934d09SEd Schouten t->t_curattr.ta_format |= TF_BLINK;
11699b934d09SEd Schouten break;
11709b934d09SEd Schouten case 7: /* Reverse. */
11719b934d09SEd Schouten t->t_curattr.ta_format |= TF_REVERSE;
11729b934d09SEd Schouten break;
11739b934d09SEd Schouten case 22: /* Remove bold. */
11749b934d09SEd Schouten t->t_curattr.ta_format &= ~TF_BOLD;
11759b934d09SEd Schouten break;
11769b934d09SEd Schouten case 24: /* Remove underline. */
11779b934d09SEd Schouten t->t_curattr.ta_format &= ~TF_UNDERLINE;
11789b934d09SEd Schouten break;
11799b934d09SEd Schouten case 25: /* Remove blink. */
11809b934d09SEd Schouten t->t_curattr.ta_format &= ~TF_BLINK;
11819b934d09SEd Schouten break;
11829b934d09SEd Schouten case 27: /* Remove reverse. */
11839b934d09SEd Schouten t->t_curattr.ta_format &= ~TF_REVERSE;
11849b934d09SEd Schouten break;
11859b934d09SEd Schouten case 30: /* Set foreground color: black */
11869b934d09SEd Schouten case 31: /* Set foreground color: red */
11879b934d09SEd Schouten case 32: /* Set foreground color: green */
11889b934d09SEd Schouten case 33: /* Set foreground color: brown */
11899b934d09SEd Schouten case 34: /* Set foreground color: blue */
11909b934d09SEd Schouten case 35: /* Set foreground color: magenta */
11919b934d09SEd Schouten case 36: /* Set foreground color: cyan */
11929b934d09SEd Schouten case 37: /* Set foreground color: white */
11939b934d09SEd Schouten t->t_curattr.ta_fgcolor = n - 30;
11949b934d09SEd Schouten break;
119556a4365bSEd Schouten case 38: /* Set foreground color: 256 color mode */
119656a4365bSEd Schouten if (i + 2 >= ncmds || cmds[i + 1] != 5)
119756a4365bSEd Schouten continue;
119856a4365bSEd Schouten t->t_curattr.ta_fgcolor = cmds[i + 2];
119956a4365bSEd Schouten i += 2;
120056a4365bSEd Schouten break;
12019b934d09SEd Schouten case 39: /* Set default foreground color. */
12029b934d09SEd Schouten t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor;
12039b934d09SEd Schouten break;
12049b934d09SEd Schouten case 40: /* Set background color: black */
12059b934d09SEd Schouten case 41: /* Set background color: red */
12069b934d09SEd Schouten case 42: /* Set background color: green */
12079b934d09SEd Schouten case 43: /* Set background color: brown */
12089b934d09SEd Schouten case 44: /* Set background color: blue */
12099b934d09SEd Schouten case 45: /* Set background color: magenta */
12109b934d09SEd Schouten case 46: /* Set background color: cyan */
12119b934d09SEd Schouten case 47: /* Set background color: white */
12129b934d09SEd Schouten t->t_curattr.ta_bgcolor = n - 40;
12139b934d09SEd Schouten break;
121456a4365bSEd Schouten case 48: /* Set background color: 256 color mode */
121556a4365bSEd Schouten if (i + 2 >= ncmds || cmds[i + 1] != 5)
121656a4365bSEd Schouten continue;
121756a4365bSEd Schouten t->t_curattr.ta_bgcolor = cmds[i + 2];
121856a4365bSEd Schouten i += 2;
121956a4365bSEd Schouten break;
12209b934d09SEd Schouten case 49: /* Set default background color. */
12219b934d09SEd Schouten t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor;
12229b934d09SEd Schouten break;
122356a4365bSEd Schouten case 90: /* Set bright foreground color: black */
122456a4365bSEd Schouten case 91: /* Set bright foreground color: red */
122556a4365bSEd Schouten case 92: /* Set bright foreground color: green */
122656a4365bSEd Schouten case 93: /* Set bright foreground color: brown */
122756a4365bSEd Schouten case 94: /* Set bright foreground color: blue */
122856a4365bSEd Schouten case 95: /* Set bright foreground color: magenta */
122956a4365bSEd Schouten case 96: /* Set bright foreground color: cyan */
123056a4365bSEd Schouten case 97: /* Set bright foreground color: white */
123192223bddSPoul-Henning Kamp t->t_curattr.ta_fgcolor = (n - 90) + 8;
123256a4365bSEd Schouten break;
123356a4365bSEd Schouten case 100: /* Set bright background color: black */
123456a4365bSEd Schouten case 101: /* Set bright background color: red */
123556a4365bSEd Schouten case 102: /* Set bright background color: green */
123656a4365bSEd Schouten case 103: /* Set bright background color: brown */
123756a4365bSEd Schouten case 104: /* Set bright background color: blue */
123856a4365bSEd Schouten case 105: /* Set bright background color: magenta */
123956a4365bSEd Schouten case 106: /* Set bright background color: cyan */
124056a4365bSEd Schouten case 107: /* Set bright background color: white */
124192223bddSPoul-Henning Kamp t->t_curattr.ta_bgcolor = (n - 100) + 8;
124256a4365bSEd Schouten break;
12439b934d09SEd Schouten default:
12449b934d09SEd Schouten teken_printf("unsupported attribute %u\n", n);
12459b934d09SEd Schouten }
12469b934d09SEd Schouten }
12479b934d09SEd Schouten }
12489b934d09SEd Schouten
12499b934d09SEd Schouten static void
teken_subr_set_top_and_bottom_margins(teken_t * t,unsigned int top,unsigned int bottom)12509b934d09SEd Schouten teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top,
12519b934d09SEd Schouten unsigned int bottom)
12529b934d09SEd Schouten {
12539b934d09SEd Schouten
12549b934d09SEd Schouten /* Adjust top row number. */
12559b934d09SEd Schouten if (top > 0)
12569b934d09SEd Schouten top--;
12579b934d09SEd Schouten /* Adjust bottom row number. */
12589b934d09SEd Schouten if (bottom == 0 || bottom > t->t_winsize.tp_row)
12599b934d09SEd Schouten bottom = t->t_winsize.tp_row;
12609b934d09SEd Schouten
12619b934d09SEd Schouten /* Invalid arguments. */
12629b934d09SEd Schouten if (top >= bottom - 1) {
12639b934d09SEd Schouten top = 0;
12649b934d09SEd Schouten bottom = t->t_winsize.tp_row;
12659b934d09SEd Schouten }
12669b934d09SEd Schouten
12670475bba7SEd Schouten /* Apply scrolling region. */
12689b934d09SEd Schouten t->t_scrollreg.ts_begin = top;
12699b934d09SEd Schouten t->t_scrollreg.ts_end = bottom;
12700475bba7SEd Schouten if (t->t_stateflags & TS_ORIGIN)
12719b934d09SEd Schouten t->t_originreg = t->t_scrollreg;
12720475bba7SEd Schouten
12730475bba7SEd Schouten /* Home cursor to the top left of the scrolling region. */
12749b934d09SEd Schouten t->t_cursor.tp_row = t->t_originreg.ts_begin;
12759b934d09SEd Schouten t->t_cursor.tp_col = 0;
12769b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
12779b934d09SEd Schouten teken_funcs_cursor(t);
12789b934d09SEd Schouten }
12799b934d09SEd Schouten
12809b934d09SEd Schouten static void
teken_subr_single_height_double_width_line(const teken_t * t)128192223bddSPoul-Henning Kamp teken_subr_single_height_double_width_line(const teken_t *t)
12829b934d09SEd Schouten {
12839b934d09SEd Schouten
128492223bddSPoul-Henning Kamp (void)t;
12859b934d09SEd Schouten teken_printf("single height double width???\n");
12869b934d09SEd Schouten }
12879b934d09SEd Schouten
12889b934d09SEd Schouten static void
teken_subr_single_height_single_width_line(const teken_t * t)128992223bddSPoul-Henning Kamp teken_subr_single_height_single_width_line(const teken_t *t)
12909b934d09SEd Schouten {
12919b934d09SEd Schouten
129292223bddSPoul-Henning Kamp (void)t;
12939b934d09SEd Schouten teken_printf("single height single width???\n");
12949b934d09SEd Schouten }
12959b934d09SEd Schouten
12969b934d09SEd Schouten static void
teken_subr_string_terminator(const teken_t * t)129792223bddSPoul-Henning Kamp teken_subr_string_terminator(const teken_t *t)
12989b934d09SEd Schouten {
12999b934d09SEd Schouten
130092223bddSPoul-Henning Kamp (void)t;
13014a11e7f1SEd Schouten /*
13024a11e7f1SEd Schouten * Strings are already terminated in teken_input_char() when ^[
13034a11e7f1SEd Schouten * is inserted.
13044a11e7f1SEd Schouten */
13059b934d09SEd Schouten }
13069b934d09SEd Schouten
13079b934d09SEd Schouten static void
teken_subr_tab_clear(teken_t * t,unsigned int cmd)13089b934d09SEd Schouten teken_subr_tab_clear(teken_t *t, unsigned int cmd)
13099b934d09SEd Schouten {
13109b934d09SEd Schouten
13119b934d09SEd Schouten switch (cmd) {
13129b934d09SEd Schouten case 0:
13139b934d09SEd Schouten teken_tab_clear(t, t->t_cursor.tp_col);
13149b934d09SEd Schouten break;
13159b934d09SEd Schouten case 3:
131692223bddSPoul-Henning Kamp memset(t->t_tabstops, 0, T_NUMCOL / 8);
131792223bddSPoul-Henning Kamp break;
131892223bddSPoul-Henning Kamp default:
13199b934d09SEd Schouten break;
13209b934d09SEd Schouten }
13219b934d09SEd Schouten }
13229b934d09SEd Schouten
13239b934d09SEd Schouten static void
teken_subr_vertical_position_absolute(teken_t * t,unsigned int row)13249b934d09SEd Schouten teken_subr_vertical_position_absolute(teken_t *t, unsigned int row)
13259b934d09SEd Schouten {
13269b934d09SEd Schouten
132792223bddSPoul-Henning Kamp row = (row - 1) + t->t_originreg.ts_begin;
1328b8d356b3SEd Schouten t->t_cursor.tp_row = row < t->t_originreg.ts_end ?
1329b8d356b3SEd Schouten row : t->t_originreg.ts_end - 1;
13309b934d09SEd Schouten
13319b934d09SEd Schouten t->t_stateflags &= ~TS_WRAPPED;
13329b934d09SEd Schouten teken_funcs_cursor(t);
13339b934d09SEd Schouten }
13343eb27bf0SPoul-Henning Kamp
13353eb27bf0SPoul-Henning Kamp static void
teken_subr_repeat_last_graphic_char(teken_t * t,unsigned int rpts)13363eb27bf0SPoul-Henning Kamp teken_subr_repeat_last_graphic_char(teken_t *t, unsigned int rpts)
13373eb27bf0SPoul-Henning Kamp {
1338e06f6f73SEd Schouten unsigned int max_repetitions;
13393eb27bf0SPoul-Henning Kamp
1340e06f6f73SEd Schouten max_repetitions = t->t_winsize.tp_row * t->t_winsize.tp_col;
1341e06f6f73SEd Schouten if (rpts > max_repetitions)
1342e06f6f73SEd Schouten rpts = max_repetitions;
13433eb27bf0SPoul-Henning Kamp for (; t->t_last != 0 && rpts > 0; rpts--)
13443eb27bf0SPoul-Henning Kamp teken_subr_regular_character(t, t->t_last);
13453eb27bf0SPoul-Henning Kamp }
1346