aboutsummaryrefslogtreecommitdiff
path: root/TUI/unix.jai
diff options
context:
space:
mode:
Diffstat (limited to 'TUI/unix.jai')
-rw-r--r--TUI/unix.jai136
1 files changed, 99 insertions, 37 deletions
diff --git a/TUI/unix.jai b/TUI/unix.jai
index 6bcf13a..20d1a2a 100644
--- a/TUI/unix.jai
+++ b/TUI/unix.jai
@@ -14,93 +14,158 @@
// Input modes.
+ // https://elixir.bootlin.com/glibc/latest/source/bits/termios.h
Input_Modes :: enum_flags u32 {
IGNBRK; // Ignore break condition.
BRKINT; // Signal interrupt on break.
IGNPAR; // Ignore characters with parity errors.
PARMRK; // Mark parity and framing errors.
+
INPCK; // Enable input parity check.
ISTRIP; // Strip 8th bit off characters.
INLCR; // Map NL to CR on input.
IGNCR; // Ignore CR.
+
ICRNL; // Map CR to NL on input.
IXON; // Enable start/stop output control.
IXOFF; // Enable start/stop input control.
IXANY; // Any character will restart after stop.
- __NOT_USED__;
+
+ _1000_;
IMAXBEL; // Ring bell when input queue is full.
IUCLC; // Translate upper case input to lower case.
+ _8000_;
+ }
+
+ // Output modes.
+ // https://elixir.bootlin.com/glibc/latest/source/bits/termios.h
+ Output_Modes :: enum_flags u32 {
+ OPOST; // Perform output processing.
+ ONLCR; // Map NL to CR-NL on output.
+ _UNUSED_0004_;
+ ONOEOT; // Discard EOT (^D) on output.
+ OCRNL; // Map CR to NL.
+ ONOCR; // Discard CR's when on column 0.
+ ONLRET; // Move to column 0 on NL.
+ _UNUSED_0080_;
}
+ // Control modes.
+ // https://elixir.bootlin.com/glibc/latest/source/bits/termios.h
+ Control_Modes :: enum_flags u32 {
+ CIGNORE; // Ignore these control flags.
+ _0002_;
+ _0004_;
+ _0008_;
+
+ _0010_;
+ _0020_;
+ _0040_;
+ _0080_;
+
+ _0100_;
+ _0200_;
+ CSTOPB; // Two stop bits instead of one.
+ CREAD; // Enable receiver.
+
+ PARENB; // Parity enable.
+ PARODD; // Odd parity instead of even.
+ HUPCL; // Hang up on last close.
+ CLOCAL; // Ignore modem status lines.
+
+ CRTSCTS; // RTS/CTS flow control.
+ CDTRCTS; // DTR/CTS flow control.
+ _0004_0000_;
+ _0008_0000_;
+
+ MDMBUF; // DTR/DCD flow control.
+ }
+
+ CHWFLOW :Control_Modes : (.MDMBUF | .CRTSCTS | .CDTRCTS); // All types of flow control.
+ CS5 :Control_Modes : 0x0000; // 5 bits per byte.
+ CS6 :Control_Modes : 0x0100; // 6 bits per byte.
+ CS7 :Control_Modes : 0x0200; // 7 bits per byte.
+ CS8 :Control_Modes : CS6|CS7; // 8 bits per byte.
+ CSIZE :Control_Modes : CS5|CS6|CS7|CS8; // Number of bits per byte (mask).
+
// Local modes.
+ // https://elixir.bootlin.com/glibc/latest/source/bits/termios.h
Local_Modes :: enum_flags u32 {
ECHOKE; // Visual erase for KILL.
ECHOE; // Visual erase for ERASE.
ECHOK; // Echo NL after KILL.
ECHO; // Enable echo.
+
ECHONL; // Echo NL even if ECHO is off.
ECHOPRT; // Hardcopy visual erase.
ECHOCTL; // Echo control characters as ^X.
ISIG; // Enable signals.
+
ICANON; // Do erase and kill processing.
ALTWERASE; // Alternate WERASE algorithm.
IEXTEN; // Enable DISCARD and LNEXT.
EXTPROC; // External processing.
+
+ _1000_;
+ _2000_;
+ _4000_;
+ _8000_;
+
+ _0001_0000_;
+ _0002_0000_;
+ // TODO Maybe reduce the amount of unused flags by setting the value when there are holes on the table.
+ // TOSTOP :: 0x0004_0000; // Send SIGTTOU for background output.
TOSTOP; // Send SIGTTOU for background output.
FLUSHO; // Output being flushed (state).
+
XCASE; // Canonical upper/lower case.
NOKERNINFO; // Disable VSTATUS.
+ _0040_0000_;
+ _0080_0000_;
+
+ _0100_0000_;
PENDIN; // Retype pending input (state).
+ _0400_0000_;
NOFLSH; // Disable flush after interrupt.
-
}
-
+
Terminal_IO_Mode :: struct {
- c_iflag : u32; // Input mode flags.
- c_oflag : u32; // Output mode flags.
- c_cflag : u32; // Control modes flags.
- c_lflag : u32; // Local modes flags.
- c_line : u8; // Line discipline.
- c_cc : [32]u8; // Control characters.
+ c_iflag : Input_Modes; // Input mode flags.
+ c_oflag : Output_Modes; // Output mode flags.
+ c_cflag : Control_Modes; // Control modes flags.
+ c_lflag : Local_Modes; // Local modes flags.
+ c_line : u8; // Line discipline.
+ c_cc : [32]u8; // Control characters.
c_ispeed : u32; // Input speed (baud rates).
c_ospeed : u32; // Output speed (baud rates).
}
- initial_tio_mode : Terminal_IO_Mode;
+ initial_tio_mode: Terminal_IO_Mode;
default_tio_mode: Terminal_IO_Mode;
- blocking_tio_mode: Terminal_IO_Mode;
- unblocking_tio_mode: Terminal_IO_Mode;
+ human_tio_mode: Terminal_IO_Mode;
#scope_export
OS_prepare_terminal :: () {
- // TODO Required to do unlocking input.
tcgetattr(STDIN_FILENO, *initial_tio_mode);
- default_tio_mode := initial_tio_mode;
- default_tio_mode.c_iflag &= 0xFFFFFA14;// ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
- default_tio_mode.c_oflag &= 0xFFFFFFFE;// ~OPOST;
- default_tio_mode.c_lflag &= 0xFFFF7FB4;// ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- default_tio_mode.c_cflag &= 0xFFFFFECF;// ~(CSIZE | PARENB);
- default_tio_mode.c_cflag |= 0x00000030; // TODO WHAT IS THIS?
+ default_tio_mode = initial_tio_mode;
+ default_tio_mode.c_iflag &= ~(.IGNBRK | .BRKINT | .PARMRK | .ISTRIP | .INLCR | .IGNCR | .ICRNL | .IXOFF);
+ default_tio_mode.c_oflag &= ~(.OPOST);
+ default_tio_mode.c_cflag &= ~(CSIZE | .PARENB);
+ default_tio_mode.c_lflag &= ~(.ECHOCTL |.ECHO | .ECHOE | .ECHOKE);
- blocking_tio_mode = default_tio_mode;
- blocking_tio_mode.c_iflag |= xx cast(Input_Modes)(.IXOFF | .ICRNL);
- blocking_tio_mode.c_lflag |= xx cast(Local_Modes)(.NOKERNINFO | .ECHO | .ECHOE | .ECHOKE);
-
- unblocking_tio_mode = default_tio_mode;
- iflags: Input_Modes = (.IGNBRK | .BRKINT | .PARMRK | .ISTRIP | .INLCR | .IGNCR | .ICRNL | .IXON);
- unblocking_tio_mode.c_iflag &= xx ~(iflags);
- lflags: Local_Modes = (.ECHO | .ECHONL | .ICANON | .IEXTEN);
- unblocking_tio_mode.c_lflag &= xx ~lflags;
+ human_tio_mode = default_tio_mode;
+ human_tio_mode.c_iflag |= (.IXOFF | .ICRNL);
+ human_tio_mode.c_lflag |= (.NOKERNINFO | .ECHO | .ECHOE | .ECHOKE);
tcsetattr(STDIN_FILENO, 0, *default_tio_mode);
}
OS_reset_terminal :: () {
- tcsetattr(STDIN_FILENO, 0, *initial_tio_mode); // return echo
+ tcsetattr(STDIN_FILENO, 0, *initial_tio_mode);
}
OS_get_terminal_size :: () -> rows: int, columns: int {
@@ -125,19 +190,16 @@ OS_get_terminal_size :: () -> rows: int, columns: int {
return rows, columns;
}
-// TODO Maybe we should use a NON-BLOCKING state by default... and only change to blocking when performing a HUMAN read...?
-
OS_set_input_mode :: (mode: Input_Mode) {
+ tio_mode: *Terminal_IO_Mode = ---;
if mode == {
case .HUMAN;
- tcsetattr(STDIN_FILENO, 0, *blocking_tio_mode);
- // TODO get_error_value_and_string :: () -> (error_code: OS_Error_Code, description: string)
- case .MACHINE;
- tcsetattr(STDIN_FILENO, 0, *unblocking_tio_mode);
- // TODO get_error_value_and_string :: () -> (error_code: OS_Error_Code, description: string)
+ tio_mode = *human_tio_mode;
case;
- // TODO ERROR
+ tio_mode = *default_tio_mode;
}
+ tcsetattr(STDIN_FILENO, 0, tio_mode);
+ // TODO get_error_value_and_string :: () -> (error_code: OS_Error_Code, description: string)
}
OS_read_input :: (buffer: *u8, bytes_to_read: s64) -> bytes_read: s64, error: bool = false, error_message: string = "" {