home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
keyboard
/
keymacro_436
/
keysupport.c
< prev
next >
Wrap
Text File
|
1991-01-15
|
7KB
|
321 lines
/****************************************************************************
*
* 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);
}
}