news.utdallas.edu!convex!convex!cs.utexas.edu!qt.cs.utexas.edu!yale.edu!yale!gumby!destroyer!cs.ubc.ca!uw-beaver!fluke!dbc Wed Mar 3 13:09:26 CST 1993
Article: 1330 of comp.lang.perl
Xref: feenix.metronet.com comp.lang.perl:1330
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!convex!convex!cs.utexas.edu!qt.cs.utexas.edu!yale.edu!yale!gumby!destroyer!cs.ubc.ca!uw-beaver!fluke!dbc
From:
[email protected] (Dan Carson)
#Subject: Re: Testing input character if arrow or function key etc (DOS).
Message-ID: <
[email protected]>
Organization: John Fluke Mfg. Co., Inc., Everett, WA
References: <
[email protected]>
Date: Tue, 2 Mar 1993 17:16:37 GMT
Lines: 90
In article <
[email protected]>
[email protected] (Chaim Manaster) writes:
>The question is in two parts:
>1) How do you get a single character returned from the keyboard
>without requiring a carriage return after the keypress? I have been
>directed to the perl FAQ, unfortunately, it is totaly moot on
>how to do this for MSDOS systems. I have tried simply using
>$key = getc; or $key = <STDIN>; which required a carriage return
>and didn't quite work as expected.
>
>2) Once you have the keypress stored in $key, how do you test
>to see if it was either an arrow key, HOME, END, PGUP, PGDN, a
>function key (F1-F12) or some other non-printable key?
>i.e. $key == ???????
>
>Please be DOS specific as this is system dependent.
>
>I have tried something like:
>$key = <STDIN>;
>print oct($key);
>
>to see if that would give me a clue as to what value these keys
>returned to no avail. (I tried with chop($key) as well).
>
>Thank you very much for the help.
>
>Henry Manaster
>
>--
>***************************************************************************
> Henry Manaster * EMail:
[email protected]
> Brooklyn, NY *
> *
> Disclaimer: The above is not necessarily MY opinion nor that
> of anyone else :-) ????!
>****************************************************************************
>
This should be added to the FAQ, I've answered this question in this group
several times.
Question 1: To put the PC in "raw" mode, use ioctl with some magic numbers
gleaned from msdos.c (Perl source file) and Ralf Brown's interrupt list
(comes across the net every so often):
$old_ioctl = ioctl(STDIN,0,0); # Gets device info
$old_ioctl &= 0xff;
ioctl(STDIN,1,$old_ioctl | 32); # Writes it back, setting bit 5
Then to read a single character:
sysread(STDIN,$c,1); # Read a single character
And to put the PC back to "cooked" mode:
ioctl(STDIN,1,$old_ioctl); # Sets it back to cooked mode.
Question 2: So now you have $c. If ord($c) == 0, you have a two byte code,
which means you hit a special key. Read another byte (sysread(STDIN,$c,1)),
and that value tells you what combination it was according to this table:
# PC 2-byte keycodes = ^@ + the following:
# HEX KEYS
# --- ----
# 0F SHF TAB
# 10-19 ALT QWERTYUIOP
# 1E-26 ALT ASDFGHJKL
# 2C-32 ALT ZXCVBNM
# 3B-44 F1-F10
# 47-49 HOME,UP,PgUp
# 4B LEFT
# 4D RIGHT
# 4F-53 END,DOWN,PgDn,Ins,Del
# 54-5D SHF F1-F10
# 5E-67 CTR F1-F10
# 68-71 ALT F1-F10
# 73-77 CTR LEFT,RIGHT,END,PgDn,HOME
# 78-83 ALT 1234567890-=
# 84 CTR PgUp
This is all trial and error I did a long time ago, I hope I'm reading the
file that worked.
Good luck-
[email protected]
Dan Carson
John Fluke Mfg.
Everett, WA