feat: standard vga support (mode switching, framebuffer remapping)
[lunaix-os.git] / lunaix-os / hal / term / lcntls / ansi_cntl.c
diff --git a/lunaix-os/hal/term/lcntls/ansi_cntl.c b/lunaix-os/hal/term/lcntls/ansi_cntl.c
new file mode 100644 (file)
index 0000000..a11781e
--- /dev/null
@@ -0,0 +1,57 @@
+#include <hal/term.h>
+
+#include <lunaix/process.h>
+
+#define CTRL_MNEMO(chr) (chr - 'A' + 1)
+
+static inline int
+__ansi_actcontrol(struct term* termdev, char chr)
+{
+    struct linebuffer* lbuf = &termdev->line;
+    switch (chr) {
+        case '\0':            // EOL
+        case CTRL_MNEMO('D'): // EOF
+            return 0;
+
+        case CTRL_MNEMO('C'): // INTR
+            signal_send(termdev->fggrp, SIGINT);
+            break;
+
+        case '\r': // CR
+            termdev->line.ptr = 0;
+            return 1;
+
+        case '\x08': // ERASE
+            return line_put_next(lbuf, chr, -1);
+
+        case CTRL_MNEMO('Q'): // QUIT
+            signal_send(termdev->fggrp, SIGKILL);
+            return 1;
+
+        case CTRL_MNEMO('Z'): // SUSP
+            signal_send(termdev->fggrp, SIGSTOP);
+            return 1;
+
+        default:
+            if ((int)chr < 32) {
+                line_put_next(lbuf, '^', 0);
+                chr += 64;
+            }
+            break;
+    }
+
+    return line_put_next(lbuf, chr, 0);
+}
+
+static size_t
+ansi_lcntl_process(struct term* termdev, char* line, size_t len)
+{
+    size_t i = 0;
+    while (i < len && __ansi_actcontrol(termdev, line[i])) {
+        i++;
+    }
+
+    return i;
+}
+
+struct term_lcntl ansi_line_controller = { .apply = ansi_lcntl_process };
\ No newline at end of file