SINGER@SPAR-20.ARPA (David Singer) (09/03/87)
Date: Wed 2 Sep 87 13:23:54-PDT
From: David Singer <SINGER@SPAR-20.ARPA>
Subject: Keyboard auto-repeat
To: news-makers@brillig.umd.edu
Cc: evans@SUN.COM, news-makers@SPAR-20.ARPA
Here's a simple implementation of keyboard auto-repeat; it should be loaded
before anything that wants the value of ascii_keymap (I load it in my
user.ps). The initial and repeat delay is tunable through the REPEAT_private
dictionary. Note that simply loading this file does NOT turn on auto-repeat;
use the autorepeat function to start it (and stoprepeat to stop it).
%%%
%%% Auto-repeat the keyboard.
%%%
%%% D.W. Singer
%%% Schlumberger Palo Alto Research.
%%%
%%% Create a process which listens for keyboard down
%%% transitions; when one happens, remember the key and
%%% keystate, and start a timer event. When the timer fires
%%% send out a new event and re-start it. When the up
%%% transition happens, cancel the timer.
/REPEAT_private 30 dict begin
/initial_delay 1 3 div 60 div def % 1/3 second
/repeat_delay 1 20 div 60 div def % 20 per second
/repeater_process null def
/repeater_event null def
/interest_event null def
currentdict end def
%% Fix ascii_keymap so that it also contains encoded ascii,
%% so that events can also be distributed with ascii strokes
%% directly in them.
ascii_keymap maxlength 256 eq
{
/ascii_keymap ascii_keymap 512 dict copy def
0 1 255
{ ascii_keymap exch dup put } for
} if
/autorepeat {
REPEAT_private /repeater_process
{
newprocessgroup
REPEAT_private begin
/interest_event createevent def
interest_event /Action [ /DownTransition /UpTransition /AutoRepeat ] put
interest_event /Priority 10 put
interest_event /Name ascii_keymap put
%%interest_event /Name null put
interest_event /Canvas null put
interest_event /Exclusivity true put
interest_event expressinterest
/repeater_event null def
{
awaitevent
dup /Action get /UpTransition eq
{
%%(stopping\n) print
redistributeevent
repeater_event null eq not
{ repeater_event recallevent
/repeater_event null def } if
}
{
repeater_event null eq not
{ %%(cancelling\n) print
repeater_event recallevent
/repeater_event null def } if
/repeater_event createevent def
[ /Action /Name /TimeStamp /ClientData
/XLocation /YLocation %%/Canvas
]
{ 2 copy get repeater_event 3 1 roll put } forall
redistributeevent
repeater_event /ClientData get /AutoRepeat eq
%%repeater_event /Action get /AutoRepeat eq
{
%%(repeating %\n) [ repeater_event /Name get ] printf
repeater_event /TimeStamp
repeater_event /TimeStamp get repeat_delay add put
}
{
%%(starting %\n) [ repeater_event /Name get ] printf
repeater_event /TimeStamp
repeater_event /TimeStamp get initial_delay add put
} ifelse
repeater_event /ClientData /AutoRepeat put
repeater_event /Process null put
%%repeater_event /Action /AutoRepeat put
repeater_event sendevent
} ifelse
} loop
} fork put
} def
/stoprepeat { REPEAT_private /repeater_process get killprocess } def
-------