#!/usr/bin/perl
#{desc: echos the keys back to the user, escaped.  Useful for noting escape codes of odd keys}
#======================================================================
# Last modified Time-stamp: "2014-03-17 06:23:41 MDT sburke@cpan.org"
use constant DEBUG => 1;
use strict; use warnings;

die "I won't work without a controlling terminal\n Aborting"
  unless have_terminal();

$| = 1;
$0 = "echo-keys";
my $Lifetime = 20; # how long we'll live, in seconds
 # TODO: set from command-line

#======================================================================
my $End = $^T + $Lifetime;

use Time::HiRes qw(usleep); # Yes, now we get fractional times
use Term::ReadKey;
use constant SLEEP_MICROSECONDS => 80_000; # so "250_000" is 250ms = 1/4 sec

my %Escapes;
Main();
exit;
#======================================================================


sub Main {
  print "I'm process $$ and I'll quit after $Lifetime seconds of idle time.\nReady!\n\n";

  init_escapes();

  ReadMode 4; # Turn off controls keys
  Mainloop();
  ReadMode 0;
  DEBUG and print "Done.\n";
  print "\n";
  exit;
}

#======================================================================

sub have_terminal {
  0==system('tty', '--quiet');
}

sub init_escapes {
  foreach my $e ( 0 .. 0x2F, 0x7F .. 0xFF ) {
    $Escapes{ chr($e) } = sprintf '\%02x', $e;
  }

  my @them = (
   "\a" => '\a', # ding!
   "\b" => '\b', # BS
   "\e" => '\[', # ESC
   "\f" => '\f', # FF
   "\t" => '\t', # tab
   "\r" => '\r',
   "\n" => '\n',
   '"' => '\"',
   '\\' => '\\\\',
   '$' => '\\$',
   '@' => '\\@',
   '%' => '\\%',
   '#' => '\\#',
  );
  while(@them) {
    my($from,$to) = splice @them, 0, 2;
    die "NO-TO?" unless defined $to; # sanity
    $Escapes{$from} = $to;
    DEBUG > 9 and print "   Setting escape for $to\n";
  }

  return;
}

#======================================================================
sub Mainloop {

  # vars we'll use in the loops.  Preallocate for speed, I guess
  my(
    $keys,
    $key, $showform, $charnum);

  print
q[
\x03  \003    3  \03], "\n";



  # Loop over CHUNKS of strings
  while(1) {
    $keys = '';

    while(1) { # Loop over chars in this chunk
      usleep SLEEP_MICROSECONDS; # otherwise we're BUSYWAITING the processor!
      if( time() >= $End ) {
        print "(Time is up)\n";
	return;
      }
      $key = ReadKey(-1);
      last unless defined $key; # bust back out into our chunks-loop


      # Otherwise we saw a key, and...
      $showform = $Escapes{$key};
      $showform = $key unless defined $showform;

      $charnum  = unpack('C', $key);
      #  $charnum, $charnum, $charnum ,$showform;

      printf '\x%1$02x  \%1$03o  %1$3d  %2$s%3$s',
        $charnum, $showform, "\n";

      if( $key eq "\cc" ) { # byebye, on demand
        DEBUG and print "(Quitting on demand)\n";
        $| = 1;
        return;
      }

      $keys .= $showform;

      $End = time() + $Lifetime; # extend our lifetime
    }

    if(length $keys > 1) {
          print "\t\t\t$keys\n";
    }

  }
  return;
}

#======================================================================

__END__
