Which OS are you using? Behavior of the Term varies even in Win32 cmd vs command.com. (added this).. and make sure you are setting binmode... something like so:
ReadMode 3; # stty mode
binmode STDIN, ":raw";
while($key = ReadKey()){
print ord $key;
}
before you grab a key or you will get funky stuff :) | [reply] [d/l] |
Mostly linux, but it should be portable -- but shouldn't ReadKey do OS dependent stuff for me ?
--
Jaap Karssenberg || Pardus (Larus)? <pardus@cpan.org>
>>>> Zoidberg: So many memories, so many strange fluids gushing out of patients' bodies.... <<<<
| [reply] |
It's not really OS dependant, actually. It depends on the terminal / terminal emulator you're using. Term::ReadKey is more low-level, and assumes you will figure out what terminal-type the user has and interpret accordingly.
Perhaps you should look at the source of Term::Readline::Perl to see how it handles multi-char escape sequences, as it uses a similar system as you, with the hashes and all.
bbfu
Black flowers blossum
Fearless on my breath
| [reply] |
Do you get the whole string of the pressed key at once, like: \e\UP_ARROW_CODE? If so, you can trim the \e code and put the rest in the hash. If you get a single \e - this is your escape key, you can put it in the hash too. Can't you solve your problem with regexps? | [reply] [d/l] |
No I get the escape sequence as single chars, one by one.
Once I've decided it is an escape sequence I read in the complete sequence (once again using time-outs) and look up this string in a hash.
But the problem are the time-outs, the time-outs are unrelyable and I would like to get rid of them.
--
Jaap Karssenberg || Pardus (Larus)? <pardus@cpan.org>
>>>> Zoidberg: So many memories, so many strange fluids gushing out of patients' bodies.... <<<<
| [reply] |
Use timeout to distinguish \e from Arrow, but use firm values after that. E.g. if Arrows are 3 chars long, read 1 char, if \e
use action for \e which is read 1 char with timeout (timeout means real action for \e), if ok (and starts Arrowsequence) read last char without timeout. | [reply] |
At least under unix (I wont even try to assume win32's behaviour), all keyboard control keys, such as cursor arrows, function keys, home/insert/del and friends, follow the escape code immediately with a '[' when dumped into the keyboard input buffer. So it would be reasonably safe to have your code immediately assume that escape was pressed by itself if the following character was NOT '['. The key sequence 'ESC','[' is highly unlikely to be used for anything other than the function/control keys.
So, if the escape character WAS followed by '[', you can immediately jump to a keyboard control key parser, which 'listens' for a variable length sequence depending on the characters that follow.
On a linux console, F1 through F5 are represented by '\e[[A' through '\e[[E'. F6 through F12 return '\e[[17~' through '\e[[24~', cursor keys return '\e[A' through '\e[D', and the INS/DEL/PG/etc matrix returns '\e[1~' through '\e[6~', respectively. So there are some easy-to-recognize patterns to look for.
As someone else might have stated, the character sequences you get when someone hits a function or cursor control key are completely dependent on the OS that the keyboard is attached to. Luckily, most OSs adhere to the lowest common denominator of vt100 and/or ansi terminal emulation when passing data to the running program.
The "raw" data coming from the keyboard are called scancodes, and they're usually exactly one byte in length, and have more correlation to the position of the key on the keyboard membrane matrix than what's on the keycap. Luckily, that's pretty standardized as well, but you wouldn't need to worry about the scancodes at all in your case.
| [reply] |