PROGRAMMERS MANUAL


Technical Specifications
CKBD.PRG is a resident program which enhances the keyboard driver in 
TOS. It uses the XBRA identifier  'CKBD' (Composed characters KeyBoard 
Driver). CKBD.PRG hooks itself into the following system vectors:
	ikbdsys
	mousevec
	VBL slot
	resvector		(only on TOS versions without cookie 
jar)
	kcl_hook, bell_hook	(only TOS prior to v1.6, KAOS prior to 
v1.4.1)

CKBD.PRG installs a cookie as well, same identifier 'CKBD'. It contains 
a pointer to a function dispatcher:
C-declaration:	long cdecl ckbd( int opcode, ... );
By calling this dispatcher the following functions can be accessed: 
IDENTIFY, EXTKEY, COMPOSE, ALT_NNN, CKEYTBL, CBIOSKEYS. From CKBD 
version 1.2 also DEADKEY and MOUSE_CFG.


Function definitions & descriptions
The COOKIE contains a pointer to a dispatcher called ckbd().
C-declaration: cdecl long setup(int opcode, ...);

IDENTIFY	opcode 0
returns in a0 and d0 a pointer to a C-style ASCII string. This string 
is read only.
	const char *ckbd(IDENTIFY);

EXTKEY	opcode 1
switches the Extkey mode on/off and returns the current status.
	long ckbd(EXTKEY, int mode);
		mode:	-1 (INQUIRE), 0 (OFF), 1 (ON)
		return:	current status

COMPOSE	opcode 2
switches the COMPOSE mode on/off and returns the current status.
	long ckbd(COMPOSE, int mode);
		mode:	-1 (INQUIRE)
				0 Set mode, bit mapped:
			bit #0:     OFF/ON
			bit #1:     DEC/MULTICHAR MODE
			bit #2:     ORDER SENSITIVE NO/YES
		return:   current status.

ALT_NNN	opcode 3
controls the ALT-ASCII function.
	long ckbd(ALT_NNN, int mode);
		mode:	-1 (INQUIRE), 0 (OFF), 1 (ON)
		return:	current status.

CKEYTBL	opcode 4
controls the keyboard mapping tables (kbd layout).
	long ckbd(CKEYTBL, char *unshift, char *shift, char *caps,
				                             char 
				                             *compose );
		unshift, shift, caps:
			Pointers to the corresponding tables
			(identical to XBIOS Keytbl tables)
		compose:	pointer to the compose table.
		return:	pointer to an extended keytbl struct (XKEYTAB, 
		readonly)

Note: if a pointer has the value NULL or -1L this value is not changed, 
the old table is still used. The four tables are copied into a buffer 
in CKBD.PRG so that the caller does not need to keep the installed 
tables in RAM. That's why even ACC's or CPX modules can install new 
tables.

CBIOSKEYS	opcode 5
switches between the system tables and and the newly installed tables 
if available.
	int ckbd(CBIOSKEYS, switch);
		switch:	-1  INQUIRE  - returns last setup value only
				(0,1,2 or 3)
			0: bitmapped:
			bit #0: keyboard table (SET: use secondary)
			bit #1: compose tables (SET: use secondary)
		return:	last setup value.

DEADKEY	opcode 6
controls the deadkey function
	long ckbd(DEADKEY, short mode, char *deadkeys)
		mode:	-1 (INQUIRE), 0 (OFF), 1 (ON), 2 (SETUP)
	deadkeys:	if mode==SETUP: *deadkeys must be a pointer to 
	a null terminated string with the new deadkeys.
		if mode==INQUIRE: *deadkeys can be a pointer to a 16 
		byte buffer in which CKBD will copy the string with the 
		currently used deadkeys. Set this ptr to NULL if not 
		used.
		return:	current setup mode

MOUSE_CFG	opcode 7
Controls the mouse speeder.
	int ckbd(MOUSE_CFG, int mode, MSPEEDER_SETUP *mdata);
		mode:	-1: INQUIRE
			0: OFF - deactivate Speeder (*mdata may be NULL)
			1: ON  - activate Speeder (*mdata may be NULL)

			2: SET - install new params
	return:	ptr to an MSPEEDER_SETUP-struct with the active data. 
	Readonly!.



Data structures

XKEYTAB
Struct used by XKEYTAB function call.
typedef struct {
	char    *unshift;
	char    *shift;
	char    *caps;
	comptab *compose;
} XKEYTAB;

char	Unshift_keymap[128];
char	Shift_keymap[128];
char	Capslock_keymap[128];


COMPTAB_ENTRY
The compose table is an array of entries of the type 'COMPTAB_ENTRY'. 
These entries define the possible compose sequences. A compose sequence 
is defined by the main character, the overlay character and the 
resulting ascii code. These three bytes are ascii codes, NOT scancodes. 
The last byte in a COMPTAB_ENTRY is reserved and will be used for 
flags. The last entry in the compose table must be zero, e.g. a 
COMPTAB_ENTRY with four zerobytes. The table may have any length 
between 2 and 256 entries.

typedef struct {
	char    primary;	/* main character */
	char    secondary;	/* overlay character */
	char    composed;	/* resulting composed character */
	char    flags;		/* flags, reserved. Must be zero! */
} COMPTAB_ENTRY;

COMPTAB_ENTRY compose_table[];


MSPEEDER_SETUP
This structure contains the setup data for the mouse speeder. The 
polynomial factors and the x/y ratio values are 8 bit fixpoint data, 
which is (int)(float_val*256). The default values for mouse resolution 
is 100 dpi, the default value for the screen resolution is 72 dpi. 
These values correspond to a standard Atari mouse and a SM 124 monitor.

typedef struct {
	struct {
	     unsigned resvd	:13;
	     unsigned lefthand	:1;       /* Button L/R swap */
	     unsigned unused	:1;       /* old feature, removed... */
	     unsigned activity	:1;       /* Speeder ON/OFF */
	} switches;
	short       polynomial[4];	/* speeder polynomial factors 
	x4...x1*/
	short       rotation;	/* rotation in degrees, -180..360 deg*/
	short       ratio;		/* X:Y ratio * 256! */
	short       mouse_rez;	/* M.resolution in dpi (100)  */
	short       screen_rez;	/* screen rez in dpi   ( 72)  */
} MSPEEDER_SETUP;



CKB - file format
For more information about this format see the source code examples.


PROGRAMMING CORRECTLY
As soon as a more sophisticated keyboard readout routine is needed the 
programmer has a problem. How do I recognize every key correctly 
without interfering with other utilities...

IT IS WRONG to read only the scancodes. This will be one of those 
programs which cannot make the difference between 'y' and 'z'.

IT IS WRONG to include a completely new keyboard driver in your 
program. This will interfere for sure with other applications which is 
a catastrophe in a multitasking enviroment.
NO KEY COMBINATION IS INVALID (MURPHY'S LAW!). The scan code zero is 
perfectly possible - in that case it didn't originate from the keyboard 
but from a composed characters driver like CKBD. This is also true in 
TOS 3.06/2.06 which generate such codes when entreing an ALT-ascii 
combination.

To make sure that Deadkey and especially Extkey works as required two 
rules must be applied:
1.	BACKSPACE (Scan $0E, ASCII $08) must be executed even in 
conjunction with CONTROL and/or SHIFT keys unless you use directly the 
bios keycode which contains the correct shift status. AES is somewhat 
buggy in that respect.
2.	Very fast keystrokes must not be disregarded. Extkey, Deadkey 
and Compose Character may under some circumstances send two keycodes 
for one keystroke!!


---eof---
