From 83fa0a85281118103b4f8bf82dcb25cacb42d982 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Mon, 21 Sep 2026 10:54:49 +0000 Subject: add raw mode --- include/line/mode.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ module-test/line_test.cc | 33 +++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 include/line/mode.h create mode 100644 module-test/line_test.cc diff --git a/include/line/mode.h b/include/line/mode.h new file mode 100644 index 0000000..8811e66 --- /dev/null +++ b/include/line/mode.h @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include + +using namespace std; // TODO: remove + +namespace ov4 +{ + +inline termios attr; + +void disable_raw() +{ + tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr); +} + +void enable_raw() +{ + termios attr_raw; + tcgetattr(STDIN_FILENO, &attr); + tcgetattr(STDIN_FILENO, &attr_raw); + + // LOCAL + + // disable + // echo + // canonical + // signal + // disable post-input processing, aka control-V + attr_raw.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN); + + // INPUT + + // disable + // software flow control, aka control-S/Q + // \n and \r conversion + attr_raw.c_iflag &= ~(IXON | ICRNL); + + // OUTPUT + + // disable + // post-output processing + attr_raw.c_oflag &= ~(OPOST); + + // misc + attr_raw.c_iflag &= ~(BRKINT | INPCK | ISTRIP); + attr_raw.c_cflag |= ~(CS8); + + atexit(disable_raw); + + // TCSAFLUSH + // the change shall occur after all output written to fildes is transmitted + // and all input so far received but not read shall be discarded before the change is made + tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr_raw); +} + +} diff --git a/module-test/line_test.cc b/module-test/line_test.cc new file mode 100644 index 0000000..7bc16df --- /dev/null +++ b/module-test/line_test.cc @@ -0,0 +1,33 @@ +/* + * test line editor + $ g++ \ + module-test/line_test.cc \ + -std=c++26 -Iinclude -Ithird_party/magic_enum/include \ + -O0 -ggdb3 -fno-omit-frame-pointer -fno-inline -D_GLIBCXX_ASSERTIONS \ + -o module-test/line_test.out + * + */ + + +#include +#include + +#include "line/mode.h" + +using namespace std; +using namespace ov4; + +int main() +{ + enable_raw(); + char c; + while (read(STDIN_FILENO, &c, 1) == 1) + { + if (c == 'q') break; + if (iscntrl(c)) + print("control: {}\r\n", static_cast(c)); + else + print("entered: {}\r\n", c); + } + return 0; +} -- cgit v1.3.1-4-g156e