aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TUI/module.jai4
-rw-r--r--TUI/unix.jai13
-rw-r--r--TUI/windows.jai46
3 files changed, 38 insertions, 25 deletions
diff --git a/TUI/module.jai b/TUI/module.jai
index 73f9260..df88f0c 100644
--- a/TUI/module.jai
+++ b/TUI/module.jai
@@ -418,6 +418,8 @@ input_buffer : [8] u8; // TODO FIXME Input buffer is too small!!!
input_string : string;
input_override : Key;
+was_resized : bool;
+
#run {
// TODO FIXME DEBUG HACK or maybe... let it be?!
// Some tests.
@@ -628,7 +630,7 @@ user_line_input :: (count_limit: int, is_visible: bool = true) -> string, Key {
}
case;
- if is_escape_code(key) continue; - TODO NOT WORKING FIX THIS
+ if is_escape_code(key) continue; // TODO NOT WORKING FIX THIS
key_str := to_string(key);
str.data[idx] = key_str.data[0];
idx += 1;
diff --git a/TUI/unix.jai b/TUI/unix.jai
index a35c2dc..dd53921 100644
--- a/TUI/unix.jai
+++ b/TUI/unix.jai
@@ -1,8 +1,8 @@
#scope_file
#import "Atomics";
-#import "POSIX";
#import "System";
+#import "POSIX";
// Required to do unlocking input.
libc :: #system_library "libc";
@@ -204,7 +204,6 @@
////////////////////////////////////////////////////////////////////////////////
// Resize detection
-was_resized : bool;
resize_handler :: (signal_code : s32) #c_call {
new_context : Context;
@@ -232,11 +231,6 @@ restore_resize_handler :: () {
#scope_export
-OS_flush_input :: inline () {
- TCIFLUSH :: 0; // TODO Is this always zero in all systems?
- tcflush(STDIN_FILENO, TCIFLUSH);
-}
-
OS_prepare_terminal :: () {
tcgetattr(STDIN_FILENO, *initial_tio_mode); // TODO Log error using `log()` from jai/modules/Basic/Print.jai ?
raw_tio_mode = initial_tio_mode;
@@ -258,6 +252,11 @@ OS_reset_terminal :: () {
tcsetattr(STDIN_FILENO, 0, *initial_tio_mode); // TODO Log on error.
}
+OS_flush_input :: inline () {
+ TCIFLUSH :: 0; // TODO Is this always zero in all systems?
+ tcflush(STDIN_FILENO, TCIFLUSH);
+}
+
OS_read_input :: (buffer: *u8, bytes_to_read: s64) -> bytes_read: s64, error: bool = false, error_message: string = "" {
bytes_read := read(STDIN_FILENO, buffer, xx bytes_to_read);
if bytes_read < 0 {
diff --git a/TUI/windows.jai b/TUI/windows.jai
index 68c2a1d..ed8c996 100644
--- a/TUI/windows.jai
+++ b/TUI/windows.jai
@@ -1,7 +1,8 @@
#scope_file
-#import "Windows";
+#import "Atomics";
#import "System";
+#import "Windows";
// https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
// https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#designate-character-set
@@ -100,7 +101,7 @@ OS_prepare_terminal :: () {
// stdin
- stdin = GetStdHandle(STD_INPUT_HANDLE );
+ stdin = GetStdHandle(STD_INPUT_HANDLE);
if stdin == INVALID_HANDLE_VALUE {
print("Invalid input handler.", to_standard_error = true);
return;
@@ -147,6 +148,15 @@ OS_reset_terminal :: () {
}
}
+OS_flush_input :: inline () {
+ // TODO - https://learn.microsoft.com/en-us/windows/console/flushconsoleinputbuffer
+ // BOOL WINAPI FlushConsoleInputBuffer(_In_ HANDLE hConsoleInput);
+ /* NOTE
+ This API is not recommended and does not have a virtual terminal equivalent.
+ Attempting to empty the input queue all at once can destroy state in the queue in an unexpected manner.
+ */
+}
+
OS_get_terminal_size :: () -> rows: int, columns: int {
ScreenBufferInfo: CONSOLE_SCREEN_BUFFER_INFO;
@@ -157,21 +167,6 @@ 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) {
- if mode == {
- case .HUMAN;
- assert(SetConsoleMode(stdin, xx blocking_stdin_mode), "Failed to set input mode to blocking mode.");
- // TODO get_error_value_and_string :: () -> (error_code: OS_Error_Code, description: string)
- case .MACHINE;
- assert(SetConsoleMode(stdin, xx unblocking_stdin_mode), "Failed to set input mode to unblocking mode.");
- // TODO get_error_value_and_string :: () -> (error_code: OS_Error_Code, description: string)
- case;
- // TODO ERROR
- }
-}
-
OS_read_input :: (buffer: *u8, bytes_to_read: s64) -> bytes_read: s64, error: bool = false, error_message: string = "" {
assert(bytes_to_read <= 0x7fff_ffff, "The Windows API only allows to read up to s32 bytes from the standard input.");
bytes_read: s32;
@@ -182,3 +177,20 @@ OS_read_input :: (buffer: *u8, bytes_to_read: s64) -> bytes_read: s64, error: bo
}
return bytes_read;
}
+
+OS_wait_for_input :: (timeout_milliseconds: s32) -> is_input_available: bool {
+ /* TODO
+ Try to implement using:
+ https://learn.microsoft.com/en-us/windows/console/reading-input-buffer-events
+ https://learn.microsoft.com/en-us/windows/console/readconsoleinput
+ */
+ fds := pollfd.[ .{ fd = STDIN_FILENO, events = POLLIN, revents = 0 } ];
+ nfds := fds.count;
+ poll_return := poll(fds.data, xx nfds, xx timeout_milliseconds); // TODO Wait for input using poll syscall. This breaks and throws '-1 | 4 | Interrupted system call' when we resize the window while polling.
+ error_code, error_message := get_error_value_and_string(); // FIXME Not used.
+ return ifx poll_return > 0 then true else false;
+}
+
+OS_was_terminal_resized :: () -> bool {
+ return atomic_swap(*was_resized, false); // TODO If the windows implementation is similar, we may push this into the main module file.
+}