Term::ReadKey on Win? 5.005 vs 5.8.8?

D

Dr.Ruud

Ilya Zakharevich schreef:
Dr.Ruud:

On a "correctly set up" read() from "DOS console", pressing `Left'
should generate two characters, 0 and 75; likewise for other special
keys.

perl was run from a Win2000 CMD.EXE console. I am not aware of anything
special on this system.

Then I have no idea what it is you write about in the part quoted with
"> >>"... And the fault of PerlIO is not yet proven...

I am retrying the USE_GETC options ... yes, confirmed what was written
there. The source that I used:

#!/usr/bin/perl
use strict;
use warnings;

use constant # Unix # Win32 #
{ USE_CONIN => 0 # 0 # 1 #
, USE_GETC => 0 # - # - #
, SET_BINMODE => 0 # 0 # 1 #
, SET_READMODE => 4 # 5 # 4/5 #
};

use Term::ReadKey; # if defined SET_READMODE;

sub my_getc {
my $in = @_ ? shift : <STDIN>;
return getc $in if USE_GETC;
my $buf;
return -1 if read($in, $buf, 1) < 1;
return substr($buf, 0, 1);
}

my $fname = USE_CONIN ? 'CONIN$' : '-';

open my $con, "+< $fname" or die "Can't open '$fname': $!";

if (defined SET_READMODE) {
ReadMode SET_READMODE, $con;
}

if (SET_BINMODE) {
binmode $con or die "Can't binmode '$fname': $!";
}

while ( defined($_ = my_getc($con)) ) {
my $ord = ord;
print "Esc " if $ord == 27;
print "|$_| " if $ord >= 32;
print "<", $ord, ">\n";
last if $ord == 3;
}

if (defined SET_READMODE) {
ReadMode 0, $con;
}

close $con;
__END__

This produces a burst of three <13>s, once the third Enter is hit. So
the <13>s get delayed, but none gets eaten.
With USE_GETC set to 1, I need to hit Enter four times, after which a
burst of three <13>s is displayed. So one gets eaten.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
perl was run from a Win2000 CMD.EXE console. I am not aware of anything
special on this system.

"Special" is the OS+CRTL, how it treats reading from console.
Apprently, your OS+CRTL is not "smart" enough. Pity, this means that
Term::ReadLine::perl is not going to be useful on Win* soon...
This produces a burst of three <13>s, once the third Enter is hit. So
the <13>s get delayed, but none gets eaten.
With USE_GETC set to 1, I need to hit Enter four times, after which a
burst of three <13>s is displayed. So one gets eaten.

Aha, this is more clear now. So read() produces different results
than getc(); yet another sigh...

Thanks,
Ilya
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Dr.Ruud:

"Special" is the OS+CRTL, how it treats reading from console.

I meant special compared to other Win2000 + ActivePerl installations.
Maybe others with Win-XP/2k/NT/ME/9x can test the code in
and report if they do get 2 codes
when pressing `Left', etc.

Apprently, your OS+CRTL is not "smart" enough. Pity, this means that
Term::ReadLine::perl is not going to be useful on Win* soon...

Unless I provide you with a Win32::get(u)c? It is not hard for me to
make that, since most is already done by Win32::Console, and from
Term::ReadPassword::Win32 also much can be used.

Aha, this is more clear now. So read() produces different results
than getc(); yet another sigh...

Well, it could make looking for the problem inside getc() a little
easier.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
Unless I provide you with a Win32::get(u)c?

If it is in Term::ReadKey - maybe. [But probably not if it returns
unicode character for "LeftArrow" when one presses Left key. Pressing
Left should be reported "out of band". What if the user wants to
input a string which contains a LeftArrow character? Hmm, maybe this
may be handled with control-Q?]
Well, it could make looking for the problem inside getc() a little
easier.

Well, the principal problem is with read(). Fixing it may force the
getc() problem to disappear as well.

Yours,
Ilya
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Dr.Ruud:
Ilya:

Unless I provide you with a Win32::get(u)c?

If it is in Term::ReadKey - maybe. [But probably not if it returns
unicode character for "LeftArrow" when one presses Left key. Pressing
Left should be reported "out of band". What if the user wants to
input a string which contains a LeftArrow character? Hmm, maybe this
may be handled with control-Q?]

Out of band is OK.
Is the historical initial zero byte enough out of band?
Is returning a string longer than 1 character, OK for a new getc()?

Well, the principal problem is with read(). Fixing it may force the
getc() problem to disappear as well.

So that should be addressed first then. Could you more technically
describe how you see this "problem with read" now?
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
Out of band is OK.
Is the historical initial zero byte enough out of band?
Is returning a string longer than 1 character, OK for a new getc()?

Actually, this is a great idea (getc() returning more than 1 char to
indicate out-of-band data). Hmm, but maybe one should better decrease
the coolness of this, and return some object reference instead.

Thanks,
Ilya
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
So that should be addressed first then. Could you more technically
describe how you see this "problem with read" now?

