KeyWatch V2.1
=============

     --- Program-independent keyboard shortcuts

Written by Manfred Lippert
Email: mani@mani.de
Web:   http://www.mani.de

What is KeyWatch?
=================

KeyWatch supervises all keyboard input that is made when a key is 
pressed while the Control plus Alternate keys are held down. Furthermore 
KeyWatch offers other programs the possibility of "hooking into" such 
key-presses. This makes program-independent keyboard shortcuts (that can 
be used with more than one running application) possible.

One program that uses KeyWatch is, for instance, the jinnee desktop. If 
KeyWatch is installed then shortcuts are possible at any time in 
jinnee's installed applications, as long as such shortcuts are triggered 
with Control+Alternate combinations. This also applies to the Quick-keys.
For this KeyWatch has to be installed before jinnee is launched.


Installation
============

KeyWatch from version 2.0 onwards only works together with "Trapper". 
Trapper is a tool that simplifies the development of system extensions.

KeyWatch is best started from the AUTO folder. One must ensure that 
it is started after Trapper. Under MagiC one should use the file 
AUTOEXEC.BAT to establish the order of the AUTO folder programs (see 
the MagiC docs). The order can also be shown and changed in some boot 
managers.

Warning: KeyWatch V1.0 was still launched from the START folder, but 
KeyWatch V1.0 should no longer be used. Due to its very meagre stack it 
does not get along with Trapper, for instance, and for this reason also 
conflicts with other system extensions are very likely. KeyWatch from 
version 2.0 onwards installs itself via Trapper into the system and 
hence is appreciably more stable, hooking into the system in a much 
cleaner and more effective manner.

Notes: KeyWatch only works if during installation there is enough room 
in the cookie-jar for the KeyWatch cookie. KeyWatch does not itself 
extend the cookie-jar. If there is no more room in the cookie-jar, 
KeyWatch from version 2.0 onwards displays a corresponding error message.

From MagiC 6 onwards one can set the size of the cookie-jar in the 
MAGX.INF. This is done, for instance, with the line

cookies=50

in the #[boot] section of the MAGX.INF file.


Freeware
========

KeyWatch may be distributed freely - but only with this text and both 
unaltered.

Trapper is equally Freeware.


For programmers
===============

KeyWatch installs a cookie named 'KyWt' whose value points to the 
following structure:

typedef struct {
	int cdecl (*install_func)(keywatch_func func);
	void cdecl (*remove_func)(keywatch_func func);
} KEYWATCH_COOKIE_STRUCT;

where the parameter keywatch_func is defined as follows:

typedef int cdecl (*keywatch_func)(int key, int shift);

So install_func is a pointer to a function which one interrogates when 
one wants to hook-in a shortcut routine. As the parameter one passes
precisely this routine.

If install_func returns a value that is not equal to 0, then the 
installation was successful.

In this case it is imperative that remove_func is called at program 
termination in order to deinstall the routine again.

IMPORTANT: Programs that hook into KeyWatch have to also hook 
themselves into the etv_term vector, and unhook themselves again when 
this jumps out of KeyWatch. Otherwise it is inevitable that a crash 
will occur with following Control+Alt key-presses when a program that 
has hooked itself into KeyWatch is "kicked out" of memory. For 
instance when one terminates it brutally from MagiC's Task-manager, 
or when it simply crashes. KeyWatch itself cannot check whether a 
program is still present.

About the hook-in routine itelf:

keywatch_func is a pointer to a function that should be called for 
every Control+Alternate key-press.

The routine is passed the pressed 'normal' key as a parameter in key, 
and the pressed modifier keys in shift. The format of key is the same 
as returned by evnt_keybd(): Bits 0-7 = ASCII code, bits 8-15 = scan 
code. The format of shift is the same as returned by Kbshift().

The function must return a non-zero value (in register d0) if the key 
was evaluated. If the routine could not do anything with the 
functions, on the other hand, then it has to return 0! This is the 
only way that other hooked in shortcut routines get a chance to get at 
the keys.

The routine may (following C conventions) only alter the registers
D0,D1,D2,A0,A1.

Warning! You have to make sure that the hooked-in routine runs under 
other applications! The key is filtered out from evnt_multi of the 
topped application, and the hooked-in routine is called so to speak 
from this application. So one should be careful with AES calls or 
similar. In addition the routine should use as little of the stack as 
possible.

One could, for example, evaluate whether one can make use of the 
keypress and if so just send oneself an AV_SENDKEY message. That 
allows you to do very little in the "foreign" program, with the main 
handling done cleanly in one's main program.

Example in pseudo-C code:

int cdecl keywatch_keyfunc(int key, int shift)
{
	/* Use as little of the stack here as possible 
	   and be careful with AES calls! */

	if ( >can use key< ) {	/* Only a test */
		int msg[8];
		msg[0] = AV_SENDKEY;
		msg[1] = my_pid;
		msg[2] = 0;
		msg[3] = shift;
		msg[4] = key;
		msg[5] = 0;
		msg[6] = 0;
		msg[7] = 0;
		appl_write(my_pid, 16, msg);	/* Send keypress to main program! */
		return TRUE;
	}
	return FALSE;
}


And a final note:

All programs hooked into KeyWatch have to share keyboard events 
between them. It is therefore very useful for the user to be able to 
freely assign the shortcuts of KeyWatch programs, or more simply just 
be able to switch them off.
KeyWatch programmers should respect this.


History
========

V2.1, 2.3.1999
--------------

- Serious bug remedied, now runs more leanly

V2.0, 6.2.1999
--------------

- Conversion to Trapper
- Installation in AUTO folder
- Output of error messages with failed installation
- Interface (cookie) has remained fully compatible

V1.0, July 1997
---------------

- First version


Have fun!
Manfred Lippert

------------------------------------
English translation Peter West, DDP
