aboutsummaryrefslogtreecommitdiff
path: root/TUI/unix.jai
diff options
context:
space:
mode:
Diffstat (limited to 'TUI/unix.jai')
-rw-r--r--TUI/unix.jai63
1 files changed, 63 insertions, 0 deletions
diff --git a/TUI/unix.jai b/TUI/unix.jai
new file mode 100644
index 0000000..439447d
--- /dev/null
+++ b/TUI/unix.jai
@@ -0,0 +1,63 @@
+#import "POSIX";
+
+
+ __term : My_Termios;
+
+ My_Termios :: struct {
+ c_iflag : u32; // Input mode flags.
+ c_oflag : u32; // Output mode flags.
+ c_cflag : u32; // Control modes flags.
+ c_lflag : u32; // Local modes flags.
+ c_line : u8; // Line discipline.
+ c_cc : [32]u8; // Control characters.
+ c_ispeed : u32; // Input speed (baud rates).
+ c_ospeed : u32; // Output speed (baud rates).
+ }
+
+ // Required to do unlocking input.
+ libc :: #system_library "libc";
+
+ // https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcsetattr.c.html
+ tcsetattr :: (fd : s32, optional_actions : s32, termios_p : *My_Termios) -> s32 #foreign libc;
+
+ // https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcgetattr.c.html
+ tcgetattr :: (fd : s32, termios_p : *My_Termios) -> s32 #foreign libc;
+
+
+OS_prepare_terminal :: () {
+ // TODO Required to do unlocking input.
+ tcgetattr(STDIN_FILENO, *__term);
+ term_new := __term;
+
+ term_new.c_iflag &= 0xFFFFFA14;// ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
+ term_new.c_oflag &= 0xFFFFFFFE;// ~OPOST;
+ term_new.c_lflag &= 0xFFFF7FB4;// ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ term_new.c_cflag &= 0xFFFFFECF;// ~(CSIZE | PARENB);
+ term_new.c_cflag |= 0x00000030;
+
+ tcsetattr(STDIN_FILENO, 0, *term_new);
+}
+
+OS_reset_terminal :: () {
+ tcsetattr(STDIN_FILENO, 0, *__term); // return echo
+}
+
+OS_get_terminal_size :: () -> rows: int, columns: int {
+ buffer: [512] u8;
+ write_string(Commands.QueryWindowSizeInChars);
+ bytes_read := read(STDIN_FILENO, buffer.data, buffer.count-1);
+
+ str := to_string(buffer.data, bytes_read);
+
+ // Result: [8;79;156t
+ assert(
+ buffer.data[0] == #char "\e" &&
+ buffer.data[1] == #char "[" &&
+ buffer.data[2] == #char "8",
+ "Query windows size in chars returned invalid response.");
+
+ parts := split(str, ";");
+ rows := parse_int(*parts[1]);
+ columns := parse_int(*parts[2]);
+ return rows, columns;
+}