[comp.sys.atari.st.tech] Simulating keypress

fabian@etek.chalmers.se (Martin Fabian) (04/05/91)

Is there any (legal) way to simulate a keypress from inside
a program. Since the ikbdsys reads the keys directly off the
UART, this seems like 'mission: impossible' to me. Any
suggestions any one ?

M Fabian, fabian@contrl.chalmers.se
          fabian@etek.chalmers.se

"Nuclear arms can wipe out life on earth, if used properly."
                                                   (D Byrne)

vsnyder@jato.jpl.nasa.gov (Van Snyder) (04/06/91)

In article <1991Apr5.151946.25763@etek.chalmers.se> fabian@etek.chalmers.se (Martin Fabian) writes:
>
>Is there any (legal) way to simulate a keypress from inside
>a program. Since the ikbdsys reads the keys directly off the
>UART, this seems like 'mission: impossible' to me. Any
>suggestions any one ?
>
I'd like to get hold of keypresses.  It's easy to get hold of mouse
motions by inserting your own handler in place of the mousevec in
the struct returned by XBIOS' kbdvec function.  But how do you get
hold of keypresses?  Must you intercept the keyboard packet handler
and interpret all the packets?

Thanks in advance,


-- 
vsnyder@jato.Jpl.Nasa.Gov
ames!elroy!jato!vsnyder
vsnyder@jato.uucp

neil@cs.hw.ac.uk (Neil Forsyth) (04/08/91)

In article <1991Apr6.000637.20676@jato.jpl.nasa.gov> vsnyder@jato.Jpl.Nasa.Gov 
(Van Snyder) writes:
>I'd like to get hold of keypresses.  It's easy to get hold of mouse
>motions by inserting your own handler in place of the mousevec in
>the struct returned by XBIOS' kbdvec function.  But how do you get
>hold of keypresses?  Must you intercept the keyboard packet handler
>and interpret all the packets?

If you want to know if the key is up or down then I'm afraid the answer is yes.
If you just want to catch the key (scancode and ascii) entering the keyboard
buffer then intercept the ikbdsys vector with a routine that checks the buffer
pointers before and after calling the original. If the buffer pointer has
changed then a key just entered the buffer. One use of this is to program
macros on the function keys. (ie. If F0 enteres buffer, remove it and place
something else in there)

>Thanks in advance,

Your welcome in retreat.

>vsnyder@jato.Jpl.Nasa.Gov
>ames!elroy!jato!vsnyder
>vsnyder@jato.uucp

+----------------------------------------------------------------------------+
! DISCLAIMER:Unless otherwise stated, the above comments are entirely my own !
!                                                                            !
! Neil Forsyth                      JANET:  neil@uk.ac.hw.cs                 !
! Dept. of Computer Science         ARPA:   neil@cs.hw.ac.uk                 !
! Heriot-Watt University            UUCP:   ..!ukc!cs.hw.ac.uk!neil          !
! Edinburgh, Scotland, UK           "That was never 5 minutes!"              !
+----------------------------------------------------------------------------+

csbrod@immd4.informatik.uni-erlangen.de (Claus Brod) (04/08/91)

>In article <1991Apr5.151946.25763@etek.chalmers.se> fabian@etek.chalmers.se (Martin Fabian) writes:
>>
>>Is there any (legal) way to simulate a keypress from inside
>>a program. Since the ikbdsys reads the keys directly off the
>>UART, this seems like 'mission: impossible' to me. Any
>>suggestions any one ?

In a GEM program, use appl_tplay to simulate a keyboard event.
In a TOS-only program, you might find it sufficient to manipulate
the BIOS keyboard buffer accessible via some function (I forgot
the name, sorry). The appl_tplay method, however, is cleaner
and should be preferred.

>I'd like to get hold of keypresses.  It's easy to get hold of mouse
>motions by inserting your own handler in place of the mousevec in
>the struct returned by XBIOS' kbdvec function.  But how do you get
>hold of keypresses?  Must you intercept the keyboard packet handler
>and interpret all the packets?

Alternatively, you can watch the BIOS keyboard buffer contents
accessible by the abovementioned, still unnamed function 8-)

