diff options
| author | dam <dam@gudinoff> | 2023-09-19 01:58:23 +0100 |
|---|---|---|
| committer | dam <dam@gudinoff> | 2023-09-19 01:58:23 +0100 |
| commit | 470702f3ef0645b47c11ff54b9a6b0a5e9e8caab (patch) | |
| tree | d682986d8e4098a7811d6c0141c285f6c0e52a19 | |
| parent | ee1a68abb41ec7d0f76b458b5340d08a3f881a2b (diff) | |
| download | task-time-tracker-470702f3ef0645b47c11ff54b9a6b0a5e9e8caab.tar.zst task-time-tracker-470702f3ef0645b47c11ff54b9a6b0a5e9e8caab.zip | |
First implementation of vterm window size query.
| -rw-r--r-- | ttt.jai | 10 | ||||
| -rw-r--r-- | tui.jai | 109 |
2 files changed, 113 insertions, 6 deletions
@@ -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; @@ -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; + }; +} |
