diff options
| author | dam <dam@gudinoff> | 2023-08-29 09:21:24 +0100 |
|---|---|---|
| committer | dam <dam@gudinoff> | 2023-08-29 09:21:24 +0100 |
| commit | 76f3be800b9306a0a63c9f888b5e61c27ea35c0e (patch) | |
| tree | 9c2aeb28895acd9751b60622a121db49027e2a5b /tio.jai | |
| parent | 9ea152093b2eb2c3704cc7fbaa9e6cc5ae3d80f8 (diff) | |
| download | task-time-tracker-76f3be800b9306a0a63c9f888b5e61c27ea35c0e.tar.zst task-time-tracker-76f3be800b9306a0a63c9f888b5e61c27ea35c0e.zip | |
Attempting to replace ncurses.
Diffstat (limited to 'tio.jai')
| -rw-r--r-- | tio.jai | 142 |
1 files changed, 126 insertions, 16 deletions
@@ -1,4 +1,10 @@ +#module_parameters(ENABLE_SIGINT := true, ENABLE_SIGQUIT := true); + +#import "Basic"; + +// TODO Eventually, I'll need to add #scope_module ... + terminal_state : struct { // size : ivec2; width: s32; @@ -15,18 +21,22 @@ terminal_state : struct { __term : My_Termios; My_Termios :: struct { - c_iflag : u32; - c_oflag : u32; - c_cflag : u32; - c_lflag : u32; - unknown_pad : u8; - c_cc : [32]u8; - c_ispeed : u32; - c_ospeed : u32; + c_iflag : u32; // Input mode flags. + c_oflag : u32; // Output mode flags. + c_cflag : u32; // Control mode flags. + c_lflag : u32; // Local mode flags. + c_line : u8; // Line discipline. + c_cc : [32]u8; // Control characters. + c_ispeed : u32; // Input speed. + c_ospeed : u32; // Output speed. } 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; } else { @@ -57,6 +67,52 @@ Graphics_Mode :: struct { bcol256 : u8; } +Key :: enum u64 { + READ_ERROR :: 0xffffffff_ffffffff; + + UP :: 0x41_5b1b; + DOWN :: 0x42_5b1b; + RIGHT :: 0x43_5b1b; + LEFT :: 0x44_5b1b; + + CTRL_UP :: 0x4135_3b315b1b; + CTRL_DOWN :: 0x4235_3b315b1b; + CTRL_RIGHT :: 0x4335_3b315b1b; + CTRL_LEFT :: 0x4435_3b315b1b; + + SHIFT_UP :: 0x4132_3b315b1b; + SHIFT_DOWN :: 0x4232_3b315b1b; + SHIFT_RIGHT :: 0x4332_3b315b1b; + SHIFT_LEFT :: 0x4432_3b315b1b; + + CTRL_SHIFT_UP :: 0x4136_3b315b1b; + CTRL_SHIFT_DOWN :: 0x4236_3b315b1b; + CTRL_SHIFT_RIGHT:: 0x4336_3b315b1b; + CTRL_SHIFT_LEFT :: 0x4436_3b315b1b; + + ALT_UP :: 0x4133_3b315b1b; + ALT_DOWN :: 0x4233_3b315b1b; + ALT_RIGHT :: 0x4333_3b315b1b; + ALT_LEFT :: 0x4433_3b315b1b; + + CTRL_C :: 0x03; + CTRL_V :: 0x16; + CTRL_X :: 0x18; + CTRL_Y :: 0x19; + CTRL_Z :: 0x1A; + CTRL_BACKSLASH :: 0x1C; + + // ALT_SHIFT_UP :: 0x4133_3b315b1b; + // ALT_SHIFT_DOWN :: 0x4233_3b315b1b; + // ALT_SHIFT_RIGHT :: 0x4333_3b315b1b; + // ALT_SHIFT_LEFT :: 0x4433_3b315b1b; + + ENTER :: 0x0D; + ESCAPE :: 0x1B; + BACKSPACE :: 0x7F; + DELETE :: 0x7E335B1B; +} + Color :: enum u8 { RESET :: 0; DEFAULT :: 39; @@ -81,11 +137,40 @@ Color :: enum u8 { BRIGHT_WHITE :: 97; } -__old_logger : type_of(context.logger); +update_terminal_size :: () { + TIOCGWINSZ :: 0x5413; + winsize : struct { + ws_row, ws_col, ws_xpixel, ws_ypixel : u16; + } + ioctl(0, TIOCGWINSZ, *winsize); + terminal_state.width = xx winsize.ws_col; + terminal_state.height = xx winsize.ws_row; +} initialize :: () { #if OS == .LINUX { - tcgetattr(STDIN_FILENO, *__term); + + tui_write("\e[?25l"); // hide cursor + tui_write("\e7"); // save cursor position + tui_write("\e[?1047h"); // switch screen + tui_write("\e[?30l"); // hide scrollbar + + tui_write("\e[H"); // move to top left corner + tui_write("\e[0m"); // set default mode + tui_write("\e[2J"); // clear screen + { + 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); + } + update_terminal_size(); } else { assert(false, "procedure call on unsupported OS\n"); } @@ -95,22 +180,47 @@ terminate :: () { #if OS == .LINUX { tcsetattr(STDIN_FILENO, 0, *__term); // return echo - tio_write("\e[?47l"); // restore screen - tio_write("\e8"); // restore cursor - tio_write("\e[?25h"); // show cursor - tio_write("\e[?30h"); // show scrollbar + tui_write("\e[?47l"); // restore screen + tui_write("\e8"); // restore cursor + tui_write("\e[?25h"); // show cursor + tui_write("\e[?30h"); // show scrollbar terminal_state = .{}; - context.logger = __old_logger; } else { assert(false, "procedure call on unsupported OS\n"); } } -tio_write :: (str : string) { +tui_write :: (str : string) { #if OS == .LINUX { write(STDIN_FILENO, str.data, xx str.count); } else { assert(false, "procedure call on unsupported OS\n"); } } + +buffer: [..] Key; + +tui_ungetch :: (key: Key) { + array_add(*buffer, key); +} + +tui_getch :: (block := true) -> Key { + #if OS == .LINUX { + buf : Key = xx 0; + if buffer.count > 0 return pop(*buffer); + l := read(STDIN_FILENO, (cast(*u8)*buf), 8); //!!! + check_signal :: inline (key : Key) { + #if ENABLE_SIGINT if key == .CTRL_C raise(SIGINT); //!!! + #if ENABLE_SIGQUIT if key == .CTRL_BACKSLASH raise(SIGQUIT); + } + check_signal(buf); + return ifx l <= 0 then Key.READ_ERROR else buf; + } else { + return .READ_ERROR; + } +} + +tui_clear_screen :: inline () { + tui_write("\e[2J"); +} |
