aboutsummaryrefslogtreecommitdiff
path: root/tio.jai
diff options
context:
space:
mode:
Diffstat (limited to 'tio.jai')
-rw-r--r--tio.jai142
1 files changed, 126 insertions, 16 deletions
diff --git a/tio.jai b/tio.jai
index 37c7e4a..f6ee0cb 100644
--- a/tio.jai
+++ b/tio.jai
@@ -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");
+}