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---