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: dbc@tc.fluke.COM (Dan Carson) #Subject: Re: Testing input character if arrow or function key etc (DOS). Message-ID: <1993Mar2.171637.21894@tc.fluke.COM> Organization: John Fluke Mfg. Co., Inc., Everett, WA References: <1493@alsys1.aecom.yu.edu> Date: Tue, 2 Mar 1993 17:16:37 GMT Lines: 90 In article <1493@alsys1.aecom.yu.edu> manaster@yu1.yu.edu (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 = ; 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 = ; >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: manaster@yu1.yu.edu > 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- dbc@tc.fluke.COM Dan Carson John Fluke Mfg. Everett, WA