1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

termios: new termios module (#17792)

* termio: new termio module

move the tcgetattr and tcsetattr functions in a new termio module.
The code needed refactoring as different OS have different fields
size, position and number for the C.termios structure, which
could not be correctly expressed consitently otherwise.

It has the positive side effect to reduce the number of unsafe calls.
New testing code was also added for the readline module as it is
relying of the feature.

* apply 2023 copyright to the new files too
This commit is contained in:
Thomas Mangin
2023-03-30 06:58:52 +01:00
committed by GitHub
parent 0826102e0a
commit 580d9cedc7
25 changed files with 921 additions and 723 deletions

View File

@@ -1,10 +0,0 @@
module ui
pub struct C.termios {
mut:
c_iflag int
c_oflag int
c_cflag int
c_lflag int
c_cc [20]u8
}

View File

@@ -1,11 +0,0 @@
module ui
pub struct C.termios {
mut:
c_iflag int
c_oflag int
c_cflag int
c_lflag int
// c_line byte
c_cc [10]int
}

View File

@@ -5,9 +5,8 @@ module ui
import os
import time
import term.termios
#include <termios.h>
#include <sys/ioctl.h>
#include <signal.h>
pub struct C.winsize {
@@ -15,25 +14,19 @@ pub struct C.winsize {
ws_col u16
}
fn C.tcgetattr(fd int, termios_p &C.termios) int
fn C.tcsetattr(fd int, optional_actions int, const_termios_p &C.termios) int
fn C.ioctl(fd int, request u64, arg voidptr) int
const termios_at_startup = get_termios()
[inline]
fn get_termios() C.termios {
mut t := C.termios{}
C.tcgetattr(C.STDIN_FILENO, &t)
fn get_termios() termios.Termios {
mut t := termios.Termios{}
termios.tcgetattr(C.STDIN_FILENO, mut t)
return t
}
[inline]
fn get_terminal_size() (u16, u16) {
winsz := C.winsize{}
C.ioctl(0, C.TIOCGWINSZ, &winsz)
termios.ioctl(0, termios.flag(C.TIOCGWINSZ), voidptr(&winsz))
return winsz.ws_row, winsz.ws_col
}
@@ -60,16 +53,16 @@ fn (mut ctx Context) termios_setup() ! {
return error('not running under a TTY')
}
mut termios := get_termios()
mut tios := get_termios()
if ctx.cfg.capture_events {
// Set raw input mode by unsetting ICANON and ECHO,
// as well as disable e.g. ctrl+c and ctrl.z
termios.c_iflag &= ~(C.IGNBRK | C.BRKINT | C.PARMRK | C.IXON)
termios.c_lflag &= ~(C.ICANON | C.ISIG | C.ECHO | C.IEXTEN | C.TOSTOP)
tios.c_iflag &= termios.invert(C.IGNBRK | C.BRKINT | C.PARMRK | C.IXON)
tios.c_lflag &= termios.invert(C.ICANON | C.ISIG | C.ECHO | C.IEXTEN | C.TOSTOP)
} else {
// Set raw input mode by unsetting ICANON and ECHO
termios.c_lflag &= ~(C.ICANON | C.ECHO)
tios.c_lflag &= termios.invert(C.ICANON | C.ECHO)
}
if ctx.cfg.hide_cursor {
@@ -85,9 +78,9 @@ fn (mut ctx Context) termios_setup() ! {
if !ctx.cfg.skip_init_checks {
// prevent blocking during the feature detections, but allow enough time for the terminal
// to send back the relevant input data
termios.c_cc[C.VTIME] = 1
termios.c_cc[C.VMIN] = 0
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios)
tios.c_cc[C.VTIME] = 1
tios.c_cc[C.VMIN] = 0
termios.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, mut tios)
// feature-test the SU spec
sx, sy := get_cursor_position()
print('${bsu}${esu}')
@@ -105,9 +98,9 @@ fn (mut ctx Context) termios_setup() ! {
ctx.enable_rgb = supports_truecolor()
}
// Prevent stdin from blocking by making its read time 0
termios.c_cc[C.VTIME] = 0
termios.c_cc[C.VMIN] = 0
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &termios)
tios.c_cc[C.VTIME] = 0
tios.c_cc[C.VMIN] = 0
termios.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, mut tios)
// enable mouse input
print('\x1b[?1003h\x1b[?1006h')
flush_stdout()
@@ -205,7 +198,8 @@ fn supports_truecolor() bool {
fn termios_reset() {
// C.TCSANOW ??
C.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, &ui.termios_at_startup)
mut startup := ui.termios_at_startup
termios.tcsetattr(C.STDIN_FILENO, C.TCSAFLUSH, mut startup)
print('\x1b[?1003l\x1b[?1006l\x1b[?25h')
flush_stdout()
c := ctx_ptr