Number: 661

Date: 11-Apr-84 18':18':32

Submitter: masinter.PA

Source: masinter

Subject: document how to redefine \KEYHANDLER

Lisp Version: 11 Apr 84

Description: '
'
Received': from RUTGERS.ARPA by PARC-MAXC.ARPA;  8 APR 84 14':02':37 PST'
Date': 8 Apr 84 17':02':47 EST'
From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
Subject': How do you redefine \KEYHANDLER1'
To': lispsupport.pa'
cc': masinter.pa, raim.pasa, SHULMAN@RUTGERS.ARPA'
'
'
	I asked this before but never received an answer':'
'
	Under program control I would like to redefine the definition of'
\KEYHANDLER1.  How do I stick the new definition into a running system'
without having to execute a (HARDRESET)?'
'
	This is very important since the Tutorial will have to do this'
and the answer to this question is holding me up.'
'
	Thanks.'
'
'
							Jeff'
-------'
'
Received': from RUTGERS.ARPA by PARC-MAXC.ARPA;  9 APR 84 14':34':51 PST'
Date': 9 Apr 84 17':33':42 EST'
From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
Subject': Re': How do you redefine \KEYHANDLER1'
To': Masinter.pa'
cc': lispsupport.pa, raim.pasa'
In-Reply-To': Message from "Masinter.pa@Xerox.ARPA" of 9 Apr 84 16':33':00 EST'
'
'
	The problem I am having is getting *my* version of'
