aboutsummaryrefslogtreecommitdiff
path: root/tui.jai
diff options
context:
space:
mode:
Diffstat (limited to 'tui.jai')
-rw-r--r--tui.jai109
1 files changed, 107 insertions, 2 deletions
diff --git a/tui.jai b/tui.jai
index 3c868ee..564e9ba 100644
--- a/tui.jai
+++ b/tui.jai
@@ -1,4 +1,5 @@
#import "Basic";
+#import "String";
Drawings :: struct {
CornerBR :: "\x6A";
@@ -42,6 +43,8 @@ Commands :: struct {
HideCursor :: "\e[?25l";
StartBlinking :: "\e[?25h]";
StopBlinking :: "\e[?25l]";
+ SaveCursorPosition :: "\e7";
+ RestoreCursorPosition :: "\e8";
// Cursor Shape
DefaultShape :: "\e[0 q";
@@ -66,11 +69,25 @@ Commands :: struct {
}
start :: () {
- write_strings(Commands.EnterAlternateBuffer, Commands.SetUTF8, Commands.HideCursor);
+ // 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);
+
+ write_strings(Commands.HideCursor, Commands.SaveCursorPosition, Commands.EnterAlternateBuffer, Commands.SetUTF8);
}
stop :: () {
- write_strings(Commands.EnterMainBuffer, Commands.ShowCursor);
+ write_strings(Commands.EnterMainBuffer, Commands.RestoreCursorPosition, Commands.ShowCursor);
+
+ tcsetattr(STDIN_FILENO, 0, *__term); // return echo
}
draw_box :: (x: int, y: int, width: int, height: int, to_standard_error := false) {
@@ -120,3 +137,91 @@ draw_box :: (x: int, y: int, width: int, height: int, to_standard_error := false
clear_screen :: inline () {
write_string(Commands.ClearScreen);
}
+
+// read_input: () -> string;
+
+#if OS == .LINUX {
+ #import "Basic";
+ #import "POSIX";
+
+ __term : My_Termios;
+
+ My_Termios :: struct {
+ c_iflag : u32; // Input modes.
+ c_oflag : u32; // Output modes.
+ c_cflag : u32; // Control modes.
+ c_lflag : u32; // Local modes.
+ unknown_pad : u8;
+ c_cc : [32]u8; // Special characters.
+ c_ispeed : u32; // Input baud rates.
+ c_ospeed : u32; // Output baud rates.
+ }
+
+ // Required to do unlocking input.
+ libc :: #system_library "libc";
+ tcsetattr :: (fd : s32, optional_actions : s32, termios_p : *My_Termios) -> s32 #foreign libc;
+ tcgetattr :: (fd : s32, termios_p : *My_Termios) -> s32 #foreign libc;
+
+
+
+ read_input :: () -> string {
+ buffer: [8192] u8;
+ bytes_read := read(STDIN_FILENO, buffer.data, buffer.count-1);
+ str := to_string(buffer.data, bytes_read);
+ return str;
+ };
+
+ get_cena :: () -> 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;
+ }
+
+}
+else #if OS == .WINDOWS {
+ #import "Windows";
+
+ kernel32 :: #system_library "kernel32";
+
+ stdin, stdout : HANDLE;
+
+ stdin = GetStdHandle( STD_INPUT_HANDLE );
+
+ ReadConsoleA :: (
+ hConsoleHandle: HANDLE,
+ buff : *u8,
+ chars_to_read : s32,
+ chars_read : *s32,
+ lpInputControl := *void
+ ) -> bool #foreign kernel32;
+
+ // #run read_input = () -> string {
+ read_input :: () -> string {
+ MAX_BYTES_TO_READ :: 1024;
+ temp : [MAX_BYTES_TO_READ] u8;
+ result: string = ---;
+ bytes_read : s32;
+
+ if !ReadConsoleA( stdin, temp.data, xx temp.count, *bytes_read )
+ return "";
+
+ result.data = alloc(bytes_read);
+ result.count = bytes_read;
+ memcpy(result.data, temp.data, bytes_read);
+ return result;
+ };
+}