----------------------------------------------------------------------
Claus Brod, Am Felsenkeller 2,			Things. Take. Time.
D-8772 Marktheidenfeld, West Germany		(Piet Hein)
csbrod@medusa.informatik.uni-erlangen.de
Claus Brod@wue.maus.de
----------------------------------------------------------------------

fabian@etek.chalmers.se (Martin Fabian) (04/08/91)

In article <1991Apr6.000637.20676@jato.jpl.nasa.gov>, vsnyder@jato.jpl.nasa.gov (Van Snyder) writes:
|> I'd like to get hold of keypresses.  It's easy to get hold of mouse
|> motions by inserting your own handler in place of the mousevec in
|> the struct returned by XBIOS' kbdvec function.  But how do you get
|> hold of keypresses?  Must you intercept the keyboard packet handler
|> and interpret all the packets?
|> 
|> Thanks in advance,
|> 
|> 
|> -- 
|> vsnyder@jato.Jpl.Nasa.Gov
|> ames!elroy!jato!vsnyder
|> vsnyder@jato.uucp

This seems like exactly my problem. Since the ikbdsys, address of
which is also returned by kbdvec, reads the keys off the UART there
really does not seem to be any other way of doing that. The difference
between the mousevec and the keyboard routines, is that the mousevec
is passed the address of the mouse packet, whereas the keyboard routine
is not (or do I have that wrong ?).

Perhaps you could intercept the actual interrupt routine in some way ?

M Fabian, fabian@contrl.chalmers.se
          fabian@etek.chalmers.se

"Nuclear arms can wipe out life on earth, if used properly."
                                                   (D Byrne)

bjoern@drdhh.hanse.de (Bjoern Kriews) (04/09/91)

From article <1991Apr5.151946.25763@etek.chalmers.se>, by fabian@etek.chalmers.se (Martin Fabian):
> 
> Is there any (legal) way to simulate a keypress from inside
> a program. 

This is not too legal, but it works:

'io' is Iorec(KBD);
'bits' are the special keys
'scan' is the keycode to be written 
'k_xx' are the Keytbl() scan->ascii tables.

void queue_key(unsigned int scan, unsigned int bits)
{
     unsigned int next;
     if( ( next = io->ibuftl + 4 ) >= io->ibufsiz )
          next = 0;
     if( next == io->ibufhd )
          return;
     *(int*)((char*)io->ibuf+next  = scan | bits << 8;
     *(int*)((char*)io->ibuf+next+2)    =
     ( bits & KB_CAPS ? k_cl
                : bits & ( KB_SHIFTL | KB_SHIFTR ) ? k_sh
                                       : k_us
     ) [scan];
     io->ibuftl = next;
}

Hope that helps,
	Bjoern


---
bjoern@drdhh.hanse.de = Bjoern Kriews / Stormsweg 6 / 2000 Hamburg 76 / FRG
"gaaga mahwe Bjoern urgl ufzae Turbo-C bnub"     (J. Willamowius)

adamd@rhi.hi.is (Adam David) (04/10/91)

In <1991Apr5.151946.25763@etek.chalmers.se> fabian@etek.chalmers.se (Martin Fabian) writes:

>Is there any (legal) way to simulate a keypress from inside a program.

You find the address of the raw keyboard buffer using the XBIOS function iovec.
Keyboard scancodes can then be inserted directly into the buffer. You will want
to disable interrupts or otherwise stop the real keyboard input while you are
simulating keypresses (if you prefer not to have mixed input). Whatever you put
into that buffer will be picked up by the BIOS the next time(s) it gets some
input from the keyboard device, just as if it was actually typed in.

In <1991Apr8.160108.22367@etek.chalmers.se> fabian@etek.chalmers.se (Martin Fabian) writes:
>In <1991Apr6.000637.20676@jato.jpl.nasa.gov>, vsnyder@jato.jpl.nasa.gov (Van Snyder) writes:

>|> I'd like to get hold of keypresses.  It's easy to get hold of mouse
>|> motions by inserting your own handler in place of the mousevec in
>|> the struct returned by XBIOS' kbdvec function.

>This seems like exactly my problem. Since the ikbdsys, address of
>which is also returned by kbdvec, reads the keys off the UART there
>really does not seem to be any other way of doing that.

>Perhaps you could intercept the actual interrupt routine in some way ?

This can be done but is not to be recommended. This is the system programmer's
domain and is the right place to modify the keyboard handling systemwide. This
is for instance the only sensible place to patch in a national keyboard routine.
If applications programmers start fiddling with this we might end up having to
replace the ikbd chip to get tamper-proof keyboard handling. This is Iceland, we
need access to weird key combinations within other peoples' programs, to get the
full range of characters even when programs read the scancodes directly.

Please stay away from patching the ikbdsys routine unless:
1) you fully understand the implications of the changes made, this includes
   certain timing constraints.