Still hard to tell, your reports are now very complete, but not very
comprehensible. Is my understanding correct (Win*, 5.8.8,
'+< CONIN$', ReadMode(4)):

| no-binmode | binmode
--------------------------------------------------------------------------
getc | eats 1st \r, delays until the 4th \r | <--same
read(...,1) | delays until the 4th \r | no problem
--------------------------------------------------------------------------

?

Thanks,
Ilya
 
D

Dr.Ruud

Ilya Zakharevich schreef:
Dr.Ruud:
[attribution repaired] Ilya:
Well, the principal problem is with read(). Fixing it may force the
getc() problem to disappear as well.
So that should be addressed first then. Could you more technically
describe how you see this "problem with read" now?

Still hard to tell, your reports are now very complete, but not very
comprehensible. Is my understanding correct (Win*, 5.8.8,
'+< CONIN$', ReadMode(4)):

| no-binmode | binmode
------------+--------------------------------------+------------
getc | eats 1st \r, delays until the 4th \r | <--same
read(...,1) | delays until the 4th \r | no problem
------------+--------------------------------------+------------

See used source in sig.

getc + no-binmode: the first 3 \r's don't show, the 4th \r shows, but
there are still 2 (so 1 is lost) waiting to come out. These 2 come out
if you hit a different responding key then a \r key (meaning Ctrl-M and
Enter), after which the \r-behaviour is reset. Ctrl-J is dead, as are
Ctrl-Enter and function keys and curor keys. Ctrl-@ returns 0, Ctrl-^
30, Ctrl-[ 27, etc.

read + no-binmode: almost the same as getc + no-binmode, but the 3rd \r
is returned, and not a single \r is lost. Again, the 2 delayed ones
don't come out until you hit a non-dead, non-\r key, after which the
\r-behaviour is reset again.

getc + binmode: all "normal" keys (alphanumeric, punctuation,
ctrl-combinations) return immediately their value. Still dead are:
Ctrl-J, Ctrl-Enter, function and cursor keys.

read + binmode: the same as getc + binmode.

So this time, with the same source, I don't see the \r-bursts anymore
when only using the \r-key. Two \r's are delayed until a non-\r key is
pressed. I have no good explanation for this changed behaviour. (I have
been playing with ioctl-settings before, so maybe the console was in a
different ioctl-mode then.)

--
Affijn, Ruud

"Gewoon is een tijger."

#!/usr/bin/perl
use strict;
use warnings;

use constant # Unix # Win32 #
{ USE_CONIN => 1 # 0 # 1 #
, USE_GETC => 0 # - # - #
, SET_BINMODE => 0 # 0 # 1 #
, SET_READMODE => 4 # 5 # 4/5 #
};

use Term::ReadKey; # if defined SET_READMODE;

sub my_getc {
my $in = @_ ? shift : <STDIN>;
return getc $in if USE_GETC;
my $buf;
return -1 if read($in, $buf, 1) < 1;
return substr($buf, 0, 1);
}

my $fname = USE_CONIN ? 'CONIN$' : '-';

open my $con, "+< $fname" or die "Can't open '$fname': $!";

if (defined SET_READMODE) {
ReadMode SET_READMODE, $con;
}

if (SET_BINMODE) {
binmode $con or die "Can't binmode '$fname': $!";
}

while ( defined($_ = my_getc($con)) ) {
my $ord = ord;
print "Esc " if $ord == 27;
print "|$_| " if $ord >= 32;
print "<", $ord, ">\n";
last if $ord == 3;
}

if (defined SET_READMODE) {
ReadMode 0, $con;
}

close $con;
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud

| no-binmode | binmode
------------+--------------------------------------+---------------------
getc | eats 1st \r, delays until the 4th \r or non-\r | no problem
read(...,1) | delays until the 3th \r or non-\r | no problem
------------+--------------------------------------+---------------------

I hope it is a correct summary...

.....
read + binmode: the same as getc + binmode.

Thanks, this is all complete and clear.
So this time, with the same source, I don't see the \r-bursts anymore
when only using the \r-key.

Now it is all back to the beginning. I do not have a slightest idea
WHAT you compare with WHAT here, and it annulates all the good stuff
you wrote before...
Two \r's are delayed until a non-\r key is
pressed. I have no good explanation for this changed behaviour. (I have
been playing with ioctl-settings before, so maybe the console was in a
different ioctl-mode then.)

Should I understand it as the behaviour described before is happening
in a freshly-created console, and doing some stty.exe calls may
slightly improve the action?

[I saw reports that calling stty.exe changes the console behaviour,
even though stty.exe is CygWin, and the calling application is not.]

Thanks,
Ilya
 
D

Dr.Ruud

Ilya Zakharevich schreef:
| no-binmode | binmode
------------+------------------------------------------------+-------- ---
getc | eats 1st-\r, delays until the 4th-\r or non-\r | no problem
read(...,1) | delays until the 3rd-\r or non-\r | no problem


I did "s/(\d(?:rd|st|th)) /$1-/" to emphasize that "non-\r" must be read
as "1st-non-\r".

I am not sure that it eats the 1st-\r; it eats one \r, but maybe not
exactly the 1st.

The summary is probably not OK with my last test, because the \r that
ends the delaying phase, does not dig up the two delayed \r's, while a
non-\r (at any moment) does.

| no-binmode | binmode
------------+-------------------------------------+---------
getc | eats \r, delays 2 \r's until non-\r | \r's OK
read(...,1) | delays 2 \r's until non-\r | \r's OK
------------+-------------------------------------+---------

Thanks, this is all complete and clear.


Now it is all back to the beginning. I do not have a slightest idea
WHAT you compare with WHAT here, and it annulates all the good stuff
you wrote before...

"when only using the \r-key".
So the bursts didn't occur (in the latest test) when only using an
\r-key, and the two "delayed \r's" remained delayed until a non-\r-key
was hit.

I also reluctantly tried whether "$|=1" would make any difference, but
it didn't.

Should I understand it as the behaviour described before is happening
in a freshly-created console, and doing some stty.exe calls may
slightly improve the action?

I was just gessing (there), because I haven't found a way to get the
"\r-bursts with hitting just a \r-key", as it did before. With "burst" I
mean that the two delayed \r's are returned before the last hit key is
returned, so a happening of three quick getc-returns in a row.

[I saw reports that calling stty.exe changes the console behaviour,
even though stty.exe is CygWin, and the calling application is not.]

There is often a Cygwin ssh console window active as well, and that also
starts via cmd.exe (as the avast virusscanner nicely reports), so maybe
there is interference there. I'll try more tests with a fresh system.

That Cygwin has a "perl, v5.8.7 built for cygwin-thread-multi-64int"
that I didn't yet use for testing.
Heheh, great, I started "joe" in there to edit a Perl-source, and it
color codes the Perl syntax. I tried "pico -w", but this Cygwin doesn't
have many editors installed, and I have worked a lot (many years ago)
with Wordstar so those keys are still in my muscle's memory.

Is there a POSIX::termios for Win32?
 
A

Adam Kennedy

Dr.Ruud said:
Ilya Zakharevich schreef:

perl was run from a Win2000 CMD.EXE console. I am not aware of anything
special on this system.



I am retrying the USE_GETC options ... yes, confirmed what was written
there. The source that I used:

#!/usr/bin/perl
use strict;
use warnings;

use constant # Unix # Win32 #
{ USE_CONIN => 0 # 0 # 1 #
, USE_GETC => 0 # - # - #
, SET_BINMODE => 0 # 0 # 1 #
, SET_READMODE => 4 # 5 # 4/5 #
};

use Term::ReadKey; # if defined SET_READMODE;

sub my_getc {
my $in = @_ ? shift : <STDIN>;
return getc $in if USE_GETC;
my $buf;
return -1 if read($in, $buf, 1) < 1;
return substr($buf, 0, 1);
}

my $fname = USE_CONIN ? 'CONIN$' : '-';

open my $con, "+< $fname" or die "Can't open '$fname': $!";

if (defined SET_READMODE) {
ReadMode SET_READMODE, $con;
}

if (SET_BINMODE) {
binmode $con or die "Can't binmode '$fname': $!";
}

while ( defined($_ = my_getc($con)) ) {
my $ord = ord;
print "Esc " if $ord == 27;
print "|$_| " if $ord >= 32;
print "<", $ord, ">\n";
last if $ord == 3;
}

if (defined SET_READMODE) {
ReadMode 0, $con;
}

close $con;
__END__

This produces a burst of three <13>s, once the third Enter is hit. So
the <13>s get delayed, but none gets eaten.
With USE_GETC set to 1, I need to hit Enter four times, after which a
burst of three <13>s is displayed. So one gets eaten.

To add more data points to this, I can report the following on Win2K
Vanilla Perl 5.8.8.

Lines (in round braces) represent my actions, other lines are as
printed, all occur in the order listed.

C:\Documents and Settings\adam\My Documents>perl terminal.pl
(press 'b' key)
|b| <98>
(press 'enter' key)
(press 'c' key)
<13>
|c| <99>
(press 'enter' key)
(press 'enter' key)
(press 'd' key)
<13>
<13>
|d| <100>
(press 'enter key')
(press 'enter key')
(press 'enter key')
<13>
(press 'e' key)
<13>
<13>
|e| <101>
(ctrl-c to quit)
<3>

Adam K
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Dr.Ruud
Unless I provide you with a Win32::get(u)c? It is not hard for me to
make that, since most is already done by Win32::Console, and from
Term::ReadPassword::Win32 also much can be used.

Actually, a better (?) solution may be to store the `record' in TRK's
Win32PeekChar() in a static variable, and make the API to query
modifiers and keysymbol of a key (as in "NumLock-Alt-Shift-Gray-/").
This way the reader can detect a read of "\0", and query the actual
key via the new API. Maybe even mouse events can be made detectable
this way...

Yours,
Ilya
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top