The script at the end of this message is a stripped down version of a
larger program that demonstrates some problems I'm having tracking the
"keyDown" and "keyUp" events.

Thanks to Chris Nandor and Paul McCann for straightening me out on the
proper coding on "require" the script should work on both MacPerl 5.6.1b2
and 5.2.0r4.

When a "keyDown" event is detected the script captures the time and stores
it...
  $k{$key} = $sec;

When a "keyUp" event has occured for the same keyboard key the code
subtracts $k{$key} from the time to see how long the key was down.

Problems occur when a modifier key, such as the shift key, is pressed (or
released) after a "keyDown" event occurs and is continuously held through
the "keyUp" event. I've figured a simple way to handle alphabetical keys
but the other keys produce shifted characters without any obvious ascii
relationship.

I've experimented with something like...
  $ascii = $ev->character;
  $k($ascii) = $sec;
and was about to start building a table of corresponding shifted/unshifted
nonalphabetic keys, but wondered if there is a solution I'm missing.

Also, there seems to be a limit to the number of simultaneously down keys
that the program can track. My iBook running OS 9.1 and MacPerl 5.6.1b2 can
track quite a few more than my 604 PPC running OS 7.5.5 and MacPerl
5.2.0r4. I haven't done much testing to find the specifics or to see if the
difference is caused by the processor speeds, the OS, the version of
MacPerl, or the amount of memory assigned to MacPerl. I suspect the latter.
Any one know, or care to speculate.

Thirdly, in a script like this, does it make sense to try to measure the
diffence in time between "keyUp" and "keyDown" more accurately than to the
nearest tenth of a second.

Thanks,

David Seay
http://www.mastercall.com/g-s/

----------

#!perl

use Mac::Events;
use Mac::Events qw(@Event $CurrentEvent);
use Mac::LowMem;
if($] > 5.006) { require Time::HiRes }

  $Event[keyDown] = \&keyDown_Handler;
  $Event[keyUp]   = \&keyUp_Handler;
  LMSetSysEvtMask(LMGetSysEvtMask() | keyUpMask);

  print "Hold down one or more keys. (Press cmd \".\" to quit)\n\n";
  while (! $flag) { WaitNextEvent }
  print "\nDONE!\n";
exit;

sub keyDown_Handler {
    &getEvent;
    if (($CurrentEvent->modifiers & 256) == 256 && $key eq ".") { $flag = 1 }
    $k{$key} = $sec;
    printf(" \'$key\' = down  ASCII = %3d\n",$ascii);
}

sub keyUp_Handler {
    &getEvent;
    if ($k{$key}) {
        $dif = $sec - $k{$key};
        $elapsed = substr($dif,0,index($dif,'.') + 2);
        printf(" \'$key\' = up    ASCII = %3d  (down for $elapsed
seconds)\n",$ascii);
        $k{$key} = "";
    } else {
        printf(" \'$key\' = up    ASCII = %3d (wasn\'t down",$ascii);
        if ($k{"\u$key"}) {
            print " but \'\u$key\' was)\n";
            $k{"\u$key"} = "";
        } elsif ($k{"\l$key"}) {
            print " but \'\l$key\' was)\n";
            $k{"\l$key"} = "";
        } else { print "... What key was down?)\n" }
    }
}

sub getEvent {
    if($] > 5.006) {
        ($seconds, $microseconds) = Time::HiRes::gettimeofday();
        $sec = "$seconds.$microseconds";
    } else { $sec = time }
    my($ev) = @_;
    $ascii = $ev->character;
    $key = chr($ascii);
}

__END__



Reply via email to