aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordam <dam@gudinoff>2023-09-19 01:58:23 +0100
committerdam <dam@gudinoff>2023-09-19 01:58:23 +0100
commit470702f3ef0645b47c11ff54b9a6b0a5e9e8caab (patch)
treed682986d8e4098a7811d6c0141c285f6c0e52a19
parentee1a68abb41ec7d0f76b458b5340d08a3f881a2b (diff)
downloadtask-time-tracker-470702f3ef0645b47c11ff54b9a6b0a5e9e8caab.tar.zst
task-time-tracker-470702f3ef0645b47c11ff54b9a6b0a5e9e8caab.zip
First implementation of vterm window size query.
-rw-r--r--ttt.jai10
-rw-r--r--tui.jai109
2 files changed, 113 insertions, 6 deletions
diff --git a/ttt.jai b/ttt.jai
index 8ac98c8..bb17489 100644
--- a/ttt.jai
+++ b/ttt.jai
@@ -1186,14 +1186,16 @@ main :: () {
// https://github.com/MicrosoftDocs/Console-Docs/blob/main/docs/console-virtual-terminal-sequences.md
TUI.start();
TUI.clear_screen();
- TUI.draw_box(1,1,24,13);
+ rows, columns := TUI.get_cena();
+ TUI.draw_box(1,1,columns, rows);
// TODO get size of console... its being displayed... but we want to collect it.
// write_string(TUI.Commands.QueryCursorPosition);
- write_string(TUI.Commands.QueryWindowSizeInChars);
+ // write_string(TUI.Commands.QueryWindowSizeInChars);
+ // wow := TUI.read_input();
sleep_milliseconds(3000);
- // write_string(TUI.Commands.ShowCursor);
TUI.stop();
- // write_string(TUI.Commands.QueryDeviceAttributes);
+
+ print("--- --- ---\nRxC = %x%\n", rows, columns);
return;
str: string;
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;
+ };
+}