aboutsummaryrefslogtreecommitdiff
path: root/src/engine/io/terminal.hpp
blob: 27455bbee744428d816ccc6cd0520aa4198a54e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once

#include <termios.h>

enum class TerminalControlModeFlag
{
	csize = 0000060,
	cs5 = 0000000,
	cs6 = 0000020,
	cs7 = 0000040,
	cs8 = 0000060,
	cstopb = 0000100,
	cread = 0000200,
	parenb = 0000400,
	parodd = 0001000,
	hupcl = 0002000,
	clocal = 0004000,
};

enum class TerminalInputModeFlag
{
	ignbrk = 0000001,  // Ignore break condition
	brkint = 0000002,  // Signal interrupt on break
	ignpar = 0000004,  // Ignore characters with parity errors
	parmrk = 0000010,  // Mark parity and framing errors
	inpck = 0000020,   // Enable input parity check
	istrip = 0000040,  // Strip = 8,th bit off characters
	inlcr = 0000100,   // Map NL to CR on input
	igncr = 0000200,   // Ignore CR
	icrnl = 0000400,   // Map CR to NL on input
	iuclc = 0001000,   // Map uppercase characters to lowercase on input (not in POSIX)
	ixon = 0002000,	   // Enable start/stop output control
	ixany = 0004000,   // Enable any character to restart output
	ixoff = 0010000,   // Enable start/stop input control
	imaxbel = 0020000, // Ring bell when input queue is full (not in POSIX)
	iutf8 = 0040000,   // Input is UTF8 (not in POSIX)
};

enum class TerminalOutputModeFlag
{
	opost = 0000001,  // Post-process output
	olcuc = 0000002,  // Map lowercase characters to uppercase on output (not in POSIX)
	onlcr = 0000004,  // Map NL to CR-NL on output
	ocrnl = 0000010,  // Map CR to NL on output
	onocr = 0000020,  // No CR output at column = 0
	onlret = 0000040, // NL performs CR function
	ofill = 0000100,  // Use fill characters for delay
	ofdel = 0000200,  // Fill is DEL
	nldly = 0000400,  // Select newline delays:
	nl0 = 0000000,	  // Newline type = 0
	nl1 = 0000400,	  // Newline type = 1
	crdly = 0003000,  // Select carriage-return delays:
	cr0 = 0000000,	  // Carriage-return delay type = 0
	cr1 = 0001000,	  // Carriage-return delay type = 1
	cr2 = 0002000,	  // Carriage-return delay type = 2
	cr3 = 0003000,	  // Carriage-return delay type = 3
	tabdly = 0014000, // Select horizontal-tab delays:
	tab0 = 0000000,	  // Horizontal-tab delay type = 0
	tab1 = 0004000,	  // Horizontal-tab delay type = 1
	tab2 = 0010000,	  // Horizontal-tab delay type = 2
	tab3 = 0014000,	  // Expand tabs to spaces
	bsdly = 0020000,  // Select backspace delays:
	bs0 = 0000000,	  // Backspace-delay type = 0
	bs1 = 0020000,	  // Backspace-delay type = 1
	ffdly = 0100000,  // Select form-feed delays:
	ff0 = 0000000,	  // Form-feed delay type = 0
	ff1 = 0100000,	  // Form-feed delay type = 1
	vtdly = 0040000,  // Select vertical-tab delays:
	vt0 = 0000000,	  // Vertical-tab delay type = 0
	vt1 = 0040000,	  // Vertical-tab delay type = 1
	xtabs = 0014000,
};

enum class TerminalLocalModeFlag
{
	isig = 0000001, // When any of the characters INTR, QUIT, SUSP, or DSUSP are received,
					// generate the corresponding signal
	icanon = 0000002, // Canonical input
	xcase = 0000004,
	echo = 0000010,	   // Echo input characters
	echoe = 0000020,   // Echo erase character as error-correcting backspace
	echok = 0000040,   // Echo KILL
	echonl = 0000100,  // Echo NL
	noflsh = 0000200,  // Disable flush after interrupt or quit
	tostop = 0000400,  // Send SIGTTOU for background output
	echoctl = 0001000, /* If ECHO is also set, terminal special characters
					other than TAB, NL, START, and STOP are echoed as
					^X, where X is the character with ASCII code = 0,x40
					greater than the special character
					(not in POSIX) */
	echoprt = 0002000, /* If ICANON and ECHO are also set, characters are
					printed as they are being erased
					(not in POSIX) */
	echoke = 0004000,  /* If ICANON is also set, KILL is echoed by erasing
				   each character on the line, as specified by ECHOE
				   and ECHOPRT (not in POSIX) */
	flusho = 0010000,  /* Output is being flushed  This flag is toggled by
				   typing the DISCARD character (not in POSIX) */
	pendin = 0040000,  /* All characters in the input queue are reprinted
				   when the next character is read
				   (not in POSIX) */
	iexten = 0100000,  // Enable implementation-defined input processing
	extproc = 0200000,
};

class TerminalState
{
public:
	TerminalState() = default;

	explicit TerminalState(termios term_attrs) noexcept;

	void set_input_mode_flag(TerminalInputModeFlag flag, bool is_on) noexcept;

	void set_output_mode_flag(TerminalOutputModeFlag flag, bool is_on) noexcept;

	void set_control_mode_flag(TerminalControlModeFlag flag, bool is_on) noexcept;

	void set_local_mode_flag(TerminalLocalModeFlag flag, bool is_on) noexcept;

	auto get_attributes() noexcept -> termios;

private:
	termios _term_attrs;
};

auto get_terminal_state(int term_fd) noexcept -> TerminalState;

void set_terminal_state(int term_fd, TerminalState state) noexcept;