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 #include <sys/cdefs.h>
309b934d09SEd Schouten #if defined(__FreeBSD__) && defined(_KERNEL)
319b934d09SEd Schouten #include <sys/param.h>
32c5b3acf2SEd Schouten #include <sys/limits.h>
339b934d09SEd Schouten #include <sys/lock.h>
349b934d09SEd Schouten #include <sys/systm.h>
359b934d09SEd Schouten #define teken_assert(x) MPASS(x)
3682625856SToomas Soome #elif defined(__FreeBSD__) && defined(_STANDALONE)
3782625856SToomas Soome #include <stand.h>
3882625856SToomas Soome #include <sys/limits.h>
3982625856SToomas Soome #include <assert.h>
4082625856SToomas Soome #define teken_assert(x) assert(x)
4182625856SToomas Soome #else /* !(__FreeBSD__ && _STANDALONE) */
429b934d09SEd Schouten #include <sys/types.h>
439b934d09SEd Schouten #include <assert.h>
44c5b3acf2SEd Schouten #include <limits.h>
45a54dd632SEd Schouten #include <stdint.h>
469b934d09SEd Schouten #include <stdio.h>
479b934d09SEd Schouten #include <string.h>
489b934d09SEd Schouten #define teken_assert(x) assert(x)
4982625856SToomas Soome #endif /* __FreeBSD__ && _STANDALONE */
509b934d09SEd Schouten
51ecc16c8dSEd Schouten /* debug messages */
52ecc16c8dSEd Schouten #define teken_printf(x,...)
53ecc16c8dSEd Schouten
549b934d09SEd Schouten /* Private flags for t_stateflags. */
553a8a07eaSEd Schouten #define TS_FIRSTDIGIT 0x0001 /* First numeric digit in escape sequence. */
563a8a07eaSEd Schouten #define TS_INSERT 0x0002 /* Insert mode. */
573a8a07eaSEd Schouten #define TS_AUTOWRAP 0x0004 /* Autowrap. */
583a8a07eaSEd Schouten #define TS_ORIGIN 0x0008 /* Origin mode. */
593a8a07eaSEd Schouten #define TS_WRAPPED 0x0010 /* Next character should be printed on col 0. */
603a8a07eaSEd Schouten #define TS_8BIT 0x0020 /* UTF-8 disabled. */
613a8a07eaSEd Schouten #define TS_CONS25 0x0040 /* cons25 emulation. */
623a8a07eaSEd Schouten #define TS_INSTRING 0x0080 /* Inside string. */
633a8a07eaSEd Schouten #define TS_CURSORKEYS 0x0100 /* Cursor keys mode. */
6490bdbe95SBruce Evans #define TS_CONS25KEYS 0x0400 /* Fuller cons25 emul (fix function keys). */
659b934d09SEd Schouten
669b934d09SEd Schouten /* Character that blanks a cell. */
679b934d09SEd Schouten #define BLANK ' '
689b934d09SEd Schouten
69fbcd1b6eSEd Schouten #include "teken.h"
70fbcd1b6eSEd Schouten #include "teken_wcwidth.h"
71fbcd1b6eSEd Schouten #include "teken_scs.h"
72fbcd1b6eSEd Schouten
739b934d09SEd Schouten static teken_state_t teken_state_init;
749b934d09SEd Schouten
759b934d09SEd Schouten /*
769b934d09SEd Schouten * Wrappers for hooks.
779b934d09SEd Schouten */
789b934d09SEd Schouten
799b934d09SEd Schouten static inline void
teken_funcs_bell(const teken_t * t)8092223bddSPoul-Henning Kamp teken_funcs_bell(const teken_t *t)
819b934d09SEd Schouten {
829b934d09SEd Schouten
8392223bddSPoul-Henning Kamp teken_assert(t->t_funcs->tf_bell != NULL);
849b934d09SEd Schouten t->t_funcs->tf_bell(t->t_softc);
859b934d09SEd Schouten }
869b934d09SEd Schouten
879b934d09SEd Schouten static inline void
teken_funcs_cursor(const teken_t * t)8892223bddSPoul-Henning Kamp teken_funcs_cursor(const teken_t *t)
899b934d09SEd Schouten {
909b934d09SEd Schouten
919b934d09SEd Schouten teken_assert(t->t_cursor.tp_row < t->t_winsize.tp_row);
929b934d09SEd Schouten teken_assert(t->t_cursor.tp_col < t->t_winsize.tp_col);
939b934d09SEd Schouten
9492223bddSPoul-Henning Kamp teken_assert(t->t_funcs->tf_cursor != NULL);
959b934d09SEd Schouten t->t_funcs->tf_cursor(t->t_softc, &t->t_cursor);
969b934d09SEd Schouten }
979b934d09SEd Schouten
989b934d09SEd Schouten static inline void
teken_funcs_putchar(const teken_t * t,const teken_pos_t * p,teken_char_t c,const teken_attr_t * a)9992223bddSPoul-Henning Kamp teken_funcs_putchar(const teken_t *t, const teken_pos_t *p, teken_char_t c,
1009b934d09SEd Schouten const teken_attr_t *a)
1019b934d09SEd Schouten {
1029b934d09SEd Schouten
1039b934d09SEd Schouten teken_assert(p->tp_row < t->t_winsize.tp_row);
1049b934d09SEd Schouten teken_assert(p->tp_col < t->t_winsize.tp_col);
1059b934d09SEd Schouten
10692223bddSPoul-Henning Kamp teken_assert(t->t_funcs->tf_putchar != NULL);
1079b934d09SEd Schouten t->t_funcs->tf_putchar(t->t_softc, p, c, a);
1089b934d09SEd Schouten }
1099b934d09SEd Schouten
1109b934d09SEd Schouten static inline void
teken_funcs_fill(const teken_t * t,const teken_rect_t * r,const teken_char_t c,const teken_attr_t * a)11192223bddSPoul-Henning Kamp teken_funcs_fill(const teken_t *t, const teken_rect_t *r,
1129b934d09SEd Schouten const teken_char_t c, const teken_attr_t *a)
1139b934d09SEd Schouten {
1149b934d09SEd Schouten
1159b934d09SEd Schouten teken_assert(r->tr_end.tp_row > r->tr_begin.tp_row);
1169b934d09SEd Schouten teken_assert(r->tr_end.tp_row <= t->t_winsize.tp_row);
1179b934d09SEd Schouten teken_assert(r->tr_end.tp_col > r->tr_begin.tp_col);
1189b934d09SEd Schouten teken_assert(r->tr_end.tp_col <= t->t_winsize.tp_col);
1199b934d09SEd Schouten
12092223bddSPoul-Henning Kamp teken_assert(t->t_funcs->tf_fill != NULL);
1219b934d09SEd Schouten t->t_funcs->tf_fill(t->t_softc, r, c, a);
1229b934d09SEd Schouten }
1239b934d09SEd Schouten
1249b934d09SEd Schouten static inline void
teken_funcs_copy(const teken_t * t,const teken_rect_t * r,const teken_pos_t * p)12592223bddSPoul-Henning Kamp teken_funcs_copy(const teken_t *t, const teken_rect_t *r, const teken_pos_t *p)
1269b934d09SEd Schouten {
1279b934d09SEd Schouten
1289b934d09SEd Schouten teken_assert(r->tr_end.tp_row > r->tr_begin.tp_row);
1299b934d09SEd Schouten teken_assert(r->tr_end.tp_row <= t->t_winsize.tp_row);
1309b934d09SEd Schouten teken_assert(r->tr_end.tp_col > r->tr_begin.tp_col);
1319b934d09SEd Schouten teken_assert(r->tr_end.tp_col <= t->t_winsize.tp_col);
1329b934d09SEd Schouten teken_assert(p->tp_row + (r->tr_end.tp_row - r->tr_begin.tp_row) <= t->t_winsize.tp_row);
1339b934d09SEd Schouten teken_assert(p->tp_col + (r->tr_end.tp_col - r->tr_begin.tp_col) <= t->t_winsize.tp_col);
1349b934d09SEd Schouten
13592223bddSPoul-Henning Kamp teken_assert(t->t_funcs->tf_copy != NULL);
1369b934d09SEd Schouten t->t_funcs->tf_copy(t->t_softc, r, p);
1379b934d09SEd Schouten }
1389b934d09SEd Schouten
1399b934d09SEd Schouten static inline void
teken_funcs_pre_input(const teken_t * t)140547e74a8SJean-Sébastien Pédron teken_funcs_pre_input(const teken_t *t)
141547e74a8SJean-Sébastien Pédron {
142547e74a8SJean-Sébastien Pédron
1434812c5c5SConrad Meyer if (t->t_funcs->tf_pre_input != NULL)
144547e74a8SJean-Sébastien Pédron t->t_funcs->tf_pre_input(t->t_softc);
145547e74a8SJean-Sébastien Pédron }
146547e74a8SJean-Sébastien Pédron
147547e74a8SJean-Sébastien Pédron static inline void
teken_funcs_post_input(const teken_t * t)148547e74a8SJean-Sébastien Pédron teken_funcs_post_input(const teken_t *t)
149547e74a8SJean-Sébastien Pédron {
150547e74a8SJean-Sébastien Pédron
1514812c5c5SConrad Meyer if (t->t_funcs->tf_post_input != NULL)
152547e74a8SJean-Sébastien Pédron t->t_funcs->tf_post_input(t->t_softc);
153547e74a8SJean-Sébastien Pédron }
154547e74a8SJean-Sébastien Pédron
155547e74a8SJean-Sébastien Pédron static inline void
teken_funcs_param(const teken_t * t,int cmd,unsigned int value)15692223bddSPoul-Henning Kamp teken_funcs_param(const teken_t *t, int cmd, unsigned int value)
1579b934d09SEd Schouten {
1589b934d09SEd Schouten
15992223bddSPoul-Henning Kamp teken_assert(t->t_funcs->tf_param != NULL);
1609b934d09SEd Schouten t->t_funcs->tf_param(t->t_softc, cmd, value);
1619b934d09SEd Schouten }
1629b934d09SEd Schouten
1639b934d09SEd Schouten static inline void
teken_funcs_respond(const teken_t * t,const void * buf,size_t len)16492223bddSPoul-Henning Kamp teken_funcs_respond(const teken_t *t, const void *buf, size_t len)
1659b934d09SEd Schouten {
1669b934d09SEd Schouten
16792223bddSPoul-Henning Kamp teken_assert(t->t_funcs->tf_respond != NULL);
1689b934d09SEd Schouten t->t_funcs->tf_respond(t->t_softc, buf, len);
1699b934d09SEd Schouten }
1709b934d09SEd Schouten
1719b934d09SEd Schouten #include "teken_subr.h"
1729b934d09SEd Schouten #include "teken_subr_compat.h"
1739b934d09SEd Schouten
1749b934d09SEd Schouten /*
1759b934d09SEd Schouten * Programming interface.
1769b934d09SEd Schouten */
1779b934d09SEd Schouten
1789b934d09SEd Schouten void
teken_init(teken_t * t,const teken_funcs_t * tf,void * softc)1799b934d09SEd Schouten teken_init(teken_t *t, const teken_funcs_t *tf, void *softc)
1809b934d09SEd Schouten {
1819b934d09SEd Schouten teken_pos_t tp = { .tp_row = 24, .tp_col = 80 };
1829b934d09SEd Schouten
1839b934d09SEd Schouten t->t_funcs = tf;
1849b934d09SEd Schouten t->t_softc = softc;
1859b934d09SEd Schouten
1869b934d09SEd Schouten t->t_nextstate = teken_state_init;
187eba77f5cSEd Schouten t->t_stateflags = 0;
188eba77f5cSEd Schouten t->t_utf8_left = 0;
1899b934d09SEd Schouten
1909b934d09SEd Schouten t->t_defattr.ta_format = 0;
1919b934d09SEd Schouten t->t_defattr.ta_fgcolor = TC_WHITE;
1929b934d09SEd Schouten t->t_defattr.ta_bgcolor = TC_BLACK;
1939b934d09SEd Schouten teken_subr_do_reset(t);
1949b934d09SEd Schouten
1959b934d09SEd Schouten teken_set_winsize(t, &tp);
1969b934d09SEd Schouten }
1979b934d09SEd Schouten
1989b934d09SEd Schouten static void
teken_input_char(teken_t * t,teken_char_t c)1999b934d09SEd Schouten teken_input_char(teken_t *t, teken_char_t c)
2009b934d09SEd Schouten {
2019b934d09SEd Schouten
2024a11e7f1SEd Schouten /*
2034a11e7f1SEd Schouten * There is no support for DCS and OSC. Just discard strings
2044a11e7f1SEd Schouten * until we receive characters that may indicate string
2054a11e7f1SEd Schouten * termination.
2064a11e7f1SEd Schouten */
2074a11e7f1SEd Schouten if (t->t_stateflags & TS_INSTRING) {
2084a11e7f1SEd Schouten switch (c) {
2094a11e7f1SEd Schouten case '\x1B':
2104a11e7f1SEd Schouten t->t_stateflags &= ~TS_INSTRING;
2114a11e7f1SEd Schouten break;
2124a11e7f1SEd Schouten case '\a':
2134a11e7f1SEd Schouten t->t_stateflags &= ~TS_INSTRING;
2144a11e7f1SEd Schouten return;
2154a11e7f1SEd Schouten default:
2164a11e7f1SEd Schouten return;
2174a11e7f1SEd Schouten }
2184a11e7f1SEd Schouten }
2194a11e7f1SEd Schouten
2209b934d09SEd Schouten switch (c) {
2219b934d09SEd Schouten case '\0':
2229b934d09SEd Schouten break;
2239b934d09SEd Schouten case '\a':
2249b934d09SEd Schouten teken_subr_bell(t);
2259b934d09SEd Schouten break;
2269b934d09SEd Schouten case '\b':
2279b934d09SEd Schouten teken_subr_backspace(t);
2289b934d09SEd Schouten break;
2299b934d09SEd Schouten case '\n':
2309b934d09SEd Schouten case '\x0B':
2319b934d09SEd Schouten teken_subr_newline(t);
2329b934d09SEd Schouten break;
2339b934d09SEd Schouten case '\x0C':
2349b934d09SEd Schouten teken_subr_newpage(t);
2359b934d09SEd Schouten break;
2369b934d09SEd Schouten case '\x0E':
237eba77f5cSEd Schouten if (t->t_stateflags & TS_CONS25)
238eba77f5cSEd Schouten t->t_nextstate(t, c);
239eba77f5cSEd Schouten else
240cd531e74SEd Schouten t->t_curscs = 1;
2419b934d09SEd Schouten break;
2429b934d09SEd Schouten case '\x0F':
243eba77f5cSEd Schouten if (t->t_stateflags & TS_CONS25)
244eba77f5cSEd Schouten t->t_nextstate(t, c);
245eba77f5cSEd Schouten else
246cd531e74SEd Schouten t->t_curscs = 0;
2479b934d09SEd Schouten break;
2489b934d09SEd Schouten case '\r':
2499b934d09SEd Schouten teken_subr_carriage_return(t);
2509b934d09SEd Schouten break;
2519b934d09SEd Schouten case '\t':
2529b934d09SEd Schouten teken_subr_horizontal_tab(t);
2539b934d09SEd Schouten break;
2549b934d09SEd Schouten default:
2559b934d09SEd Schouten t->t_nextstate(t, c);
2569b934d09SEd Schouten break;
2579b934d09SEd Schouten }
2589b934d09SEd Schouten
2599b934d09SEd Schouten /* Post-processing assertions. */
2609b934d09SEd Schouten teken_assert(t->t_cursor.tp_row >= t->t_originreg.ts_begin);
2619b934d09SEd Schouten teken_assert(t->t_cursor.tp_row < t->t_originreg.ts_end);
2629b934d09SEd Schouten teken_assert(t->t_cursor.tp_row < t->t_winsize.tp_row);
2639b934d09SEd Schouten teken_assert(t->t_cursor.tp_col < t->t_winsize.tp_col);
2649b934d09SEd Schouten teken_assert(t->t_saved_cursor.tp_row < t->t_winsize.tp_row);
2659b934d09SEd Schouten teken_assert(t->t_saved_cursor.tp_col < t->t_winsize.tp_col);
2669b934d09SEd Schouten teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row);
2679b934d09SEd Schouten teken_assert(t->t_scrollreg.ts_begin < t->t_scrollreg.ts_end);
2689b934d09SEd Schouten /* Origin region has to be window size or the same as scrollreg. */
2699b934d09SEd Schouten teken_assert((t->t_originreg.ts_begin == t->t_scrollreg.ts_begin &&
2709b934d09SEd Schouten t->t_originreg.ts_end == t->t_scrollreg.ts_end) ||
2719b934d09SEd Schouten (t->t_originreg.ts_begin == 0 &&
2729b934d09SEd Schouten t->t_originreg.ts_end == t->t_winsize.tp_row));
2739b934d09SEd Schouten }
2749b934d09SEd Schouten
2759b934d09SEd Schouten static void
teken_input_byte(teken_t * t,unsigned char c)2769b934d09SEd Schouten teken_input_byte(teken_t *t, unsigned char c)
2779b934d09SEd Schouten {
2789b934d09SEd Schouten
2799b934d09SEd Schouten /*
2809b934d09SEd Schouten * UTF-8 handling.
2819b934d09SEd Schouten */
282eba77f5cSEd Schouten if ((c & 0x80) == 0x00 || t->t_stateflags & TS_8BIT) {
2839b934d09SEd Schouten /* One-byte sequence. */
2849b934d09SEd Schouten t->t_utf8_left = 0;
2859b934d09SEd Schouten teken_input_char(t, c);
2869b934d09SEd Schouten } else if ((c & 0xe0) == 0xc0) {
2879b934d09SEd Schouten /* Two-byte sequence. */
2889b934d09SEd Schouten t->t_utf8_left = 1;
2899b934d09SEd Schouten t->t_utf8_partial = c & 0x1f;
2909b934d09SEd Schouten } else if ((c & 0xf0) == 0xe0) {
2919b934d09SEd Schouten /* Three-byte sequence. */
2929b934d09SEd Schouten t->t_utf8_left = 2;
2939b934d09SEd Schouten t->t_utf8_partial = c & 0x0f;
2949b934d09SEd Schouten } else if ((c & 0xf8) == 0xf0) {
2959b934d09SEd Schouten /* Four-byte sequence. */
2969b934d09SEd Schouten t->t_utf8_left = 3;
2979b934d09SEd Schouten t->t_utf8_partial = c & 0x07;
2989b934d09SEd Schouten } else if ((c & 0xc0) == 0x80) {
2999b934d09SEd Schouten if (t->t_utf8_left == 0)
3009b934d09SEd Schouten return;
3019b934d09SEd Schouten t->t_utf8_left--;
3029b934d09SEd Schouten t->t_utf8_partial = (t->t_utf8_partial << 6) | (c & 0x3f);
3039b934d09SEd Schouten if (t->t_utf8_left == 0) {
3049b934d09SEd Schouten teken_printf("Got UTF-8 char %x\n", t->t_utf8_partial);
3059b934d09SEd Schouten teken_input_char(t, t->t_utf8_partial);
3069b934d09SEd Schouten }
3079b934d09SEd Schouten }
3089b934d09SEd Schouten }
3099b934d09SEd Schouten
3109b934d09SEd Schouten void
teken_input(teken_t * t,const void * buf,size_t len)3119b934d09SEd Schouten teken_input(teken_t *t, const void *buf, size_t len)
3129b934d09SEd Schouten {
3139b934d09SEd Schouten const char *c = buf;
3149b934d09SEd Schouten
315547e74a8SJean-Sébastien Pédron teken_funcs_pre_input(t);
3169b934d09SEd Schouten while (len-- > 0)
3179b934d09SEd Schouten teken_input_byte(t, *c++);
318547e74a8SJean-Sébastien Pédron teken_funcs_post_input(t);
3199b934d09SEd Schouten }
3209b934d09SEd Schouten
321eba77f5cSEd Schouten const teken_pos_t *
teken_get_cursor(const teken_t * t)32292223bddSPoul-Henning Kamp teken_get_cursor(const teken_t *t)
323eba77f5cSEd Schouten {
324eba77f5cSEd Schouten
325eba77f5cSEd Schouten return (&t->t_cursor);
326eba77f5cSEd Schouten }
327eba77f5cSEd Schouten
3289b934d09SEd Schouten void
teken_set_cursor(teken_t * t,const teken_pos_t * p)3299b934d09SEd Schouten teken_set_cursor(teken_t *t, const teken_pos_t *p)
3309b934d09SEd Schouten {
3319b934d09SEd Schouten
3329b934d09SEd Schouten /* XXX: bounds checking with originreg! */
3339b934d09SEd Schouten teken_assert(p->tp_row < t->t_winsize.tp_row);
3349b934d09SEd Schouten teken_assert(p->tp_col < t->t_winsize.tp_col);
3359b934d09SEd Schouten
3369b934d09SEd Schouten t->t_cursor = *p;
3379b934d09SEd Schouten }
3389b934d09SEd Schouten
3399b934d09SEd Schouten const teken_attr_t *
teken_get_curattr(const teken_t * t)34092223bddSPoul-Henning Kamp teken_get_curattr(const teken_t *t)
3419b934d09SEd Schouten {
3429b934d09SEd Schouten
3439b934d09SEd Schouten return (&t->t_curattr);
3449b934d09SEd Schouten }
3459b934d09SEd Schouten
3469b934d09SEd Schouten void
teken_set_curattr(teken_t * t,const teken_attr_t * a)3479b934d09SEd Schouten teken_set_curattr(teken_t *t, const teken_attr_t *a)
3489b934d09SEd Schouten {
3499b934d09SEd Schouten
3509b934d09SEd Schouten t->t_curattr = *a;
3519b934d09SEd Schouten }
3529b934d09SEd Schouten
3539b934d09SEd Schouten const teken_attr_t *
teken_get_defattr(const teken_t * t)35492223bddSPoul-Henning Kamp teken_get_defattr(const teken_t *t)
3559b934d09SEd Schouten {
3569b934d09SEd Schouten
3579b934d09SEd Schouten return (&t->t_defattr);
3589b934d09SEd Schouten }
3599b934d09SEd Schouten
3609b934d09SEd Schouten void
teken_set_defattr(teken_t * t,const teken_attr_t * a)3619b934d09SEd Schouten teken_set_defattr(teken_t *t, const teken_attr_t *a)
3629b934d09SEd Schouten {
3639b934d09SEd Schouten
3649b934d09SEd Schouten t->t_curattr = t->t_saved_curattr = t->t_defattr = *a;
3659b934d09SEd Schouten }
3669b934d09SEd Schouten
367eba77f5cSEd Schouten const teken_pos_t *
teken_get_winsize(const teken_t * t)36892223bddSPoul-Henning Kamp teken_get_winsize(const teken_t *t)
369eba77f5cSEd Schouten {
370eba77f5cSEd Schouten
371eba77f5cSEd Schouten return (&t->t_winsize);
372eba77f5cSEd Schouten }
373eba77f5cSEd Schouten
374f821d023SAleksandr Rybalko static void
teken_trim_cursor_pos(teken_t * t,const teken_pos_t * new)3750205ddebSAleksandr Rybalko teken_trim_cursor_pos(teken_t *t, const teken_pos_t *new)
376f821d023SAleksandr Rybalko {
377f821d023SAleksandr Rybalko const teken_pos_t *cur;
378f821d023SAleksandr Rybalko
379f821d023SAleksandr Rybalko cur = &t->t_winsize;
380f821d023SAleksandr Rybalko
381f821d023SAleksandr Rybalko if (cur->tp_row < new->tp_row || cur->tp_col < new->tp_col)
382f821d023SAleksandr Rybalko return;
383f821d023SAleksandr Rybalko if (t->t_cursor.tp_row >= new->tp_row)
384f821d023SAleksandr Rybalko t->t_cursor.tp_row = new->tp_row - 1;
385f821d023SAleksandr Rybalko if (t->t_cursor.tp_col >= new->tp_col)
386f821d023SAleksandr Rybalko t->t_cursor.tp_col = new->tp_col - 1;
387f821d023SAleksandr Rybalko }
388f821d023SAleksandr Rybalko
3899b934d09SEd Schouten void
teken_set_winsize(teken_t * t,const teken_pos_t * p)3909b934d09SEd Schouten teken_set_winsize(teken_t *t, const teken_pos_t *p)
3919b934d09SEd Schouten {
3929b934d09SEd Schouten
3930205ddebSAleksandr Rybalko teken_trim_cursor_pos(t, p);
3949b934d09SEd Schouten t->t_winsize = *p;
395b03552b5SEd Schouten teken_subr_do_reset(t);
3969b934d09SEd Schouten }
3979b934d09SEd Schouten
398e06d84fcSEd Schouten void
teken_set_winsize_noreset(teken_t * t,const teken_pos_t * p)39927cf7d04SAleksandr Rybalko teken_set_winsize_noreset(teken_t *t, const teken_pos_t *p)
40027cf7d04SAleksandr Rybalko {
40127cf7d04SAleksandr Rybalko
4020205ddebSAleksandr Rybalko teken_trim_cursor_pos(t, p);
40327cf7d04SAleksandr Rybalko t->t_winsize = *p;
40427cf7d04SAleksandr Rybalko teken_subr_do_resize(t);
40527cf7d04SAleksandr Rybalko }
40627cf7d04SAleksandr Rybalko
40727cf7d04SAleksandr Rybalko void
teken_set_8bit(teken_t * t)408e06d84fcSEd Schouten teken_set_8bit(teken_t *t)
409e06d84fcSEd Schouten {
410e06d84fcSEd Schouten
411eba77f5cSEd Schouten t->t_stateflags |= TS_8BIT;
412eba77f5cSEd Schouten }
413eba77f5cSEd Schouten
414eba77f5cSEd Schouten void
teken_set_cons25(teken_t * t)415eba77f5cSEd Schouten teken_set_cons25(teken_t *t)
416eba77f5cSEd Schouten {
417eba77f5cSEd Schouten
4183a199184SBruce Evans t->t_stateflags |= TS_CONS25;
4193a199184SBruce Evans }
4203a199184SBruce Evans
4213a199184SBruce Evans void
teken_set_cons25keys(teken_t * t)4223a199184SBruce Evans teken_set_cons25keys(teken_t *t)
4233a199184SBruce Evans {
4243a199184SBruce Evans
4253a199184SBruce Evans t->t_stateflags |= TS_CONS25KEYS;
426e06d84fcSEd Schouten }
427e06d84fcSEd Schouten
4289b934d09SEd Schouten /*
4299b934d09SEd Schouten * State machine.
4309b934d09SEd Schouten */
4319b934d09SEd Schouten
4329b934d09SEd Schouten static void
teken_state_switch(teken_t * t,teken_state_t * s)4339b934d09SEd Schouten teken_state_switch(teken_t *t, teken_state_t *s)
4349b934d09SEd Schouten {
4359b934d09SEd Schouten
4369b934d09SEd Schouten t->t_nextstate = s;
4379b934d09SEd Schouten t->t_curnum = 0;
4389b934d09SEd Schouten t->t_stateflags |= TS_FIRSTDIGIT;
4399b934d09SEd Schouten }
4409b934d09SEd Schouten
4419b934d09SEd Schouten static int
teken_state_numbers(teken_t * t,teken_char_t c)4429b934d09SEd Schouten teken_state_numbers(teken_t *t, teken_char_t c)
4439b934d09SEd Schouten {
4449b934d09SEd Schouten
4459b934d09SEd Schouten teken_assert(t->t_curnum < T_NUMSIZE);
4469b934d09SEd Schouten
4479b934d09SEd Schouten if (c >= '0' && c <= '9') {
4489b934d09SEd Schouten if (t->t_stateflags & TS_FIRSTDIGIT) {
449c5b3acf2SEd Schouten /* First digit. */
4509b934d09SEd Schouten t->t_stateflags &= ~TS_FIRSTDIGIT;
451c5b3acf2SEd Schouten t->t_nums[t->t_curnum] = c - '0';
452cd69db4bSEd Schouten } else if (t->t_nums[t->t_curnum] < UINT_MAX / 100) {
453c5b3acf2SEd Schouten /*
454cd69db4bSEd Schouten * There is no need to continue parsing input
455cd69db4bSEd Schouten * once the value exceeds the size of the
456cd69db4bSEd Schouten * terminal. It would only allow for integer
457cd69db4bSEd Schouten * overflows when performing arithmetic on the
458cd69db4bSEd Schouten * cursor position.
459cd69db4bSEd Schouten *
460cd69db4bSEd Schouten * Ignore any further digits if the value is
461cd69db4bSEd Schouten * already UINT_MAX / 100.
462c5b3acf2SEd Schouten */
463c5b3acf2SEd Schouten t->t_nums[t->t_curnum] =
464c5b3acf2SEd Schouten t->t_nums[t->t_curnum] * 10 + c - '0';
4659b934d09SEd Schouten }
4669b934d09SEd Schouten return (1);
4679b934d09SEd Schouten } else if (c == ';') {
4689b934d09SEd Schouten if (t->t_stateflags & TS_FIRSTDIGIT)
4699b934d09SEd Schouten t->t_nums[t->t_curnum] = 0;
4709b934d09SEd Schouten
4719b934d09SEd Schouten /* Only allow a limited set of arguments. */
4729b934d09SEd Schouten if (++t->t_curnum == T_NUMSIZE) {
4739b934d09SEd Schouten teken_state_switch(t, teken_state_init);
4749b934d09SEd Schouten return (1);
4759b934d09SEd Schouten }
4769b934d09SEd Schouten
4779b934d09SEd Schouten t->t_stateflags |= TS_FIRSTDIGIT;
4789b934d09SEd Schouten return (1);
4799b934d09SEd Schouten } else {
4809b934d09SEd Schouten if (t->t_stateflags & TS_FIRSTDIGIT && t->t_curnum > 0) {
4819b934d09SEd Schouten /* Finish off the last empty argument. */
4829b934d09SEd Schouten t->t_nums[t->t_curnum] = 0;
4839b934d09SEd Schouten t->t_curnum++;
4849b934d09SEd Schouten } else if ((t->t_stateflags & TS_FIRSTDIGIT) == 0) {
4859b934d09SEd Schouten /* Also count the last argument. */
4869b934d09SEd Schouten t->t_curnum++;
4879b934d09SEd Schouten }
4889b934d09SEd Schouten }
4899b934d09SEd Schouten
4909b934d09SEd Schouten return (0);
4919b934d09SEd Schouten }
4929b934d09SEd Schouten
4932610c9f2SBruce Evans #define k TC_BLACK
4942610c9f2SBruce Evans #define b TC_BLUE
495cf8880d5SEd Maste #define y TC_YELLOW
4962610c9f2SBruce Evans #define c TC_CYAN
4972610c9f2SBruce Evans #define g TC_GREEN
4982610c9f2SBruce Evans #define m TC_MAGENTA
4992610c9f2SBruce Evans #define r TC_RED
5002610c9f2SBruce Evans #define w TC_WHITE
5012610c9f2SBruce Evans #define K (TC_BLACK | TC_LIGHT)
5022610c9f2SBruce Evans #define B (TC_BLUE | TC_LIGHT)
503cf8880d5SEd Maste #define Y (TC_YELLOW | TC_LIGHT)
5042610c9f2SBruce Evans #define C (TC_CYAN | TC_LIGHT)
5052610c9f2SBruce Evans #define G (TC_GREEN | TC_LIGHT)
5062610c9f2SBruce Evans #define M (TC_MAGENTA | TC_LIGHT)
5072610c9f2SBruce Evans #define R (TC_RED | TC_LIGHT)
5082610c9f2SBruce Evans #define W (TC_WHITE | TC_LIGHT)
5092610c9f2SBruce Evans
5102610c9f2SBruce Evans /**
5112610c9f2SBruce Evans * The xterm-256 color map has steps of 0x28 (in the range 0-0xff), except
5122610c9f2SBruce Evans * for the first step which is 0x5f. Scale to the range 0-6 by dividing
5132610c9f2SBruce Evans * by 0x28 and rounding down. The range of 0-5 cannot represent the
5142610c9f2SBruce Evans * larger first step.
5152610c9f2SBruce Evans *
5162610c9f2SBruce Evans * This table is generated by the follow rules:
5172610c9f2SBruce Evans * - if all components are equal, the result is black for (0, 0, 0) and
5182610c9f2SBruce Evans * (2, 2, 2), else white; otherwise:
5192610c9f2SBruce Evans * - subtract the smallest component from all components
5202610c9f2SBruce Evans * - if this gives only one nonzero component, then that is the color
5212610c9f2SBruce Evans * - else if one component is 2 or more larger than the other nonzero one,
5222610c9f2SBruce Evans * then that component gives the color
5232610c9f2SBruce Evans * - else there are 2 nonzero components. The color is that of a small
5242610c9f2SBruce Evans * equal mixture of these components (cyan, yellow or magenta). E.g.,
5252610c9f2SBruce Evans * (0, 5, 6) (Turquoise2) is a much purer cyan than (0, 2, 3)
5262610c9f2SBruce Evans * (DeepSkyBlue4), but we map both to cyan since we can't represent
5272610c9f2SBruce Evans * delicate shades of either blue or cyan and blue would be worse.
5282610c9f2SBruce Evans * Here it is important that components of 1 never occur. Blue would
5292610c9f2SBruce Evans * be twice as large as green in (0, 1, 2).
5302610c9f2SBruce Evans */
5312610c9f2SBruce Evans static const teken_color_t teken_256to8tab[] = {
5321370fa33SBruce Evans /* xterm normal colors: */
5331370fa33SBruce Evans k, r, g, y, b, m, c, w,
5342610c9f2SBruce Evans
5351370fa33SBruce Evans /* xterm bright colors: */
5361370fa33SBruce Evans k, r, g, y, b, m, c, w,
5372610c9f2SBruce Evans
5382610c9f2SBruce Evans /* Red0 submap. */
5392610c9f2SBruce Evans k, b, b, b, b, b,
5402610c9f2SBruce Evans g, c, c, b, b, b,
5412610c9f2SBruce Evans g, c, c, c, b, b,
5422610c9f2SBruce Evans g, g, c, c, c, b,
5432610c9f2SBruce Evans g, g, g, c, c, c,
5442610c9f2SBruce Evans g, g, g, g, c, c,
5452610c9f2SBruce Evans
5462610c9f2SBruce Evans /* Red2 submap. */
5472610c9f2SBruce Evans r, m, m, b, b, b,
5482610c9f2SBruce Evans y, k, b, b, b, b,
5492610c9f2SBruce Evans y, g, c, c, b, b,
5502610c9f2SBruce Evans g, g, c, c, c, b,
5512610c9f2SBruce Evans g, g, g, c, c, c,
5522610c9f2SBruce Evans g, g, g, g, c, c,
5532610c9f2SBruce Evans
5542610c9f2SBruce Evans /* Red3 submap. */
5552610c9f2SBruce Evans r, m, m, m, b, b,
5562610c9f2SBruce Evans y, r, m, m, b, b,
5572610c9f2SBruce Evans y, y, w, b, b, b,
5582610c9f2SBruce Evans y, y, g, c, c, b,
5592610c9f2SBruce Evans g, g, g, c, c, c,
5602610c9f2SBruce Evans g, g, g, g, c, c,
5612610c9f2SBruce Evans
5622610c9f2SBruce Evans /* Red4 submap. */
5632610c9f2SBruce Evans r, r, m, m, m, b,
5642610c9f2SBruce Evans r, r, m, m, m, b,
5652610c9f2SBruce Evans y, y, r, m, m, b,
5662610c9f2SBruce Evans y, y, y, w, b, b,
5672610c9f2SBruce Evans y, y, y, g, c, c,
5682610c9f2SBruce Evans g, g, g, g, c, c,
5692610c9f2SBruce Evans
5702610c9f2SBruce Evans /* Red5 submap. */
5712610c9f2SBruce Evans r, r, r, m, m, m,
5722610c9f2SBruce Evans r, r, r, m, m, m,
5732610c9f2SBruce Evans r, r, r, m, m, m,
5742610c9f2SBruce Evans y, y, y, r, m, m,
5752610c9f2SBruce Evans y, y, y, y, w, b,
5762610c9f2SBruce Evans y, y, y, y, g, c,
5772610c9f2SBruce Evans
5782610c9f2SBruce Evans /* Red6 submap. */
5792610c9f2SBruce Evans r, r, r, r, m, m,
5802610c9f2SBruce Evans r, r, r, r, m, m,
5812610c9f2SBruce Evans r, r, r, r, m, m,
5822610c9f2SBruce Evans r, r, r, r, m, m,
5832610c9f2SBruce Evans y, y, y, y, r, m,
5842610c9f2SBruce Evans y, y, y, y, y, w,
5852610c9f2SBruce Evans
5862610c9f2SBruce Evans /* Grey submap. */
5872610c9f2SBruce Evans k, k, k, k, k, k,
5882610c9f2SBruce Evans k, k, k, k, k, k,
5892610c9f2SBruce Evans w, w, w, w, w, w,
5902610c9f2SBruce Evans w, w, w, w, w, w,
5912610c9f2SBruce Evans };
5922610c9f2SBruce Evans
5932610c9f2SBruce Evans /*
5942610c9f2SBruce Evans * This table is generated from the previous one by setting TC_LIGHT for
5952610c9f2SBruce Evans * entries whose luminosity in the xterm256 color map is 60% or larger.
5962610c9f2SBruce Evans * Thus the previous table is currently not really needed. It will be
5972610c9f2SBruce Evans * used for different fine tuning of the tables.
5982610c9f2SBruce Evans */
5992610c9f2SBruce Evans static const teken_color_t teken_256to16tab[] = {
6001370fa33SBruce Evans /* xterm normal colors: */
6011370fa33SBruce Evans k, r, g, y, b, m, c, w,
6022610c9f2SBruce Evans
6031370fa33SBruce Evans /* xterm bright colors: */
6041370fa33SBruce Evans K, R, G, Y, B, M, C, W,
6052610c9f2SBruce Evans
6062610c9f2SBruce Evans /* Red0 submap. */
6072610c9f2SBruce Evans k, b, b, b, b, b,
6082610c9f2SBruce Evans g, c, c, b, b, b,
6092610c9f2SBruce Evans g, c, c, c, b, b,
6102610c9f2SBruce Evans g, g, c, c, c, b,
6112610c9f2SBruce Evans g, g, g, c, c, c,
6122610c9f2SBruce Evans g, g, g, g, c, c,
6132610c9f2SBruce Evans
6142610c9f2SBruce Evans /* Red2 submap. */
6152610c9f2SBruce Evans r, m, m, b, b, b,
6162610c9f2SBruce Evans y, K, b, b, B, B,
6172610c9f2SBruce Evans y, g, c, c, B, B,
6182610c9f2SBruce Evans g, g, c, c, C, B,
6192610c9f2SBruce Evans g, G, G, C, C, C,
6202610c9f2SBruce Evans g, G, G, G, C, C,
6212610c9f2SBruce Evans
6222610c9f2SBruce Evans /* Red3 submap. */
6232610c9f2SBruce Evans r, m, m, m, b, b,
6242610c9f2SBruce Evans y, r, m, m, B, B,
6252610c9f2SBruce Evans y, y, w, B, B, B,
6262610c9f2SBruce Evans y, y, G, C, C, B,
6272610c9f2SBruce Evans g, G, G, C, C, C,
6282610c9f2SBruce Evans g, G, G, G, C, C,
6292610c9f2SBruce Evans
6302610c9f2SBruce Evans /* Red4 submap. */
6312610c9f2SBruce Evans r, r, m, m, m, b,
6322610c9f2SBruce Evans r, r, m, m, M, B,
6332610c9f2SBruce Evans y, y, R, M, M, B,
6342610c9f2SBruce Evans y, y, Y, W, B, B,
6352610c9f2SBruce Evans y, Y, Y, G, C, C,
6362610c9f2SBruce Evans g, G, G, G, C, C,
6372610c9f2SBruce Evans
6382610c9f2SBruce Evans /* Red5 submap. */
6392610c9f2SBruce Evans r, r, r, m, m, m,
6402610c9f2SBruce Evans r, R, R, M, M, M,
6412610c9f2SBruce Evans r, R, R, M, M, M,
6422610c9f2SBruce Evans y, Y, Y, R, M, M,
6432610c9f2SBruce Evans y, Y, Y, Y, W, B,
6442610c9f2SBruce Evans y, Y, Y, Y, G, C,
6452610c9f2SBruce Evans
6462610c9f2SBruce Evans /* Red6 submap. */
6472610c9f2SBruce Evans r, r, r, r, m, m,
6482610c9f2SBruce Evans r, R, R, R, M, M,
6492610c9f2SBruce Evans r, R, R, R, M, M,
6502610c9f2SBruce Evans r, R, R, R, M, M,
6512610c9f2SBruce Evans y, Y, Y, Y, R, M,
6522610c9f2SBruce Evans y, Y, Y, Y, Y, W,
6532610c9f2SBruce Evans
6542610c9f2SBruce Evans /* Grey submap. */
6552610c9f2SBruce Evans k, k, k, k, k, k,
6562610c9f2SBruce Evans K, K, K, K, K, K,
6572610c9f2SBruce Evans w, w, w, w, w, w,
6582610c9f2SBruce Evans W, W, W, W, W, W,
6592610c9f2SBruce Evans };
6602610c9f2SBruce Evans
6612610c9f2SBruce Evans #undef k
6622610c9f2SBruce Evans #undef b
6632610c9f2SBruce Evans #undef y
6642610c9f2SBruce Evans #undef c
6652610c9f2SBruce Evans #undef g
6662610c9f2SBruce Evans #undef m
6672610c9f2SBruce Evans #undef r
6682610c9f2SBruce Evans #undef w
6692610c9f2SBruce Evans #undef K
6702610c9f2SBruce Evans #undef B
6712610c9f2SBruce Evans #undef Y
6722610c9f2SBruce Evans #undef C
6732610c9f2SBruce Evans #undef G
6742610c9f2SBruce Evans #undef M
6752610c9f2SBruce Evans #undef R
6762610c9f2SBruce Evans #undef W
6772610c9f2SBruce Evans
67856a4365bSEd Schouten teken_color_t
teken_256to8(teken_color_t c)67956a4365bSEd Schouten teken_256to8(teken_color_t c)
68056a4365bSEd Schouten {
68156a4365bSEd Schouten
6822610c9f2SBruce Evans return (teken_256to8tab[c % 256]);
68356a4365bSEd Schouten }
68456a4365bSEd Schouten
6852610c9f2SBruce Evans teken_color_t
teken_256to16(teken_color_t c)6862610c9f2SBruce Evans teken_256to16(teken_color_t c)
6872610c9f2SBruce Evans {
68856a4365bSEd Schouten
6892610c9f2SBruce Evans return (teken_256to16tab[c % 256]);
69056a4365bSEd Schouten }
69156a4365bSEd Schouten
6923a8a07eaSEd Schouten static const char * const special_strings_cons25[] = {
6933a8a07eaSEd Schouten [TKEY_UP] = "\x1B[A", [TKEY_DOWN] = "\x1B[B",
6943a8a07eaSEd Schouten [TKEY_LEFT] = "\x1B[D", [TKEY_RIGHT] = "\x1B[C",
6953a8a07eaSEd Schouten
6963a8a07eaSEd Schouten [TKEY_HOME] = "\x1B[H", [TKEY_END] = "\x1B[F",
697d80a1e6cSEd Schouten [TKEY_INSERT] = "\x1B[L", [TKEY_DELETE] = "\x7F",
6983a8a07eaSEd Schouten [TKEY_PAGE_UP] = "\x1B[I", [TKEY_PAGE_DOWN] = "\x1B[G",
6993a8a07eaSEd Schouten
7003a8a07eaSEd Schouten [TKEY_F1] = "\x1B[M", [TKEY_F2] = "\x1B[N",
7013a8a07eaSEd Schouten [TKEY_F3] = "\x1B[O", [TKEY_F4] = "\x1B[P",
7023a8a07eaSEd Schouten [TKEY_F5] = "\x1B[Q", [TKEY_F6] = "\x1B[R",
7033a8a07eaSEd Schouten [TKEY_F7] = "\x1B[S", [TKEY_F8] = "\x1B[T",
7043a8a07eaSEd Schouten [TKEY_F9] = "\x1B[U", [TKEY_F10] = "\x1B[V",
7053a8a07eaSEd Schouten [TKEY_F11] = "\x1B[W", [TKEY_F12] = "\x1B[X",
7063a8a07eaSEd Schouten };
7073a8a07eaSEd Schouten
7083a8a07eaSEd Schouten static const char * const special_strings_ckeys[] = {
7093a8a07eaSEd Schouten [TKEY_UP] = "\x1BOA", [TKEY_DOWN] = "\x1BOB",
7103a8a07eaSEd Schouten [TKEY_LEFT] = "\x1BOD", [TKEY_RIGHT] = "\x1BOC",
7113a8a07eaSEd Schouten
7123a8a07eaSEd Schouten [TKEY_HOME] = "\x1BOH", [TKEY_END] = "\x1BOF",
7133a8a07eaSEd Schouten };
7143a8a07eaSEd Schouten
7153a8a07eaSEd Schouten static const char * const special_strings_normal[] = {
7163a8a07eaSEd Schouten [TKEY_UP] = "\x1B[A", [TKEY_DOWN] = "\x1B[B",
7173a8a07eaSEd Schouten [TKEY_LEFT] = "\x1B[D", [TKEY_RIGHT] = "\x1B[C",
7183a8a07eaSEd Schouten
7193a8a07eaSEd Schouten [TKEY_HOME] = "\x1B[H", [TKEY_END] = "\x1B[F",
720d80a1e6cSEd Schouten [TKEY_INSERT] = "\x1B[2~", [TKEY_DELETE] = "\x1B[3~",
7213a8a07eaSEd Schouten [TKEY_PAGE_UP] = "\x1B[5~", [TKEY_PAGE_DOWN] = "\x1B[6~",
7223a8a07eaSEd Schouten
7233a8a07eaSEd Schouten [TKEY_F1] = "\x1BOP", [TKEY_F2] = "\x1BOQ",
7243a8a07eaSEd Schouten [TKEY_F3] = "\x1BOR", [TKEY_F4] = "\x1BOS",
7253a8a07eaSEd Schouten [TKEY_F5] = "\x1B[15~", [TKEY_F6] = "\x1B[17~",
7263a8a07eaSEd Schouten [TKEY_F7] = "\x1B[18~", [TKEY_F8] = "\x1B[19~",
7273a8a07eaSEd Schouten [TKEY_F9] = "\x1B[20~", [TKEY_F10] = "\x1B[21~",
7283a8a07eaSEd Schouten [TKEY_F11] = "\x1B[23~", [TKEY_F12] = "\x1B[24~",
7293a8a07eaSEd Schouten };
7303a8a07eaSEd Schouten
7313a8a07eaSEd Schouten const char *
teken_get_sequence(const teken_t * t,unsigned int k)73292223bddSPoul-Henning Kamp teken_get_sequence(const teken_t *t, unsigned int k)
7333a8a07eaSEd Schouten {
7343a8a07eaSEd Schouten
7353a8a07eaSEd Schouten /* Cons25 mode. */
73690bdbe95SBruce Evans if ((t->t_stateflags & (TS_CONS25 | TS_CONS25KEYS)) ==
73790bdbe95SBruce Evans (TS_CONS25 | TS_CONS25KEYS))
73890bdbe95SBruce Evans return (NULL); /* Don't override good kbd(4) strings. */
7393a8a07eaSEd Schouten if (t->t_stateflags & TS_CONS25 &&
7403a8a07eaSEd Schouten k < sizeof special_strings_cons25 / sizeof(char *))
7413a8a07eaSEd Schouten return (special_strings_cons25[k]);
7423a8a07eaSEd Schouten
7433a8a07eaSEd Schouten /* Cursor keys mode. */
7443a8a07eaSEd Schouten if (t->t_stateflags & TS_CURSORKEYS &&
7453a8a07eaSEd Schouten k < sizeof special_strings_ckeys / sizeof(char *))
7463a8a07eaSEd Schouten return (special_strings_ckeys[k]);
7473a8a07eaSEd Schouten
7483a8a07eaSEd Schouten /* Default xterm sequences. */
7493a8a07eaSEd Schouten if (k < sizeof special_strings_normal / sizeof(char *))
7503a8a07eaSEd Schouten return (special_strings_normal[k]);
7513a8a07eaSEd Schouten
7523a8a07eaSEd Schouten return (NULL);
7533a8a07eaSEd Schouten }
7543a8a07eaSEd Schouten
7559b934d09SEd Schouten #include "teken_state.h"
756