Cleaner terminal command code

This commit is contained in:
Emmanuel BENOîT 2022-10-30 09:58:00 +01:00
parent a4e6b8b4a0
commit ce4528b8fe

View file

@ -340,36 +340,66 @@ sub flush_term_and_read_pos($)
return $col, $line, @pending; return $col, $line, @pending;
} }
sub get_cursor_pos sub term_open
{ {
local $| = 1;
open(my $ttyIn, '<:bytes' , '/dev/tty'); open(my $ttyIn, '<:bytes' , '/dev/tty');
open(my $ttyOut, '>:bytes' , '/dev/tty'); open(my $ttyOut, '>:bytes' , '/dev/tty');
# Enable raw mode
my $term = POSIX::Termios->new; my $term = POSIX::Termios->new;
return [$ttyIn, $ttyOut, $term];
}
sub term_close
{
my ($ttyIn, $ttyOut, $term) = @{ $_[0] };
close $ttyOut;
close $ttyIn;
@{ $_[0] } = ();
}
sub term_set_raw
{
my ($ttyIn, $ttyOut, $term) = @{ $_[0] };
my $ttyInFd = fileno $ttyIn; my $ttyInFd = fileno $ttyIn;
$term->getattr($ttyInFd); $term->getattr($ttyInFd);
my $oTerm = $term ->getlflag; my $oTerm = $term->getlflag;
$term->setlflag($oTerm & ~( ECHO | ECHOK | ICANON )); $term->setlflag($oTerm & ~( ECHO | ECHOK | ICANON ));
$term->setcc(VTIME, 1); $term->setcc(VTIME, 1);
$term->setattr($ttyInFd, TCSANOW); $term->setattr($ttyInFd, TCSANOW);
return $oTerm
}
# Read position sub term_set_cooked
syswrite $ttyOut, "\033[6n", 4; {
my ($col, $line, @pending) = flush_term_and_read_pos $ttyIn; my ($ttyIn, $ttyOut, $term) = @{ $_[0] };
my $oTerm = $_[1];
# Restore input using TIOCSTI (0x5412)
foreach my $pByte (@pending) {
ioctl $ttyIn, 0x5412, $pByte;
}
# Enable cooked mode
$term->setlflag($oTerm); $term->setlflag($oTerm);
$term->setcc(VTIME, 0); $term->setcc(VTIME, 0);
$term->setattr($ttyInFd, TCSANOW); $term->setattr(fileno( $ttyIn ), TCSANOW);
}
close $ttyIn; # Fake input using TIOCSTI (0x5412)
close $ttyOut; sub term_feed
{
my ($ttyIn, $ttyOut, $term) = @{ $_[0] };
shift;
foreach my $pByte (@_) {
ioctl $term->[0], 0x5412, $pByte;
}
}
sub get_cursor_pos
{
local $| = 1;
my $term = term_open;
my $oTerm = term_set_raw($term);
# Read position then restore input
syswrite $term->[1], "\033[6n", 4;
my ($col, $line, @pending) = flush_term_and_read_pos $term->[0];
term_feed $term, @pending;
term_set_cooked($term, $oTerm);
term_close($term);
return $line, $col; return $line, $col;
} }