diff options
Diffstat (limited to 'TUI')
| -rw-r--r-- | TUI/module.jai | 46 | ||||
| -rw-r--r-- | TUI/unix.jai | 88 |
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); |
