#pragma once #include 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;