xref: /freebsd/sys/sys/terminal.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
127cf7d04SAleksandr Rybalko /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3c4e20cadSPedro 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 #ifndef _SYS_TERMINAL_H_
3227cf7d04SAleksandr Rybalko #define	_SYS_TERMINAL_H_
3327cf7d04SAleksandr Rybalko 
3427cf7d04SAleksandr Rybalko #include <sys/param.h>
3527cf7d04SAleksandr Rybalko #include <sys/_lock.h>
3627cf7d04SAleksandr Rybalko #include <sys/_mutex.h>
3727cf7d04SAleksandr Rybalko #include <sys/cons.h>
3827cf7d04SAleksandr Rybalko #include <sys/linker_set.h>
3927cf7d04SAleksandr Rybalko #include <sys/ttycom.h>
4027cf7d04SAleksandr Rybalko 
4127cf7d04SAleksandr Rybalko #include <teken/teken.h>
4227cf7d04SAleksandr Rybalko 
437344ee18SMarius Strobl #include "opt_syscons.h"
447344ee18SMarius Strobl #include "opt_teken.h"
457344ee18SMarius Strobl 
4627cf7d04SAleksandr Rybalko struct terminal;
4727cf7d04SAleksandr Rybalko struct thread;
4827cf7d04SAleksandr Rybalko struct tty;
4927cf7d04SAleksandr Rybalko 
5027cf7d04SAleksandr Rybalko /*
5127cf7d04SAleksandr Rybalko  * The terminal layer is an abstraction on top of the TTY layer and the
5227cf7d04SAleksandr Rybalko  * console interface.  It can be used by system console drivers to
5327cf7d04SAleksandr Rybalko  * easily interact with the kernel console and TTYs.
5427cf7d04SAleksandr Rybalko  *
5527cf7d04SAleksandr Rybalko  * Terminals contain terminal emulators, which means console drivers
5627cf7d04SAleksandr Rybalko  * don't need to implement their own terminal emulator. The terminal
5727cf7d04SAleksandr Rybalko  * emulator deals with UTF-8 exclusively. This means that term_char_t,
5827cf7d04SAleksandr Rybalko  * the data type used to store input/output characters will always
5927cf7d04SAleksandr Rybalko  * contain Unicode codepoints.
6027cf7d04SAleksandr Rybalko  *
6127cf7d04SAleksandr Rybalko  * To save memory usage, the top bits of term_char_t will contain other
6227cf7d04SAleksandr Rybalko  * attributes, like colors. Right now term_char_t is composed as
6327cf7d04SAleksandr Rybalko  * follows:
6427cf7d04SAleksandr Rybalko  *
6527cf7d04SAleksandr Rybalko  *  Bits  Meaning
6627cf7d04SAleksandr Rybalko  *  0-20: Character value
67a6c26592SEd Schouten  * 21-25: Bold, underline, blink, reverse, right part of CJK fullwidth character
6827cf7d04SAleksandr Rybalko  * 26-28: Foreground color
6927cf7d04SAleksandr Rybalko  * 29-31: Background color
7027cf7d04SAleksandr Rybalko  */
7127cf7d04SAleksandr Rybalko 
7227cf7d04SAleksandr Rybalko typedef uint32_t term_char_t;
7327cf7d04SAleksandr Rybalko #define	TCHAR_CHARACTER(c)	((c) & 0x1fffff)
74a6c26592SEd Schouten #define	TCHAR_FORMAT(c)		(((c) >> 21) & 0x1f)
7527cf7d04SAleksandr Rybalko #define	TCHAR_FGCOLOR(c)	(((c) >> 26) & 0x7)
767344ee18SMarius Strobl #define	TCHAR_BGCOLOR(c)	(((c) >> 29) & 0x7)
777344ee18SMarius Strobl 
787344ee18SMarius Strobl typedef teken_attr_t term_attr_t;
7927cf7d04SAleksandr Rybalko 
8027cf7d04SAleksandr Rybalko typedef teken_color_t term_color_t;
817344ee18SMarius Strobl #define	TCOLOR_FG(c)	(((c) & 0x7) << 26)
827344ee18SMarius Strobl #define	TCOLOR_BG(c)	(((c) & 0x7) << 29)
8327cf7d04SAleksandr Rybalko #define	TCOLOR_LIGHT(c)	((c) | 0x8)
8427cf7d04SAleksandr Rybalko #define	TCOLOR_DARK(c)	((c) & ~0x8)
857344ee18SMarius Strobl 
867344ee18SMarius Strobl #define	TFORMAT(c)	(((c) & 0x1f) << 21)
877344ee18SMarius Strobl 
887344ee18SMarius Strobl /* syscons(4) compatible color attributes for foreground text */
897344ee18SMarius Strobl #define	FG_BLACK		TCOLOR_FG(TC_BLACK)
907344ee18SMarius Strobl #define	FG_BLUE			TCOLOR_FG(TC_BLUE)
917344ee18SMarius Strobl #define	FG_GREEN		TCOLOR_FG(TC_GREEN)
927344ee18SMarius Strobl #define	FG_CYAN			TCOLOR_FG(TC_CYAN)
937344ee18SMarius Strobl #define	FG_RED			TCOLOR_FG(TC_RED)
947344ee18SMarius Strobl #define	FG_MAGENTA		TCOLOR_FG(TC_MAGENTA)
95cf8880d5SEd Maste #define	FG_BROWN		TCOLOR_FG(TC_YELLOW)
967344ee18SMarius Strobl #define	FG_LIGHTGREY		TCOLOR_FG(TC_WHITE)
977344ee18SMarius Strobl #define	FG_DARKGREY		(TFORMAT(TF_BOLD) | TCOLOR_FG(TC_BLACK))
987344ee18SMarius Strobl #define	FG_LIGHTBLUE		(TFORMAT(TF_BOLD) | TCOLOR_FG(TC_BLUE))
997344ee18SMarius Strobl #define	FG_LIGHTGREEN		(TFORMAT(TF_BOLD) | TCOLOR_FG(TC_GREEN))
1007344ee18SMarius Strobl #define	FG_LIGHTCYAN		(TFORMAT(TF_BOLD) | TCOLOR_FG(TC_CYAN))
1017344ee18SMarius Strobl #define	FG_LIGHTRED		(TFORMAT(TF_BOLD) | TCOLOR_FG(TC_RED))
1027344ee18SMarius Strobl #define	FG_LIGHTMAGENTA		(TFORMAT(TF_BOLD) | TCOLOR_FG(TC_MAGENTA))
103cf8880d5SEd Maste #define	FG_YELLOW		(TFORMAT(TF_BOLD) | TCOLOR_FG(TC_YELLOW))
1047344ee18SMarius Strobl #define	FG_WHITE		(TFORMAT(TF_BOLD) | TCOLOR_FG(TC_WHITE))
1057344ee18SMarius Strobl #define	FG_BLINK		TFORMAT(TF_BLINK)
1067344ee18SMarius Strobl 
1077344ee18SMarius Strobl /* syscons(4) compatible color attributes for text background */
1087344ee18SMarius Strobl #define	BG_BLACK		TCOLOR_BG(TC_BLACK)
1097344ee18SMarius Strobl #define	BG_BLUE			TCOLOR_BG(TC_BLUE)
1107344ee18SMarius Strobl #define	BG_GREEN		TCOLOR_BG(TC_GREEN)
1117344ee18SMarius Strobl #define	BG_CYAN			TCOLOR_BG(TC_CYAN)
1127344ee18SMarius Strobl #define	BG_RED			TCOLOR_BG(TC_RED)
1137344ee18SMarius Strobl #define	BG_MAGENTA		TCOLOR_BG(TC_MAGENTA)
114cf8880d5SEd Maste #define	BG_BROWN		TCOLOR_BG(TC_YELLOW)
1157344ee18SMarius Strobl #define	BG_LIGHTGREY		TCOLOR_BG(TC_WHITE)
1167344ee18SMarius Strobl #define	BG_DARKGREY		(TFORMAT(TF_BOLD) | TCOLOR_BG(TC_BLACK))
1177344ee18SMarius Strobl #define	BG_LIGHTBLUE		(TFORMAT(TF_BOLD) | TCOLOR_BG(TC_BLUE))
1187344ee18SMarius Strobl #define	BG_LIGHTGREEN		(TFORMAT(TF_BOLD) | TCOLOR_BG(TC_GREEN))
1197344ee18SMarius Strobl #define	BG_LIGHTCYAN		(TFORMAT(TF_BOLD) | TCOLOR_BG(TC_CYAN))
1207344ee18SMarius Strobl #define	BG_LIGHTRED		(TFORMAT(TF_BOLD) | TCOLOR_BG(TC_RED))
1217344ee18SMarius Strobl #define	BG_LIGHTMAGENTA		(TFORMAT(TF_BOLD) | TCOLOR_BG(TC_MAGENTA))
122cf8880d5SEd Maste #define	BG_YELLOW		(TFORMAT(TF_BOLD) | TCOLOR_BG(TC_YELLOW))
1237344ee18SMarius Strobl #define	BG_WHITE		(TFORMAT(TF_BOLD) | TCOLOR_BG(TC_WHITE))
1247344ee18SMarius Strobl 
1257344ee18SMarius Strobl #ifndef TERMINAL_NORM_ATTR
1267344ee18SMarius Strobl #ifdef SC_NORM_ATTR
1277344ee18SMarius Strobl #define	TERMINAL_NORM_ATTR	SC_NORM_ATTR
1287344ee18SMarius Strobl #else
1297344ee18SMarius Strobl #define	TERMINAL_NORM_ATTR	(FG_LIGHTGREY | BG_BLACK)
1307344ee18SMarius Strobl #endif
1317344ee18SMarius Strobl #endif
1327344ee18SMarius Strobl 
1337344ee18SMarius Strobl #ifndef TERMINAL_KERN_ATTR
1347344ee18SMarius Strobl #ifdef SC_KERNEL_CONS_ATTR
1357344ee18SMarius Strobl #define	TERMINAL_KERN_ATTR	SC_KERNEL_CONS_ATTR
1367344ee18SMarius Strobl #else
1377344ee18SMarius Strobl #define	TERMINAL_KERN_ATTR	(FG_WHITE | BG_BLACK)
1387344ee18SMarius Strobl #endif
1397344ee18SMarius Strobl #endif
1407344ee18SMarius Strobl 
14127cf7d04SAleksandr Rybalko typedef teken_pos_t term_pos_t;
14227cf7d04SAleksandr Rybalko typedef teken_rect_t term_rect_t;
14327cf7d04SAleksandr Rybalko 
14427cf7d04SAleksandr Rybalko typedef void tc_cursor_t(struct terminal *tm, const term_pos_t *p);
14527cf7d04SAleksandr Rybalko typedef void tc_putchar_t(struct terminal *tm, const term_pos_t *p,
14627cf7d04SAleksandr Rybalko     term_char_t c);
14727cf7d04SAleksandr Rybalko typedef void tc_fill_t(struct terminal *tm, const term_rect_t *r,
14827cf7d04SAleksandr Rybalko     term_char_t c);
14927cf7d04SAleksandr Rybalko typedef void tc_copy_t(struct terminal *tm, const term_rect_t *r,
15027cf7d04SAleksandr Rybalko     const term_pos_t *p);
151547e74a8SJean-Sébastien Pédron typedef void tc_pre_input_t(struct terminal *tm);
152547e74a8SJean-Sébastien Pédron typedef void tc_post_input_t(struct terminal *tm);
15327cf7d04SAleksandr Rybalko typedef void tc_param_t(struct terminal *tm, int cmd, unsigned int arg);
15427cf7d04SAleksandr Rybalko typedef void tc_done_t(struct terminal *tm);
15527cf7d04SAleksandr Rybalko 
15627cf7d04SAleksandr Rybalko typedef void tc_cnprobe_t(struct terminal *tm, struct consdev *cd);
15727cf7d04SAleksandr Rybalko typedef int tc_cngetc_t(struct terminal *tm);
15827cf7d04SAleksandr Rybalko 
1593e206539SJean-Sébastien Pédron typedef void tc_cngrab_t(struct terminal *tm);
1603e206539SJean-Sébastien Pédron typedef void tc_cnungrab_t(struct terminal *tm);
1613e206539SJean-Sébastien Pédron 
16227cf7d04SAleksandr Rybalko typedef void tc_opened_t(struct terminal *tm, int opened);
16327cf7d04SAleksandr Rybalko typedef int tc_ioctl_t(struct terminal *tm, u_long cmd, caddr_t data,
16427cf7d04SAleksandr Rybalko     struct thread *td);
1657a1a32c4SAleksandr Rybalko typedef int tc_mmap_t(struct terminal *tm, vm_ooffset_t offset,
1667a1a32c4SAleksandr Rybalko     vm_paddr_t * paddr, int nprot, vm_memattr_t *memattr);
16727cf7d04SAleksandr Rybalko typedef void tc_bell_t(struct terminal *tm);
16827cf7d04SAleksandr Rybalko 
16927cf7d04SAleksandr Rybalko struct terminal_class {
17027cf7d04SAleksandr Rybalko 	/* Terminal emulator. */
17127cf7d04SAleksandr Rybalko 	tc_cursor_t	*tc_cursor;
17227cf7d04SAleksandr Rybalko 	tc_putchar_t	*tc_putchar;
17327cf7d04SAleksandr Rybalko 	tc_fill_t	*tc_fill;
17427cf7d04SAleksandr Rybalko 	tc_copy_t	*tc_copy;
175547e74a8SJean-Sébastien Pédron 	tc_pre_input_t	*tc_pre_input;
176547e74a8SJean-Sébastien Pédron 	tc_post_input_t	*tc_post_input;
17727cf7d04SAleksandr Rybalko 	tc_param_t	*tc_param;
17827cf7d04SAleksandr Rybalko 	tc_done_t	*tc_done;
17927cf7d04SAleksandr Rybalko 
18027cf7d04SAleksandr Rybalko 	/* Low-level console interface. */
18127cf7d04SAleksandr Rybalko 	tc_cnprobe_t	*tc_cnprobe;
18227cf7d04SAleksandr Rybalko 	tc_cngetc_t	*tc_cngetc;
18327cf7d04SAleksandr Rybalko 
1843e206539SJean-Sébastien Pédron 	/* DDB & panic handling. */
1853e206539SJean-Sébastien Pédron 	tc_cngrab_t	*tc_cngrab;
1863e206539SJean-Sébastien Pédron 	tc_cnungrab_t	*tc_cnungrab;
1873e206539SJean-Sébastien Pédron 
18827cf7d04SAleksandr Rybalko 	/* Misc. */
18927cf7d04SAleksandr Rybalko 	tc_opened_t	*tc_opened;
19027cf7d04SAleksandr Rybalko 	tc_ioctl_t	*tc_ioctl;
1917a1a32c4SAleksandr Rybalko 	tc_mmap_t	*tc_mmap;
19227cf7d04SAleksandr Rybalko 	tc_bell_t	*tc_bell;
19327cf7d04SAleksandr Rybalko };
19427cf7d04SAleksandr Rybalko 
19527cf7d04SAleksandr Rybalko struct terminal {
19627cf7d04SAleksandr Rybalko 	const struct terminal_class *tm_class;
19727cf7d04SAleksandr Rybalko 	void		*tm_softc;
19827cf7d04SAleksandr Rybalko 	struct mtx	 tm_mtx;
19927cf7d04SAleksandr Rybalko 	struct tty	*tm_tty;
20027cf7d04SAleksandr Rybalko 	teken_t		 tm_emulator;
20127cf7d04SAleksandr Rybalko 	struct winsize	 tm_winsize;
20227cf7d04SAleksandr Rybalko 	unsigned int	 tm_flags;
20327cf7d04SAleksandr Rybalko #define	TF_MUTE		0x1	/* Drop incoming data. */
20427cf7d04SAleksandr Rybalko #define	TF_BELL		0x2	/* Bell needs to be sent. */
20527cf7d04SAleksandr Rybalko #define	TF_CONS		0x4	/* Console device (needs spinlock). */
20627cf7d04SAleksandr Rybalko 	struct consdev	*consdev;
20727cf7d04SAleksandr Rybalko };
20827cf7d04SAleksandr Rybalko 
20927cf7d04SAleksandr Rybalko #ifdef _KERNEL
21027cf7d04SAleksandr Rybalko 
21127cf7d04SAleksandr Rybalko struct terminal *terminal_alloc(const struct terminal_class *tc, void *softc);
21227cf7d04SAleksandr Rybalko void	terminal_maketty(struct terminal *tm, const char *fmt, ...);
213da49f6bcSJean-Sébastien Pédron void	terminal_set_cursor(struct terminal *tm, const term_pos_t *pos);
21427cf7d04SAleksandr Rybalko void	terminal_set_winsize_blank(struct terminal *tm,
2157344ee18SMarius Strobl     const struct winsize *size, int blank, const term_attr_t *attr);
21627cf7d04SAleksandr Rybalko void	terminal_set_winsize(struct terminal *tm, const struct winsize *size);
21727cf7d04SAleksandr Rybalko void	terminal_mute(struct terminal *tm, int yes);
21827cf7d04SAleksandr Rybalko void	terminal_input_char(struct terminal *tm, term_char_t c);
21927cf7d04SAleksandr Rybalko void	terminal_input_raw(struct terminal *tm, char c);
22027cf7d04SAleksandr Rybalko void	terminal_input_special(struct terminal *tm, unsigned int k);
22127cf7d04SAleksandr Rybalko 
22227cf7d04SAleksandr Rybalko void	termcn_cnregister(struct terminal *tm);
22327cf7d04SAleksandr Rybalko 
22427cf7d04SAleksandr Rybalko /* Kernel console helper interface. */
22527cf7d04SAleksandr Rybalko extern const struct consdev_ops termcn_cnops;
22627cf7d04SAleksandr Rybalko 
22727cf7d04SAleksandr Rybalko #define	TERMINAL_DECLARE_EARLY(name, class, softc)			\
22827cf7d04SAleksandr Rybalko 	static struct terminal name = {					\
22927cf7d04SAleksandr Rybalko 		.tm_class = &class,					\
23027cf7d04SAleksandr Rybalko 		.tm_softc = softc,					\
23127cf7d04SAleksandr Rybalko 		.tm_flags = TF_CONS,					\
23227cf7d04SAleksandr Rybalko 	};								\
23327cf7d04SAleksandr Rybalko 	CONSOLE_DEVICE(name ## _consdev, termcn_cnops, &name)
23427cf7d04SAleksandr Rybalko 
23527cf7d04SAleksandr Rybalko #endif /* _KERNEL */
23627cf7d04SAleksandr Rybalko 
23727cf7d04SAleksandr Rybalko #endif /* !_SYS_TERMINAL_H_ */
238