aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/line/mode.h59
-rw-r--r--module-test/line_test.cc33
2 files changed, 92 insertions, 0 deletions
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 <unistd.h>
+#include <termios.h>
+#include <stdlib.h>
+
+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 <iostream>
+#include <print>
+
+#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<unsigned char>(c));
+ else
+ print("entered: {}\r\n", c);
+ }
+ return 0;
+}