\KEYHANDLER1 to work.  Basically what I want to do is pull the rug out'
from under the old version and stick in mine.  Doing a'
MOVD(\MYKEYHANDLER1 \KEYHANDLER1) doesn''t change the one that is'
running.  What I need to know is what needs to be done then to ''reset'''
the system to run this new version.  It seems either restarting lisp'
or a (HARDRESET) attempts to do the trick.  However, everytime I have'
tried a (HARDRESET) at this point, it blew my image to Lisp heaven (this'
*may* be because I was using the new \KEYHANDLER1 version in the Fugue.4 '
system.  I just received Fugue.6 and have yet to try it there.)'
	Anyway, there has to be some "clean" method to do this (like is'
done when lisp starts.)  What is it?'
'
							Jeff'
-------'
Subject': Re': How do you redefine \KEYHANDLER1'
In-reply-to': SHULMAN''s message of 9 Apr 84 17':33':42 EST'
To': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
cc': Masinter, lispsupport, raim.pasa'
'
Jeff':'
'
your key handler must be LOCKED DOWN, using \LOCKFN. Also, you have to be careful; when you MOVD from \MYKEYHANDLER1 to \KEYHANDLER1 it may actually copy the definition.'
'
Thus, what you really need to do is CHANGENAME(\KEYHANDLER \KEYHANDLER1 \MYKEYHANDLER).'
'
This needs to go into the ''folklore'' document, I guess.'
'
-----'
'
Return-Path': SHULMAN@RUTGERS.ARPA'
Received': from RUTGERS.ARPA by Xerox.ARPA ; 21 APR 84 12':25':40 PST'
Date': 21 Apr 84 15':25':15 EST'
From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
Subject': \KEYHANDLER (again)'
To': masinter.pa'
cc': lispsupport.pa'
'
'
	Ok, I \LOCKFN''ed my own version of \KEYHANDLER1 and did the'
CHANGENAME.  Now, in order for it to ''take effect'', I have to do a'
(HARDRESET).  Clearly this is not what I want to do during the'
tutorial.  I have tried all manner of combinations of RETTO''s and'
RETFROM''s to no avail (other than halting my DLion.)  Could someone'
please tell me the ''magic'' to get \KEYHANDLER to start over with'
\MYKEYHANDLER1 ''on the fly.''  Thanks.'
'
							Jeff'
'
P.S.  *Is* there a ''folklore'' manual?  Can you get me a copy please if it'
exists?'
'
-------'
'
Date': 22 APR 84 00':21 PST'
From': MASINTER.PA'
Subject': keyhandler, etc.'
To':   shulman@rutgers'
cc':   lispsupport'
'
There is a folklore manual, but all of the pages are blank.'
'
Sorry, \KEYHANDLER1 never gives up control. You gotta boot it. HARDRESET is the simplest way.'
'
Whatcha wanna do is just install your KEYHANDLER at the beginning of the session or when you are loading up or whatever.'
'
You can make something happen after a HARDRESET by BKSYSBUF-ing it, for example, so you don''t really lose control.'
'
-----'
'
Return-Path': SHULMAN@RUTGERS.ARPA'
Received': from RUTGERS.ARPA by Xerox.ARPA ; 01 MAY 84 07':15':41 PDT'
Date': 1 May 84 10':15':27 EDT'
From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
Subject': "Illegal Address" errors under \PAGEFAULT'
To': masinter.pa'
cc': lispsupport.pa, raim.pasa, SHULMAN@RUTGERS.ARPA'
'
[The context of all this is the keyboard/mouse recorder/playback functions'
 I am working on for the Tutorial and general users package.  Fugue.6 on'
 a DLion.]'
'
1. To set up my version of \KEYHANDLER1 I a) \LOCKFN it down, CHANGECALLER''s'
   in \KEYHANDLER to it and then do a (HARDRESET).  It all seems fine.'
'
2. To begin recording a user function sets a global to a large (10000) '
   element WORD array and sets a "ready to record flag".'
'
3. When my  new key handler detects this it initializes a few things '
   including an internal variable to the BASE of the array'
   (via fetching'' (ARRAYP BASE)) and waits for the user to signal to'
   start.'
'
4. Once the user gives this signal it goes about filling this array'
   via calls to \PUTBASE and \PUTBASEBYTE (with the appropriate doubling'
   of the word address for \PUTBASEBYTE) with various things '
   (like \FIXP boxes for the time deltas, byte keys indicating what comes next'
   and small numbers like cursor positions, mouse key state and kbdad''s.)  '
   Again this seems to all work fine.'
'
5. It keeps doing this until it either fills the array or receives the'
   "stop" signal from the user.'
'
6. After it receives the stop signal (or fills the array) it will tell the '
   user it stopped and go back to "normal" mode.'
'
7. Within a few seconds of this "normal" mode (say the time it takes to'
   type two "]") it goes into this page fault never to be seen alive'
   again.  (It displays the ol'' 9305(?) on the DLion MPC.  Using TELERAID'
   I found out that this was an "Illegal Address" under \PAGEFAULT under'
   \FAULTHANDLER.)'
'
[Aside': This is no fun matter.  I must restart my DLion (thank you for'
 having "Remote Boot"!) and reload my system (which includes a LOADCOMP '
 of LLKEY and a file with the necessary items pulled from EXPORTS.ALL.)'
 Total time': about 15 minutes.  I have done this about 60 (yes *sixty*) '
 times already in the past two weeks, I am just about ready to call in '
 "Lawn Doctor".)]'
'
8. In a moment of reconciliation with my machine late last night I decided to'
   make this array only 512 words long.  That time I did not get the'
   page fault (at least not within the time it took me to try some'
   other code that made the machine die (that was probably my fault but'
   I haven''t had time (nor was I in the mood) to look into that yet.))'
'
'
So, what is going on?  I have a funny suspicion that this large array'
must be "locked down" when I use it and "unlocked" when I am done?'
How does one do that?  Does this global pointer need to be "locked"?'
Please don''t tell me to only use 512 word arrays since this only gives'
about 5 seconds worth of recoding time.'
'
[Aside': It really *would* be nice if there really were a "folklore/systems" '
 manual containing things like this a) for us poor system developers on the'
 east coast who can''t walk down the hall and ask a wizard and b) when'
 PARC is flattened in the pending earthquake (heaven forbid) '
 [you guys should move east for the next 10 years ':-) ]'
'
Thanks.'
'
							Jeff'
-------'
'
Date':  1 May 84 11':41 PDT'
From': masinter.pa'
Subject': Re': "Illegal Address" errors under \PAGEFAULT'
In-reply-to': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>''s message of 1 May 84 10':15':27 EDT'
To': SHULMAN@RUTGERS'
cc': masinter.pa, lispsupport.pa, raim.pasa'
'
Jeffrey':'
'
I''m sorry if this wasn''t clear':'
'
EVERY function and EVERY datastructure and EVERY valuecell and EVERY definition cell of ANYTHING that is run under the keyboard handler MUST be absolutely LOCKED down.'
'
This is because the keyboard process runs even during pagefaults, and the page fault handler is not reentrant.'
'
It may be that what you are doing under \KEYHANDLER1 should be done with a \PERIODIC.INTERRUPT. The constraints for what you can do under a \PERIODIC.INTERRUPT are less stringent. (However, any function run as a \PERIODIC.INTERRUPT must either check for \INTERRUPTABLE or else not allocate any storage or touch any system global data structure.)'
'
-----'
'
Date': 10 May 84 12':15 PDT'
From': Masinter.pa'
Subject': problems with RECORDER'
To': shulman@rutgers'
cc': Burton, LispSupport, Raim.pasa'
'
'
Jeff': I am convinced after looking at this code that this is just the wrong approach. I think you should put the stuff about mouse movement and keystrokes recording and playback into GETMOUSESTATE and \GETKEY rather than into the key handler. I started typing in the following long list of problems, but the main problem is that you will  get into a number of race conditions and otherwise non-reproducable typescripts because of the timing coordination. Your current recording scenario is too dependent on timing coordination, e.g., what it means to push a mouse button down really depends on whether a window has popped up. It might make more sense to get into WINDOW.MOUSE.HANDLER and have the recording be a list of S-expressions of events and typein. '
'
All parts of the system that I am aware of (including WINDOW.MOUSE.HANDLER and menu etc.) use GETMOUSESTATE to determine what the mouse state is, and KEYDOWNP (and its macro expansion, KEYDOWNP1), and \GETKEY to get things out of the keyboard input buffer. Why not put the recording hooks in there, which gives you a much safer place to stand, and is far more synchronized with the events of the window world rather than the dependent on exact timing.'
'
(One of the things this attempt to do a recording package correlates with is the desire for the system to ''queue'' button events. Because button events aren''t queued, it is non-deterministic whether a given button press will be seen by the window system.)'
'
Anyway, here was my analysis. Summary is that I don''t think that this is a fruitful approach...'
'
'
\RECORDER.KEYHANDLER1 was calling \LOCKVAR.'
This is not OK. The variable must be locked before \RECORDER.KEYHANDLER1 is called.'
Likewise, it is not ok to call CREATECELL or use any cells that you don''t lock down inside \KEYHANDLER1.'
'
Also, you call \STOP, which calls \UNLOCKPAGES, which is inappropriate.'
'
You probably should keep time in ''TICKS'' rather than milliseconds.'
'
you call "printout" underneath \KEYHANDLER!!! absolutely wrong. KEYHANDLER can run at absolutely arbitrary times, including when you are pagefaulting in the prompt window.'
'
You want to set and use the global variable \RECORDING.ARRRAY.BASE'
'
Let me say it again': EVERY variable and EVERY datastructure which is TOUCHED by \KEYHANDLER MUST be LOCKED down COMPLETELY  and TOTALLY without ANY exception.'
'
I started to make the edits, but they are absolutely massive.'
'
-----'
'
Return-Path': SHULMAN@RUTGERS.ARPA'
Received': from RUTGERS.ARPA by Xerox.ARPA ; 10 MAY 84 15':28':32 PDT'
Date': 10 May 84 18':29':04 EDT'
From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
Subject': Re': problems with RECORDER'
To': Masinter.pa'
cc': Burton.pa, LispSupport.pa, Raim.pasa, SHULMAN@RUTGERS.ARPA'
In-Reply-To': Message from "Masinter.pa@XEROX.ARPA" of 10 May 84 15':15':00 EDT'
'
'
	Alright, I''ll pop one level higher and rewrite \GETKEY, KEYDOWNP,'
KEYDOWNP1 and GETMOUSESTATE.  Thanks for giving it a look.'
	BTW, there is still one small problem':  Only those keys that'
are neither interrupts nor "shift" keys are actually put into the'
key buffer by \DECODETRANSITION.  Would it be better to put my hooks'
in here (\KEYHANDLER1 directly calls \DOTRANSITIONS whichs in turn calls'
\DECODETRANSITION.  Is this far enough removed to be OK to redefine without'
all the messy \LOCKVAR stuff?)'
	Thanks again.'
'
							Jeff'
-------'
'
Date': 10 May 84 16':02 PDT'
From': masinter.pa'
Subject': Re': problems with RECORDER'
In-reply-to': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>''s message of 10 May 84 18':29':04 EDT'
To': SHULMAN@RUTGERS'
cc': Masinter.pa, Burton.pa, LispSupport.pa, Raim.pasa'
'
sorry, no. But the only place in the ''user'' level of the system that look at the keys down are still under KEYDOWNP1...'
'
-----'
'
Return-Path': SHULMAN@RUTGERS.ARPA'
Received': from RUTGERS.ARPA by Xerox.ARPA ; 10 MAY 84 16':53':03 PDT'
Date': 10 May 84 19':53':28 EDT'
From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
Subject': Re': problems with RECORDER'
To': Masinter.pa'
cc': Burton.pa, LispSupport.pa, Raim.pasa, SHULMAN@RUTGERS.ARPA'
In-Reply-To': Message from "Masinter.pa@XEROX.ARPA" of 10 May 84 15':15':00 EDT'
'
'
	One other thing':  Your ideas will work fine for recording the'
keyboard and mouse keys, but will not work for recording/playing mouse'
movement.  How should I do that?  You once mentioned something about'
a periodic interrupt, what is it and how does it work?'
	My first thoughts are to do thing like this':'
'
	A modified \KEYHANDLER1 that used a global locked block of 3 cells'
	(I just noticed the function \ALLOCLOCKED which will do this)':'
		a) A "state"'
		b) The mouse X location'
		c) The mouse Y location'
	When the "state" is "normal" this new \KEYHANDLER1 would'
	continue to use (\GETBASE \EM.MOUSE[x,y] 0) to get the'
	mouse position.'
	When the "state" is "recording" it would stuff these values'
	into my block.'
	When the "state" is "playback" it would use the values in'
	the block as the mouse location.'
'
	Some "outside" function would be responsible for taking/putting '
these values from/into an array.  This function has to run as close to'
real time as possible for things to work right.  The only thing that comes'
close (under \KEYHANDLER1) is that \CAUSE.PERIODIC.INTERRUPT stuff.  How'
can I use it?  Can I set the \PERIODIC.INTERRUPT.FREQUENCY to something'
less than 60 (say 5-10 might be reasonable, 1 if I really can) without'
affecting anything else?'
'
	If there is some other way to run a function in unison with the'
\KEYHANDLER I could do that too.  Any function that can be prempted for ANY'
reason will not work (which I why I chose \KEYHANDLER1 in the first'
place.)'
'
							Jeff'
-------'
'
Date': 11 May 84 12':26 PDT'
From': masinter.pa'
Subject': Re': problems with RECORDER'
In-reply-to': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>''s message of 10 May 84 19':53':28 EDT'
To': SHULMAN@RUTGERS'
cc': Masinter.pa, Burton.pa, LispSupport.pa, Raim.pasa'
'
Sure it will':'
'
when recording, then, whenever anyone calls GETMOUSESTATE, you record the mouse location (you might want to remember some other ''check'' information.'
'
For playback, I think you need a special version of \KEYHANDLER1 that'
has a SINGLE flag, called \TRACK.MOUSE. If the flag is NIL'
\KEYHANDLER ignores changes to the mouse position. (You might want'
to make ''typing something'' turn mouse tracking back on)'
'
(This is a very simple mod to KEYHANDLER1 that uses only a single extra global variable whose value is only NIL or T.'
'
Playback would just set \TRACK.MOUSE  to NIL; calls to GETMOUSESTATE would also CHANGE the cursor position.'
'
Everything important and complicated is then done outside of the \KEYHANDLER process in a safe place.'
'
You don''t NEED to cause any periodic interrupts unless your playback wanted to simulate interrupting an otherwise runaway process that didn''t block. However, you can''t really simulate one of those ANYWAY because of multiple possible race conditions (the interrupt won''t strike at EXACTLY the same time after EXACTLY the same computation.)'
'
I think that you think this won''t work, and I don''t understand why.'
'
Larry'
'
-----'
'
Return-Path': SHULMAN@RUTGERS.ARPA'
Received': from RUTGERS.ARPA by Xerox.ARPA ; 12 MAY 84 07':37':14 PDT'
Date': 12 May 84 10':37':37 EDT'
From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
Subject': Re': problems with RECORDER'
To': masinter.pa'
cc': Burton.pa, LispSupport.pa, Raim.pasa, SHULMAN@RUTGERS.ARPA'
In-Reply-To': Message from "masinter.pa@XEROX.ARPA" of 11 May 84 15':26':00 EDT'
'
'
	I''ll give it a try.  The reason I am skeptical is that I am'
not sure GETMOUSESTATE gets called *all* the time.  I know it gets called'
in the MOUSE process loop but what happens during GC?'
	I still think I want to put keyboard handling in \KEYHANDLER1 for'
the reasons I already mentioned (i.e. not *all* keys are put into the'
keyboard buffer.)  If it fails I guess I''ll have to put it into \GETKEY.'
'
							Jeff'
-------'
'
From': masinter.pa'
Date': 12-May-84 10':08':42 PDT'
Subject': Re': problems with RECORDER'
In-reply-to': SHULMAN@RUTGERS.ARPA''s message of 12 May 84 10':37':37 EDT'
To': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
cc': masinter, Burton, LispSupport, Raim.pasa'
'
Jeff, its an issue of synchronization. The playback may be a bit more styalized than the input, but I think it can be made to be acceptable.'
'
It doesn''t matter how often GETMOUSESTATE and friends are called. What matters is that they are called ANY TIME the system CARES where the mouse is and what buttons are down. '
'
(BTW, I think you may also have to fake \PEEKKEY too.)'
'
-----'
'
Return-Path': SHULMAN@RUTGERS.ARPA'
Received': from RUTGERS.ARPA by Xerox.ARPA ; 13 MAY 84 10':36':17 PDT'
Date': 13 May 84 13':35':24 EDT'
From': Jeffrey Shulman <SHULMAN@RUTGERS.ARPA>'
Subject': New RECORDER'
To': masinter.pa'
cc': burton.pa, lispsupport.pa, raim.pasa, SHULMAN@RUTGERS.ARPA'
'
'
	Following the advice and Larry and JonL I seem to be getting somewhere.'
I can now reliably record the mouse under a new GETMOUSESTATE (I am working'
on recording the keyboard now.)'
	There is still one more problem':  Under my new \KEYHANDLER1 the mouse'
freezes when it goes to the edges of the screen on my DLion.  I have tracked'
this down to that "repeatuntil" loop in the \SETMOUSEXY macro.  Could I be'
using an outdated version of LLKEY (mine is LLKEY.':120 dated 1/8/84)?  I am'
also using a fairly old EXPORTS.ALL (I am actually using a small subset'
which I put a copy of on [MAXC]<1100USERS>EXPORTS.LLKEY) which might also'
cause problems.'
	Looking on [MAXC]<BLISP> I noticed that LLKEY is now up around version'
148.  Could I be given access to <BLISP>? (I *was* able to read files on it'
at one time but not any longer.)  I have signed a non-disclosure agreement as'
part of my consulting contract.'
'
							Jeff'
'
P.S.  I''ll place an alpha copy of the new RECORDER on <1100USERS> as soon as'
I get key handling working.'
-------'
'
'


Workaround: 

Test Case: 

Edit-By: Masinter.PA

Edit-Date:  7-Jun-84 18':12':15

Attn: Lisp

Assigned To: 

In/By: 

Disposition: 

System: Operating System

Subsystem: Keyboard

Machine: 

Disk: 

Microcode Version: 

Memory Size: 

File Server: 

Server Software Version: 

Difficulty: Moderate

Frequency: 

Impact: Moderate

Priority: Perhaps

Status: Open

Problem Type: Documentation

Source Files: