367 lines
7.5 KiB
Perl
367 lines
7.5 KiB
Perl
#!/usr/bin/perl -w
|
|
|
|
#use strict vars;
|
|
|
|
#use Term::ReadKey qw( ReadMode ReadKey );
|
|
#my $x;
|
|
#ReadMode 3;
|
|
#print "Read 1\n";
|
|
#$x = ReadKey(0);
|
|
#print "X=$x\n";
|
|
#print "Read 2\n";
|
|
#$x = ReadKey(0);
|
|
#print "X=$x\n";
|
|
#ReadMode 0;
|
|
#__END__;
|
|
|
|
my $interactive = ( @ARGV && $ARGV[0] =~ /interactive/ );
|
|
|
|
BEGIN { print "1..8\n"; }
|
|
END { print "not ok 1\n" unless $loaded }
|
|
use Term::ReadKey;
|
|
|
|
$loaded = 1;
|
|
print "ok 1\n";
|
|
|
|
use Fcntl;
|
|
|
|
if ( not exists $ENV{COLUMNS} )
|
|
{
|
|
$ENV{COLUMNS} = 80;
|
|
$ENV{LINES} = 24;
|
|
}
|
|
|
|
if ( $^O =~ /Win32/i )
|
|
{
|
|
sysopen( IN, 'CONIN$', O_RDWR ) or die "Unable to open console input:$!";
|
|
sysopen( OUT, 'CONOUT$', O_RDWR ) or die "Unable to open console output:$!";
|
|
}
|
|
else
|
|
{
|
|
|
|
if ( open( IN, "</dev/tty" ) )
|
|
{
|
|
*OUT = *IN;
|
|
die "Foo" unless -t OUT;
|
|
}
|
|
else
|
|
{
|
|
|
|
# Okay we are going to cheat a skip
|
|
foreach my $skip ( 2 .. 8 )
|
|
{
|
|
print "ok $skip # skip /dev/tty is absent\n";
|
|
}
|
|
exit;
|
|
}
|
|
}
|
|
|
|
*IN = *IN; # Make single-use warning go away
|
|
$| = 1;
|
|
|
|
my $size1 = join( ",", GetTerminalSize( \IN ) );
|
|
my $size2 = join( ",", GetTerminalSize("IN") );
|
|
my $size3 = join( ",", GetTerminalSize(*IN) );
|
|
my $size4 = join( ",", GetTerminalSize( \*IN ) );
|
|
|
|
if ( ( $size1 eq $size2 ) && ( $size2 eq $size3 ) && ( $size3 eq $size4 ) )
|
|
{
|
|
print "ok 2\n";
|
|
}
|
|
else
|
|
{
|
|
print "not ok 2\n";
|
|
}
|
|
|
|
sub makenicelist
|
|
{
|
|
my (@list) = @_;
|
|
my ( $i, $result );
|
|
$result = "";
|
|
for ( $i = 0 ; $i < @list ; $i++ )
|
|
{
|
|
$result .= ", " if $i > 0;
|
|
$result .= "and " if $i == @list - 1 and @list > 1;
|
|
$result .= $list[$i];
|
|
}
|
|
$result;
|
|
}
|
|
|
|
sub makenice
|
|
{
|
|
my ($char) = $_[0];
|
|
if ( ord($char) < 32 ) { $char = "^" . pack( "c", ord($char) + 64 ) }
|
|
elsif ( ord($char) > 126 ) { $char = ord($char) }
|
|
$char;
|
|
}
|
|
|
|
sub makeunnice
|
|
{
|
|
my ($char) = $_[0];
|
|
$char =~ s/^\^(.)$/pack("c",ord($1)-64)/eg;
|
|
$char =~ s/(\d{1,3})/pack("c",$1+0)/eg;
|
|
$char;
|
|
}
|
|
|
|
my $response;
|
|
|
|
eval {
|
|
|
|
if ( &Term::ReadKey::termoptions() == 1 )
|
|
{
|
|
$response =
|
|
"Term::ReadKey is using TERMIOS, as opposed to TERMIO or SGTTY.\n";
|
|
}
|
|
elsif ( &Term::ReadKey::termoptions() == 2 )
|
|
{
|
|
$response =
|
|
"Term::ReadKey is using TERMIO, as opposed to TERMIOS or SGTTY.\n";
|
|
}
|
|
elsif ( &Term::ReadKey::termoptions() == 3 )
|
|
{
|
|
$response =
|
|
"Term::ReadKey is using SGTTY, as opposed to TERMIOS or TERMIO.\n";
|
|
}
|
|
elsif ( &Term::ReadKey::termoptions() == 4 )
|
|
{
|
|
$response =
|
|
"Term::ReadKey is trying to make do with stty; facilites may be limited.\n";
|
|
}
|
|
elsif ( &Term::ReadKey::termoptions() == 5 )
|
|
{
|
|
$response = "Term::ReadKey is using Win32 functions.\n";
|
|
}
|
|
else
|
|
{
|
|
$response =
|
|
"Term::ReadKey could not find any way to manipulate the terminal.\n";
|
|
}
|
|
|
|
print "ok 3\n";
|
|
};
|
|
|
|
print "not ok 3\n" if $@;
|
|
|
|
print $response if $interactive;
|
|
|
|
eval {
|
|
push( @modes, "O_NODELAY" ) if &Term::ReadKey::blockoptions() & 1;
|
|
push( @modes, "poll()" ) if &Term::ReadKey::blockoptions() & 2;
|
|
push( @modes, "select()" ) if &Term::ReadKey::blockoptions() & 4;
|
|
push( @modes, "Win32" ) if &Term::ReadKey::blockoptions() & 8;
|
|
|
|
print "ok 4\n";
|
|
};
|
|
|
|
print "not ok 4\n" if $@;
|
|
|
|
if ($interactive)
|
|
{
|
|
if ( &Term::ReadKey::blockoptions() == 0 )
|
|
{
|
|
print "No methods found to implement non-blocking reads.\n";
|
|
print
|
|
" (If your computer supports poll(), you might like to read through ReadKey.xs)\n";
|
|
}
|
|
else
|
|
{
|
|
print "Non-blocking reads possible via ", makenicelist(@modes), ".\n";
|
|
print $modes[0] . " will be used. " if @modes > 0;
|
|
print $modes[1] . " will be used for timed reads."
|
|
if @modes > 1
|
|
and $modes[0] eq "O_NODELAY";
|
|
print "\n";
|
|
}
|
|
}
|
|
|
|
eval {
|
|
@size = GetTerminalSize(OUT);
|
|
print "ok 5\n";
|
|
};
|
|
|
|
print "not ok 5\n" if $@;
|
|
|
|
if ($interactive)
|
|
{
|
|
if ( !@size )
|
|
{
|
|
print
|
|
"GetTerminalSize was incapable of finding the size of your terminal.";
|
|
}
|
|
else
|
|
{
|
|
print "Using GetTerminalSize, it appears that your terminal is\n";
|
|
print "$size[0] characters wide by $size[1] high.\n\n";
|
|
}
|
|
|
|
}
|
|
|
|
eval {
|
|
@speeds = GetSpeed();
|
|
print "ok 6\n";
|
|
};
|
|
|
|
print "not ok 6\n" if $@;
|
|
|
|
if ($interactive)
|
|
{
|
|
if (@speeds)
|
|
{
|
|
print "Apparently, you are connected at ", join( "/", @speeds ),
|
|
" baud.\n";
|
|
}
|
|
else
|
|
{
|
|
print "GetSpeed couldn't tell your connection baud rate.\n\n";
|
|
}
|
|
print "\n";
|
|
}
|
|
|
|
eval {
|
|
%chars = GetControlChars(IN);
|
|
print "ok 7\n";
|
|
};
|
|
|
|
print "not ok 7\n" if $@;
|
|
|
|
%origchars = %chars;
|
|
|
|
if ($interactive)
|
|
{
|
|
for $c ( keys %chars ) { $chars{$c} = makenice( $chars{$c} ) }
|
|
|
|
print "Control chars = (",
|
|
join( ', ', map( "$_ => $chars{$_}", keys %chars ) ), ")\n";
|
|
}
|
|
|
|
eval {
|
|
SetControlChars( %origchars, IN );
|
|
print "ok 8\n";
|
|
};
|
|
|
|
print "not ok 8\n" if $@;
|
|
|
|
#SetControlChars("FOOFOO"=>"Q");
|
|
#SetControlChars("INTERRUPT"=>"\x5");
|
|
|
|
END { ReadMode 0, IN; } # Just if something goes weird
|
|
|
|
exit(0) unless $interactive;
|
|
|
|
print "\nAnd now for the interactive tests.\n";
|
|
|
|
print
|
|
"\nThis is ReadMode 1. It's guarranteed to give you cooked input. All the\n";
|
|
print "signals and editing characters may be used as usual.\n";
|
|
|
|
ReadMode 1, IN;
|
|
|
|
print "\nYou may enter some text here: ";
|
|
|
|
$t = ReadLine 0, IN;
|
|
|
|
chop $t;
|
|
|
|
print "\nYou entered `$t'.\n";
|
|
|
|
ReadMode 2, IN;
|
|
|
|
print
|
|
"\nThis is ReadMode 2. It's just like #1, but echo is turned off. Great\n";
|
|
print "for passwords.\n";
|
|
|
|
print "\nYou may enter some invisible text here: ";
|
|
|
|
$t = ReadLine 0, IN;
|
|
|
|
chop $t;
|
|
|
|
print "\nYou entered `$t'.\n";
|
|
|
|
ReadMode 3, IN;
|
|
|
|
print
|
|
"\nI won't demonstrate ReadMode 3 here. It's your standard cbreak mode,\n";
|
|
print
|
|
"with editing characters disabled, single character at a time input, but\n";
|
|
print "with the control characters still enabled.\n";
|
|
|
|
print "\n";
|
|
|
|
print
|
|
"I'm now putting the terminal into ReadMode 4 and using non-blocking reads.\n";
|
|
print
|
|
"All signals should be disabled, including xon-xoff. You should only be\n";
|
|
print "able to exit this loop via 'q'.\n";
|
|
|
|
ReadMode 4, IN;
|
|
$k = "";
|
|
|
|
#$in = *STDIN;
|
|
$in = \*IN; # or *IN or "IN"
|
|
while ( $k ne "q" )
|
|
{
|
|
print "Press a key, or \"q\" to stop: ";
|
|
$count = 0;
|
|
|
|
#print "IN = $in\n";
|
|
$count++ while !defined( $k = ReadKey( -1, $in ) );
|
|
|
|
#print "IN2 = $in\n";
|
|
print "\nYou pressed `", makenice($k),
|
|
"' after the loop rolled over $count times\n";
|
|
}
|
|
ReadMode 0, IN;
|
|
|
|
print "\nHere is a similar loop which times out after two seconds:\n";
|
|
|
|
ReadMode 4, IN;
|
|
$k = "";
|
|
|
|
#$in = *STDIN;
|
|
$in = \*IN; # or *IN or "IN"
|
|
while ( $k ne "q" )
|
|
{
|
|
print "Press a key, or \"q\" to stop: ";
|
|
$count = 0;
|
|
|
|
#print "IN = $in\n";
|
|
print "Timeout! " while !defined( $k = ReadKey( 2, $in ) );
|
|
|
|
#print "IN2 = $in\n";
|
|
print "\nYou pressed `", makenice($k), "'\n";
|
|
}
|
|
|
|
print
|
|
"\nLastly, ReadMode 5, which also affects output (except under Win32).\n\n";
|
|
|
|
ReadMode 5, IN;
|
|
|
|
print
|
|
"This should be a diagonal line (except under Win32): *\n*\n*\n\*\n*\n*\r\n\r\n";
|
|
print "And this should be a moving spot:\r\n\r\n";
|
|
|
|
$width = ( GetTerminalSize(OUT) )[0];
|
|
$width /= 2;
|
|
$width--;
|
|
if ( $width < 10 ) { $width = 10; }
|
|
|
|
for ( $i = 0 ; $i < 20 ; $i += .15 )
|
|
{
|
|
print "\r";
|
|
print( " " x ( ( cos($i) + 1 ) * $width ) );
|
|
print "*";
|
|
select( undef, undef, undef, 0.01 );
|
|
print "\r";
|
|
print( " " x ( ( cos($i) + 1 ) * $width ) );
|
|
print " ";
|
|
}
|
|
print "\r ";
|
|
|
|
print "\n\r\n";
|
|
|
|
ReadMode 0, IN;
|
|
|
|
print "That's all, folks!\n";
|
|
|