Re: Non blocking keyboard
Good work! thanks for your sharing. ;) On Fri, Oct 14, 2011 at 7:37 AM, Barry Brevik wrote: > Last week I had posted a query about getting keyboard input in a non > blocking way. > > I received several replies, so I thought I would post back the code I > developed which seems to work. > > This is not the code I will end up using; it is more like a proof of > concept program. > > use strict; > use warnings; > use Win32::Console; > > my $signame = ''; > my $havebrk = 0; > > $SIG{INT} = sub {$signame = $_[0]; $havebrk = 1;};# CTRL-C. > $SIG{BREAK} = sub {$signame = $_[0]; $havebrk = 1;};# CTRL-BREAK, > CTRL-ScrollLock. > > my $STDIN = new Win32::Console(STD_INPUT_HANDLE); > $STDIN -> Mode(ENABLE_PROCESSED_INPUT); > > while (1) > { > if ($STDIN->GetEvents()) > { ># We do this inner loop here to make shure that we read ># all of the characters in the key buffer. >while ($STDIN->GetEvents()) >{ ># Read console event. >my @input = $STDIN->Input(); > > # input[0] is the event type- 1 for keyboard, 2 for mouse. So what > is 0 for? >if (defined $input[0] and $input[0] == 1) > { >my ($eventType, $keyState, $keyCount, $keyCode, $scanCode, > $keyValue, $keyFlags) = @input; > >if ($havebrk) {die "User termination on signal $signame.\n\n";} > ># KeyState of 1 means key down. >if ($keyState == 1) >{ > if ($keyValue == 0x00) > { ># Most control keys fall in here. >if ($keyCode == 16) {print "\nSHIFT key pressed.\n";} >if ($keyCode == 17) {print "\nCTRL key pressed.\n";} >if ($keyCode == 18) {print "\nALT key pressed.\n";} >if ($keyCode == 19) {print "\nBREAK key pressed.\n";} >if ($keyCode == 20) {print "\nCAPS LOCK key pressed.\n";} >if ($keyCode == 33) {print "\nPG UP key pressed.\n";} >if ($keyCode == 34) {print "\nPG DN key pressed.\n";} >if ($keyCode == 35) {print "\nEND key pressed.\n";} >if ($keyCode == 36) {print "\nHOME key pressed.\n";} >if ($keyCode == 37) {print "\nLEFT ARROW key pressed.\n";} >if ($keyCode == 38) {print "\nUP ARROW key pressed.\n";} >if ($keyCode == 39) {print "\nRIGHT ARROW key pressed.\n";} >if ($keyCode == 40) {print "\nDOWN ARROW key pressed.\n";} >if ($keyCode == 45) {print "\nINS key pressed.\n";} >if ($keyCode == 46) {print "\nDEL key pressed.\n";} >if ($keyCode == 91) {print "\nLEFT WINDOWS key > pressed.\n";} >if ($keyCode == 92) {print "\nRIGHT WINDOWS key > pressed.\n";} >if ($keyCode == 93) {print "\nCONTEXT key pressed.\n";} >if ($keyCode == 112) {print "\nF1 pressed.\n";} >if ($keyCode == 113) {print "\nF2 pressed.\n";} >if ($keyCode == 114) {print "\nF3 pressed.\n";} >if ($keyCode == 115) {print "\nF4 pressed.\n";} >if ($keyCode == 116) {print "\nF5 pressed.\n";} >if ($keyCode == 117) {print "\nF6 pressed.\n";} >if ($keyCode == 118) {print "\nF7 pressed.\n";} >if ($keyCode == 119) {print "\nF8 pressed.\n";} >if ($keyCode == 120) {print "\nF9 pressed.\n";} >if ($keyCode == 121) {print "\nF10 pressed.\n";} >if ($keyCode == 122) {print "\nF11 pressed.\n";} >if ($keyCode == 123) {print "\nF12 pressed.\n";} >if ($keyCode == 144) {print "\nNUM LOCK pressed.\n";} >if ($keyCode == 145) {print "\nSCROLL LOCK pressed.\n";} > } > > elsif ($keyValue >= 0x7f) > { ># High line draw chars etc fall in here, however ># I was never able to get it to trigger. >print "High char pressed.\n"; > } > > else > { ># *Almost* Everything else is a printable ASCII character. >if($keyValue == 8) {print "BACKSPACE key pressed.\n";} >elsif ($keyValue == 9) {print "TAB key pressed.\n";} >elsif ($keyValue == 13) {print "ENTER key pressed.\n";} >elsif ($keyValue == 27) {print "ESC key pressed.\n";} >else >{ > # When here, presumably a printable character has been > pressed. > my $keyChr = chr($keyValue); > print "\nChar pressed: $keyChr\n"; >} > } >} > ># KeyState of 0 means that a key was released. >elsif ($keyState == 0) >{ > if ($keyValue == 0x00) > { >if ($keyCode == 16) {print "SHIFT key released.\n\n";} >if ($keyCode == 17) {print "CTRL key released.\n\n";} >if ($keyCode == 18) {print "ALT key released.\n\n";} >if ($keyCode == 19) {print "BREAK key released.\n\n";} >if ($keyCode == 20) {print "CAPS LOCK key released.\n\n";} >
RE: Non-blocking keyboard?
I want to thank those who responded; it was all good advice. It turns out that what I was looking for was GetEvents. I really need to pay more attention to the module docs. > > I think you wanted to call PeekInput() instead of Input() here. > > But GetEvents() may be even better if you only want to see if > there are waiting keyboard events at all. > > Cheers, > -Jan ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Non-blocking keyboard?
On Fri, 07 Oct 2011, Barry Brevik wrote: > I'm writing a program where a process runs in a loop. I want to > process keyboard input without disturbing the main process in the > loop. I'm trying to use the Win32::Console module for this task (see > code below), but the module blocks on the Input statement. > > Is there some way to make this non-blocking, or maybe even use a > different technique entirely that does not block? I tried whipping an > IOCTL statement on it, but I either did it wrong, or it does not work. > > use strict; > use warnings; > use Win32::Console; > > my $STDIN = new Win32::Console(STD_INPUT_HANDLE); > $STDIN->Mode(ENABLE_PROCESSED_INPUT); > > # Un-buffer STDOUT. > select((select(STDOUT), $| = 1)[0]); > > while (1) > { > my @input = $STDIN->Input(); I think you wanted to call PeekInput() instead of Input() here. But GetEvents() may be even better if you only want to see if there are waiting keyboard events at all. > if (defined $input[0] and $input[0] == 1) > { > if ($input[1]) > { > last if $input[5] == 27; # ESC key. > if ($input[5] == 8) {print "\x08", ' ', "\x08"; next;} # > Backspace key. > print chr($input[5]); > } > } > } Cheers, -Jan ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Non-blocking keyboard?
Hi, I also thought of Term::ReadKey and gave it a shot, but it reports that non-blocking mode does not work under windows. Also looked at the 'select' statement, but that appears to only work for sockets under windows. Ken > From: perl-win32-users-boun...@listserv.activestate.com [mailto:perl- > win32-users-boun...@listserv.activestate.com] On Behalf Of JONES, > ROBERT E CTR USAF AETC TTMS/TTMS > Sent: Friday, October 07, 2011 1:06 PM > To: Barry Brevik; perl-win32-users@listserv.activestate.com > Subject: RE: Non-blocking keyboard? > > > You might want to look into the Term::Readkey module. > > > Robert Jones, BSP, BSCS > Keesler AFB > > -Original Message- > From: perl-win32-users-boun...@listserv.activestate.com [mailto:perl- > win32-users-boun...@listserv.activestate.com] On Behalf Of Barry Brevik > Sent: Friday, October 07, 2011 11:46 AM > To: perl-win32-users@listserv.activestate.com > Subject: Non-blocking keyboard? > > I'm writing a program where a process runs in a loop. I want to process > keyboard input without disturbing the main process in the loop. I'm > trying to use the Win32::Console module for this task (see code below), > but the module blocks on the Input statement. > > Is there some way to make this non-blocking, or maybe even use a > different technique entirely that does not block? I tried whipping an > IOCTL statement on it, but I either did it wrong, or it does not work. > > use strict; > use warnings; > use Win32::Console; > > my $STDIN = new Win32::Console(STD_INPUT_HANDLE); > $STDIN->Mode(ENABLE_PROCESSED_INPUT); > > # Un-buffer STDOUT. > select((select(STDOUT), $| = 1)[0]); > > while (1) > { > my @input = $STDIN->Input(); > if (defined $input[0] and $input[0] == 1) > { > if ($input[1]) > { > last if $input[5] == 27; # ESC key. > if ($input[5] == 8) {print "\x08", ' ', "\x08"; next;} # > Backspace key. > print chr($input[5]); > } > } > } > > As an aside, I think we need to get more traffic on this list somehow. > > Barry Brevik ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Non-blocking keyboard?
You might want to look into the Term::Readkey module. Robert Jones, BSP, BSCS Keesler AFB -Original Message- From: perl-win32-users-boun...@listserv.activestate.com [mailto:perl-win32-users-boun...@listserv.activestate.com] On Behalf Of Barry Brevik Sent: Friday, October 07, 2011 11:46 AM To: perl-win32-users@listserv.activestate.com Subject: Non-blocking keyboard? I'm writing a program where a process runs in a loop. I want to process keyboard input without disturbing the main process in the loop. I'm trying to use the Win32::Console module for this task (see code below), but the module blocks on the Input statement. Is there some way to make this non-blocking, or maybe even use a different technique entirely that does not block? I tried whipping an IOCTL statement on it, but I either did it wrong, or it does not work. use strict; use warnings; use Win32::Console; my $STDIN = new Win32::Console(STD_INPUT_HANDLE); $STDIN->Mode(ENABLE_PROCESSED_INPUT); # Un-buffer STDOUT. select((select(STDOUT), $| = 1)[0]); while (1) { my @input = $STDIN->Input(); if (defined $input[0] and $input[0] == 1) { if ($input[1]) { last if $input[5] == 27; # ESC key. if ($input[5] == 8) {print "\x08", ' ', "\x08"; next;} # Backspace key. print chr($input[5]); } } } As an aside, I think we need to get more traffic on this list somehow. Barry Brevik ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs