home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * KeySupport.c ---------- Keymacro support routines.
- *
- * Author ---------------- Olaf Barthel, MXM
- * Brabeckstrasse 35
- * D-3000 Hannover 71
- *
- * KeyMacro © Copyright 1990 by MXM; Executable program,
- * documentation and source code are shareware. If you like
- * this program a small donation will entitle you to receive
- * updates and new programs from MXM.
- *
- ****************************************************************************/
-
- /* AllocRem():
- *
- * Allocate public memory and keep track of its size.
- */
-
- VOID *
- AllocRem(LONG ByteSize,LONG Requirements)
- {
- LONG *MemoryBlock = NULL;
- LONG RemSize = ByteSize + sizeof(LONG);
-
- if(ByteSize > 0)
- MemoryBlock = (LONG *)AllocMem(RemSize,Requirements);
-
- if(MemoryBlock)
- *MemoryBlock++ = RemSize;
-
- return((VOID *)MemoryBlock);
- }
-
- /* FreeRem():
- *
- * Free a tracked portion of memory.
- */
-
- VOID *
- FreeRem(LONG *MemoryBlock)
- {
- if(MemoryBlock--)
- FreeMem(MemoryBlock,*MemoryBlock);
-
- return(NULL);
- }
-
- /* SendMacroMsg(scm_Msg,scm_Port):
- *
- * Post a cloned macro message to a MsgPort.
- */
-
- VOID *
- SendMacroMsg(struct MacroMessage *scm_Msg,struct MsgPort *scm_Port)
- {
- struct MacroMessage *scm_TempMsg;
-
- if(scm_TempMsg = (struct MacroMessage *)AllocRem(sizeof(struct MacroMessage),MEMF_PUBLIC | MEMF_CLEAR))
- {
- CopyMem(scm_Msg,scm_TempMsg,sizeof(struct MacroMessage));
-
- scm_TempMsg -> mm_Message . mn_Node . ln_Name = (char *)scm_TempMsg;
- scm_TempMsg -> mm_Message . mn_ReplyPort = NULL;
- scm_TempMsg -> mm_Message . mn_Length = sizeof(struct MacroMessage);
-
- PutMsg(scm_Port,(struct Message *)scm_TempMsg);
- }
-
- return((VOID *)scm_TempMsg);
- }
-
- /* PackQualifiers():
- *
- * Pack a couple of qualifiers indicated by a keymap
- * qualifier tag (sortof).
- */
-
- STATIC UWORD
- PackQualifiers(BYTE Bits)
- {
- UWORD Qualifier = 0;
-
- if(Bits & KCF_SHIFT)
- Qualifier |= IEQUALIFIER_LSHIFT;
-
- if(Bits & KCF_ALT)
- Qualifier |= IEQUALIFIER_LALT;
-
- if(Bits & KCF_CONTROL)
- Qualifier |= IEQUALIFIER_CONTROL;
-
- return(Qualifier);
- }
-
- /* ScanKeyMap():
- *
- * Scan a given part of the keymap area and handle the
- * necessary Ansi<->InputEvent conversion.
- */
-
- BYTE
- ScanKeyMap(UBYTE Hi,UBYTE Offset,UBYTE *KeyTable,UBYTE *KeyTypes,UBYTE AnsiKey,struct InputEvent *Event)
- {
- /* This table contains the qualifiers associated with
- * the various KeyType flag bits.
- */
-
- STATIC struct {
- UBYTE QualBits;
- UWORD Qualifiers[4];
- } QualType[8] = {
- KC_NOQUAL, 0, 0, 0, 0,
- KCF_SHIFT, 0, 0, IEQUALIFIER_LSHIFT, 0,
- KCF_ALT, 0, 0, IEQUALIFIER_LALT, 0,
- KCF_CONTROL, 0, 0, IEQUALIFIER_CONTROL, 0,
- KCF_ALT|KCF_SHIFT, IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT, IEQUALIFIER_LALT, IEQUALIFIER_LSHIFT, 0,
- KCF_CONTROL|KCF_ALT, IEQUALIFIER_CONTROL|IEQUALIFIER_LALT, IEQUALIFIER_CONTROL, IEQUALIFIER_LALT, 0,
- KCF_CONTROL|KCF_SHIFT, IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT, IEQUALIFIER_CONTROL, IEQUALIFIER_LSHIFT, 0,
- KC_VANILLA, IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT, IEQUALIFIER_LALT, IEQUALIFIER_LSHIFT, 0
- };
-
- BYTE *String;
- SHORT i,j,k;
-
- /* Scan the area. */
-
- for(i = 0 ; i < Hi ; i++)
- {
- /* This one's a dead key or dead-key-modifiable. */
-
- if(KeyTypes[i] & KCF_DEAD)
- {
- String = (BYTE *)(((ULONG *)KeyTable)[i]);
-
- /* There a eight two-byte-pairs. The first
- * byte indicates the type of the dead
- * key.
- */
-
- for(j = 0 ; j < 8 ; j++)
- {
- switch(String[2 * j])
- {
- /* Vanilla key. */
-
- case 0: if((UBYTE)String[2 * j + 1] == AnsiKey)
- {
- Event -> ie_Qualifier = PackQualifiers(j);
- Event -> ie_Code = Offset + i;
-
- return(TRUE);
- }
-
- break;
-
- /* Dead key modifiable, let's hope
- * that the first character in
- * the table indicates our ansi key.
- */
-
- case DPF_MOD: if((UBYTE)String[String[2 * j + 1]] == AnsiKey)
- {
- Event -> ie_Qualifier = PackQualifiers(j);
- Event -> ie_Code = Offset + i;
-
- return(TRUE);
- }
-
- break;
-
- /* Ignore the rest. */
-
- default: break;
- }
- }
- }
-
- /* Is a string mapped to this key? */
-
- if(KeyTypes[i] & KCF_STRING)
- {
- String = (BYTE *)(((ULONG *)KeyTable)[i]);
-
- /* We need only 1 character strings. */
-
- if(String[0] == 1)
- {
- if((UBYTE)String[String[1]] == AnsiKey)
- {
- for(k = 0 ; k < 8 ; k++)
- {
- if(QualType[k] . QualBits == (KeyTypes[i] & KC_VANILLA))
- {
- Event -> ie_Qualifier = QualType[k] . Qualifiers[j];
- Event -> ie_Code = Offset + i;
-
- return(TRUE);
- }
- }
- }
- }
-
- /* Find the approriate qualifier. */
-
- for(j = 0 ; j < 3 ; j++)
- {
- if(KeyTypes[i] & (1 << j))
- {
- if(String[2 + (2 * j)] == 1)
- {
- if((UBYTE)String[String[3 + (2 * j)]] == AnsiKey)
- {
- for(k = 0 ; k < 8 ; k++)
- {
- if(QualType[k] . QualBits == (KeyTypes[i] & KC_VANILLA))
- {
- Event -> ie_Qualifier = QualType[k] . Qualifiers[j];
- Event -> ie_Code = Offset + i;
-
- return(TRUE);
- }
- }
- }
- }
- }
- }
- }
- else
- {
- /* It's a fair vanilla key. */
-
- for(j = 0 ; j < 4 ; j++)
- {
- if(AnsiKey == KeyTable[4 * i + j])
- {
- for(k = 0 ; k < 8 ; k++)
- {
- if(QualType[k] . QualBits == KeyTypes[i])
- {
- Event -> ie_Qualifier = QualType[k] . Qualifiers[j];
- Event -> ie_Code = Offset + i;
-
- return(TRUE);
- }
- }
- }
- }
- }
- }
-
- return(FALSE);
- }
-
- STATIC VOID
- PutKey(struct InputEvent *Event,UBYTE RawKey)
- {
- Event -> ie_Qualifier = 0;
- Event -> ie_Code = RawKey;
- }
-
- /* KeyInvert():
- *
- * Find the qualifier & code which generate the Ansi
- * character passed to this routine.
- */
-
- BYTE
- KeyInvert(UBYTE AnsiKey,struct InputEvent *Event,struct KeyMap *KeyMap)
- {
- /* Careful: if this is actually a control character
- * (return, escape, etc.) we will check the
- * high keymap table first, else the low
- * keymap table.
- */
-
- switch(AnsiKey)
- {
- case ' ': PutKey(Event,0x40);
- return(TRUE);
-
- case '\b': PutKey(Event,0x41);
- return(TRUE);
-
- case '\t': PutKey(Event,0x42);
- return(TRUE);
-
- case '\n':
- case '\r': PutKey(Event,0x44);
- return(TRUE);
-
- case '\33': PutKey(Event,0x45);
- return(TRUE);
-
- case '\177': PutKey(Event,0x46);
- return(TRUE);
- /*
- This does - strange enough - not work correctly. Can you
- discover why?
-
- case ' ':
- case '\b':
- case '\t':
- case '\n':
- case '\r':
- case '\33':
- case '\177': if(!ScanKeyMap(0x28,0x40,KeyMap -> km_HiKeyMap,KeyMap -> km_HiKeyMapTypes,AnsiKey,Event))
- return(ScanKeyMap(0x40,0x00,KeyMap -> km_LoKeyMap,KeyMap -> km_LoKeyMapTypes,AnsiKey,Event));
- else
- return(TRUE);
- */
- /* Check the low keymap table first. */
-
- default: if(!ScanKeyMap(0x40,0x00,KeyMap -> km_LoKeyMap,KeyMap -> km_LoKeyMapTypes,AnsiKey,Event))
- return(ScanKeyMap(0x28,0x40,KeyMap -> km_HiKeyMap,KeyMap -> km_HiKeyMapTypes,AnsiKey,Event));
- else
- return(TRUE);
- }
- }
-