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__