Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!cs.utexas.edu!convex!usenet From: tchrist@convex.COM (Tom Christiansen) Newsgroups: comp.lang.perl Subject: Re: Perl keyboard processing Message-ID: <1991May18.211524.24055@convex.com> Date: 18 May 91 21:15:24 GMT References: <1357@unet.UUCP> Sender: usenet@convex.com (news access account) Reply-To: tchrist@convex.COM (Tom Christiansen) Organization: CONVEX Software Development, Richardson, TX Lines: 78 Nntp-Posting-Host: pixel.convex.com From the keyboard of jukoff@imram.net.com (Steve Jukoff): :This perl script is simply a loop to read and process keyboard input. :Some tricky problems arise: : :1) I'd like a "read" routine to immediately process each character; : I don't want the user to be required to hit . stty cbreak, or raw, or whatever sysV wants you to incant. :2) I need to process all characters including: : 1) Control chars, and easy. : 2) Special keyboard characters, i.e. UP-Arrow, HOME, etc. not too easy. :3) I need "immediate flush mode" for the user prompt. : (Something to do with select() but what I tried didn't work). you have the wrong handle. :# user_input is a "switch" to process keyboard input :sub user_input { : open (TTY, "/dev/tty") || die "Can't open /dev/tty" ; : : # Perl idiom to force a per-write flush on FILEHANDLE -- Doesn't : # seem to work. : select((select(TTY), $| = 1)[$[]) ; : : # Needed: immediately process single character input : : # Set "non-canonical mode": do not (pre-)interpret control chars : # system "stty raw"; : # works but now I need to know how to match control chars. : # And I need to catch signals in order to reset the terminal. : : for (;;) { : print "Enter choice: " ; # Needed: print *unbuffered* you unbuffered TTY, not STDOUT. make sure not to use the same handle for both in and out though. this idiom is open seen: open (TTYIN, "/dev/tty") || die "Can't open /dev/tty" ; and then unbuffer TTYOUT as before. : $char = getc(TTY) ; : : # A Perl switch construct : # Needed: capability to match control chars : # and special keyboard characters, i.e. DOWN-ARROW, END, etc. : $char =~ /\D+/ && do { print "non-digit entered\n" ; next ; } ; : : $char =~ /\d+/ && do { print "digit entered\n" ; next ; } : :# (?) $char =~ /#Control-X#/ && do { print "Control-X entered\n" ; next ; } Using octal escapes is probably easiest. char eq "\030" && do { print "Control-X entered\n" ; | (You probably want equality not /pattern/ tests.) : :# (?) $char =~ /#UP-ARROW#/ && do { print "Up-arrow entered\n" ; next ; } Much harder. These are multi-char sequences. You should probably parse the current termcap to figure out what "up" really is, since "\033OA" is probably a bad assumption. --tom -- Tom Christiansen tchrist@convex.com convex!tchrist "So much mail, so little time."