home *** CD-ROM | disk | FTP | other *** search
- /* 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;
- {
- ULONG 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, (ULONG *)&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."
- */
- UWORD 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 = 0;
- register WORD type;
- register LONG *p; /* points to four-byte lokeymap entry */
- WORD found_it = 0;
-
- *indexp = *qualp = 0;
-
- p = (LONG *) km->km_LoKeyMap;
-
- do {
- /* determine type of key */
- if ((type = km->km_LoKeyMapTypes[code] ) == KC_VANILLA) {
- found_it = checkVanilla((UBYTE *)p, value, qualp);
- } else if (type & KCF_DEAD) {
- found_it = checkDead((UBYTE **)p, value, qualp, indexp);
- }
- /**
- else if (type & KCF_STRING) {
- }
- **/
- else if (!(type & KCF_NOP)) {
- found_it = checkNormal((LONG)p, value, (UWORD)type, qualp);
- }
-
- ++p;
- } while (!found_it && ++code < KEYMAPSIZE);
-
- *codep = code;
- return (code);
- }
-
- /*
- * packs code|qual of previous key (should be keys) in *dead_vudup
- * returns code, <0 if failure
- */
- VOID IndexKey(inx, km, dead_vudup)
- ULONG inx;
- struct KeyMap *km;
- ULONG *dead_vudup;
- {
- /* find keystroke which generates index */
-
- register WORD code = 0;
- UWORD **p; /* points to four-byte lokeymap entry */
- register UWORD *deadthing;
- WORD i;
- WORD qual = 0;
- LONG vudu;
-
- p = (UWORD **) km->km_LoKeyMap;
-
- 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((WORD)i, &qual);
- goto FOUND_IT;
- }
- }
- }
- ++p;
- } while (++code < KEYMAPSIZE);
-
- 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;
- }
- }
-
-
- WORD 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 WORD 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);
- }
-
- WORD checkVanilla(p, val, qualp)
- UBYTE *p; /* note: byte pointer */
- UBYTE val;
- UWORD *qualp;
- {
- register WORD 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);
- }
-
-
- WORD checkDead(keybase, val, qualp, indexp)
- UBYTE **keybase; /* note: byte pointer */
- UBYTE val;
- UWORD *qualp;
- ULONG *indexp;
- {
- WORD i;
- WORD j;
-
- register UWORD *p = (UWORD *) *keybase;
- /* need to remember keybase for offsets */
-
- UBYTE *deadp;
- WORD 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((WORD)i, qualp);
- return (1);
- }
- }
-
- return (0);
- }
-
- /* figure out qualifier from position */
- WORD deadQual(wordpos, qualp)
- WORD 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;
- return (0);
- }
-
-
-