2) the change does not destroy or undo any previously applied patches.
   (but you don't know what these patches are, so leave it alone).
The normal way of modifying keyboard input is by patching the BIOS bconin
routine. The scancode is also returned here so you can do just about anything
you like with the keyboard input using bconin.
--
Adam David.  (adamd@rhi.hi.is)

fabian@etek.chalmers.se (Martin Fabian) (04/11/91)

In article <3032@krafla.rhi.hi.is>, adamd@rhi.hi.is (Adam David) writes:

|> You find the address of the raw keyboard buffer using the XBIOS function iovec.
|> Keyboard scancodes can then be inserted directly into the buffer. You will want
|> to disable interrupts or otherwise stop the real keyboard input while you are
|> simulating keypresses (if you prefer not to have mixed input). Whatever you put
|> into that buffer will be picked up by the BIOS the next time(s) it gets some
|> input from the keyboard device, just as if it was actually typed in.

OK, but does this also apply to evnt_keybd and evnt_multi ?
And what about the keyclick, the ikbdsys handles that. Fact ?

M Fabian, fabian@contrl.chalmers.se
          fabian@etek.chalmers.se

warwick@cs.uq.oz.au (Warwick Allison) (04/12/91)

Would it be sufficient to just generate IKBD packets and
call whatever vector is recorded in the structure returned
by the XBIOS funtion kbv_base (approx) ?  That sounds like
the most obvious, robust, correct method.  Comments?

Warwick.
--
  _--_|\   	warwick@cs.uq.oz.au
 /      *  <--	Computer Science Department,
 \_.--._/ 	University of Queensland,
       v    	AUSTRALIA.

adamd@rhi.hi.is (Adam David) (04/13/91)

In <1991Apr11.160849.14152@etek.chalmers.se> fabian@etek.chalmers.se (Martin Fabian) writes:

[about inserting scancodes into the keyboard buffer]

>OK, but does this also apply to evnt_keybd and evnt_multi ?

There is an interrupt vector that resolves into the various handlers for
MIDI, keyboard, etc. However, I think it is the actual keyboard handler
that flags the keyboard events. Therefore, you are also looking for a legal
way of flagging the events.

>And what about the keyclick, the ikbdsys handles that. Fact ?

Yes, the keyboard click is triggered there. If you want to generate a real
keyclick, you also need a hook into the system keyclick.

Adam David.  (adamd@rhi.hi.is)

nox@jelal.north.de (Juergen Lock) (04/19/91)

moin bjoern!

From article <2654.04.91@drdhh.hanse.de>, by bjoern@drdhh.hanse.de (Bjoern Kriews):
> From article <1991Apr5.151946.25763@etek.chalmers.se>, by fabian@etek.chalmers.se (Martin Fabian):
>> 
>> Is there any (legal) way to simulate a keypress from inside
>> a program. 
> 
> This is not too legal, but it works:
> [queue_key() code deleted]

 yes, but beware of race conditions! or in other words, disabling
interrupts while doing these things sounds like a veeery good idea...
(reminds me of that `phantom typist' thing - is it fixed now? well at
least you're _not_ the first one who, while dealing with interrupts,
didn't think of murphy's law 25 hours a day. :-)
> 
> Hope that helps,
> 	Bjoern
 so do i, (and bjoern, tell me when you read this - your one
made those ~100km from you to me in `only' seven days!),
	Juergen

PS: yes you guess it, my german is better...
-- 
J"urgen Lock / ..!nicedel!lynx1!jelal!nox / d09c@dhbrrz41.bitnet
							...ohne Gewehr