aboutsummaryrefslogtreecommitdiff
path: root/TUI
diff options
context:
space:
mode:
Diffstat (limited to 'TUI')
-rw-r--r--TUI/module.jai46
-rw-r--r--TUI/unix.jai88
2 files changed, 95 insertions, 39 deletions
diff --git a/TUI/module.jai b/TUI/module.jai
index 044fd65..bfed510 100644
--- a/TUI/module.jai
+++ b/TUI/module.jai
@@ -108,11 +108,13 @@ assert_is_initialized :: inline () {
}
set_next_key :: (key: Key) {
+ assert_is_initialized();
input_override = key;
}
get_key :: (timeout_milliseconds: s32 = -1) -> Key {
-
+ assert_is_initialized();
+
// BBBB BBBB & 1100 0000 == 10XX XXXX -> is continuation byte
is_utf8_continuation_byte :: inline (byte: u8) -> bool {
return (byte & 0xC0) == 0x80;
@@ -196,21 +198,21 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
/// /// /// /// /// /// /// /// ///
// DEBUG
- br, bc := get_cursor_position();
- column := 3;
- row += 1;
- nr, rc := get_terminal_size();
-
- if row >= (rc - 5) then row = 5;
-
- set_cursor_position(row, column);
- for 0..input_string.count-1 {
- print("%:% | ",
- FormatInt.{base= 2, minimum_digits = 8, value = input_string[it]},
- FormatInt.{base= 16, minimum_digits = 2, value = input_string[it]},
- ); // TODO DEBUG
- }
- set_cursor_position(br, bc);
+ // br, bc := get_cursor_position();
+ // column := 3;
+ // row += 1;
+ // nr, rc := get_terminal_size();
+ //
+ // if row >= (rc - 5) then row = 5;
+//
+ // set_cursor_position(row, column);
+ // for 0..input_string.count-1 {
+ // print("%:% | ",
+ // FormatInt.{base= 2, minimum_digits = 8, value = input_string[it]},
+ // FormatInt.{base= 16, minimum_digits = 2, value = input_string[it]},
+ // ); // TODO DEBUG
+ // }
+ // set_cursor_position(br, bc);
/// /// /// /// /// /// /// /// ///
advance(*input_string, utf8_bytes);
@@ -221,6 +223,7 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
}
get_str :: (count_limit: int = -1, allocator: Allocator = temp) -> string {
+ assert_is_initialized();
assert(allocator.proc != null, "Argument 'allocator.proc' has invalid null value.");
if count_limit < 0 {
@@ -270,6 +273,7 @@ flush_input :: () {
}
draw_box :: (x: int, y: int, width: int, height: int) {
+ assert_is_initialized();
// TODO Check if using a String_Builder improves performance (measure it)!
// TODO Validate input parameters against the terminal size.
@@ -315,13 +319,13 @@ draw_box :: (x: int, y: int, width: int, height: int) {
// TODO Maybe rename to "clear()"
clear_terminal :: inline () {
- assert(initialized, "TUI is not ready.");
+ assert_is_initialized();
write_string(Commands.ClearScreen);
}
// TODO Maybe rename to "get_size()"
get_terminal_size :: () -> rows: int, columns: int {
- assert(initialized, "TUI is not ready.");
+ assert_is_initialized();
rows, columns: int = ---;
#if OS == .WINDOWS {
rows, columns = OS_get_terminal_size();
@@ -359,15 +363,15 @@ get_terminal_size :: () -> rows: int, columns: int {
}
set_cursor_position :: (row: int, column: int) {
- assert(initialized, "TUI is not ready.");
+ assert_is_initialized();
auto_release_temp();
tmp_string := tprint(Commands.SetCursorPosition, row, column);
write_string(tmp_string);
}
get_cursor_position :: () -> row: int, column: int {
- assert(initialized, "TUI is not ready."); // TODO Should I use this inside each and every procedure?
-
+ assert_is_initialized();
+
auto_release_temp();
flush_input();
diff --git a/TUI/unix.jai b/TUI/unix.jai
index 2c34122..03a371b 100644
--- a/TUI/unix.jai
+++ b/TUI/unix.jai
@@ -6,19 +6,9 @@
// Required to do unlocking input.
libc :: #system_library "libc";
-
-
- // int poll(struct pollfd *fds, nfds_t nfds, int timeout);
- pollfd :: struct {
- fd : s32; // File descriptor.
- events : s16; // Requested events.
- revents : s16; // Returned events.
- };
- poll :: (fds: *pollfd, nfds: u32, timeout: s32) -> s32 #foreign libc;
-
// TODO Remote this.
- cfmakeraw :: (termios: *Terminal_IO_Mode) -> void #foreign libc;
+ // cfmakeraw :: (termios: *Terminal_IO_Mode) -> void #foreign libc;
/* https://elixir.bootlin.com/glibc/glibc-2.28/source/termios/cfmakeraw.c#L22
void
cfmakeraw (struct termios *t)
@@ -32,19 +22,81 @@
t->c_cc[VTIME] = 0;
}
*/
-
+
// https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcsetattr.c.html
- tcsetattr :: (fd: s32, optional_actions: s32, termios_p : *Terminal_IO_Mode) -> s32 #foreign libc;
+ // tcsetattr :: (fd: s32, optional_actions: s32, termios_p : *Terminal_IO_Mode) -> s32 #foreign libc;
+ tcsetattr :: (fd: s32, optional_actions: s32, termios_p : *Terminal_IO_Mode) -> s32 {
+ // TODO IMPLEMENT ME
+
+ #if OS == .LINUX {
+ TCSETS :: 0x5402;
+ TCSETSW :: 0x5403;
+ TCSETSF :: 0x5404;
+ tcflag_t :: u32;
+ cc_t :: u8;
+ __KERNEL_NCCS :: 19;
+ __kernel_termios :: struct {
+ c_iflag : tcflag_t; // input mode flags
+ c_oflag : tcflag_t; // output mode flags
+ c_cflag : tcflag_t; // control mode flags
+ c_lflag : tcflag_t; // local mode flags
+ c_line : cc_t; // line discipline
+ c_cc : [__KERNEL_NCCS]cc_t; // control characters
+ };
+
+ k_termios: __kernel_termios;
+ cmd: u64;
+ if optional_actions == {
+ case xx SetAttributesActions.TCSANOW;
+ cmd = TCSETS;
+ case xx SetAttributesActions.TCSADRAIN;
+ cmd = TCSETSW;
+
+ case xx SetAttributesActions.TCSAFLUSH;
+ cmd = TCSETSF;
+
+ case;
+ return EINVAL;
+ }
+ // k_termios.c_iflag = termios_p.c_iflag & ~IBAUD0;
+ k_termios.c_iflag = xx termios_p.c_iflag;
+ k_termios.c_oflag = xx termios_p.c_oflag;
+ k_termios.c_cflag = xx termios_p.c_cflag;
+ k_termios.c_lflag = xx termios_p.c_lflag;
+ k_termios.c_line = xx termios_p.c_line;
+ // #if _HAVE_C_ISPEED && _HAVE_STRUCT_TERMIOS_C_ISPEED
+ // k_termios.c_ispeed = termios_p->c_ispeed;
+ // #endif
+ // #if _HAVE_C_OSPEED && _HAVE_STRUCT_TERMIOS_C_OSPEED
+ // k_termios.c_ospeed = termios_p->c_ospeed;
+ // #endif
+ memcpy(*k_termios.c_cc[0], *termios_p.c_cc[0], __KERNEL_NCCS * 1);//size_of(cc_t));
+ return ioctl(fd, cmd, *k_termios);
+ }
+ #if OS == .MACOS {
+ // return __ioctl (fd, TIOCSETAF, termios_p);
+ #assert(false, "NOT IMPLEMENTED");
+ }
+ return 0;
+ }
+
// https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcgetattr.c.html
tcgetattr :: (fd: s32, termios_p: *Terminal_IO_Mode) -> s32 #foreign libc;
-
+ // tcgetattr :: (fd: s32, termios_p: *Terminal_IO_Mode) -> s32 {
+ // TODO IMPLEMENT ME
+ // }
+
// https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcflush.c.html
- tcflush :: (fd: s32, queue_selector: s32) -> s32 #foreign libc;
-
+ // tcflush :: (fd: s32, queue_selector: s32) -> s32 #foreign libc;
+ tcflush :: inline (fd: s32, queue_selector: s32) -> s32 {
+ TCFLSH :: 0x540B;
+ return ioctl(fd, TCFLSH, queue_selector);
+ }
+
// Information for the termios.h enums is platform dependent and was retrieved from:
// https://elixir.bootlin.com/glibc/latest/source/sysdeps/unix/sysv/linux/bits/termios.h
-
+
// Set Attributes Actions.
SetAttributesActions :: enum u32 {
TCSANOW :: 0; // Change immediately.
@@ -187,7 +239,7 @@ OS_flush_input :: inline () {
}
OS_prepare_terminal :: () {
- tcgetattr(STDIN_FILENO, *initial_tio_mode); // TODO Log on error.
+ tcgetattr(STDIN_FILENO, *initial_tio_mode); // TODO Log error using `log()` from jai/modules/Basic/Print.jai ?
raw_tio_mode = initial_tio_mode;
raw_tio_mode.c_iflag &= ~(.IGNBRK | .BRKINT | .PARMRK | .ISTRIP | .INLCR | .IGNCR | .ICRNL | .IXON);
raw_tio_mode.c_oflag &= ~(.OPOST);