teken_subr.h revision 197115
11558Srgrimes/*-
21558Srgrimes * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
31558Srgrimes * All rights reserved.
41558Srgrimes *
51558Srgrimes * Redistribution and use in source and binary forms, with or without
61558Srgrimes * modification, are permitted provided that the following conditions
71558Srgrimes * are met:
81558Srgrimes * 1. Redistributions of source code must retain the above copyright
91558Srgrimes *    notice, this list of conditions and the following disclaimer.
101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111558Srgrimes *    notice, this list of conditions and the following disclaimer in the
121558Srgrimes *    documentation and/or other materials provided with the distribution.
131558Srgrimes *
141558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
151558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
161558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
171558Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
181558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
191558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
201558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
211558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
221558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
231558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
241558Srgrimes * SUCH DAMAGE.
251558Srgrimes *
261558Srgrimes * $FreeBSD: head/sys/teken/teken_subr.h 197115 2009-09-12 10:34:34Z ed $
271558Srgrimes */
281558Srgrimes
291558Srgrimesstatic void teken_subr_cursor_up(teken_t *, unsigned int);
301558Srgrimesstatic void teken_subr_erase_line(teken_t *, unsigned int);
311558Srgrimesstatic void teken_subr_regular_character(teken_t *, teken_char_t);
321558Srgrimesstatic void teken_subr_reset_to_initial_state(teken_t *);
331558Srgrimesstatic void teken_subr_save_cursor(teken_t *);
341558Srgrimes
351558Srgrimesstatic inline int
3637906Scharnierteken_tab_isset(teken_t *t, unsigned int col)
3723685Speter{
3837906Scharnier	unsigned int b, o;
3937906Scharnier
4050476Speter	if (col >= T_NUMCOL)
411558Srgrimes		return ((col % 8) == 0);
421558Srgrimes
431558Srgrimes	b = col / (sizeof(unsigned int) * 8);
441558Srgrimes	o = col % (sizeof(unsigned int) * 8);
451558Srgrimes
461558Srgrimes	return (t->t_tabstops[b] & (1 << o));
4766907Swollman}
481558Srgrimes
491558Srgrimesstatic inline void
501558Srgrimesteken_tab_clear(teken_t *t, unsigned int col)
511558Srgrimes{
521558Srgrimes	unsigned int b, o;
53103949Smike
5473986Sobrien	if (col >= T_NUMCOL)
551558Srgrimes		return;
561558Srgrimes
571558Srgrimes	b = col / (sizeof(unsigned int) * 8);
581558Srgrimes	o = col % (sizeof(unsigned int) * 8);
5966907Swollman
601558Srgrimes	t->t_tabstops[b] &= ~(1 << o);
611558Srgrimes}
621558Srgrimes
631558Srgrimesstatic inline void
641558Srgrimesteken_tab_set(teken_t *t, unsigned int col)
651558Srgrimes{
661558Srgrimes	unsigned int b, o;
671558Srgrimes
68128175Sgreen	if (col >= T_NUMCOL)
69128175Sgreen		return;
7021174Sguido
711558Srgrimes	b = col / (sizeof(unsigned int) * 8);
721558Srgrimes	o = col % (sizeof(unsigned int) * 8);
731558Srgrimes
741558Srgrimes	t->t_tabstops[b] |= 1 << o;
751558Srgrimes}
7698542Smckusick
771558Srgrimesstatic void
781558Srgrimesteken_tab_default(teken_t *t)
791558Srgrimes{
801558Srgrimes	unsigned int i;
8198542Smckusick
821558Srgrimes	memset(&t->t_tabstops, 0, T_NUMCOL / 8);
831558Srgrimes
841558Srgrimes	for (i = 8; i < T_NUMCOL; i += 8)
851558Srgrimes		teken_tab_set(t, i);
861558Srgrimes}
871558Srgrimes
8898542Smckusickstatic void
891558Srgrimesteken_subr_do_scroll(teken_t *t, int amount)
901558Srgrimes{
911558Srgrimes	teken_rect_t tr;
9292837Simp	teken_pos_t tp;
9392837Simp
9492837Simp	teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row);
9592837Simp	teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row);
9692837Simp	teken_assert(amount != 0);
9792837Simp
9892837Simp	/* Copy existing data 1 line up. */
9992837Simp	if (amount > 0) {
10092837Simp		/* Scroll down. */
10192837Simp
10292837Simp		/* Copy existing data up. */
10392837Simp		if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
10492837Simp			tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount;
10592837Simp			tr.tr_begin.tp_col = 0;
10692837Simp			tr.tr_end.tp_row = t->t_scrollreg.ts_end;
10792837Simp			tr.tr_end.tp_col = t->t_winsize.tp_col;
10892837Simp			tp.tp_row = t->t_scrollreg.ts_begin;
1091558Srgrimes			tp.tp_col = 0;
1101558Srgrimes			teken_funcs_copy(t, &tr, &tp);
1111558Srgrimes
1121558Srgrimes			tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount;
1131558Srgrimes		} else {
114128175Sgreen			tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
1151558Srgrimes		}
1161558Srgrimes
1171558Srgrimes		/* Clear the last lines. */
1181558Srgrimes		tr.tr_begin.tp_col = 0;
1191558Srgrimes		tr.tr_end.tp_row = t->t_scrollreg.ts_end;
1201558Srgrimes		tr.tr_end.tp_col = t->t_winsize.tp_col;
1211558Srgrimes		teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
1221558Srgrimes	} else {
123128175Sgreen		/* Scroll up. */
124128175Sgreen		amount = -amount;
125128175Sgreen
1261558Srgrimes		/* Copy existing data down. */
12723685Speter		if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
1281558Srgrimes			tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
12923685Speter			tr.tr_begin.tp_col = 0;
1301558Srgrimes			tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount;
1311558Srgrimes			tr.tr_end.tp_col = t->t_winsize.tp_col;
1321558Srgrimes			tp.tp_row = t->t_scrollreg.ts_begin + amount;
1331558Srgrimes			tp.tp_col = 0;
1341558Srgrimes			teken_funcs_copy(t, &tr, &tp);
1351558Srgrimes
1361558Srgrimes			tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount;
1371558Srgrimes		} else {
1381558Srgrimes			tr.tr_end.tp_row = t->t_scrollreg.ts_end;
1391558Srgrimes		}
1401558Srgrimes
1411558Srgrimes		/* Clear the first lines. */
1421558Srgrimes		tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
1431558Srgrimes		tr.tr_begin.tp_col = 0;
1441558Srgrimes		tr.tr_end.tp_col = t->t_winsize.tp_col;
1451558Srgrimes		teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
1461558Srgrimes	}
1471558Srgrimes}
1481558Srgrimes
1491558Srgrimesstatic ssize_t
1501558Srgrimesteken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16])
1511558Srgrimes{
1521558Srgrimes
1531558Srgrimes	switch (cmd) {
15421174Sguido	case 5: /* Operating status. */
15521174Sguido		strcpy(response, "0n");
15621174Sguido		return (2);
15721174Sguido	case 6: { /* Cursor position. */
15821174Sguido		int len;
1591558Srgrimes
1601558Srgrimes		len = snprintf(response, 16, "%u;%uR",
1611558Srgrimes		    (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1,
16292837Simp		    t->t_cursor.tp_col + 1);
1631558Srgrimes
16492837Simp		if (len >= 16)
1651558Srgrimes			return (-1);
1661558Srgrimes		return (len);
1671558Srgrimes	}
1681558Srgrimes	case 15: /* Printer status. */
1691558Srgrimes		strcpy(response, "13n");
1701558Srgrimes		return (3);
1711558Srgrimes	case 25: /* UDK status. */
1721558Srgrimes		strcpy(response, "20n");
1731558Srgrimes		return (3);
1741558Srgrimes	case 26: /* Keyboard status. */
1751558Srgrimes		strcpy(response, "27;1n");
1761558Srgrimes		return (5);
1771558Srgrimes	default:
1781558Srgrimes		teken_printf("Unknown DSR\n");
1791558Srgrimes		return (-1);
1801558Srgrimes	}
1811558Srgrimes}
1821558Srgrimes
1831558Srgrimesstatic void
18492837Simpteken_subr_alignment_test(teken_t *t)
1851558Srgrimes{
1861558Srgrimes	teken_rect_t tr;
1871558Srgrimes
1881558Srgrimes	t->t_scrollreg.ts_begin = 0;
1891558Srgrimes	t->t_scrollreg.ts_end = t->t_winsize.tp_row;
190128175Sgreen
191128175Sgreen	t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
192128175Sgreen	t->t_stateflags &= ~TS_WRAPPED;
193128175Sgreen	teken_funcs_cursor(t);
194128175Sgreen
195128175Sgreen	tr.tr_begin.tp_row = 0;
196128175Sgreen	tr.tr_begin.tp_col = 0;
197128175Sgreen	tr.tr_end = t->t_winsize;
198128175Sgreen	teken_funcs_fill(t, &tr, 'E', &t->t_defattr);
1991558Srgrimes}
2001558Srgrimes
2011558Srgrimesstatic void
2021558Srgrimesteken_subr_backspace(teken_t *t)
2031558Srgrimes{
2041558Srgrimes
2051558Srgrimes#ifdef TEKEN_XTERM
2061558Srgrimes	if (t->t_cursor.tp_col == 0)
2071558Srgrimes		return;
2081558Srgrimes
2091558Srgrimes	t->t_cursor.tp_col--;
2101558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
2111558Srgrimes#else /* !TEKEN_XTERM */
2121558Srgrimes	if (t->t_cursor.tp_col == 0) {
2131558Srgrimes		if (t->t_cursor.tp_row == t->t_originreg.ts_begin)
2141558Srgrimes			return;
2151558Srgrimes		t->t_cursor.tp_row--;
2161558Srgrimes		t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
2171558Srgrimes	} else {
21898542Smckusick		t->t_cursor.tp_col--;
21998542Smckusick	}
2201558Srgrimes#endif /* TEKEN_XTERM */
2211558Srgrimes
22298542Smckusick	teken_funcs_cursor(t);
2231558Srgrimes}
2241558Srgrimes
2251558Srgrimesstatic void
2261558Srgrimesteken_subr_bell(teken_t *t)
2271558Srgrimes{
2281558Srgrimes
2291558Srgrimes	teken_funcs_bell(t);
2301558Srgrimes}
2311558Srgrimes
2321558Srgrimesstatic void
2331558Srgrimesteken_subr_carriage_return(teken_t *t)
23498542Smckusick{
23598542Smckusick
2361558Srgrimes	t->t_cursor.tp_col = 0;
2371558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
2381558Srgrimes	teken_funcs_cursor(t);
2391558Srgrimes}
24034851Sjkh
24134851Sjkhstatic void
24234851Sjkhteken_subr_cursor_backward(teken_t *t, unsigned int ncols)
2431558Srgrimes{
2441558Srgrimes
24537240Sbde	if (ncols > t->t_cursor.tp_col)
2461558Srgrimes		t->t_cursor.tp_col = 0;
2471558Srgrimes	else
2481558Srgrimes		t->t_cursor.tp_col -= ncols;
2491558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
2501558Srgrimes	teken_funcs_cursor(t);
2511558Srgrimes}
2521558Srgrimes
25337240Sbdestatic void
2541558Srgrimesteken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs)
2551558Srgrimes{
2561558Srgrimes
2571558Srgrimes	do {
2581558Srgrimes		/* Stop when we've reached the beginning of the line. */
2591558Srgrimes		if (t->t_cursor.tp_col == 0)
2601558Srgrimes			break;
2611558Srgrimes
2621558Srgrimes		t->t_cursor.tp_col--;
2631558Srgrimes
2641558Srgrimes		/* Tab marker set. */
26523685Speter		if (teken_tab_isset(t, t->t_cursor.tp_col))
26623685Speter			ntabs--;
2671558Srgrimes	} while (ntabs > 0);
2681558Srgrimes
2691558Srgrimes	teken_funcs_cursor(t);
2701558Srgrimes}
2711558Srgrimes
2721558Srgrimesstatic void
2731558Srgrimesteken_subr_cursor_down(teken_t *t, unsigned int nrows)
2741558Srgrimes{
2751558Srgrimes
2761558Srgrimes	if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end)
2771558Srgrimes		t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
2781558Srgrimes	else
27923685Speter		t->t_cursor.tp_row += nrows;
28023685Speter	t->t_stateflags &= ~TS_WRAPPED;
28123685Speter	teken_funcs_cursor(t);
28223685Speter}
28323685Speter
28498542Smckusickstatic void
28590820Siedowseteken_subr_cursor_forward(teken_t *t, unsigned int ncols)
28690820Siedowse{
28790820Siedowse
2881558Srgrimes	if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
2891558Srgrimes		t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
2901558Srgrimes	else
2911558Srgrimes		t->t_cursor.tp_col += ncols;
2921558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
2931558Srgrimes	teken_funcs_cursor(t);
29437906Scharnier}
2951558Srgrimes
2961558Srgrimesstatic void
2971558Srgrimesteken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs)
29892837Simp{
2991558Srgrimes
30098542Smckusick	do {
30198542Smckusick		/* Stop when we've reached the end of the line. */
3021558Srgrimes		if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1)
3031558Srgrimes			break;
3041558Srgrimes
3051558Srgrimes		t->t_cursor.tp_col++;
3061558Srgrimes
3071558Srgrimes		/* Tab marker set. */
3081558Srgrimes		if (teken_tab_isset(t, t->t_cursor.tp_col))
3091558Srgrimes			ntabs--;
31090827Siedowse	} while (ntabs > 0);
31190827Siedowse
3121558Srgrimes	teken_funcs_cursor(t);
31369906Siedowse}
3141558Srgrimes
31569906Siedowsestatic void
31669906Siedowseteken_subr_cursor_next_line(teken_t *t, unsigned int ncols)
31769906Siedowse{
31869906Siedowse
3191558Srgrimes	t->t_cursor.tp_col = 0;
3201558Srgrimes	teken_subr_cursor_down(t, ncols);
321128175Sgreen}
322128175Sgreen
323128175Sgreenstatic void
324128175Sgreenteken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col)
3251558Srgrimes{
3261558Srgrimes
3271558Srgrimes	t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
3281558Srgrimes	if (row >= t->t_originreg.ts_end)
3291558Srgrimes		t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
33090608Siedowse
3311558Srgrimes	t->t_cursor.tp_col = col - 1;
33290608Siedowse	if (t->t_cursor.tp_col >= t->t_winsize.tp_col)
3331558Srgrimes		t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
3341558Srgrimes
3351558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
33690820Siedowse	teken_funcs_cursor(t);
3371558Srgrimes}
33890820Siedowse
33990820Siedowsestatic void
34090820Siedowseteken_subr_cursor_position_report(teken_t *t, unsigned int cmd)
34190820Siedowse{
34290820Siedowse	char response[18] = "\x1B[";
34390820Siedowse	ssize_t len;
3441558Srgrimes
3451558Srgrimes	len = teken_subr_do_cpr(t, cmd, response + 2);
3461558Srgrimes	if (len < 0)
34790820Siedowse		return;
3481558Srgrimes
34990820Siedowse	teken_funcs_respond(t, response, len + 2);
3501558Srgrimes}
3511558Srgrimes
3521558Srgrimesstatic void
3531558Srgrimesteken_subr_cursor_previous_line(teken_t *t, unsigned int ncols)
3541558Srgrimes{
3551558Srgrimes
3561558Srgrimes	t->t_cursor.tp_col = 0;
35769906Siedowse	teken_subr_cursor_up(t, ncols);
35869906Siedowse}
35969906Siedowse
3601558Srgrimesstatic void
3611558Srgrimesteken_subr_cursor_up(teken_t *t, unsigned int nrows)
3621558Srgrimes{
3631558Srgrimes
3641558Srgrimes	if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row)
3651558Srgrimes		t->t_cursor.tp_row = t->t_scrollreg.ts_begin;
3661558Srgrimes	else
36790820Siedowse		t->t_cursor.tp_row -= nrows;
3681558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
3691558Srgrimes	teken_funcs_cursor(t);
3701558Srgrimes}
37137240Sbde
3721558Srgrimesstatic void
3731558Srgrimesteken_subr_delete_character(teken_t *t, unsigned int ncols)
3741558Srgrimes{
37569906Siedowse	teken_rect_t tr;
3761558Srgrimes
3771558Srgrimes	tr.tr_begin.tp_row = t->t_cursor.tp_row;
3781558Srgrimes	tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
3791558Srgrimes	tr.tr_end.tp_col = t->t_winsize.tp_col;
3801558Srgrimes
3811558Srgrimes	if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
3821558Srgrimes		tr.tr_begin.tp_col = t->t_cursor.tp_col;
3831558Srgrimes	} else {
3841558Srgrimes		/* Copy characters to the left. */
385128175Sgreen		tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols;
386128175Sgreen		teken_funcs_copy(t, &tr, &t->t_cursor);
387128175Sgreen
388128175Sgreen		tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols;
389128175Sgreen	}
390128175Sgreen
391128175Sgreen	/* Blank trailing columns. */
392128175Sgreen	teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
393128175Sgreen}
394128175Sgreen
395128175Sgreenstatic void
396128175Sgreenteken_subr_delete_line(teken_t *t, unsigned int nrows)
397128175Sgreen{
3981558Srgrimes	teken_rect_t tr;
3991558Srgrimes
4001558Srgrimes	tr.tr_begin.tp_col = 0;
4011558Srgrimes	tr.tr_end.tp_row = t->t_scrollreg.ts_end;
4021558Srgrimes	tr.tr_end.tp_col = t->t_winsize.tp_col;
4031558Srgrimes
4041558Srgrimes	if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
4051558Srgrimes		tr.tr_begin.tp_row = t->t_cursor.tp_row;
4061558Srgrimes	} else {
4071558Srgrimes		teken_pos_t tp;
4081558Srgrimes
4091558Srgrimes		/* Copy rows up. */
4101558Srgrimes		tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows;
4111558Srgrimes		tp.tp_row = t->t_cursor.tp_row;
4121558Srgrimes		tp.tp_col = 0;
4131558Srgrimes		teken_funcs_copy(t, &tr, &tp);
4141558Srgrimes
41537240Sbde		tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows;
4161558Srgrimes	}
4171558Srgrimes
4181558Srgrimes	/* Blank trailing rows. */
4191558Srgrimes	teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
4201558Srgrimes}
42137240Sbde
4221558Srgrimesstatic void
4231558Srgrimesteken_subr_device_control_string(teken_t *t __unused)
4241558Srgrimes{
42598542Smckusick
42698542Smckusick	teken_printf("device control string???\n");
42798542Smckusick}
42885635Sdillon
4291558Srgrimesstatic void
4301558Srgrimesteken_subr_device_status_report(teken_t *t, unsigned int cmd)
4311558Srgrimes{
4321558Srgrimes	char response[19] = "\x1B[?";
43390820Siedowse	ssize_t len;
4341558Srgrimes
4351558Srgrimes	len = teken_subr_do_cpr(t, cmd, response + 3);
4361558Srgrimes	if (len < 0)
4371558Srgrimes		return;
4381558Srgrimes
4391558Srgrimes	teken_funcs_respond(t, response, len + 3);
4401558Srgrimes}
4411558Srgrimes
44298542Smckusickstatic void
44390827Siedowseteken_subr_double_height_double_width_line_top(teken_t *t __unused)
44498542Smckusick{
44590608Siedowse
44690608Siedowse	teken_printf("double height double width top\n");
44790608Siedowse}
44890608Siedowse
44990608Siedowsestatic void
45090608Siedowseteken_subr_double_height_double_width_line_bottom(teken_t *t __unused)
45190608Siedowse{
45290608Siedowse
45390608Siedowse	teken_printf("double height double width bottom\n");
45490827Siedowse}
4551558Srgrimes
45690827Siedowsestatic void
45790827Siedowseteken_subr_erase_character(teken_t *t, unsigned int ncols)
45890827Siedowse{
45990827Siedowse	teken_rect_t tr;
46090827Siedowse
46190827Siedowse	tr.tr_begin = t->t_cursor;
46290827Siedowse	tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
4631558Srgrimes
46490827Siedowse	if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
46537240Sbde		tr.tr_end.tp_col = t->t_winsize.tp_col;
4661558Srgrimes	else
4671558Srgrimes		tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
4681558Srgrimes
4691558Srgrimes	teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
4701558Srgrimes}
47190608Siedowse
4721558Srgrimesstatic void
4731558Srgrimesteken_subr_erase_display(teken_t *t, unsigned int mode)
4741558Srgrimes{
4751558Srgrimes	teken_rect_t r;
4761558Srgrimes
4771558Srgrimes	r.tr_begin.tp_col = 0;
4781558Srgrimes	r.tr_end.tp_col = t->t_winsize.tp_col;
4791558Srgrimes
4801558Srgrimes	switch (mode) {
4811558Srgrimes	case 1: /* Erase from the top to the cursor. */
4821558Srgrimes		teken_subr_erase_line(t, 1);
4831558Srgrimes
4841558Srgrimes		/* Erase lines above. */
4851558Srgrimes		if (t->t_cursor.tp_row == 0)
4861558Srgrimes			return;
4871558Srgrimes		r.tr_begin.tp_row = 0;
48892837Simp		r.tr_end.tp_row = t->t_cursor.tp_row;
4891558Srgrimes		break;
4901558Srgrimes	case 2: /* Erase entire display. */
4911558Srgrimes		r.tr_begin.tp_row = 0;
4921558Srgrimes		r.tr_end.tp_row = t->t_winsize.tp_row;
4931558Srgrimes		break;
4941558Srgrimes	default: /* Erase from cursor to the bottom. */
4951558Srgrimes		teken_subr_erase_line(t, 0);
4961558Srgrimes
49798542Smckusick		/* Erase lines below. */
4981558Srgrimes		if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1)
4991558Srgrimes			return;
5001558Srgrimes		r.tr_begin.tp_row = t->t_cursor.tp_row + 1;
5011558Srgrimes		r.tr_end.tp_row = t->t_winsize.tp_row;
5021558Srgrimes		break;
5031558Srgrimes	}
5041558Srgrimes
5051558Srgrimes	teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
5061558Srgrimes}
5071558Srgrimes
5081558Srgrimesstatic void
5091558Srgrimesteken_subr_erase_line(teken_t *t, unsigned int mode)
51092837Simp{
5111558Srgrimes	teken_rect_t r;
5121558Srgrimes
5131558Srgrimes	r.tr_begin.tp_row = t->t_cursor.tp_row;
5141558Srgrimes	r.tr_end.tp_row = t->t_cursor.tp_row + 1;
5151558Srgrimes
5161558Srgrimes	switch (mode) {
5171558Srgrimes	case 1: /* Erase from the beginning of the line to the cursor. */
5181558Srgrimes		r.tr_begin.tp_col = 0;
5191558Srgrimes		r.tr_end.tp_col = t->t_cursor.tp_col + 1;
5201558Srgrimes		break;
5211558Srgrimes	case 2: /* Erase entire line. */
5221558Srgrimes		r.tr_begin.tp_col = 0;
5231558Srgrimes		r.tr_end.tp_col = t->t_winsize.tp_col;
5241558Srgrimes		break;
5258871Srgrimes	default: /* Erase from cursor to the end of the line. */
5261558Srgrimes		r.tr_begin.tp_col = t->t_cursor.tp_col;
527128175Sgreen		r.tr_end.tp_col = t->t_winsize.tp_col;
5281558Srgrimes		break;
5291558Srgrimes	}
5301558Srgrimes
5311558Srgrimes	teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
53292837Simp}
5331558Srgrimes
53485635Sdillonstatic void
53598542Smckusickteken_subr_g0_scs_special_graphics(teken_t *t __unused)
53685635Sdillon{
53798542Smckusick
5381558Srgrimes	teken_scs_set(t, 0, teken_scs_special_graphics);
53985635Sdillon}
5401558Srgrimes
5411558Srgrimesstatic void
54237240Sbdeteken_subr_g0_scs_uk_national(teken_t *t __unused)
5431558Srgrimes{
5441558Srgrimes
5451558Srgrimes	teken_scs_set(t, 0, teken_scs_uk_national);
5461558Srgrimes}
5471558Srgrimes
54892837Simpstatic void
5491558Srgrimesteken_subr_g0_scs_us_ascii(teken_t *t __unused)
55023685Speter{
55123685Speter
552100207Smckusick	teken_scs_set(t, 0, teken_scs_us_ascii);
5531558Srgrimes}
5541558Srgrimes
5551558Srgrimesstatic void
5561558Srgrimesteken_subr_g1_scs_special_graphics(teken_t *t __unused)
557100207Smckusick{
558100207Smckusick
559100207Smckusick	teken_scs_set(t, 1, teken_scs_special_graphics);
560100207Smckusick}
561100207Smckusick
562100207Smckusickstatic void
563100207Smckusickteken_subr_g1_scs_uk_national(teken_t *t __unused)
564100207Smckusick{
56598542Smckusick
56698542Smckusick	teken_scs_set(t, 1, teken_scs_uk_national);
5671558Srgrimes}
5681558Srgrimes
5691558Srgrimesstatic void
5701558Srgrimesteken_subr_g1_scs_us_ascii(teken_t *t __unused)
5711558Srgrimes{
5721558Srgrimes
5731558Srgrimes	teken_scs_set(t, 1, teken_scs_us_ascii);
5741558Srgrimes}
5751558Srgrimes
5761558Srgrimesstatic void
5771558Srgrimesteken_subr_horizontal_position_absolute(teken_t *t, unsigned int col)
5781558Srgrimes{
5791558Srgrimes
5801558Srgrimes	t->t_cursor.tp_col = col - 1;
5811558Srgrimes	if (t->t_cursor.tp_col >= t->t_winsize.tp_col)
5821558Srgrimes		t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
5831558Srgrimes
5841558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
5851558Srgrimes	teken_funcs_cursor(t);
5861558Srgrimes}
5871558Srgrimes
5881558Srgrimesstatic void
5891558Srgrimesteken_subr_horizontal_tab(teken_t *t)
5901558Srgrimes{
5911558Srgrimes#ifdef TEKEN_XTERM
5921558Srgrimes	teken_rect_t tr;
5931558Srgrimes
5941558Srgrimes	tr.tr_begin = t->t_cursor;
5951558Srgrimes	teken_subr_cursor_forward_tabulation(t, 1);
5961558Srgrimes	tr.tr_end.tp_row = tr.tr_begin.tp_row + 1;
5971558Srgrimes	tr.tr_end.tp_col = t->t_cursor.tp_col;
5981558Srgrimes
59996113Siedowse	/* Blank region that we skipped. */
60098542Smckusick	if (tr.tr_end.tp_col > tr.tr_begin.tp_col)
60196113Siedowse		teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
602100207Smckusick#else /* !TEKEN_XTERM */
603100207Smckusick
60496113Siedowse	teken_subr_cursor_forward_tabulation(t, 1);
60595943Siedowse#endif /* TEKEN_XTERM */
60696113Siedowse}
6071558Srgrimes
6086305Smartinstatic void
60923685Speterteken_subr_horizontal_tab_set(teken_t *t)
61023685Speter{
61123685Speter
61223685Speter	teken_tab_set(t, t->t_cursor.tp_col);
61323685Speter}
61435852Sjkh
61535852Sjkhstatic void
6166305Smartinteken_subr_index(teken_t *t)
61723685Speter{
61823685Speter
6196305Smartin	if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) {
6206305Smartin		t->t_cursor.tp_row++;
6216305Smartin		t->t_stateflags &= ~TS_WRAPPED;
62298542Smckusick		teken_funcs_cursor(t);
6236305Smartin	} else {
624100207Smckusick		teken_subr_do_scroll(t, 1);
625100207Smckusick	}
62623685Speter}
6276305Smartin
6286305Smartinstatic void
6296305Smartinteken_subr_insert_character(teken_t *t, unsigned int ncols)
6301558Srgrimes{
6311558Srgrimes	teken_rect_t tr;
6321558Srgrimes
6331558Srgrimes	tr.tr_begin = t->t_cursor;
6341558Srgrimes	tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
6351558Srgrimes
6361558Srgrimes	if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
63735852Sjkh		tr.tr_end.tp_col = t->t_winsize.tp_col;
63835852Sjkh	} else {
63998542Smckusick		teken_pos_t tp;
6401558Srgrimes
6411558Srgrimes		/* Copy characters to the right. */
6421558Srgrimes		tr.tr_end.tp_col = t->t_winsize.tp_col - ncols;
6431558Srgrimes		tp.tp_row = t->t_cursor.tp_row;
6441558Srgrimes		tp.tp_col = t->t_cursor.tp_col + ncols;
64598542Smckusick		teken_funcs_copy(t, &tr, &tp);
6461558Srgrimes
647100207Smckusick		tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
648100207Smckusick	}
64923685Speter
6501558Srgrimes	/* Blank current location. */
6511558Srgrimes	teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
6521558Srgrimes}
6531558Srgrimes
6541558Srgrimesstatic void
6551558Srgrimesteken_subr_insert_line(teken_t *t, unsigned int nrows)
6561558Srgrimes{
6571558Srgrimes	teken_rect_t tr;
6581558Srgrimes
65935852Sjkh	tr.tr_begin.tp_row = t->t_cursor.tp_row;
66035852Sjkh	tr.tr_begin.tp_col = 0;
66121149Simp	tr.tr_end.tp_col = t->t_winsize.tp_col;
66221149Simp
6631558Srgrimes	if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
6641558Srgrimes		tr.tr_end.tp_row = t->t_scrollreg.ts_end;
6651558Srgrimes	} else {
6661558Srgrimes		teken_pos_t tp;
6671558Srgrimes
66898542Smckusick		/* Copy lines down. */
6691558Srgrimes		tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows;
6701558Srgrimes		tp.tp_row = t->t_cursor.tp_row + nrows;
6711558Srgrimes		tp.tp_col = 0;
672100207Smckusick		teken_funcs_copy(t, &tr, &tp);
673100207Smckusick
67463283Sdwmalone		tr.tr_end.tp_row = t->t_cursor.tp_row + nrows;
6751558Srgrimes	}
6761558Srgrimes
6771558Srgrimes	/* Blank current location. */
6781558Srgrimes	teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
6791558Srgrimes}
6801558Srgrimes
6811558Srgrimesstatic void
6821558Srgrimesteken_subr_keypad_application_mode(teken_t *t)
6831558Srgrimes{
68492837Simp
6851558Srgrimes	teken_funcs_param(t, TP_KEYPADAPP, 1);
6861558Srgrimes}
6871558Srgrimes
6881558Srgrimesstatic void
6891558Srgrimesteken_subr_keypad_numeric_mode(teken_t *t)
6901558Srgrimes{
6911558Srgrimes
6921558Srgrimes	teken_funcs_param(t, TP_KEYPADAPP, 0);
6931558Srgrimes}
6941558Srgrimes
69592837Simpstatic void
6961558Srgrimesteken_subr_newline(teken_t *t)
6971558Srgrimes{
6981558Srgrimes
6991558Srgrimes	t->t_cursor.tp_row++;
7001558Srgrimes
7011558Srgrimes	if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) {
7021558Srgrimes		teken_subr_do_scroll(t, 1);
7031558Srgrimes		t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
7041558Srgrimes	}
7051558Srgrimes
7061558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
7071558Srgrimes	teken_funcs_cursor(t);
7081558Srgrimes}
70992837Simp
7101558Srgrimesstatic void
71192806Sobrienteken_subr_newpage(teken_t *t)
7121558Srgrimes{
71398542Smckusick#ifdef TEKEN_XTERM
7141558Srgrimes
7151558Srgrimes	teken_subr_newline(t);
7161558Srgrimes#else /* !TEKEN_XTERM */
7171558Srgrimes	teken_rect_t tr;
7181558Srgrimes
7191558Srgrimes	tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0;
72098542Smckusick	tr.tr_end = t->t_winsize;
7211558Srgrimes	teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
7221558Srgrimes
7231558Srgrimes	t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
7241558Srgrimes	teken_funcs_cursor(t);
7251558Srgrimes#endif /* TEKEN_XTERM */
7261558Srgrimes}
72737923Simp
7281558Srgrimesstatic void
7291558Srgrimesteken_subr_next_line(teken_t *t)
73023685Speter{
73123685Speter
7321558Srgrimes	t->t_cursor.tp_col = 0;
7331558Srgrimes	teken_subr_newline(t);
7341558Srgrimes}
7351558Srgrimes
73623685Speterstatic void
73723685Speterteken_subr_pan_down(teken_t *t, unsigned int nrows)
73823685Speter{
7391558Srgrimes
7401558Srgrimes	teken_subr_do_scroll(t, (int)nrows);
74123685Speter}
74223685Speter
7431558Srgrimesstatic void
7441558Srgrimesteken_subr_pan_up(teken_t *t, unsigned int nrows)
7451558Srgrimes{
74637923Simp
7471558Srgrimes	teken_subr_do_scroll(t, -(int)nrows);
7481558Srgrimes}
7491558Srgrimes
7501558Srgrimesstatic void
7511558Srgrimesteken_subr_primary_device_attributes(teken_t *t, unsigned int request)
7521558Srgrimes{
7531558Srgrimes
7541558Srgrimes	if (request == 0) {
75537240Sbde		const char response[] = "\x1B[?1;2c";
7561558Srgrimes
7571558Srgrimes		teken_funcs_respond(t, response, sizeof response - 1);
7581558Srgrimes	} else {
75923685Speter		teken_printf("Unknown DA1\n");
7601558Srgrimes	}
7611558Srgrimes}
7621558Srgrimes
7631558Srgrimesstatic void
7641558Srgrimesteken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c,
7651558Srgrimes    int width)
7661558Srgrimes{
7671558Srgrimes
76892837Simp	if (t->t_stateflags & TS_INSERT &&
7691558Srgrimes	    tp->tp_col < t->t_winsize.tp_col - width) {
7701558Srgrimes		teken_rect_t ctr;
7711558Srgrimes		teken_pos_t ctp;
7721558Srgrimes
7731558Srgrimes		/* Insert mode. Move existing characters to the right. */
7741558Srgrimes		ctr.tr_begin = *tp;
7751558Srgrimes		ctr.tr_end.tp_row = tp->tp_row + 1;
7761558Srgrimes		ctr.tr_end.tp_col = t->t_winsize.tp_col - width;
7771558Srgrimes		ctp.tp_row = tp->tp_row;
7781558Srgrimes		ctp.tp_col = tp->tp_col + width;
7791558Srgrimes		teken_funcs_copy(t, &ctr, &ctp);
7801558Srgrimes	}
7811558Srgrimes
7821558Srgrimes	teken_funcs_putchar(t, tp, c, &t->t_curattr);
7831558Srgrimes}
7841558Srgrimes
78592837Simpstatic void
7861558Srgrimesteken_subr_regular_character(teken_t *t, teken_char_t c)
7871558Srgrimes{
7881558Srgrimes	int width;
7891558Srgrimes
7901558Srgrimes	if (t->t_utf8_left == -1) {
7911558Srgrimes#ifdef TEKEN_XTERM
7921558Srgrimes		if (c <= 0x1B)
7931558Srgrimes			return;
7941558Srgrimes#endif /* TEKEN_XTERM */
7951558Srgrimes		width = 1;
7961558Srgrimes	} else {
7971558Srgrimes		c = teken_scs_process(t, c);
7981558Srgrimes		width = teken_wcwidth(c);
7991558Srgrimes		/* XXX: Don't process zero-width characters yet. */
80092837Simp		if (width <= 0)
8011558Srgrimes			return;
8021558Srgrimes	}
8031558Srgrimes
8041558Srgrimes#ifdef TEKEN_XTERM
8051558Srgrimes	if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 &&
8061558Srgrimes	    (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) ==
8071558Srgrimes	    (TS_WRAPPED|TS_AUTOWRAP)) {
8081558Srgrimes		teken_pos_t tp;
8091558Srgrimes
8101558Srgrimes		/* Perform line wrapping. */
8111558Srgrimes
8121558Srgrimes		if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
8131558Srgrimes			/* Perform scrolling. */
8141558Srgrimes			teken_subr_do_scroll(t, 1);
8151558Srgrimes			tp.tp_row = t->t_scrollreg.ts_end - 1;
8161558Srgrimes		} else {
81792837Simp			/* No scrolling needed. */
8181558Srgrimes			tp.tp_row = t->t_cursor.tp_row + 1;
8191558Srgrimes			if (tp.tp_row == t->t_winsize.tp_row) {
8201558Srgrimes				/*
8211558Srgrimes				 * Corner case: regular character
8221558Srgrimes				 * outside scrolling region, but at the
8231558Srgrimes				 * bottom of the screen.
8241558Srgrimes				 */
8251558Srgrimes				teken_subr_do_putchar(t, &t->t_cursor,
8261558Srgrimes				    c, width);
8271558Srgrimes				return;
8281558Srgrimes			}
82992837Simp		}
8301558Srgrimes
8311558Srgrimes		tp.tp_col = 0;
83223685Speter		teken_subr_do_putchar(t, &tp, c, width);
8331558Srgrimes
8341558Srgrimes		t->t_cursor.tp_row = tp.tp_row;
8351558Srgrimes		t->t_cursor.tp_col = width;
8361558Srgrimes		t->t_stateflags &= ~TS_WRAPPED;
8371558Srgrimes	} else {
8381558Srgrimes		/* No line wrapping needed. */
8391558Srgrimes		teken_subr_do_putchar(t, &t->t_cursor, c, width);
8401558Srgrimes		t->t_cursor.tp_col += width;
84192837Simp
8421558Srgrimes		if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
8431558Srgrimes			t->t_stateflags |= TS_WRAPPED;
8441558Srgrimes			t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
8451558Srgrimes		} else {
8461558Srgrimes			t->t_stateflags &= ~TS_WRAPPED;
8471558Srgrimes		}
8481558Srgrimes	}
8491558Srgrimes#else /* !TEKEN_XTERM */
8501558Srgrimes	teken_subr_do_putchar(t, &t->t_cursor, c, width);
8511558Srgrimes	t->t_cursor.tp_col += width;
8521558Srgrimes
85392837Simp	if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
8541558Srgrimes		if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
8551558Srgrimes			/* Perform scrolling. */
8561558Srgrimes			teken_subr_do_scroll(t, 1);
8571558Srgrimes		} else {
8581558Srgrimes			/* No scrolling needed. */
8591558Srgrimes			if (t->t_cursor.tp_row < t->t_winsize.tp_row - 1)
8601558Srgrimes				t->t_cursor.tp_row++;
8611558Srgrimes		}
8621558Srgrimes		t->t_cursor.tp_col = 0;
8631558Srgrimes	}
86492837Simp#endif /* TEKEN_XTERM */
8651558Srgrimes
8661558Srgrimes	teken_funcs_cursor(t);
8671558Srgrimes}
8681558Srgrimes
8691558Srgrimesstatic void
87023685Speterteken_subr_reset_dec_mode(teken_t *t, unsigned int cmd)
8711558Srgrimes{
87290827Siedowse
8731558Srgrimes	switch (cmd) {
8741558Srgrimes	case 1: /* Cursor keys mode. */
8751558Srgrimes		teken_funcs_param(t, TP_CURSORKEYS, 0);
8761558Srgrimes		break;
8771558Srgrimes	case 2: /* DECANM: ANSI/VT52 mode. */
8781558Srgrimes		teken_printf("DECRST VT52\n");
8791558Srgrimes		break;
8801558Srgrimes	case 3: /* 132 column mode. */
8811558Srgrimes		teken_funcs_param(t, TP_132COLS, 0);
8821558Srgrimes		teken_subr_reset_to_initial_state(t);
8831558Srgrimes		break;
8841558Srgrimes	case 5: /* Inverse video. */
8851558Srgrimes		teken_printf("DECRST inverse video\n");
8861558Srgrimes		break;
8871558Srgrimes	case 6: /* Origin mode. */
8881558Srgrimes		t->t_stateflags &= ~TS_ORIGIN;
8891558Srgrimes		t->t_originreg.ts_begin = 0;
8901558Srgrimes		t->t_originreg.ts_end = t->t_winsize.tp_row;
8911558Srgrimes		t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
8921558Srgrimes		t->t_stateflags &= ~TS_WRAPPED;
8931558Srgrimes		teken_funcs_cursor(t);
8941558Srgrimes		break;
8951558Srgrimes	case 7: /* Autowrap mode. */
8961558Srgrimes		t->t_stateflags &= ~TS_AUTOWRAP;
8971558Srgrimes		break;
8981558Srgrimes	case 8: /* Autorepeat mode. */
8991558Srgrimes		teken_funcs_param(t, TP_AUTOREPEAT, 0);
9001558Srgrimes		break;
9011558Srgrimes	case 25: /* Hide cursor. */
9021558Srgrimes		teken_funcs_param(t, TP_SHOWCURSOR, 0);
9031558Srgrimes		break;
9041558Srgrimes	case 40: /* Disallow 132 columns. */
9051558Srgrimes		teken_printf("DECRST allow 132\n");
9061558Srgrimes		break;
9071558Srgrimes	case 45: /* Disable reverse wraparound. */
9081558Srgrimes		teken_printf("DECRST reverse wraparound\n");
9091558Srgrimes		break;
9101558Srgrimes	case 47: /* Switch to alternate buffer. */
9111558Srgrimes		teken_printf("Switch to alternate buffer\n");
9121558Srgrimes		break;
9131558Srgrimes	default:
91437240Sbde		teken_printf("Unknown DECRST: %u\n", cmd);
9151558Srgrimes	}
9161558Srgrimes}
9171558Srgrimes
9181558Srgrimesstatic void
9191558Srgrimesteken_subr_reset_mode(teken_t *t, unsigned int cmd)
9201558Srgrimes{
9211558Srgrimes
9221558Srgrimes	switch (cmd) {
9231558Srgrimes	case 4:
9241558Srgrimes		t->t_stateflags &= ~TS_INSERT;
9251558Srgrimes		break;
9261558Srgrimes	default:
9271558Srgrimes		teken_printf("Unknown reset mode: %u\n", cmd);
9281558Srgrimes	}
9291558Srgrimes}
9301558Srgrimes
9311558Srgrimesstatic void
9321558Srgrimesteken_subr_do_reset(teken_t *t)
9331558Srgrimes{
9341558Srgrimes
9351558Srgrimes	t->t_curattr = t->t_defattr;
9361558Srgrimes	t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
9371558Srgrimes	t->t_scrollreg.ts_begin = 0;
9381558Srgrimes	t->t_scrollreg.ts_end = t->t_winsize.tp_row;
9391558Srgrimes	t->t_originreg = t->t_scrollreg;
9401558Srgrimes	t->t_stateflags = TS_AUTOWRAP;
9411558Srgrimes
94223685Speter	teken_scs_set(t, 0, teken_scs_us_ascii);
9431558Srgrimes	teken_scs_set(t, 1, teken_scs_us_ascii);
9441558Srgrimes	teken_scs_switch(t, 0);
9451558Srgrimes
9461558Srgrimes	teken_subr_save_cursor(t);
9471558Srgrimes	teken_tab_default(t);
9481558Srgrimes}
9491558Srgrimes
9501558Srgrimesstatic void
9511558Srgrimesteken_subr_reset_to_initial_state(teken_t *t)
9521558Srgrimes{
9531558Srgrimes
9541558Srgrimes	teken_subr_do_reset(t);
9551558Srgrimes	teken_subr_erase_display(t, 2);
9561558Srgrimes	teken_funcs_param(t, TP_SHOWCURSOR, 1);
9571558Srgrimes	teken_funcs_cursor(t);
9581558Srgrimes}
9591558Srgrimes
9601558Srgrimesstatic void
9611558Srgrimesteken_subr_restore_cursor(teken_t *t)
9621558Srgrimes{
9631558Srgrimes
9641558Srgrimes	t->t_cursor = t->t_saved_cursor;
9651558Srgrimes	t->t_curattr = t->t_saved_curattr;
9661558Srgrimes	t->t_stateflags &= ~TS_WRAPPED;
9671558Srgrimes	teken_scs_restore(t);
9681558Srgrimes	teken_funcs_cursor(t);
9691558Srgrimes}
9701558Srgrimes
9711558Srgrimesstatic void
9721558Srgrimesteken_subr_reverse_index(teken_t *t)
97323685Speter{
9741558Srgrimes
9751558Srgrimes	if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) {
97623685Speter		t->t_cursor.tp_row--;
9771558Srgrimes		t->t_stateflags &= ~TS_WRAPPED;
97890827Siedowse		teken_funcs_cursor(t);
9791558Srgrimes	} else {
9801558Srgrimes		teken_subr_do_scroll(t, -1);
9811558Srgrimes	}
98292837Simp}
9831558Srgrimes
98492806Sobrienstatic void
9851558Srgrimesteken_subr_save_cursor(teken_t *t)
9861558Srgrimes{
9871558Srgrimes
9881558Srgrimes	t->t_saved_cursor = t->t_cursor;
9891558Srgrimes	t->t_saved_curattr = t->t_curattr;
9901558Srgrimes	teken_scs_save(t);
9911558Srgrimes}
9921558Srgrimes
9931558Srgrimesstatic void
9941558Srgrimesteken_subr_secondary_device_attributes(teken_t *t, unsigned int request)
9951558Srgrimes{
9961558Srgrimes
9971558Srgrimes	if (request == 0) {
9981558Srgrimes		const char response[] = "\x1B[>0;10;0c";
9991558Srgrimes		teken_funcs_respond(t, response, sizeof response - 1);
10001558Srgrimes	} else {
100137240Sbde		teken_printf("Unknown DA2\n");
10021558Srgrimes	}
10031558Srgrimes}
10041558Srgrimes
10051558Srgrimesstatic void
10061558Srgrimesteken_subr_set_dec_mode(teken_t *t, unsigned int cmd)
100737240Sbde{
10081558Srgrimes
10091558Srgrimes	switch (cmd) {
10101558Srgrimes	case 1: /* Cursor keys mode. */
101192837Simp		teken_funcs_param(t, TP_CURSORKEYS, 1);
10121558Srgrimes		break;
10131558Srgrimes	case 2: /* DECANM: ANSI/VT52 mode. */
10141558Srgrimes		teken_printf("DECSET VT52\n");
10151558Srgrimes		break;
1016128175Sgreen	case 3: /* 132 column mode. */
1017128175Sgreen		teken_funcs_param(t, TP_132COLS, 1);
1018128175Sgreen		teken_subr_reset_to_initial_state(t);
1019128175Sgreen		break;
10201558Srgrimes	case 5: /* Inverse video. */
10211558Srgrimes		teken_printf("DECSET inverse video\n");
10221558Srgrimes		break;
10231558Srgrimes	case 6: /* Origin mode. */
10241558Srgrimes		t->t_stateflags |= TS_ORIGIN;
10251558Srgrimes		t->t_originreg = t->t_scrollreg;
10261558Srgrimes		t->t_cursor.tp_row = t->t_scrollreg.ts_begin;
10271558Srgrimes		t->t_cursor.tp_col = 0;
10281558Srgrimes		t->t_stateflags &= ~TS_WRAPPED;
10291558Srgrimes		teken_funcs_cursor(t);
10301558Srgrimes		break;
10311558Srgrimes	case 7: /* Autowrap mode. */
10321558Srgrimes		t->t_stateflags |= TS_AUTOWRAP;
103392837Simp		break;
10341558Srgrimes	case 8: /* Autorepeat mode. */
10351558Srgrimes		teken_funcs_param(t, TP_AUTOREPEAT, 1);
10361558Srgrimes		break;
103798542Smckusick	case 25: /* Display cursor. */
103898542Smckusick		teken_funcs_param(t, TP_SHOWCURSOR, 1);
103998542Smckusick		break;
104098542Smckusick	case 40: /* Allow 132 columns. */
104198542Smckusick		teken_printf("DECSET allow 132\n");
104298542Smckusick		break;
104398542Smckusick	case 45: /* Enable reverse wraparound. */
104498542Smckusick		teken_printf("DECSET reverse wraparound\n");
104598542Smckusick		break;
104698542Smckusick	case 47: /* Switch to alternate buffer. */
104798542Smckusick		teken_printf("Switch away from alternate buffer\n");
104898542Smckusick		break;
104998542Smckusick	default:
105098542Smckusick		teken_printf("Unknown DECSET: %u\n", cmd);
105198542Smckusick	}
105298542Smckusick}
10531558Srgrimes
10541558Srgrimesstatic void
105523096Simpteken_subr_set_mode(teken_t *t, unsigned int cmd)
105698542Smckusick{
105798542Smckusick
105898542Smckusick	switch (cmd) {
10591558Srgrimes	case 4:
10601558Srgrimes		teken_printf("Insert mode\n");
106198542Smckusick		t->t_stateflags |= TS_INSERT;
106298542Smckusick		break;
106398542Smckusick	default:
106498542Smckusick		teken_printf("Unknown set mode: %u\n", cmd);
106598542Smckusick	}
106698542Smckusick}
10671558Srgrimes
106837923Simpstatic void
10691558Srgrimesteken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds,
10701558Srgrimes    unsigned int cmds[])
10711558Srgrimes{
10721558Srgrimes	unsigned int i, n;
10731558Srgrimes
10741558Srgrimes	/* No attributes means reset. */
10751558Srgrimes	if (ncmds == 0) {
10761558Srgrimes		t->t_curattr = t->t_defattr;
10771558Srgrimes		return;
107898542Smckusick	}
107937923Simp
108037923Simp	for (i = 0; i < ncmds; i++) {
108137923Simp		n = cmds[i];
108237923Simp
108337923Simp		switch (n) {
10841558Srgrimes		case 0: /* Reset. */
10851558Srgrimes			t->t_curattr = t->t_defattr;
10861558Srgrimes			break;
10871558Srgrimes		case 1: /* Bold. */
10881558Srgrimes			t->t_curattr.ta_format |= TF_BOLD;
10891558Srgrimes			break;
10901558Srgrimes		case 4: /* Underline. */
10911558Srgrimes			t->t_curattr.ta_format |= TF_UNDERLINE;
109298542Smckusick			break;
109398542Smckusick		case 5: /* Blink. */
109498542Smckusick			t->t_curattr.ta_format |= TF_BLINK;
109598542Smckusick			break;
109698542Smckusick		case 7: /* Reverse. */
109798542Smckusick			t->t_curattr.ta_format |= TF_REVERSE;
109898542Smckusick			break;
109998542Smckusick		case 22: /* Remove bold. */
110098542Smckusick			t->t_curattr.ta_format &= ~TF_BOLD;
110198542Smckusick			break;
110298542Smckusick		case 24: /* Remove underline. */
110398542Smckusick			t->t_curattr.ta_format &= ~TF_UNDERLINE;
110498542Smckusick			break;
110598542Smckusick		case 25: /* Remove blink. */
11061558Srgrimes			t->t_curattr.ta_format &= ~TF_BLINK;
11071558Srgrimes			break;
11081558Srgrimes		case 27: /* Remove reverse. */
11091558Srgrimes			t->t_curattr.ta_format &= ~TF_REVERSE;
11101558Srgrimes			break;
11111558Srgrimes		case 30: /* Set foreground color: black */
11121558Srgrimes		case 31: /* Set foreground color: red */
111398542Smckusick		case 32: /* Set foreground color: green */
111490827Siedowse		case 33: /* Set foreground color: brown */
11151558Srgrimes		case 34: /* Set foreground color: blue */
11161558Srgrimes		case 35: /* Set foreground color: magenta */
11171558Srgrimes		case 36: /* Set foreground color: cyan */
11181558Srgrimes		case 37: /* Set foreground color: white */
11191558Srgrimes			t->t_curattr.ta_fgcolor = n - 30;
11201558Srgrimes			break;
11211558Srgrimes		case 39: /* Set default foreground color. */
11221558Srgrimes			t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor;
11231558Srgrimes			break;
112492837Simp		case 40: /* Set background color: black */
11251558Srgrimes		case 41: /* Set background color: red */
11261558Srgrimes		case 42: /* Set background color: green */
11271558Srgrimes		case 43: /* Set background color: brown */
11281558Srgrimes		case 44: /* Set background color: blue */
11291558Srgrimes		case 45: /* Set background color: magenta */
11301558Srgrimes		case 46: /* Set background color: cyan */
11311558Srgrimes		case 47: /* Set background color: white */
113298542Smckusick			t->t_curattr.ta_bgcolor = n - 40;
11331558Srgrimes			break;
113498542Smckusick		case 49: /* Set default background color. */
11351558Srgrimes			t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor;
11361558Srgrimes			break;
11371558Srgrimes		default:
11381558Srgrimes			teken_printf("unsupported attribute %u\n", n);
11391558Srgrimes		}
11401558Srgrimes	}
11411558Srgrimes}
11421558Srgrimes
11431558Srgrimesstatic void
114423685Speterteken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top,
11451558Srgrimes    unsigned int bottom)
11461558Srgrimes{
114723685Speter
11481558Srgrimes	/* Adjust top row number. */
11491558Srgrimes	if (top > 0)
11501558Srgrimes		top--;
11511558Srgrimes	/* Adjust bottom row number. */
11521558Srgrimes	if (bottom == 0 || bottom > t->t_winsize.tp_row)
11531558Srgrimes		bottom = t->t_winsize.tp_row;
11541558Srgrimes
11551558Srgrimes	/* Invalid arguments. */
11561558Srgrimes	if (top >= bottom - 1) {
11571558Srgrimes		top = 0;
11581558Srgrimes		bottom = t->t_winsize.tp_row;
11591558Srgrimes	}
116037240Sbde
11611558Srgrimes	t->t_scrollreg.ts_begin = top;
11621558Srgrimes	t->t_scrollreg.ts_end = bottom;
11631558Srgrimes	if (t->t_stateflags & TS_ORIGIN) {
11641558Srgrimes		/* XXX: home cursor? */
11651558Srgrimes		t->t_originreg = t->t_scrollreg;
11661558Srgrimes		t->t_cursor.tp_row = t->t_originreg.ts_begin;
116737923Simp		t->t_cursor.tp_col = 0;
11681558Srgrimes		t->t_stateflags &= ~TS_WRAPPED;
11691558Srgrimes		teken_funcs_cursor(t);
11701558Srgrimes	}
11711558Srgrimes}
11721558Srgrimes
11731558Srgrimesstatic void
11741558Srgrimesteken_subr_single_height_double_width_line(teken_t *t __unused)
11751558Srgrimes{
11761558Srgrimes
117790573Siedowse	teken_printf("single height double width???\n");
11781558Srgrimes}
11791558Srgrimes
118092837Simpstatic void
11811558Srgrimesteken_subr_single_height_single_width_line(teken_t *t __unused)
11821558Srgrimes{
11831558Srgrimes
11841558Srgrimes	teken_printf("single height single width???\n");
118590608Siedowse}
11861558Srgrimes
11871558Srgrimesstatic void
11881558Srgrimesteken_subr_string_terminator(teken_t *t __unused)
118998542Smckusick{
11901558Srgrimes
11911558Srgrimes	teken_printf("string terminator???\n");
119290608Siedowse}
119390608Siedowse
11941558Srgrimesstatic void
11951558Srgrimesteken_subr_tab_clear(teken_t *t, unsigned int cmd)
11961558Srgrimes{
11971558Srgrimes
11981558Srgrimes	switch (cmd) {
11991558Srgrimes	case 0:
12001558Srgrimes		teken_tab_clear(t, t->t_cursor.tp_col);
12011558Srgrimes		break;
12021558Srgrimes	case 3:
120398542Smckusick		memset(&t->t_tabstops, 0, T_NUMCOL / 8);
12041558Srgrimes		break;
12051558Srgrimes	}
12061558Srgrimes}
12071558Srgrimes
120898542Smckusickstatic void
120998542Smckusickteken_subr_vertical_position_absolute(teken_t *t, unsigned int row)
121098542Smckusick{
121198542Smckusick
121298542Smckusick	t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
121398542Smckusick	if (row >= t->t_originreg.ts_end)
121498542Smckusick		t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
121598542Smckusick
121698542Smckusick
1217100207Smckusick	t->t_stateflags &= ~TS_WRAPPED;
1218100207Smckusick	teken_funcs_cursor(t);
121998542Smckusick}
12201558Srgrimes