home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d326
/
vsnap.lha
/
VSnap
/
ikm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-05
|
9KB
|
325 lines
/* ikm.c -- invert keymaps */
/** NOTICE:
* The contents of this file are copyright 1987, Jim Mackraz. All rights
* reserved. No use of the contents of this file or the compilation
* of them may be used apart from the entire Commodities Exchange
* without written permission.
*/
#define CONTROLBITS ( (1 << 5) | (1 << 6) )
/* return >= 0 if ok (no error checking now) */
ULONG
InvertKeyMap(ansicode, ie, km)
ULONG ansicode;
register struct InputEvent *ie;
struct KeyMap *km;
{
LONG kindex;
UBYTE code = 0;
extern struct KeyMap keymap;
if (km == NULL) {
km = &keymap;
}
ie->ie_Class = IECLASS_RAWKEY;
ie->ie_EventAddress = 0;
/* check for codes in (default) high map first */
switch(ansicode)
{
case ' ':
code = 0x40;/* space */
break;
case 0x08: /* backspace */
code = 0x41;
break;
case '\t': /* tab */
code = 0x42;
break;
case 0x0D: /* return */
code = 0x44;
break;
case 0x1B: /* esc */
code = 0x45;
break;
case 0x7F: /* del */
code = 0x46;
break;
}
if (code) {
ie->ie_Code = code;
ie->ie_Qualifier = 0;
return (1);
}
if (LowKeyInvert((UBYTE) ansicode, km,
&ie->ie_Code, &ie->ie_Qualifier, &kindex) >= 0) {
if (kindex) { /* was dead key, need "preceding" keystroke. */
IndexKey(kindex, km, &ie->ie_EventAddress);
}
}
return (1);
}
#define KEYMAPSIZE 64
/* LowKeyInvert returns good code else <0 if no find
*
* regarding keymap as many-to-one mapping:
* -entries for a given key are scanned so that
* the minimum number of qualifiers are associated
* with the keystroke.
* -passing a character value of zero corresponds, in
* the default keymap, to CTRL-`, which is probably a bug.
* -numerals are matched with numeric pad keystrokes (no
* qualifiers) on standard keymap. The way to specify
* a key on the number row is via its shifted value;
* specify explicitly that the qualifier is to be unshifted,
* or a "don't care."
*/
LowKeyInvert(value, km, codep, qualp, indexp)
register UBYTE value; /* translation value from low keymap */
struct KeyMap *km;
UWORD *codep; /* pointers where answers are to be put */
UWORD *qualp;
ULONG *indexp; /* dead-key index information (put into ie?) */
{
register UWORD code = KEYMAPSIZE - 1; /* last entry */
register unsigned int type;
register LONG *p; /* points to four-byte lokeymap entry */
int found_it = 0;
*indexp = *qualp = 0;
p = (LONG *) km->km_LoKeyMap + code;
do {
/* determine type of key */
if ((type = km->km_LoKeyMapTypes[code] ) == KC_VANILLA) {
found_it = checkVanilla(p, value, qualp);
} else if (type & KCF_DEAD) {
found_it = checkDead(p, value, qualp, indexp);
}
/**
else if (type & KCF_STRING) {
}
**/
else if (!(type & KCF_NOP)) {
found_it = checkNormal(p, value, type, qualp);
}
--p;
} while (!found_it && code--);
*codep = code;
return (code);
}
/*
* packs code|qual of previous key (should be keys) in *dead_vudup
* returns code, <0 if failure
*/
IndexKey(inx, km, dead_vudup)
ULONG inx;
struct KeyMap *km;
ULONG *dead_vudup;
{
/* find keystroke which generates index */
register WORD code = KEYMAPSIZE - 1; /* last entry */
UWORD **p; /* points to four-byte lokeymap entry */
register UWORD *deadthing;
int i;
WORD qual = 0;
LONG vudu;
p = (UWORD **) km->km_LoKeyMap + code;
do {
/* check each deadkey in the table */
if (km->km_LoKeyMapTypes[code] & KCF_DEAD) {
/* keymap entry is pointer to eight prefix:byte pairs */
deadthing = *p;
for (i = 0; i < 8; ++i, ++deadthing) {
/* check for index prefix and correct index */
if (*deadthing == ((DPF_DEAD << 8) | inx)) {
deadQual(i, &qual);
goto FOUND_IT;
}
}
}
--p;
} while (code--);
FOUND_IT:
/* pack as follows: [pred(-1)|qual(-1)|pred(-2)|qual(-2)] */
/* for now, 2nd previous deadkey ignored */
if (code < 0) {
*dead_vudup = 0;
} else {
vudu = code << 8;
vudu |= (0xFF & qual);
vudu <<= 16;
*dead_vudup = vudu;
}
return (code);
}
checkNormal(four_bytesp, val, type, qualp)
LONG four_bytesp;
UBYTE val;
UWORD type;
UWORD *qualp;
{
register UBYTE *p = (UBYTE *) four_bytesp; /* codes held in long word */
register int position;
/* start with last of four bytes, "more vanilla" */
p += 3;
for (position = 3; position >= 0; --position, --p) {
if (*p == val) {
switch (type) {
case KC_NOQUAL:
if (position != 3) goto NOT_THIS;
break;
case KCF_SHIFT:
if (!(position & 2)) goto NOT_THIS;
if (position == 2) *qualp |= IEQUALIFIER_LSHIFT;
break;
case KCF_ALT:
if (!(position & 2)) goto NOT_THIS;
if (position == 2) *qualp |= IEQUALIFIER_LALT;
break;
case KCF_CONTROL:
if (!(position & 2)) goto NOT_THIS;
if (position == 2) *qualp |= IEQUALIFIER_CONTROL;
break;
case KCF_ALT | KCF_CONTROL:
if (!(position & 1)) *qualp |= IEQUALIFIER_LALT;
if (!(position & 2)) *qualp |= IEQUALIFIER_CONTROL;
break;
case KCF_SHIFT | KCF_CONTROL:
if (!(position & 1)) *qualp |= IEQUALIFIER_LSHIFT;
if (!(position & 2)) *qualp |= IEQUALIFIER_CONTROL;
break;
case KCF_SHIFT | KCF_ALT:
if (!(position & 1)) *qualp |= IEQUALIFIER_LSHIFT;
if (!(position & 2)) *qualp |= IEQUALIFIER_LALT;
break;
default:
break;
}
return (1);
}
NOT_THIS: ;
}
return (0);
}
checkVanilla(p, val, qualp)
UBYTE *p; /* note: byte pointer */
UBYTE val;
UWORD *qualp;
{
register int i;
/* only one way to match a vanilla control key */
if (!(val & CONTROLBITS)) {
/* is a control code */
if ((p[3] & ~CONTROLBITS) == val) {
*qualp |= IEQUALIFIER_CONTROL;
return (1);
}
} else {
/* not a control */
for (i = 3; i >= 0; --i) {
if (p[i] == val) {
if (!(i & 1)) *qualp |= IEQUALIFIER_LSHIFT;
if (!(i & 2)) *qualp |= IEQUALIFIER_LALT;
return (1);
}
}
}
return (0);
}
checkDead(keybase, val, qualp, indexp)
UBYTE **keybase; /* note: byte pointer */
UBYTE val;
UWORD *qualp;
ULONG *indexp;
{
int i;
int j;
register UWORD *p = (UWORD *) *keybase;
/* need to remember keybase for offsets */
UBYTE *deadp;
int found_it = 0;
/* walk through eight two-byte entries, one for each qual. combo. */
for (i = 0; i < 8; ++i, ++p) {
switch (*p >> 8) {
case DPF_DEAD: /* dead keys do not themselves map to anything */
break;
case DPF_MOD: /* dead key modifiable */
deadp = *keybase + (*p & 0xFF);
/* look down the string indexed by dead-key index */
for (j = 0; j < 6; ++j) {
if (deadp[j] == val) {
found_it = 1;
*indexp = j;
break;
}
}
break;
case 0: /* normal stroke for this key */
if ((*p & 0xFF) == val) {
found_it = 1;
}
}
if (found_it) {
deadQual(i, qualp);
return (1);
}
}
return (0);
}
/* figure out qualifier from position */
deadQual(wordpos, qualp)
int wordpos; /* which word in dead-key string? */
UWORD *qualp;
{
if (wordpos & 1) *qualp |= IEQUALIFIER_LSHIFT;
if (wordpos & 2) *qualp |= IEQUALIFIER_LALT;
if (wordpos & 4) *qualp |= IEQUALIFIER_CONTROL;
}