127cf7d04SAleksandr Rybalko /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
38a36da99SPedro F. Giffuni *
427cf7d04SAleksandr Rybalko * Copyright (c) 2009 The FreeBSD Foundation
527cf7d04SAleksandr Rybalko *
627cf7d04SAleksandr Rybalko * This software was developed by Ed Schouten under sponsorship from the
727cf7d04SAleksandr Rybalko * FreeBSD Foundation.
827cf7d04SAleksandr Rybalko *
927cf7d04SAleksandr Rybalko * Redistribution and use in source and binary forms, with or without
1027cf7d04SAleksandr Rybalko * modification, are permitted provided that the following conditions
1127cf7d04SAleksandr Rybalko * are met:
1227cf7d04SAleksandr Rybalko * 1. Redistributions of source code must retain the above copyright
1327cf7d04SAleksandr Rybalko * notice, this list of conditions and the following disclaimer.
1427cf7d04SAleksandr Rybalko * 2. Redistributions in binary form must reproduce the above copyright
1527cf7d04SAleksandr Rybalko * notice, this list of conditions and the following disclaimer in the
1627cf7d04SAleksandr Rybalko * documentation and/or other materials provided with the distribution.
1727cf7d04SAleksandr Rybalko *
1827cf7d04SAleksandr Rybalko * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1927cf7d04SAleksandr Rybalko * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2027cf7d04SAleksandr Rybalko * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2127cf7d04SAleksandr Rybalko * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2227cf7d04SAleksandr Rybalko * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2327cf7d04SAleksandr Rybalko * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2427cf7d04SAleksandr Rybalko * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2527cf7d04SAleksandr Rybalko * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2627cf7d04SAleksandr Rybalko * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2727cf7d04SAleksandr Rybalko * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2827cf7d04SAleksandr Rybalko * SUCH DAMAGE.
2927cf7d04SAleksandr Rybalko */
3027cf7d04SAleksandr Rybalko
3127cf7d04SAleksandr Rybalko #include <sys/param.h>
3227cf7d04SAleksandr Rybalko #include <sys/cons.h>
3327cf7d04SAleksandr Rybalko #include <sys/consio.h>
3427cf7d04SAleksandr Rybalko #include <sys/kernel.h>
3527cf7d04SAleksandr Rybalko #include <sys/lock.h>
3627cf7d04SAleksandr Rybalko #include <sys/malloc.h>
3727cf7d04SAleksandr Rybalko #include <sys/mutex.h>
3827cf7d04SAleksandr Rybalko #include <sys/systm.h>
3927cf7d04SAleksandr Rybalko #include <sys/terminal.h>
4027cf7d04SAleksandr Rybalko #include <sys/tty.h>
4127cf7d04SAleksandr Rybalko
4227cf7d04SAleksandr Rybalko #include <machine/stdarg.h>
4327cf7d04SAleksandr Rybalko
4427cf7d04SAleksandr Rybalko static MALLOC_DEFINE(M_TERMINAL, "terminal", "terminal device");
4527cf7d04SAleksandr Rybalko
4627cf7d04SAleksandr Rybalko /*
4727cf7d04SAleksandr Rybalko * Locking.
4827cf7d04SAleksandr Rybalko *
4927cf7d04SAleksandr Rybalko * Normally we don't need to lock down the terminal emulator, because
5027cf7d04SAleksandr Rybalko * the TTY lock is already held when calling teken_input().
5127cf7d04SAleksandr Rybalko * Unfortunately this is not the case when the terminal acts as a
5227cf7d04SAleksandr Rybalko * console device, because cnputc() can be called at the same time.
5327cf7d04SAleksandr Rybalko * This means terminals may need to be locked down using a spin lock.
5427cf7d04SAleksandr Rybalko */
5527cf7d04SAleksandr Rybalko #define TERMINAL_LOCK(tm) do { \
5627cf7d04SAleksandr Rybalko if ((tm)->tm_flags & TF_CONS) \
5727cf7d04SAleksandr Rybalko mtx_lock_spin(&(tm)->tm_mtx); \
5827cf7d04SAleksandr Rybalko else if ((tm)->tm_tty != NULL) \
5927cf7d04SAleksandr Rybalko tty_lock((tm)->tm_tty); \
6027cf7d04SAleksandr Rybalko } while (0)
6127cf7d04SAleksandr Rybalko #define TERMINAL_UNLOCK(tm) do { \
6227cf7d04SAleksandr Rybalko if ((tm)->tm_flags & TF_CONS) \
6327cf7d04SAleksandr Rybalko mtx_unlock_spin(&(tm)->tm_mtx); \
6427cf7d04SAleksandr Rybalko else if ((tm)->tm_tty != NULL) \
6527cf7d04SAleksandr Rybalko tty_unlock((tm)->tm_tty); \
6627cf7d04SAleksandr Rybalko } while (0)
6727cf7d04SAleksandr Rybalko #define TERMINAL_LOCK_TTY(tm) do { \
6827cf7d04SAleksandr Rybalko if ((tm)->tm_flags & TF_CONS) \
6927cf7d04SAleksandr Rybalko mtx_lock_spin(&(tm)->tm_mtx); \
7027cf7d04SAleksandr Rybalko } while (0)
7127cf7d04SAleksandr Rybalko #define TERMINAL_UNLOCK_TTY(tm) do { \
7227cf7d04SAleksandr Rybalko if ((tm)->tm_flags & TF_CONS) \
7327cf7d04SAleksandr Rybalko mtx_unlock_spin(&(tm)->tm_mtx); \
7427cf7d04SAleksandr Rybalko } while (0)
7527cf7d04SAleksandr Rybalko #define TERMINAL_LOCK_CONS(tm) mtx_lock_spin(&(tm)->tm_mtx)
7627cf7d04SAleksandr Rybalko #define TERMINAL_UNLOCK_CONS(tm) mtx_unlock_spin(&(tm)->tm_mtx)
7727cf7d04SAleksandr Rybalko
7827cf7d04SAleksandr Rybalko /*
7927cf7d04SAleksandr Rybalko * TTY routines.
8027cf7d04SAleksandr Rybalko */
8127cf7d04SAleksandr Rybalko
8227cf7d04SAleksandr Rybalko static tsw_open_t termtty_open;
8327cf7d04SAleksandr Rybalko static tsw_close_t termtty_close;
8427cf7d04SAleksandr Rybalko static tsw_outwakeup_t termtty_outwakeup;
8527cf7d04SAleksandr Rybalko static tsw_ioctl_t termtty_ioctl;
867a1a32c4SAleksandr Rybalko static tsw_mmap_t termtty_mmap;
8727cf7d04SAleksandr Rybalko
8827cf7d04SAleksandr Rybalko static struct ttydevsw terminal_tty_class = {
8927cf7d04SAleksandr Rybalko .tsw_open = termtty_open,
9027cf7d04SAleksandr Rybalko .tsw_close = termtty_close,
9127cf7d04SAleksandr Rybalko .tsw_outwakeup = termtty_outwakeup,
9227cf7d04SAleksandr Rybalko .tsw_ioctl = termtty_ioctl,
937a1a32c4SAleksandr Rybalko .tsw_mmap = termtty_mmap,
9427cf7d04SAleksandr Rybalko };
9527cf7d04SAleksandr Rybalko
9627cf7d04SAleksandr Rybalko /*
9727cf7d04SAleksandr Rybalko * Terminal emulator routines.
9827cf7d04SAleksandr Rybalko */
9927cf7d04SAleksandr Rybalko
10027cf7d04SAleksandr Rybalko static tf_bell_t termteken_bell;
10127cf7d04SAleksandr Rybalko static tf_cursor_t termteken_cursor;
10227cf7d04SAleksandr Rybalko static tf_putchar_t termteken_putchar;
10327cf7d04SAleksandr Rybalko static tf_fill_t termteken_fill;
10427cf7d04SAleksandr Rybalko static tf_copy_t termteken_copy;
105547e74a8SJean-Sébastien Pédron static tf_pre_input_t termteken_pre_input;
106547e74a8SJean-Sébastien Pédron static tf_post_input_t termteken_post_input;
10727cf7d04SAleksandr Rybalko static tf_param_t termteken_param;
10827cf7d04SAleksandr Rybalko static tf_respond_t termteken_respond;
10927cf7d04SAleksandr Rybalko
11027cf7d04SAleksandr Rybalko static teken_funcs_t terminal_drawmethods = {
11127cf7d04SAleksandr Rybalko .tf_bell = termteken_bell,
11227cf7d04SAleksandr Rybalko .tf_cursor = termteken_cursor,
11327cf7d04SAleksandr Rybalko .tf_putchar = termteken_putchar,
11427cf7d04SAleksandr Rybalko .tf_fill = termteken_fill,
11527cf7d04SAleksandr Rybalko .tf_copy = termteken_copy,
116547e74a8SJean-Sébastien Pédron .tf_pre_input = termteken_pre_input,
117547e74a8SJean-Sébastien Pédron .tf_post_input = termteken_post_input,
11827cf7d04SAleksandr Rybalko .tf_param = termteken_param,
11927cf7d04SAleksandr Rybalko .tf_respond = termteken_respond,
12027cf7d04SAleksandr Rybalko };
12127cf7d04SAleksandr Rybalko
12227cf7d04SAleksandr Rybalko /* Kernel message formatting. */
1233001e0c9SToomas Soome static teken_attr_t kernel_message = {
1247344ee18SMarius Strobl .ta_fgcolor = TCHAR_FGCOLOR(TERMINAL_KERN_ATTR),
1257344ee18SMarius Strobl .ta_bgcolor = TCHAR_BGCOLOR(TERMINAL_KERN_ATTR),
1267344ee18SMarius Strobl .ta_format = TCHAR_FORMAT(TERMINAL_KERN_ATTR)
12727cf7d04SAleksandr Rybalko };
12827cf7d04SAleksandr Rybalko
1293001e0c9SToomas Soome static teken_attr_t default_message = {
1307344ee18SMarius Strobl .ta_fgcolor = TCHAR_FGCOLOR(TERMINAL_NORM_ATTR),
1317344ee18SMarius Strobl .ta_bgcolor = TCHAR_BGCOLOR(TERMINAL_NORM_ATTR),
1327344ee18SMarius Strobl .ta_format = TCHAR_FORMAT(TERMINAL_NORM_ATTR)
13327cf7d04SAleksandr Rybalko };
13427cf7d04SAleksandr Rybalko
1354eb235fbSBruce Evans /* Fudge fg brightness as TF_BOLD (shifted). */
1364eb235fbSBruce Evans #define TCOLOR_FG_FUDGED(color) __extension__ ({ \
1374eb235fbSBruce Evans teken_color_t _c; \
1384eb235fbSBruce Evans \
1394eb235fbSBruce Evans _c = (color); \
1404eb235fbSBruce Evans TCOLOR_FG(_c & 7) | ((_c & 8) << 18); \
1414eb235fbSBruce Evans })
1424eb235fbSBruce Evans
1434eb235fbSBruce Evans /* Fudge bg brightness as TF_BLINK (shifted). */
1444eb235fbSBruce Evans #define TCOLOR_BG_FUDGED(color) __extension__ ({ \
1454eb235fbSBruce Evans teken_color_t _c; \
1464eb235fbSBruce Evans \
1474eb235fbSBruce Evans _c = (color); \
1484eb235fbSBruce Evans TCOLOR_BG(_c & 7) | ((_c & 8) << 20); \
1494eb235fbSBruce Evans })
1504eb235fbSBruce Evans
1511370fa33SBruce Evans #define TCOLOR_256TO16(color) __extension__ ({ \
1521370fa33SBruce Evans teken_color_t _c; \
1531370fa33SBruce Evans \
1541370fa33SBruce Evans _c = (color); \
1551370fa33SBruce Evans if (_c >= 16) \
1561370fa33SBruce Evans _c = teken_256to16(_c); \
1571370fa33SBruce Evans _c; \
1581370fa33SBruce Evans })
1591370fa33SBruce Evans
1607344ee18SMarius Strobl #define TCHAR_CREATE(c, a) ((c) | TFORMAT((a)->ta_format) | \
1611370fa33SBruce Evans TCOLOR_FG_FUDGED(TCOLOR_256TO16((a)->ta_fgcolor)) | \
1621370fa33SBruce Evans TCOLOR_BG_FUDGED(TCOLOR_256TO16((a)->ta_bgcolor)))
16327cf7d04SAleksandr Rybalko
16427cf7d04SAleksandr Rybalko static void
terminal_init(struct terminal * tm)16527cf7d04SAleksandr Rybalko terminal_init(struct terminal *tm)
16627cf7d04SAleksandr Rybalko {
1673001e0c9SToomas Soome int fg, bg;
16827cf7d04SAleksandr Rybalko
16927cf7d04SAleksandr Rybalko if (tm->tm_flags & TF_CONS)
17027cf7d04SAleksandr Rybalko mtx_init(&tm->tm_mtx, "trmlck", NULL, MTX_SPIN);
1713001e0c9SToomas Soome
17227cf7d04SAleksandr Rybalko teken_init(&tm->tm_emulator, &terminal_drawmethods, tm);
1733001e0c9SToomas Soome
17411fc80a0SToomas Soome fg = bg = -1;
1753001e0c9SToomas Soome TUNABLE_INT_FETCH("teken.fg_color", &fg);
1763001e0c9SToomas Soome TUNABLE_INT_FETCH("teken.bg_color", &bg);
1773001e0c9SToomas Soome
1783001e0c9SToomas Soome if (fg != -1) {
1793001e0c9SToomas Soome default_message.ta_fgcolor = fg;
1803001e0c9SToomas Soome kernel_message.ta_fgcolor = fg;
1813001e0c9SToomas Soome }
1823001e0c9SToomas Soome if (bg != -1) {
1833001e0c9SToomas Soome default_message.ta_bgcolor = bg;
1843001e0c9SToomas Soome kernel_message.ta_bgcolor = bg;
1853001e0c9SToomas Soome }
1863001e0c9SToomas Soome
1873001e0c9SToomas Soome if (default_message.ta_bgcolor == TC_WHITE) {
1883001e0c9SToomas Soome default_message.ta_bgcolor |= TC_LIGHT;
1893001e0c9SToomas Soome kernel_message.ta_bgcolor |= TC_LIGHT;
1903001e0c9SToomas Soome }
1913001e0c9SToomas Soome
1923001e0c9SToomas Soome if (default_message.ta_bgcolor == TC_BLACK &&
1933001e0c9SToomas Soome default_message.ta_fgcolor < TC_NCOLORS)
1943001e0c9SToomas Soome kernel_message.ta_fgcolor |= TC_LIGHT;
19527cf7d04SAleksandr Rybalko teken_set_defattr(&tm->tm_emulator, &default_message);
19627cf7d04SAleksandr Rybalko }
19727cf7d04SAleksandr Rybalko
19827cf7d04SAleksandr Rybalko struct terminal *
terminal_alloc(const struct terminal_class * tc,void * softc)19927cf7d04SAleksandr Rybalko terminal_alloc(const struct terminal_class *tc, void *softc)
20027cf7d04SAleksandr Rybalko {
20127cf7d04SAleksandr Rybalko struct terminal *tm;
20227cf7d04SAleksandr Rybalko
20327cf7d04SAleksandr Rybalko tm = malloc(sizeof(struct terminal), M_TERMINAL, M_WAITOK|M_ZERO);
20427cf7d04SAleksandr Rybalko terminal_init(tm);
20527cf7d04SAleksandr Rybalko
20627cf7d04SAleksandr Rybalko tm->tm_class = tc;
20727cf7d04SAleksandr Rybalko tm->tm_softc = softc;
20827cf7d04SAleksandr Rybalko
20927cf7d04SAleksandr Rybalko return (tm);
21027cf7d04SAleksandr Rybalko }
21127cf7d04SAleksandr Rybalko
21227cf7d04SAleksandr Rybalko static void
terminal_sync_ttysize(struct terminal * tm)21327cf7d04SAleksandr Rybalko terminal_sync_ttysize(struct terminal *tm)
21427cf7d04SAleksandr Rybalko {
21527cf7d04SAleksandr Rybalko struct tty *tp;
21627cf7d04SAleksandr Rybalko
21727cf7d04SAleksandr Rybalko tp = tm->tm_tty;
21827cf7d04SAleksandr Rybalko if (tp == NULL)
21927cf7d04SAleksandr Rybalko return;
22027cf7d04SAleksandr Rybalko
22127cf7d04SAleksandr Rybalko tty_lock(tp);
22227cf7d04SAleksandr Rybalko tty_set_winsize(tp, &tm->tm_winsize);
22327cf7d04SAleksandr Rybalko tty_unlock(tp);
22427cf7d04SAleksandr Rybalko }
22527cf7d04SAleksandr Rybalko
22627cf7d04SAleksandr Rybalko void
terminal_maketty(struct terminal * tm,const char * fmt,...)22727cf7d04SAleksandr Rybalko terminal_maketty(struct terminal *tm, const char *fmt, ...)
22827cf7d04SAleksandr Rybalko {
22927cf7d04SAleksandr Rybalko struct tty *tp;
23027cf7d04SAleksandr Rybalko char name[8];
23127cf7d04SAleksandr Rybalko va_list ap;
23227cf7d04SAleksandr Rybalko
23327cf7d04SAleksandr Rybalko va_start(ap, fmt);
23427cf7d04SAleksandr Rybalko vsnrprintf(name, sizeof name, 32, fmt, ap);
23527cf7d04SAleksandr Rybalko va_end(ap);
23627cf7d04SAleksandr Rybalko
23727cf7d04SAleksandr Rybalko tp = tty_alloc(&terminal_tty_class, tm);
23827cf7d04SAleksandr Rybalko tty_makedev(tp, NULL, "%s", name);
23927cf7d04SAleksandr Rybalko tm->tm_tty = tp;
24027cf7d04SAleksandr Rybalko terminal_sync_ttysize(tm);
24127cf7d04SAleksandr Rybalko }
24227cf7d04SAleksandr Rybalko
24327cf7d04SAleksandr Rybalko void
terminal_set_cursor(struct terminal * tm,const term_pos_t * pos)244da49f6bcSJean-Sébastien Pédron terminal_set_cursor(struct terminal *tm, const term_pos_t *pos)
245da49f6bcSJean-Sébastien Pédron {
246da49f6bcSJean-Sébastien Pédron
247da49f6bcSJean-Sébastien Pédron teken_set_cursor(&tm->tm_emulator, pos);
248da49f6bcSJean-Sébastien Pédron }
249da49f6bcSJean-Sébastien Pédron
250da49f6bcSJean-Sébastien Pédron void
terminal_set_winsize_blank(struct terminal * tm,const struct winsize * size,int blank,const term_attr_t * attr)25127cf7d04SAleksandr Rybalko terminal_set_winsize_blank(struct terminal *tm, const struct winsize *size,
2527344ee18SMarius Strobl int blank, const term_attr_t *attr)
25327cf7d04SAleksandr Rybalko {
25427cf7d04SAleksandr Rybalko term_rect_t r;
25527cf7d04SAleksandr Rybalko
25627cf7d04SAleksandr Rybalko tm->tm_winsize = *size;
25727cf7d04SAleksandr Rybalko
25827cf7d04SAleksandr Rybalko r.tr_begin.tp_row = r.tr_begin.tp_col = 0;
25927cf7d04SAleksandr Rybalko r.tr_end.tp_row = size->ws_row;
26027cf7d04SAleksandr Rybalko r.tr_end.tp_col = size->ws_col;
26127cf7d04SAleksandr Rybalko
26227cf7d04SAleksandr Rybalko TERMINAL_LOCK(tm);
26327cf7d04SAleksandr Rybalko if (blank == 0)
26427cf7d04SAleksandr Rybalko teken_set_winsize_noreset(&tm->tm_emulator, &r.tr_end);
26527cf7d04SAleksandr Rybalko else
26627cf7d04SAleksandr Rybalko teken_set_winsize(&tm->tm_emulator, &r.tr_end);
26727cf7d04SAleksandr Rybalko TERMINAL_UNLOCK(tm);
26827cf7d04SAleksandr Rybalko
26919fbe1eaSAleksandr Rybalko if ((blank != 0) && !(tm->tm_flags & TF_MUTE))
2707344ee18SMarius Strobl tm->tm_class->tc_fill(tm, &r,
2717344ee18SMarius Strobl TCHAR_CREATE((teken_char_t)' ', attr));
27227cf7d04SAleksandr Rybalko
27327cf7d04SAleksandr Rybalko terminal_sync_ttysize(tm);
27427cf7d04SAleksandr Rybalko }
27527cf7d04SAleksandr Rybalko
27627cf7d04SAleksandr Rybalko void
terminal_set_winsize(struct terminal * tm,const struct winsize * size)27727cf7d04SAleksandr Rybalko terminal_set_winsize(struct terminal *tm, const struct winsize *size)
27827cf7d04SAleksandr Rybalko {
27927cf7d04SAleksandr Rybalko
2807344ee18SMarius Strobl terminal_set_winsize_blank(tm, size, 1,
2817344ee18SMarius Strobl (const term_attr_t *)&default_message);
28227cf7d04SAleksandr Rybalko }
28327cf7d04SAleksandr Rybalko
28427cf7d04SAleksandr Rybalko /*
28527cf7d04SAleksandr Rybalko * XXX: This function is a kludge. Drivers like vt(4) need to
28627cf7d04SAleksandr Rybalko * temporarily stop input when resizing, etc. This should ideally be
28727cf7d04SAleksandr Rybalko * handled within the driver.
28827cf7d04SAleksandr Rybalko */
28927cf7d04SAleksandr Rybalko
29027cf7d04SAleksandr Rybalko void
terminal_mute(struct terminal * tm,int yes)29127cf7d04SAleksandr Rybalko terminal_mute(struct terminal *tm, int yes)
29227cf7d04SAleksandr Rybalko {
29327cf7d04SAleksandr Rybalko
29427cf7d04SAleksandr Rybalko TERMINAL_LOCK(tm);
29527cf7d04SAleksandr Rybalko if (yes)
29627cf7d04SAleksandr Rybalko tm->tm_flags |= TF_MUTE;
29727cf7d04SAleksandr Rybalko else
29827cf7d04SAleksandr Rybalko tm->tm_flags &= ~TF_MUTE;
29927cf7d04SAleksandr Rybalko TERMINAL_UNLOCK(tm);
30027cf7d04SAleksandr Rybalko }
30127cf7d04SAleksandr Rybalko
30227cf7d04SAleksandr Rybalko void
terminal_input_char(struct terminal * tm,term_char_t c)30327cf7d04SAleksandr Rybalko terminal_input_char(struct terminal *tm, term_char_t c)
30427cf7d04SAleksandr Rybalko {
30527cf7d04SAleksandr Rybalko struct tty *tp;
30627cf7d04SAleksandr Rybalko
30727cf7d04SAleksandr Rybalko tp = tm->tm_tty;
30827cf7d04SAleksandr Rybalko if (tp == NULL)
30927cf7d04SAleksandr Rybalko return;
31027cf7d04SAleksandr Rybalko
311a3da01fcSEd Schouten /*
312a3da01fcSEd Schouten * Strip off any attributes. Also ignore input of second part of
313a3da01fcSEd Schouten * CJK fullwidth characters, as we don't want to return these
314a3da01fcSEd Schouten * characters twice.
315a3da01fcSEd Schouten */
316a3da01fcSEd Schouten if (TCHAR_FORMAT(c) & TF_CJK_RIGHT)
317a3da01fcSEd Schouten return;
31827cf7d04SAleksandr Rybalko c = TCHAR_CHARACTER(c);
31927cf7d04SAleksandr Rybalko
32027cf7d04SAleksandr Rybalko tty_lock(tp);
32127cf7d04SAleksandr Rybalko /*
32227cf7d04SAleksandr Rybalko * Conversion to UTF-8.
32327cf7d04SAleksandr Rybalko */
32427cf7d04SAleksandr Rybalko if (c < 0x80) {
32527cf7d04SAleksandr Rybalko ttydisc_rint(tp, c, 0);
32627cf7d04SAleksandr Rybalko } else if (c < 0x800) {
32727cf7d04SAleksandr Rybalko char str[2] = {
32827cf7d04SAleksandr Rybalko 0xc0 | (c >> 6),
32927cf7d04SAleksandr Rybalko 0x80 | (c & 0x3f)
33027cf7d04SAleksandr Rybalko };
33127cf7d04SAleksandr Rybalko
33227cf7d04SAleksandr Rybalko ttydisc_rint_simple(tp, str, sizeof str);
33327cf7d04SAleksandr Rybalko } else if (c < 0x10000) {
33427cf7d04SAleksandr Rybalko char str[3] = {
33527cf7d04SAleksandr Rybalko 0xe0 | (c >> 12),
33627cf7d04SAleksandr Rybalko 0x80 | ((c >> 6) & 0x3f),
33727cf7d04SAleksandr Rybalko 0x80 | (c & 0x3f)
33827cf7d04SAleksandr Rybalko };
33927cf7d04SAleksandr Rybalko
34027cf7d04SAleksandr Rybalko ttydisc_rint_simple(tp, str, sizeof str);
34127cf7d04SAleksandr Rybalko } else {
34227cf7d04SAleksandr Rybalko char str[4] = {
34327cf7d04SAleksandr Rybalko 0xf0 | (c >> 18),
34427cf7d04SAleksandr Rybalko 0x80 | ((c >> 12) & 0x3f),
34527cf7d04SAleksandr Rybalko 0x80 | ((c >> 6) & 0x3f),
34627cf7d04SAleksandr Rybalko 0x80 | (c & 0x3f)
34727cf7d04SAleksandr Rybalko };
34827cf7d04SAleksandr Rybalko
34927cf7d04SAleksandr Rybalko ttydisc_rint_simple(tp, str, sizeof str);
35027cf7d04SAleksandr Rybalko }
35127cf7d04SAleksandr Rybalko ttydisc_rint_done(tp);
35227cf7d04SAleksandr Rybalko tty_unlock(tp);
35327cf7d04SAleksandr Rybalko }
35427cf7d04SAleksandr Rybalko
35527cf7d04SAleksandr Rybalko void
terminal_input_raw(struct terminal * tm,char c)35627cf7d04SAleksandr Rybalko terminal_input_raw(struct terminal *tm, char c)
35727cf7d04SAleksandr Rybalko {
35827cf7d04SAleksandr Rybalko struct tty *tp;
35927cf7d04SAleksandr Rybalko
36027cf7d04SAleksandr Rybalko tp = tm->tm_tty;
36127cf7d04SAleksandr Rybalko if (tp == NULL)
36227cf7d04SAleksandr Rybalko return;
36327cf7d04SAleksandr Rybalko
36427cf7d04SAleksandr Rybalko tty_lock(tp);
36527cf7d04SAleksandr Rybalko ttydisc_rint(tp, c, 0);
36627cf7d04SAleksandr Rybalko ttydisc_rint_done(tp);
36727cf7d04SAleksandr Rybalko tty_unlock(tp);
36827cf7d04SAleksandr Rybalko }
36927cf7d04SAleksandr Rybalko
37027cf7d04SAleksandr Rybalko void
terminal_input_special(struct terminal * tm,unsigned int k)37127cf7d04SAleksandr Rybalko terminal_input_special(struct terminal *tm, unsigned int k)
37227cf7d04SAleksandr Rybalko {
37327cf7d04SAleksandr Rybalko struct tty *tp;
37427cf7d04SAleksandr Rybalko const char *str;
37527cf7d04SAleksandr Rybalko
37627cf7d04SAleksandr Rybalko tp = tm->tm_tty;
37727cf7d04SAleksandr Rybalko if (tp == NULL)
37827cf7d04SAleksandr Rybalko return;
37927cf7d04SAleksandr Rybalko
38027cf7d04SAleksandr Rybalko str = teken_get_sequence(&tm->tm_emulator, k);
38127cf7d04SAleksandr Rybalko if (str == NULL)
38227cf7d04SAleksandr Rybalko return;
38327cf7d04SAleksandr Rybalko
38427cf7d04SAleksandr Rybalko tty_lock(tp);
38527cf7d04SAleksandr Rybalko ttydisc_rint_simple(tp, str, strlen(str));
38627cf7d04SAleksandr Rybalko ttydisc_rint_done(tp);
38727cf7d04SAleksandr Rybalko tty_unlock(tp);
38827cf7d04SAleksandr Rybalko }
38927cf7d04SAleksandr Rybalko
39027cf7d04SAleksandr Rybalko /*
39127cf7d04SAleksandr Rybalko * Binding with the TTY layer.
39227cf7d04SAleksandr Rybalko */
39327cf7d04SAleksandr Rybalko
39427cf7d04SAleksandr Rybalko static int
termtty_open(struct tty * tp)39527cf7d04SAleksandr Rybalko termtty_open(struct tty *tp)
39627cf7d04SAleksandr Rybalko {
39727cf7d04SAleksandr Rybalko struct terminal *tm = tty_softc(tp);
39827cf7d04SAleksandr Rybalko
39927cf7d04SAleksandr Rybalko tm->tm_class->tc_opened(tm, 1);
40027cf7d04SAleksandr Rybalko return (0);
40127cf7d04SAleksandr Rybalko }
40227cf7d04SAleksandr Rybalko
40327cf7d04SAleksandr Rybalko static void
termtty_close(struct tty * tp)40427cf7d04SAleksandr Rybalko termtty_close(struct tty *tp)
40527cf7d04SAleksandr Rybalko {
40627cf7d04SAleksandr Rybalko struct terminal *tm = tty_softc(tp);
40727cf7d04SAleksandr Rybalko
40827cf7d04SAleksandr Rybalko tm->tm_class->tc_opened(tm, 0);
40927cf7d04SAleksandr Rybalko }
41027cf7d04SAleksandr Rybalko
41127cf7d04SAleksandr Rybalko static void
termtty_outwakeup(struct tty * tp)41227cf7d04SAleksandr Rybalko termtty_outwakeup(struct tty *tp)
41327cf7d04SAleksandr Rybalko {
41427cf7d04SAleksandr Rybalko struct terminal *tm = tty_softc(tp);
41527cf7d04SAleksandr Rybalko char obuf[128];
41627cf7d04SAleksandr Rybalko size_t olen;
41727cf7d04SAleksandr Rybalko unsigned int flags = 0;
41827cf7d04SAleksandr Rybalko
41927cf7d04SAleksandr Rybalko while ((olen = ttydisc_getc(tp, obuf, sizeof obuf)) > 0) {
42027cf7d04SAleksandr Rybalko TERMINAL_LOCK_TTY(tm);
42127cf7d04SAleksandr Rybalko if (!(tm->tm_flags & TF_MUTE)) {
42227cf7d04SAleksandr Rybalko tm->tm_flags &= ~TF_BELL;
42327cf7d04SAleksandr Rybalko teken_input(&tm->tm_emulator, obuf, olen);
42427cf7d04SAleksandr Rybalko flags |= tm->tm_flags;
42527cf7d04SAleksandr Rybalko }
42627cf7d04SAleksandr Rybalko TERMINAL_UNLOCK_TTY(tm);
42727cf7d04SAleksandr Rybalko }
42827cf7d04SAleksandr Rybalko
429c9cde825SJonathan T. Looney TERMINAL_LOCK_TTY(tm);
430c9cde825SJonathan T. Looney if (!(tm->tm_flags & TF_MUTE))
43127cf7d04SAleksandr Rybalko tm->tm_class->tc_done(tm);
432c9cde825SJonathan T. Looney TERMINAL_UNLOCK_TTY(tm);
43327cf7d04SAleksandr Rybalko if (flags & TF_BELL)
43427cf7d04SAleksandr Rybalko tm->tm_class->tc_bell(tm);
43527cf7d04SAleksandr Rybalko }
43627cf7d04SAleksandr Rybalko
43727cf7d04SAleksandr Rybalko static int
termtty_ioctl(struct tty * tp,u_long cmd,caddr_t data,struct thread * td)43827cf7d04SAleksandr Rybalko termtty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
43927cf7d04SAleksandr Rybalko {
44027cf7d04SAleksandr Rybalko struct terminal *tm = tty_softc(tp);
44127cf7d04SAleksandr Rybalko int error;
44227cf7d04SAleksandr Rybalko
44327cf7d04SAleksandr Rybalko switch (cmd) {
44427cf7d04SAleksandr Rybalko case CONS_GETINFO: {
44527cf7d04SAleksandr Rybalko vid_info_t *vi = (vid_info_t *)data;
44627cf7d04SAleksandr Rybalko const teken_pos_t *p;
44727cf7d04SAleksandr Rybalko int fg, bg;
44827cf7d04SAleksandr Rybalko
44927cf7d04SAleksandr Rybalko if (vi->size != sizeof(vid_info_t))
45027cf7d04SAleksandr Rybalko return (EINVAL);
45127cf7d04SAleksandr Rybalko
45227cf7d04SAleksandr Rybalko /* Already help the console driver by filling in some data. */
45327cf7d04SAleksandr Rybalko p = teken_get_cursor(&tm->tm_emulator);
45427cf7d04SAleksandr Rybalko vi->mv_row = p->tp_row;
45527cf7d04SAleksandr Rybalko vi->mv_col = p->tp_col;
45627cf7d04SAleksandr Rybalko
45727cf7d04SAleksandr Rybalko p = teken_get_winsize(&tm->tm_emulator);
45827cf7d04SAleksandr Rybalko vi->mv_rsz = p->tp_row;
45927cf7d04SAleksandr Rybalko vi->mv_csz = p->tp_col;
46027cf7d04SAleksandr Rybalko
46127cf7d04SAleksandr Rybalko teken_get_defattr_cons25(&tm->tm_emulator, &fg, &bg);
46227cf7d04SAleksandr Rybalko vi->mv_norm.fore = fg;
46327cf7d04SAleksandr Rybalko vi->mv_norm.back = bg;
46427cf7d04SAleksandr Rybalko /* XXX: keep vidcontrol happy; bold backgrounds. */
46527cf7d04SAleksandr Rybalko vi->mv_rev.fore = bg;
46627cf7d04SAleksandr Rybalko vi->mv_rev.back = fg & 0x7;
46727cf7d04SAleksandr Rybalko break;
46827cf7d04SAleksandr Rybalko }
46927cf7d04SAleksandr Rybalko }
47027cf7d04SAleksandr Rybalko
47127cf7d04SAleksandr Rybalko /*
47227cf7d04SAleksandr Rybalko * Unlike various other drivers, this driver will never
47327cf7d04SAleksandr Rybalko * deallocate TTYs. This means it's safe to temporarily unlock
47427cf7d04SAleksandr Rybalko * the TTY when handling ioctls.
47527cf7d04SAleksandr Rybalko */
47627cf7d04SAleksandr Rybalko tty_unlock(tp);
47727cf7d04SAleksandr Rybalko error = tm->tm_class->tc_ioctl(tm, cmd, data, td);
47827cf7d04SAleksandr Rybalko tty_lock(tp);
479ef1eabcaSJason A. Harmening if ((error == 0) && (cmd == CONS_CLRHIST)) {
480ef1eabcaSJason A. Harmening /*
481ef1eabcaSJason A. Harmening * Scrollback history has been successfully cleared,
482ef1eabcaSJason A. Harmening * so reset the cursor position to the top left of the screen.
483ef1eabcaSJason A. Harmening */
484ef1eabcaSJason A. Harmening teken_pos_t p;
485ef1eabcaSJason A. Harmening p.tp_row = 0;
486ef1eabcaSJason A. Harmening p.tp_col = 0;
487ef1eabcaSJason A. Harmening teken_set_cursor(&tm->tm_emulator, &p);
488ef1eabcaSJason A. Harmening }
48927cf7d04SAleksandr Rybalko return (error);
49027cf7d04SAleksandr Rybalko }
49127cf7d04SAleksandr Rybalko
4927a1a32c4SAleksandr Rybalko static int
termtty_mmap(struct tty * tp,vm_ooffset_t offset,vm_paddr_t * paddr,int nprot,vm_memattr_t * memattr)4937a1a32c4SAleksandr Rybalko termtty_mmap(struct tty *tp, vm_ooffset_t offset, vm_paddr_t * paddr,
4947a1a32c4SAleksandr Rybalko int nprot, vm_memattr_t *memattr)
4957a1a32c4SAleksandr Rybalko {
4967a1a32c4SAleksandr Rybalko struct terminal *tm = tty_softc(tp);
4977a1a32c4SAleksandr Rybalko
4987a1a32c4SAleksandr Rybalko return (tm->tm_class->tc_mmap(tm, offset, paddr, nprot, memattr));
4997a1a32c4SAleksandr Rybalko }
5007a1a32c4SAleksandr Rybalko
50127cf7d04SAleksandr Rybalko /*
50227cf7d04SAleksandr Rybalko * Binding with the kernel and debug console.
50327cf7d04SAleksandr Rybalko */
50427cf7d04SAleksandr Rybalko
50527cf7d04SAleksandr Rybalko static cn_probe_t termcn_cnprobe;
50627cf7d04SAleksandr Rybalko static cn_init_t termcn_cninit;
50727cf7d04SAleksandr Rybalko static cn_term_t termcn_cnterm;
50827cf7d04SAleksandr Rybalko static cn_getc_t termcn_cngetc;
50927cf7d04SAleksandr Rybalko static cn_putc_t termcn_cnputc;
51027cf7d04SAleksandr Rybalko static cn_grab_t termcn_cngrab;
51127cf7d04SAleksandr Rybalko static cn_ungrab_t termcn_cnungrab;
51227cf7d04SAleksandr Rybalko
51327cf7d04SAleksandr Rybalko const struct consdev_ops termcn_cnops = {
51427cf7d04SAleksandr Rybalko .cn_probe = termcn_cnprobe,
51527cf7d04SAleksandr Rybalko .cn_init = termcn_cninit,
51627cf7d04SAleksandr Rybalko .cn_term = termcn_cnterm,
51727cf7d04SAleksandr Rybalko .cn_getc = termcn_cngetc,
51827cf7d04SAleksandr Rybalko .cn_putc = termcn_cnputc,
51927cf7d04SAleksandr Rybalko .cn_grab = termcn_cngrab,
52027cf7d04SAleksandr Rybalko .cn_ungrab = termcn_cnungrab,
52127cf7d04SAleksandr Rybalko };
52227cf7d04SAleksandr Rybalko
52327cf7d04SAleksandr Rybalko void
termcn_cnregister(struct terminal * tm)52427cf7d04SAleksandr Rybalko termcn_cnregister(struct terminal *tm)
52527cf7d04SAleksandr Rybalko {
52627cf7d04SAleksandr Rybalko struct consdev *cp;
52727cf7d04SAleksandr Rybalko
52827cf7d04SAleksandr Rybalko cp = tm->consdev;
52927cf7d04SAleksandr Rybalko if (cp == NULL) {
53027cf7d04SAleksandr Rybalko cp = malloc(sizeof(struct consdev), M_TERMINAL,
53127cf7d04SAleksandr Rybalko M_WAITOK|M_ZERO);
53227cf7d04SAleksandr Rybalko cp->cn_ops = &termcn_cnops;
53327cf7d04SAleksandr Rybalko cp->cn_arg = tm;
53427cf7d04SAleksandr Rybalko cp->cn_pri = CN_INTERNAL;
53527cf7d04SAleksandr Rybalko sprintf(cp->cn_name, "ttyv0");
53627cf7d04SAleksandr Rybalko
53727cf7d04SAleksandr Rybalko tm->tm_flags = TF_CONS;
53827cf7d04SAleksandr Rybalko tm->consdev = cp;
53927cf7d04SAleksandr Rybalko
54027cf7d04SAleksandr Rybalko terminal_init(tm);
54127cf7d04SAleksandr Rybalko }
54227cf7d04SAleksandr Rybalko
54327cf7d04SAleksandr Rybalko /* Attach terminal as console. */
54427cf7d04SAleksandr Rybalko cnadd(cp);
54527cf7d04SAleksandr Rybalko }
54627cf7d04SAleksandr Rybalko
54727cf7d04SAleksandr Rybalko static void
termcn_cngrab(struct consdev * cp)54827cf7d04SAleksandr Rybalko termcn_cngrab(struct consdev *cp)
54927cf7d04SAleksandr Rybalko {
5503e206539SJean-Sébastien Pédron struct terminal *tm = cp->cn_arg;
55127cf7d04SAleksandr Rybalko
5523e206539SJean-Sébastien Pédron tm->tm_class->tc_cngrab(tm);
55327cf7d04SAleksandr Rybalko }
55427cf7d04SAleksandr Rybalko
55527cf7d04SAleksandr Rybalko static void
termcn_cnungrab(struct consdev * cp)55627cf7d04SAleksandr Rybalko termcn_cnungrab(struct consdev *cp)
55727cf7d04SAleksandr Rybalko {
5583e206539SJean-Sébastien Pédron struct terminal *tm = cp->cn_arg;
55927cf7d04SAleksandr Rybalko
5603e206539SJean-Sébastien Pédron tm->tm_class->tc_cnungrab(tm);
56127cf7d04SAleksandr Rybalko }
56227cf7d04SAleksandr Rybalko
56327cf7d04SAleksandr Rybalko static void
termcn_cnprobe(struct consdev * cp)56427cf7d04SAleksandr Rybalko termcn_cnprobe(struct consdev *cp)
56527cf7d04SAleksandr Rybalko {
56627cf7d04SAleksandr Rybalko struct terminal *tm = cp->cn_arg;
56727cf7d04SAleksandr Rybalko
56827cf7d04SAleksandr Rybalko if (tm == NULL) {
56927cf7d04SAleksandr Rybalko cp->cn_pri = CN_DEAD;
57027cf7d04SAleksandr Rybalko return;
57127cf7d04SAleksandr Rybalko }
57227cf7d04SAleksandr Rybalko
57327cf7d04SAleksandr Rybalko tm->consdev = cp;
57427cf7d04SAleksandr Rybalko terminal_init(tm);
57527cf7d04SAleksandr Rybalko
57627cf7d04SAleksandr Rybalko tm->tm_class->tc_cnprobe(tm, cp);
57727cf7d04SAleksandr Rybalko }
57827cf7d04SAleksandr Rybalko
57927cf7d04SAleksandr Rybalko static void
termcn_cninit(struct consdev * cp)58027cf7d04SAleksandr Rybalko termcn_cninit(struct consdev *cp)
58127cf7d04SAleksandr Rybalko {
58227cf7d04SAleksandr Rybalko
58327cf7d04SAleksandr Rybalko }
58427cf7d04SAleksandr Rybalko
58527cf7d04SAleksandr Rybalko static void
termcn_cnterm(struct consdev * cp)58627cf7d04SAleksandr Rybalko termcn_cnterm(struct consdev *cp)
58727cf7d04SAleksandr Rybalko {
58827cf7d04SAleksandr Rybalko
58927cf7d04SAleksandr Rybalko }
59027cf7d04SAleksandr Rybalko
59127cf7d04SAleksandr Rybalko static int
termcn_cngetc(struct consdev * cp)59227cf7d04SAleksandr Rybalko termcn_cngetc(struct consdev *cp)
59327cf7d04SAleksandr Rybalko {
59427cf7d04SAleksandr Rybalko struct terminal *tm = cp->cn_arg;
59527cf7d04SAleksandr Rybalko
59627cf7d04SAleksandr Rybalko return (tm->tm_class->tc_cngetc(tm));
59727cf7d04SAleksandr Rybalko }
59827cf7d04SAleksandr Rybalko
59927cf7d04SAleksandr Rybalko static void
termcn_cnputc(struct consdev * cp,int c)60027cf7d04SAleksandr Rybalko termcn_cnputc(struct consdev *cp, int c)
60127cf7d04SAleksandr Rybalko {
60227cf7d04SAleksandr Rybalko struct terminal *tm = cp->cn_arg;
60327cf7d04SAleksandr Rybalko teken_attr_t backup;
60427cf7d04SAleksandr Rybalko char cv = c;
60527cf7d04SAleksandr Rybalko
60627cf7d04SAleksandr Rybalko TERMINAL_LOCK_CONS(tm);
60727cf7d04SAleksandr Rybalko if (!(tm->tm_flags & TF_MUTE)) {
60827cf7d04SAleksandr Rybalko backup = *teken_get_curattr(&tm->tm_emulator);
60927cf7d04SAleksandr Rybalko teken_set_curattr(&tm->tm_emulator, &kernel_message);
61027cf7d04SAleksandr Rybalko teken_input(&tm->tm_emulator, &cv, 1);
61127cf7d04SAleksandr Rybalko teken_set_curattr(&tm->tm_emulator, &backup);
612c9cde825SJonathan T. Looney tm->tm_class->tc_done(tm);
61327cf7d04SAleksandr Rybalko }
61427cf7d04SAleksandr Rybalko TERMINAL_UNLOCK_CONS(tm);
61527cf7d04SAleksandr Rybalko }
61627cf7d04SAleksandr Rybalko
61727cf7d04SAleksandr Rybalko /*
61827cf7d04SAleksandr Rybalko * Binding with the terminal emulator.
61927cf7d04SAleksandr Rybalko */
62027cf7d04SAleksandr Rybalko
62127cf7d04SAleksandr Rybalko static void
termteken_bell(void * softc)62227cf7d04SAleksandr Rybalko termteken_bell(void *softc)
62327cf7d04SAleksandr Rybalko {
62427cf7d04SAleksandr Rybalko struct terminal *tm = softc;
62527cf7d04SAleksandr Rybalko
62627cf7d04SAleksandr Rybalko tm->tm_flags |= TF_BELL;
62727cf7d04SAleksandr Rybalko }
62827cf7d04SAleksandr Rybalko
62927cf7d04SAleksandr Rybalko static void
termteken_cursor(void * softc,const teken_pos_t * p)63027cf7d04SAleksandr Rybalko termteken_cursor(void *softc, const teken_pos_t *p)
63127cf7d04SAleksandr Rybalko {
63227cf7d04SAleksandr Rybalko struct terminal *tm = softc;
63327cf7d04SAleksandr Rybalko
63427cf7d04SAleksandr Rybalko tm->tm_class->tc_cursor(tm, p);
63527cf7d04SAleksandr Rybalko }
63627cf7d04SAleksandr Rybalko
63727cf7d04SAleksandr Rybalko static void
termteken_putchar(void * softc,const teken_pos_t * p,teken_char_t c,const teken_attr_t * a)63827cf7d04SAleksandr Rybalko termteken_putchar(void *softc, const teken_pos_t *p, teken_char_t c,
63927cf7d04SAleksandr Rybalko const teken_attr_t *a)
64027cf7d04SAleksandr Rybalko {
64127cf7d04SAleksandr Rybalko struct terminal *tm = softc;
64227cf7d04SAleksandr Rybalko
64327cf7d04SAleksandr Rybalko tm->tm_class->tc_putchar(tm, p, TCHAR_CREATE(c, a));
64427cf7d04SAleksandr Rybalko }
64527cf7d04SAleksandr Rybalko
64627cf7d04SAleksandr Rybalko static void
termteken_fill(void * softc,const teken_rect_t * r,teken_char_t c,const teken_attr_t * a)64727cf7d04SAleksandr Rybalko termteken_fill(void *softc, const teken_rect_t *r, teken_char_t c,
64827cf7d04SAleksandr Rybalko const teken_attr_t *a)
64927cf7d04SAleksandr Rybalko {
65027cf7d04SAleksandr Rybalko struct terminal *tm = softc;
65127cf7d04SAleksandr Rybalko
65227cf7d04SAleksandr Rybalko tm->tm_class->tc_fill(tm, r, TCHAR_CREATE(c, a));
65327cf7d04SAleksandr Rybalko }
65427cf7d04SAleksandr Rybalko
65527cf7d04SAleksandr Rybalko static void
termteken_copy(void * softc,const teken_rect_t * r,const teken_pos_t * p)65627cf7d04SAleksandr Rybalko termteken_copy(void *softc, const teken_rect_t *r, const teken_pos_t *p)
65727cf7d04SAleksandr Rybalko {
65827cf7d04SAleksandr Rybalko struct terminal *tm = softc;
65927cf7d04SAleksandr Rybalko
66027cf7d04SAleksandr Rybalko tm->tm_class->tc_copy(tm, r, p);
66127cf7d04SAleksandr Rybalko }
66227cf7d04SAleksandr Rybalko
66327cf7d04SAleksandr Rybalko static void
termteken_pre_input(void * softc)664547e74a8SJean-Sébastien Pédron termteken_pre_input(void *softc)
665547e74a8SJean-Sébastien Pédron {
666547e74a8SJean-Sébastien Pédron struct terminal *tm = softc;
667547e74a8SJean-Sébastien Pédron
668547e74a8SJean-Sébastien Pédron tm->tm_class->tc_pre_input(tm);
669547e74a8SJean-Sébastien Pédron }
670547e74a8SJean-Sébastien Pédron
671547e74a8SJean-Sébastien Pédron static void
termteken_post_input(void * softc)672547e74a8SJean-Sébastien Pédron termteken_post_input(void *softc)
673547e74a8SJean-Sébastien Pédron {
674547e74a8SJean-Sébastien Pédron struct terminal *tm = softc;
675547e74a8SJean-Sébastien Pédron
676547e74a8SJean-Sébastien Pédron tm->tm_class->tc_post_input(tm);
677547e74a8SJean-Sébastien Pédron }
678547e74a8SJean-Sébastien Pédron
679547e74a8SJean-Sébastien Pédron static void
termteken_param(void * softc,int cmd,unsigned int arg)68027cf7d04SAleksandr Rybalko termteken_param(void *softc, int cmd, unsigned int arg)
68127cf7d04SAleksandr Rybalko {
68227cf7d04SAleksandr Rybalko struct terminal *tm = softc;
68327cf7d04SAleksandr Rybalko
68427cf7d04SAleksandr Rybalko tm->tm_class->tc_param(tm, cmd, arg);
68527cf7d04SAleksandr Rybalko }
68627cf7d04SAleksandr Rybalko
68727cf7d04SAleksandr Rybalko static void
termteken_respond(void * softc,const void * buf,size_t len)68827cf7d04SAleksandr Rybalko termteken_respond(void *softc, const void *buf, size_t len)
68927cf7d04SAleksandr Rybalko {
69027cf7d04SAleksandr Rybalko #if 0
69127cf7d04SAleksandr Rybalko struct terminal *tm = softc;
69227cf7d04SAleksandr Rybalko struct tty *tp;
69327cf7d04SAleksandr Rybalko
69427cf7d04SAleksandr Rybalko /*
69527cf7d04SAleksandr Rybalko * Only inject a response into the TTY if the data actually
69627cf7d04SAleksandr Rybalko * originated from the TTY.
69727cf7d04SAleksandr Rybalko *
69827cf7d04SAleksandr Rybalko * XXX: This cannot be done right now. The TTY could pick up
69927cf7d04SAleksandr Rybalko * other locks. It could also in theory cause loops, when the
70027cf7d04SAleksandr Rybalko * TTY performs echoing of a command that generates even more
70127cf7d04SAleksandr Rybalko * input.
70227cf7d04SAleksandr Rybalko */
70327cf7d04SAleksandr Rybalko tp = tm->tm_tty;
70427cf7d04SAleksandr Rybalko if (tp == NULL)
70527cf7d04SAleksandr Rybalko return;
70627cf7d04SAleksandr Rybalko
70727cf7d04SAleksandr Rybalko ttydisc_rint_simple(tp, buf, len);
70827cf7d04SAleksandr Rybalko ttydisc_rint_done(tp);
70927cf7d04SAleksandr Rybalko #endif
71027cf7d04SAleksandr Rybalko }
711