home *** CD-ROM | disk | FTP | other *** search
- /* atie.c -- Ascii To Input Event */
-
- /* The contents of this file are copyright 1990, Mikael Karlsson.
- * You may use these routines freely in non-commerical programs,
- * provided that some notice of it's use is given in the program
- * and/or documentation.
- */
-
- struct HalfMap
- {
- UBYTE *KeyMapTypes;
- ULONG *KeyMap;
- UBYTE *Capsable;
- UBYTE *Repeatable;
- };
-
- struct DeadSpec
- {
- UBYTE ds_Prev1DownCode;
- UBYTE ds_Prev1DownQual;
- UBYTE ds_Prev2DownCode;
- UBYTE ds_Prev2DownQual;
- };
-
- #define CONTROLBITS ( ( 1 << 5) | ( 1 << 6))
- #define KEYMAPSIZE 64
-
- #define S IEQUALIFIER_LSHIFT
- #define A IEQUALIFIER_LALT
- #define C IEQUALIFIER_CONTROL
-
- /* These tables can be found in RKM Libraries & Devices 1.3 */
-
- WORD deadQuals[ 8][ 10] =
- {
- {KC_NOQUAL, 1, 0},
- {KCF_SHIFT, 2, 0, S},
- {KCF_ALT, 2, 0, A},
- {KCF_ALT + KCF_SHIFT, 4, 0, S, A, S + A},
- {KCF_CONTROL, 2, 0, C},
- {KCF_CONTROL + KCF_SHIFT, 4, 0, S, C, S + C},
- {KCF_CONTROL + KCF_ALT, 4, 0, A, C, A + C},
- {KCF_CONTROL + KCF_ALT + KCF_SHIFT, 8, 0, S, A, S + A, C, C + S, C + A, C + S + A}
- };
-
- WORD normalQuals[ 8][ 6] =
- {
- {KC_NOQUAL, 1, 0, 0, 0, 0},
- {KCF_SHIFT, 2, 0, 0, S, 0},
- {KCF_ALT, 2, 0, 0, A, 0},
- {KCF_ALT + KCF_SHIFT, 4, S + A, A, S, 0},
- {KCF_CONTROL, 2, 0, 0, C, 0},
- {KCF_CONTROL + KCF_SHIFT, 4, C + S, C, S, 0},
- {KCF_CONTROL + KCF_ALT, 4, C + A, C, A, 0},
- {KCF_CONTROL + KCF_ALT + KCF_SHIFT, 4, S + A, A, S, 0}
- };
-
- #define keytype 0
- #define combos 1
-
- #undef S
- #undef A
- #undef C
-
- STATIC WORD checkNormalQual( LONG *four_bytesp, UBYTE val, UWORD type, UWORD *qualp)
- {
- register UBYTE *p = ( UBYTE *) four_bytesp; /* codes held in long word */
- register WORD position;
- register WORD i = normalQuals[ type][ combos];
-
- position = 4;
-
- while ( i--)
- {
- --position;
- if ( p[ position] == val)
- {
- *qualp = normalQuals[ type][ position + 2];
- return 1;
- }
- }
- return 0;
- }
-
- WORD checkNormal( UBYTE *p, UBYTE val, WORD type, UWORD *qualp)
- {
- /* only one way to match a vanilla control key */
- if ( type == KC_VANILLA && ( val & CONTROLBITS) == NULL)
- { /* control vanilla */
- if ( checkNormalQual(
- ( LONG *)p,
- val | CONTROLBITS,
- type, qualp))
- {
- *qualp |= IEQUALIFIER_CONTROL;
- return ( 1);
- }
- else
- {
- return ( 0);
- }
- }
- else
- { /* not a control */
- return ( checkNormalQual( (LONG *)p, val, type, qualp));
- }
- }
-
-
- STATIC WORD checkDead( UBYTE *keybase, UBYTE val, WORD type, UWORD *qualp, ULONG *indexp)
- {
- WORD i;
- WORD j;
- register UBYTE *p = keybase; /* need to remember keybase for offsets */
- UBYTE *deadp;
-
- /* walk through two-byte entries, one for each qual. combo. */
- for ( i = 0; i < deadQuals[ type][ combos]; ++i, p += 2)
- {
- switch ( p[ 0])
- {
- case DPF_DEAD: /* dead keys do not themselves map to anything */
- break;
- case DPF_MOD: /* dead key modifiable */
- deadp = keybase + p[ 1];
- /* look down the string indexed by dead-key index */
- for ( j = 0; j < 6; ++j)
- {
- if ( deadp[ j] == val)
- {
- *qualp = deadQuals[ type][ i + 2];
- *indexp = j;
- return 1;
- }
- }
- break;
- case 0: /* normal stroke for this key */
- if ( p[ 1] == val)
- {
- *qualp = deadQuals[ type][ i + 2];
- return 1;
- }
- }
- }
- return ( 0);
- }
-
- /*
- * Calculates Code+Qual of previous dead key ( should be keys)
- * and puts them in DeapSpec.
- * returns success ( 1) or failure ( 0).
- */
- STATIC WORD BuildDeadSpec( ULONG inx, struct HalfMap *hm, WORD hms, struct DeadSpec *ds)
- {
- /* find keystroke which generates index */
-
- register WORD code = 0;
- register UBYTE *deadthing;
- register WORD i;
-
- do
- {
- /* check each deadkey in the table */
-
- if ( hm->KeyMapTypes[ code] & KCF_DEAD)
- {
- register WORD type = hm->KeyMapTypes[ code] & 7;
-
- /* keymap entry is pointer to prefix:byte pairs */
-
- deadthing = ( UBYTE *) hm->KeyMap[ code];
- for ( i = 0; i < deadQuals[ type][ combos]; ++i, deadthing += 2)
- {
- /* check for index prefix and correct index */
- if ( deadthing[ 0] == DPF_DEAD &&
- ( deadthing[ 1] & DP_2DINDEXMASK) == inx)
- {
- ds->ds_Prev1DownCode = code;
- ds->ds_Prev1DownQual = deadQuals[ type][ i + 2];
- ds->ds_Prev2DownCode = 0;
- ds->ds_Prev2DownQual = 0;
- return 1;
- }
- }
- }
- }
- while ( ++code < hms);
-
- return 0; /* Not found */
- }
-
- STATIC WORD checkString( UBYTE *keybase, UBYTE val, WORD type, UWORD *qualp)
- {
- WORD i;
- register UBYTE *p = keybase; /* need to remember keybase for offsets */
-
- /* walk through two-byte entries, one for each qual. combo. */
- for ( i = 0; i < deadQuals[ type][ combos]; ++i, p += 2)
- {
- if ( p[ 0] == 1)
- { /* One char in string */
- if ( keybase[ p[ 1]] == val)
- { /* Our char? */
- *qualp = deadQuals[ type][ i + 2];
- return 1;
- }
- }
- }
- return ( 0);
- }
-
- /* BuildEvent tries to generate an input event.
- * returns success ( 1) or failure ( 0).
- */
- STATIC UWORD BuildEvent( register UBYTE value, struct HalfMap *hm, WORD hms, struct InputEvent *ie,
- struct KeyMap *km) /* We need this to find dead prefix */
- {
- register UWORD code = 0;
- register WORD type;
- register LONG *p; /* points to four-byte lokeymap entry */
- UWORD *qualp = &ie->ie_Qualifier;
- WORD found_it = 0;
- ULONG index = 0;
-
- p = ( LONG *) hm->KeyMap;
-
- do
- {
- type = hm->KeyMapTypes[ code];
- /* determine type of key */
- if ( type & KCF_STRING)
- {
- found_it = checkString( ( UBYTE *) * p, value, type & 7, qualp);
- }
- else if ( type & KCF_DEAD)
- {
- found_it = checkDead( ( UBYTE *) * p, value, type & 7, qualp, &index);
- }
- else if ( !( type & KCF_NOP))
- {
- found_it = checkNormal( ( UBYTE *)p, value, type & 7, qualp);
- }
- ++p;
- }
- while ( !found_it && ++code < hms);
-
- if ( found_it)
- {
- ie->ie_Code = code;
- /* Successful BuildEvent. Check for dead key. */
- if ( index)
- {
- struct HalfMap *dhm;
- struct DeadSpec *ds = ( struct DeadSpec *)&ie->ie_EventAddress;
-
- dhm = ( struct HalfMap *)&km->km_LoKeyMapTypes;
- if ( BuildDeadSpec( index, dhm, 64, ds))
- {
- return 1;
- }
- dhm = ( struct HalfMap *)&km->km_HiKeyMapTypes;
- if ( BuildDeadSpec( index, dhm, 56, ds))
- {
- return 1;
- }
- return 0; /* Couldn't find index generating dead key */
- }
- else
- {
- return 1;
- }
- }
- else
- {
- return 0;
- }
- }
-
- /*
- * NAME
- * AsciiToInputEvent -- build input event to generate ascii
- *
- * SYNOPSIS
- * success = AsciiToInputEvent( ascii, inputevent, keymap)
- * ULONG AsciiToInputEvent( ULONG, struct InputEvent *, struct KeyMap *)
- *
- * FUNCTION
- * This function tries to generate an input event that, when sent
- * to the input handler, will generate the specified ascii code.
- *
- * INPUTS
- * ascii - the ascii code to be generated by the constructed
- * input event.
- *
- * inputevent - the input event that will be filled will the
- * appropriate values to generate the given ascii code.
- *
- * keymap - the keymap that the input event will be reverse-
- * engineered from.
- *
- *
- * RESULT
- * success - a boolean value indicating whether the reverse-
- * engineering was successful.
- *
- * NOTE
- * The ascii code must be available in the given keymap to be
- * generatable. Ascii values between 128 and 160 are usually
- * not available with normal keymaps.
- *
- * SEE ALSO
- * RawKeyConvert( ), V36 keymap.library/MapANSI( ).
- */
-
- ULONG AsciiToInputEvent( ULONG ascii, register struct InputEvent *ie, struct KeyMap *km)
- {
- struct HalfMap *hm;
-
- ie->ie_Class = IECLASS_RAWKEY;
- ie->ie_Qualifier = 0;
- ie->ie_EventAddress = 0;
-
- /* Some ascii values has to be treated separately
- since some programs know the difference between
- for example CTRL-M and RETURN. */
- {
- WORD code = 0;
-
- switch ( ascii)
- {
- 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;
- return 1;
- }
- }
-
- hm = ( struct HalfMap *)&km->km_LoKeyMapTypes;
- if ( BuildEvent( ( UBYTE) ascii, hm, 64, ie, km))
- {
- return 1; /* Key found in LoKeyMap */
- }
- hm = ( struct HalfMap *)&km->km_HiKeyMapTypes;
- if ( BuildEvent( ( UBYTE) ascii, hm, 56, ie, km))
- {
- ie->ie_Code += 64; /* Don't forget that we're in the hi keymap */
- return 1; /* Key found in HiKeyMap */
- }
- return 0; /* No luck */
- }
-