home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
552.lha
/
KeyMacro_v1.2
/
KeyMacro.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-08
|
26KB
|
1,307 lines
/****************************************************************************
*
* KeyMacro.c ------------ KeyMacro main process.
*
* 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.
*
****************************************************************************/
/* Buffered IO include. */
#include "MRArpFile.h"
/* Function prototypes. */
VOID SimpleRequest(UBYTE *Args,...);
VOID EraseGadget(struct RastPort *RPort,struct Gadget *Gadget,LONG Colour);
BYTE PopRequest(struct Window *pr_ParentWindow,UBYTE *pr_TitleText,UBYTE *pr_BodyText,UBYTE *pr_PosText,UBYTE *pr_NegText,BYTE pr_Default);
UBYTE * GetToken(UBYTE *s,LONG *start);
struct MacroKey * AddMacroKey(struct MacroKey *MacroKey);
BYTE Interprete(UBYTE *String,LONG Line);
BYTE UpdateList(UBYTE *Name);
BYTE GetDefaultKeyMap(VOID);
BYTE UStrCmp(UBYTE *a,UBYTE *b);
VOID * SendMacroMsg(struct MacroMessage *scm_Msg,struct MsgPort *scm_Port);
VOID * AllocRem(LONG ByteSize,LONG Requirements);
VOID * FreeRem(LONG *MemoryBlock);
ULONG KeyInvert(UBYTE AnsiKey,struct InputEvent *Event,struct KeyMap *KeyMap,BYTE Depth);
VOID main(int argc,UBYTE **argv);
/* The Arp CLI-Interface data. */
UBYTE *CLI_Template = "Startup,Q=Quit/s,D=Delay/k,P=Priority/k,I=Info/s";
UBYTE *CLI_Help = "\nUsage: \33[1mKeyMacro\33[0m <Startup File> [Quit] [Delay <Microseconds>]\n [Priority <Input handler priority>] [Info]\n";
enum { ARG_STARTUP = 1, ARG_QUIT, ARG_DELAY, ARG_PRI, ARG_INFO };
/* Easy macro. */
#define From_CLI (ThatsMe -> pr_CLI)
/* Global and shared data structures. */
extern struct ExecBase *SysBase;
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
struct MSeg *MSeg;
struct MacroKey *KeyList;
/* We use this list to identify the non-ascii keys. */
struct KeyAlias KeyTab[22] =
{
{"TAB", 0x42},
{"ESC", 0x45},
{"SPACE", 0x40},
{"RETURN", 0x44},
{"ENTER", 0x43},
{"DEL", 0x46},
{"BACKSPACE", 0x41},
{"HELP", 0x5F},
{"LEFT", 0x4F},
{"RIGHT", 0x4E},
{"UP", 0x4C},
{"DOWN", 0x4D},
{"F1", 0x50},
{"F2", 0x51},
{"F3", 0x52},
{"F4", 0x53},
{"F5", 0x54},
{"F6", 0x55},
{"F7", 0x56},
{"F8", 0x57},
{"F9", 0x58},
{"F10", 0x59}
};
/* These are the qualifiers. */
struct KeyAlias QualifierTab[9] =
{
{"NONE", 0},
{"CTRL", IEQUALIFIER_CONTROL},
{"NUMPAD", IEQUALIFIER_NUMERICPAD},
{"LSHIFT", IEQUALIFIER_LSHIFT},
{"RSHIFT", IEQUALIFIER_RSHIFT},
{"LALT", IEQUALIFIER_LALT},
{"RALT", IEQUALIFIER_RALT},
{"LAMIGA", IEQUALIFIER_LCOMMAND},
{"RAMIGA", IEQUALIFIER_RCOMMAND}
};
LONG __stdargs
CXBRK(VOID)
{
return(0);
}
VOID
SimpleRequest(UBYTE *Args,...)
{
UBYTE String[512];
va_list VarArgs;
va_start(VarArgs,Args);
ArpVSPrintf(String,Args,VarArgs);
PopRequest(NULL,(UBYTE *)"KeyMacro Request",(UBYTE *)String,NULL,NULL,FALSE);
va_end(VarArgs);
}
VOID
EraseGadget(struct RastPort *RPort,struct Gadget *Gadget,LONG Colour)
{
BYTE FgPen = RPort -> FgPen;
SetAPen(RPort,Colour);
RectFill(RPort,Gadget -> LeftEdge,Gadget -> TopEdge,Gadget -> LeftEdge + Gadget -> Width - 1,Gadget -> TopEdge + Gadget -> Height - 1);
SetAPen(RPort,FgPen);
}
VOID
CalcDimensions(UBYTE *cd_String,LONG *cd_Width,LONG *cd_Height,LONG cd_MaxWidth)
{
LONG i,cd_InLine = 0,cd_NumLines = 0;
*cd_Width = *cd_Height = 0;
for(i = 0 ; i < strlen((UBYTE *)cd_String) ; i++)
{
if(cd_String[i] == '\n' || cd_InLine == cd_MaxWidth)
{
if(cd_InLine > *cd_Width)
*cd_Width = cd_InLine;
cd_NumLines++;
cd_InLine = 0;
continue;
}
if(cd_String[i] == '\33')
{
while(cd_String[i] != 'm' && cd_String[i] != 'w' && i < strlen((UBYTE *)cd_String))
i++;
if(i >= strlen((UBYTE *)cd_String))
i = strlen((UBYTE *)cd_String) - 1;
continue;
}
if(cd_String[i] < ' ')
continue;
cd_InLine++;
}
*cd_Height = cd_NumLines;
if(cd_InLine > *cd_Width)
*cd_Width = cd_InLine;
}
BYTE
WriteConsole(struct Window *wc_Window,UBYTE *wc_String)
{
struct IOStdReq *wc_ConWrite;
struct MsgPort *wc_ConPort;
BYTE wc_Success = FALSE;
if(wc_ConPort = (struct MsgPort *)CreatePort(NULL,0))
{
if(wc_ConWrite = (struct IOStdReq *)CreateStdIO(wc_ConPort))
{
wc_ConWrite -> io_Data = (APTR)wc_Window;
wc_ConWrite -> io_Length = sizeof(struct Window);
if(!OpenDevice("console.device",0,wc_ConWrite,0))
{
wc_ConWrite -> io_Command = CMD_WRITE;
wc_ConWrite -> io_Data = (APTR)"\2330 p";
wc_ConWrite -> io_Length = -1;
DoIO(wc_ConWrite);
wc_ConWrite -> io_Data = (APTR)wc_String;
wc_ConWrite -> io_Length = -1;
DoIO(wc_ConWrite);
wc_Success = TRUE;
CloseDevice(wc_ConWrite);
}
DeleteStdIO(wc_ConWrite);
}
DeletePort(wc_ConPort);
}
return(wc_Success);
}
BYTE
PopRequest(struct Window *pr_ParentWindow,UBYTE *pr_TitleText,UBYTE *pr_BodyText,UBYTE *pr_PosText,UBYTE *pr_NegText,BYTE pr_Default)
{
STATIC struct NewWindow pr_StaticNewWindow =
{
0,0,
0,1,
0,1,
VANILLAKEY | MOUSEBUTTONS | GADGETUP | CLOSEWINDOW | CLOSEWINDOW,
RMBTRAP | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE,
(struct Gadget *)NULL,
(struct Image *)NULL,
(STRPTR)NULL,
(struct Screen *)NULL,
(struct BitMap *)NULL,
0,0,
0,0,
WBENCHSCREEN
};
STATIC struct Gadget pr_StaticGadget =
{
(struct Gadget *)NULL,
0,0,
0,0,
GADGHBOX,
RELVERIFY | GADGIMMEDIATE,
BOOLGADGET,
(APTR)NULL,
(APTR)NULL,
(struct IntuiText *)NULL,
NULL,
(APTR)NULL,
0,
(APTR)NULL
};
STATIC struct TextAttr pr_TextAttr =
{
(UBYTE *)"topaz.font",
8,
FS_NORMAL,
FPF_ROMFONT
};
struct NewWindow *pr_NewWindow;
struct Window *pr_Window;
struct IntuiMessage *pr_IMsg;
struct Gadget *pr_PosGadget = NULL,*pr_NegGadget = NULL,*pr_TempGadget;
struct Screen pr_Screen,*pr_FrontScreen;
struct TextFont *pr_TextFont;
LONG pr_Width,pr_Height;
BYTE pr_Result = FALSE;
ULONG pr_IntuiLock;
if(!pr_BodyText)
return(pr_Result);
if(!(pr_NewWindow = (struct NewWindow *)AllocMem(sizeof(struct NewWindow),MEMF_PUBLIC)))
return(pr_Result);
CopyMem(&pr_StaticNewWindow,pr_NewWindow,sizeof(struct NewWindow));
pr_IntuiLock = LockIBase(NULL);
pr_FrontScreen = IntuitionBase -> FirstScreen;
UnlockIBase(pr_IntuiLock);
if(pr_ParentWindow)
{
pr_NewWindow -> Type = CUSTOMSCREEN;
pr_NewWindow -> Screen = pr_ParentWindow -> WScreen;
}
else
OpenWorkBench();
if(!GetScreenData(&pr_Screen,sizeof(struct Screen),pr_NewWindow -> Type,pr_NewWindow -> Screen))
{
FreeMem(pr_NewWindow,sizeof(struct NewWindow));
return(pr_Result);
}
CalcDimensions(pr_BodyText,&pr_Width,&pr_Height,(pr_Screen . Width - 6) / 8);
if(pr_Height > (pr_Screen . Height - 15 - 13) / 8)
{
FreeMem(pr_NewWindow,sizeof(struct NewWindow));
return(pr_Result);
}
pr_NewWindow -> Width = pr_Width * 8 + 6 + 4;
pr_NewWindow -> Height = pr_Height * 8 + GfxBase -> DefaultFont -> tf_YSize + 7 + 19 + 2;
if(pr_TitleText)
pr_NewWindow -> Title = pr_TitleText;
else
pr_NewWindow -> Title = (UBYTE *)"System Request";
if(!pr_PosText && !pr_NegText)
pr_NegText = (UBYTE *)"Continue?";
if(pr_PosText)
{
if(!(pr_PosGadget = (struct Gadget *)AllocMem(sizeof(struct Gadget),MEMF_PUBLIC)))
{
FreeMem(pr_NewWindow,sizeof(struct NewWindow));
return(pr_Result);
}
CopyMem(&pr_StaticGadget,pr_PosGadget,sizeof(struct Gadget));
pr_PosGadget -> Width = 8 * strlen((UBYTE *)pr_PosText) + 4;
pr_PosGadget -> Height = 8 + 2;
pr_PosGadget -> LeftEdge= 3 + 2 + 3;
pr_PosGadget -> TopEdge = pr_NewWindow -> Height - 13 - 1;
}
if(pr_NegText)
{
if(!(pr_NegGadget = (struct Gadget *)AllocMem(sizeof(struct Gadget),MEMF_PUBLIC)))
{
FreeMem(pr_NewWindow,sizeof(struct NewWindow));
if(pr_PosGadget)
FreeMem(pr_PosGadget,sizeof(struct Gadget));
return(pr_Result);
}
CopyMem(&pr_StaticGadget,pr_NegGadget,sizeof(struct Gadget));
pr_NegGadget -> Width = 8 * strlen((UBYTE *)pr_NegText) + 4;
pr_NegGadget -> Height = 8 + 2;
pr_Width = pr_NegGadget -> Width + 6 + 4 + 6;
if(pr_PosGadget)
pr_Width += (pr_PosGadget -> Width + 12);
if(pr_NewWindow -> Width < pr_Width)
pr_NewWindow -> Width = pr_Width;
pr_NegGadget -> LeftEdge= pr_NewWindow -> Width - pr_NegGadget -> Width - 3 - 2 - 3;
pr_NegGadget -> TopEdge = pr_NewWindow -> Height - 13 - 1;
pr_NegGadget -> GadgetID= 1;
}
if(!pr_NegGadget && pr_NewWindow -> Width < pr_PosGadget -> Width + 6 + 4 + 6)
pr_NewWindow -> Width = pr_PosGadget -> Width + 6 + 4 + 6;
if(pr_Default && !pr_PosGadget)
pr_Default = FALSE;
if(!pr_Default && !pr_NegGadget)
pr_Default = TRUE;
if(pr_Default)
pr_TempGadget = pr_PosGadget;
else
pr_TempGadget = pr_NegGadget;
pr_NewWindow -> LeftEdge= pr_Screen . MouseX - (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2);
pr_NewWindow -> TopEdge = pr_Screen . MouseY - (pr_TempGadget -> TopEdge + pr_TempGadget -> Height / 2);
while(pr_NewWindow -> LeftEdge < 0)
pr_NewWindow -> LeftEdge++;
while(pr_NewWindow -> TopEdge < 0)
pr_NewWindow -> TopEdge++;
while(pr_NewWindow -> LeftEdge + pr_NewWindow -> Width >= pr_Screen . Width)
pr_NewWindow -> LeftEdge--;
while(pr_NewWindow -> TopEdge + pr_NewWindow -> Height >= pr_Screen . Height)
pr_NewWindow -> TopEdge--;
if(!(pr_TextFont = (struct TextFont *)OpenFont(&pr_TextAttr)))
{
if(pr_PosGadget)
FreeMem(pr_PosGadget,sizeof(struct Gadget));
if(pr_NegGadget)
FreeMem(pr_NegGadget,sizeof(struct Gadget));
FreeMem(pr_NewWindow,sizeof(struct NewWindow));
return(pr_Result);
}
if(!(pr_Window = (struct Window *)OpenWindow(pr_NewWindow)))
{
CloseFont(pr_TextFont);
if(pr_PosGadget)
FreeMem(pr_PosGadget,sizeof(struct Gadget));
if(pr_NegGadget)
FreeMem(pr_NegGadget,sizeof(struct Gadget));
FreeMem(pr_NewWindow,sizeof(struct NewWindow));
return(pr_Result);
}
SetFont(pr_Window -> RPort,pr_TextFont);
SetAPen(pr_Window -> RPort,3);
SetBPen(pr_Window -> RPort,2);
SetDrMd(pr_Window -> RPort,JAM2);
WriteConsole(pr_Window,pr_BodyText);
if(pr_PosGadget)
{
AddGadget(pr_Window,pr_PosGadget,1);
EraseGadget(pr_Window -> RPort,pr_PosGadget,2);
Move(pr_Window -> RPort,pr_PosGadget -> LeftEdge + 2,pr_PosGadget -> TopEdge + 1 + pr_TextFont -> tf_Baseline);
Text(pr_Window -> RPort,(UBYTE *)pr_PosText,strlen((UBYTE *)pr_PosText));
}
if(pr_NegGadget)
{
AddGadget(pr_Window,pr_NegGadget,1);
EraseGadget(pr_Window -> RPort,pr_NegGadget,2);
Move(pr_Window -> RPort,pr_NegGadget -> LeftEdge + 2,pr_NegGadget -> TopEdge + 1 + pr_TextFont -> tf_Baseline);
Text(pr_Window -> RPort,(UBYTE *)pr_NegText,strlen((UBYTE *)pr_NegText));
}
MoveScreen(pr_Window -> WScreen,0,- pr_Window -> WScreen -> TopEdge);
ScreenToFront(pr_Window -> WScreen);
ActivateWindow(pr_Window);
Skip1: FOREVER
{
ULONG pr_Class,pr_Code;
struct Gadget *pr_Gadget;
WaitPort(pr_Window -> UserPort);
if(pr_IMsg = (struct IntuiMessage *)GetMsg(pr_Window -> UserPort))
{
pr_Class = pr_IMsg -> Class;
pr_Code = pr_IMsg -> Code;
pr_Gadget = (struct Gadget *)pr_IMsg -> IAddress;
if(pr_Class == VANILLAKEY)
pr_Code = toupper(pr_Code);
ReplyMsg(pr_IMsg);
if(pr_Class == GADGETUP)
{
if(pr_Gadget -> GadgetID == 0)
pr_Result = TRUE;
break;
}
if(pr_Class == CLOSEWINDOW)
break;
if(pr_Class == VANILLAKEY)
{
pr_Code = toupper(pr_Code);
if((pr_Code == 'Y' || pr_Code == 'J' || pr_Code == 'V' || pr_Code == 'C' || pr_Code == 'R' || pr_Code == '\r') && pr_PosText)
{
pr_Result = TRUE;
break;
}
if((pr_Code == 'N' || pr_Code == 'Q' || pr_Code == 'B' || pr_Code == '\33') && pr_NegText)
break;
continue;
}
}
}
CloseFont(pr_TextFont);
if(pr_PosGadget)
{
RemoveGadget(pr_Window,pr_PosGadget);
FreeMem(pr_PosGadget,sizeof(struct Gadget));
}
if(pr_NegGadget)
{
RemoveGadget(pr_Window,pr_NegGadget);
FreeMem(pr_NegGadget,sizeof(struct Gadget));
}
FreeMem(pr_NewWindow,sizeof(struct NewWindow));
pr_IntuiLock = LockIBase(NULL);
if(pr_FrontScreen == IntuitionBase -> FirstScreen)
pr_FrontScreen = NULL;
UnlockIBase(pr_IntuiLock);
if(pr_FrontScreen)
ScreenToFront(pr_FrontScreen);
CloseWindow(pr_Window);
return(pr_Result);
}
/* UStrCmp():
*
* strcmp function which ignores case.
*/
BYTE
UStrCmp(UBYTE *a,UBYTE *b)
{
for( ; ToUpper(*a) == ToUpper(*b) ; a++, b++)
{
if(!(*a))
return(0);
}
return(1);
}
/* GetToken(s,start):
*
* Parse a string and split it into single tokens.
*/
UBYTE *
GetToken(UBYTE *s,LONG *start)
{
static UBYTE buffer[256];
LONG i,end = 0,quote = FALSE,maxlen = strlen(s);
UBYTE t;
if(maxlen > 255)
maxlen = 255;
if(*start > strlen(s) - 1 || !strlen(s) || !s)
return(NULL);
for(i = *start ; i <= maxlen ; i++)
{
if(!end && (s[i] == ' ' || s[i] == '\t'))
{
while((s[i] == ' ' || s[i] == '\t') && i < maxlen)
{
i++;
(*start)++;
}
}
t = s[i];
if(!end && t == '+')
{
(*start)++;
continue;
}
if(!end && t == '=')
{
strcpy(buffer,"=");
(*start)++;
return(buffer);
}
if(s[i] == '\\' && s[i + 1] == '\"')
{
i += 2;
end = i - *start + 1;
t = s[i];
}
if(t == '\"' && !quote)
{
quote = TRUE;
(*start)++;
end++;
continue;
}
if((t == '+' || t == '=' || t == ' ' || t == '\t' || t == ';') && quote)
{
end++;
continue;
}
if((t == '+' || t == '\n' || t == '=' || t == ' ' || t == 0) || (t == '\"' && quote) || (t == ';' && !quote))
{
if(t == ';' && !end)
return(NULL);
if(t == '\"')
{
strncpy(buffer,s + *start,end - 1);
buffer[end - 1] = 0;
}
else
{
strncpy(buffer,s + *start,end);
buffer[end] = 0;
}
(*start) += end;
return(buffer);
}
end++;
}
return(NULL);
}
/* AddMacroKey(MacroKey):
*
* Add a macro key to the big list.
*/
struct MacroKey *
AddMacroKey(struct MacroKey *TheKey)
{
struct MacroKey *MacroKey;
if(MacroKey = (struct MacroKey *)AllocRem(sizeof(struct MacroKey),MEMF_PUBLIC|MEMF_CLEAR))
{
ObtainSemaphore(&MSeg -> MacroSemaphore);
if(MSeg -> NumMacros == MSeg -> MaxMacros)
{
struct MacroKey **MacroList;
if(MacroList = (struct MacroKey **)AllocRem((MSeg -> MaxMacros + 10) * sizeof(struct MacroKey *),MEMF_PUBLIC|MEMF_CLEAR))
{
if(MSeg -> MacroList)
{
LONG i;
for(i = 0 ; i < MSeg -> NumMacros ; i++)
MacroList[i] = MSeg -> MacroList[i];
FreeRem(MSeg -> MacroList);
}
MSeg -> MacroList = MacroList;
MSeg -> MaxMacros += 10;
}
else
{
FreeRem(MacroKey);
return(NULL);
}
}
MSeg -> MacroList[MSeg -> NumMacros++] = MacroKey;
CopyMem(TheKey,MacroKey,sizeof(struct MacroKey));
ReleaseSemaphore(&MSeg -> MacroSemaphore);
return(MacroKey);
}
return(NULL);
}
/* Interprete(String,Line):
*
* Interprete a command line from the config file.
*/
BYTE
Interprete(UBYTE *String,LONG Line)
{
ULONG Qualifier = 0;
ULONG Code = -1;
struct InputEvent FakeEvent;
struct MacroKey NewKey;
LONG Start = 0,Key = FALSE,i,KeyCount = 0;
volatile LONG QuitLoop;
UBYTE *Token,*CommandString,*WindowName = NULL,Recognized = FALSE;
UBYTE KeyBuff1[40],KeyBuff2[40];
if(String[strlen(String) - 1] == '\n')
String[strlen(String) - 1] = 0;
if(Token = GetToken(String,&Start))
{
if(!UStrCmp("KEY",Token))
Key = TRUE;
if(UStrCmp("COMMAND",Token) && !Key)
{
SimpleRequest("Line %ld: Unknown keyword:\n\n'%s'",Line,String);
return(FALSE);
}
}
else
return(TRUE);
FOREVER
{
if(Token = GetToken(String,&Start))
{
QuitLoop = TRUE;
for(i = 0 ; i < 9 ; i++)
{
if(!UStrCmp(QualifierTab[i] . ka_Name,Token))
{
Recognized = TRUE;
QuitLoop = FALSE;
Qualifier |= QualifierTab[i] . ka_Key;
}
}
}
else
break;
if(QuitLoop)
break;
}
if(!Recognized)
{
SimpleRequest("Line %ld: Didn't recognize qualifier:\n\n'%s'",Line,String);
return(FALSE);
}
if(Token)
goto JumpIn;
if(Token = GetToken(String,&Start))
{
JumpIn: for(i = 0 ; i < 22 ; i++)
{
if(!UStrCmp(KeyTab[i] . ka_Name,Token))
{
Code = KeyTab[i] . ka_Key;
goto Next;
}
}
if(KeyInvert(Token[0],&FakeEvent,MSeg -> DefaultKeyMap,1))
Code = FakeEvent . ie_Code;
}
if(Code == -1)
{
SimpleRequest("Line %ld: Didn't recognize key:\n\n'%s'",Line,String);
return(FALSE);
}
Next: FOREVER
{
if(Token = GetToken(String,&Start))
{
if(!UStrCmp("=",Token))
break;
}
else
{
SimpleRequest("Line %ld: Statement '=' missing:\n\n'%s'",Line,String);
return(FALSE);
}
}
if(Token = GetToken(String,&Start))
strcpy(KeyBuff1,Token);
else
{
SimpleRequest("Line %ld: Didn't find macro:\n\n'%s'",Line,String);
return(FALSE);
}
if(Key)
goto AddIt;
if(!(Token = GetToken(String,&Start)))
goto AddIt;
if(UStrCmp("WINDOW",Token))
{
SimpleRequest("Line %ld: Didn't recognize 'WINDOW' statement:\n\n'%s'",Line,String);
return(FALSE);
}
if(!(Token = GetToken(String,&Start)))
{
SimpleRequest("Line %ld: Didn't find window title:\n\n'%s'",Line,String);
return(FALSE);
}
if(!(WindowName = (UBYTE *)AllocRem(strlen(Token) + 1,MEMF_PUBLIC)))
{
SimpleRequest("Can't allocate memory chunk!");
return(FALSE);
}
strcpy(WindowName,Token);
AddIt: for(i = 0 ; i < strlen(KeyBuff1) ; i++)
{
UBYTE c;
if(KeyBuff1[i] != '\\')
{
KeyBuff2[KeyCount++] = KeyBuff1[i];
continue;
}
if(i == strlen(KeyBuff1) - 1)
break;
i++;
c = 0;
switch(ToUpper(KeyBuff1[i]))
{
case 'U': c = KC_CURSORUP;
break;
case 'D': c = KC_CURSORDOWN;
break;
case 'L': c = KC_CURSORLEFT;
break;
case 'R': c = KC_CURSORRIGHT;
break;
case 'H': c = KC_HELP;
break;
case 'B': c = 8;
break;
case 'E': c = 127;
break;
case 'F': if(i == strlen(KeyBuff1) - 1)
break;
i++;
if(!isdigit(KeyBuff1[i]))
break;
if(!KeyBuff1[i] == '1')
{
c = KC_FKEY1 + KeyBuff1[i] - '1';
break;
}
if(i == strlen(KeyBuff1) - 1)
break;
i++;
if(!isdigit(KeyBuff1[i]))
{
c = KC_FKEY1;
break;
}
if(KeyBuff1[i] != '0')
break;
c = KC_FKEY10;
break;
case 'N': c = '\n';
break;
case '\\': c = '\\';
break;
default: c = KeyBuff1[i];
break;
}
if(c)
KeyBuff2[KeyCount++] = c;
}
KeyBuff2[KeyCount] = 0;
if(!(CommandString = (UBYTE *)AllocRem(strlen(KeyBuff2) + 1,MEMF_PUBLIC)))
{
SimpleRequest("Can't allocate memory chunk!");
FreeRem(WindowName);
return(FALSE);
}
strcpy(CommandString,KeyBuff2);
memset(&NewKey,0,sizeof(struct MacroKey));
NewKey . mk_CommandKey = Code;
NewKey . mk_CommandQualifier = Qualifier;
NewKey . mk_String = CommandString;
NewKey . mk_Window = WindowName;
if(Key)
NewKey . mk_Type = MK_WORD;
else
NewKey . mk_Type = MK_COMMAND;
if(AddMacroKey(&NewKey))
return(TRUE);
SimpleRequest("Line %ld: Key macro table full.",Line);
return(FALSE);
}
/* UpdateList(Name):
*
* Update the big macro key list.
*/
BYTE
UpdateList(UBYTE *Name)
{
UBYTE LineBuff[257];
LONG LineNum = 1;
ARPFileHandle *ConfigFile;
if(!Name)
Name = "S:KeyMacro.config";
GetDefaultKeyMap();
if(ConfigFile = OpenARPFile(Name,MODE_OLDFILE,976))
{
if(MSeg -> MacroList)
{
LONG i;
ObtainSemaphore(&MSeg -> MacroSemaphore);
for(i = 0 ; i < MSeg -> NumMacros ; i++)
{
if(MSeg -> MacroList[i])
{
if(MSeg -> MacroList[i] -> mk_String)
FreeRem(MSeg -> MacroList[i] -> mk_String);
if(MSeg -> MacroList[i] -> mk_Window)
FreeRem(MSeg -> MacroList[i] -> mk_Window);
FreeRem(MSeg -> MacroList[i]);
}
}
FreeRem(MSeg -> MacroList);
MSeg -> MacroList = NULL;
MSeg -> NumMacros = MSeg -> MaxMacros = 0;
ReleaseSemaphore(&MSeg -> MacroSemaphore);
}
while(FGetsARP(LineBuff,256,ConfigFile))
{
if(!Interprete(LineBuff,LineNum++))
{
CloseARPFile(ConfigFile);
return(FALSE);
}
}
CloseARPFile(ConfigFile);
}
else
{
SimpleRequest("Couldn't open configuration file!");
FreeRem(KeyList);
return(FALSE);
}
return(TRUE);
}
BYTE
GetDefaultKeyMap()
{
struct IOStdReq *ConsoleRequest;
struct MsgPort *ConsolePort;
BYTE Result = FALSE;
if(ConsolePort = CreatePort(NULL,0))
{
if(ConsoleRequest = CreateStdIO(ConsolePort))
{
if(!OpenDevice("console.device",CONU_STANDARD,ConsoleRequest,0))
{
ConsoleRequest -> io_Command = CD_ASKDEFAULTKEYMAP;
ConsoleRequest -> io_Length = sizeof(struct KeyMap);
ConsoleRequest -> io_Data = (APTR)MSeg -> DefaultKeyMap;
ConsoleRequest -> io_Flags = IOF_QUICK;
if(!DoIO(ConsoleRequest))
Result = TRUE;
CloseDevice(ConsoleRequest);
}
DeleteStdIO(ConsoleRequest);
}
DeletePort(ConsolePort);
}
return(Result);
}
/* main(argc,argv):
*
* The entry point to this program.
*/
VOID
main(int argc,UBYTE **argv)
{
struct Process *ThatsMe = (struct Process *)SysBase -> ThisTask;
UBYTE *FileName = argv[ARG_STARTUP];
LONG Created = FALSE;
LONG i;
/* Started from Workbench? */
if(!From_CLI)
FileName = NULL;
/* Look if handler process is already running. */
MSeg = (struct MSeg *)FindPort(PORTNAME);
/* Short info? */
if(argv[ARG_INFO])
{
Printf("\n\33[1m\33[33mKeyMacro\33[31m\33[0m the Amiga macro key handler.\n\n");
Printf(" This program may be non-commercially\n");
Printf(" redistributed!\n\n");
Printf("\33[1m\33[33mAuthor\33[31m\33[0m - Olaf Barthel, MXM\n");
Printf(" Brabeckstrasse 35\n");
Printf(" D-3000 Hannover 71\n\n");
Printf(" Federal Republic of Germany.\n\n");
exit(RETURN_OK);
}
/* Remove the handler? */
if(argv[ARG_QUIT])
{
Printf("Removing \33[1m\33[33mKeyMacro\33[31m\33[0m, ");
if(!MSeg)
{
Printf("failed!\a\n");
exit(RETURN_OK);
}
MSeg -> Father = (struct Task *)SysBase -> ThisTask;
if(MSeg -> Child)
{
Signal(MSeg -> Child,SIG_CLOSE);
Wait(SIG_CLOSE);
}
RemPort(&MSeg -> Port);
FreeMem(MSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME));
if(MSeg -> Segment)
UnLoadSeg(MSeg -> Segment);
if(MSeg -> MacroList)
{
for(i = 0 ; i < MSeg -> NumMacros ; i++)
{
if(MSeg -> MacroList[i])
{
if(MSeg -> MacroList[i] -> mk_String)
FreeRem(MSeg -> MacroList[i] -> mk_String);
if(MSeg -> MacroList[i] -> mk_Window)
FreeRem(MSeg -> MacroList[i] -> mk_Window);
FreeRem(MSeg -> MacroList[i]);
}
}
FreeRem(MSeg -> MacroList);
}
FreeRem(MSeg -> DefaultKeyMap);
FreeRem(MSeg);
Printf("OK.\n");
exit(RETURN_OK);
}
/* Allocate the handler data. */
if(!MSeg)
{
if(MSeg = (struct MSeg *)AllocRem(sizeof(struct MSeg),MEMF_PUBLIC | MEMF_CLEAR))
{
MSeg -> Port . mp_Flags = PA_IGNORE;
MSeg -> Port . mp_Node . ln_Pri = 0;
MSeg -> Port . mp_Node . ln_Type = NT_MSGPORT;
MSeg -> Port . mp_Node . ln_Name = AllocMem(sizeof(PORTNAME),MEMF_PUBLIC);
MSeg -> Child = NULL;
MSeg -> Father = (struct Task *)SysBase -> ThisTask;
MSeg -> SegSize = sizeof(struct MSeg);
MSeg -> RingBack = SIGBREAKF_CTRL_C;
MSeg -> Revision = REVISION;
if(argv[ARG_PRI])
MSeg -> Pri = Atol(argv[ARG_PRI]);
else
MSeg -> Pri = 51;
NewList(&MSeg -> Port . mp_MsgList);
InitSemaphore(&MSeg -> MacroSemaphore);
if(From_CLI)
{
Printf("\33[1m\33[33mKeyMacro v1.%ld \33[31m\33[0m© Copyright 1989, 1990 by \33[4mMXM\33[0m, All rights reserved.\n",REVISION);
Printf("Installing \33[33m\33[1mKeyMacro\33[0m\33[31m, ");
}
if(MSeg -> Port . mp_Node . ln_Name)
strcpy(MSeg -> Port . mp_Node . ln_Name,PORTNAME);
else
{
Failed: FreeRem(MSeg);
if(From_CLI)
Printf("failed!\a\n");
exit(RETURN_FAIL);
}
if(!(MSeg -> DefaultKeyMap = (struct KeyMap *)AllocPub(sizeof(struct KeyMap))))
goto Failed;
if(!(MSeg -> Segment = LoadSeg("KeyMacro-Handler")))
MSeg -> Segment = LoadSeg("L:KeyMacro-Handler");
if(!MSeg -> Segment)
{
if(From_CLI)
Printf("unable to find \33[33mL:KeyMacro-Handler\33[31m\a!\n");
FreeRem(MSeg -> DefaultKeyMap);
FreeRem(MSeg -> Port . mp_Node . ln_Name);
FreeRem(MSeg);
exit(RETURN_FAIL);
}
else
{
AddPort(&MSeg -> Port);
if(!CreateProc("KeyMacro-Handler",10,MSeg -> Segment,4096))
goto NoMem;
Wait(SIGBREAKF_CTRL_C);
if(!MSeg -> Child)
{
NoMem: if(From_CLI)
Printf("\33[33mFAILED!\33[31m (care to retry?)\n");
RemPort(&MSeg -> Port);
FreeRem(MSeg -> DefaultKeyMap);
FreeRem(MSeg -> Port . mp_Node . ln_Name);
if(MSeg -> Segment)
UnLoadSeg(MSeg -> Segment);
FreeRem(MSeg);
exit(RETURN_FAIL);
}
else
{
if(From_CLI)
Printf("initializing, ");
GetDefaultKeyMap();
if(From_CLI)
Puts("Okay.");
else
SimpleRequest("\33[1mKeyMacro\33[0m installed.");
Created = TRUE;
}
}
}
}
if(argv[ARG_DELAY])
{
LONG Value = Atol(argv[ARG_DELAY]);
if(Value)
{
if(Value < 10000)
{
if(From_CLI)
Printf("\33[1mKeyMacro:\33[0m Delay value too small - must be >= 10000!\n");
exit(RETURN_ERROR);
}
}
MSeg -> Delay = Value;
}
/* Update the macro key list. */
if(!Created && From_CLI)
{
Printf("\33[1mKeyMacro:\33[0m Updating macro keys... ");
if(!UpdateList(FileName))
{
Printf("FAILED!\a\n");
exit(RETURN_ERROR);
}
else
Printf("Done.\n");
}
else
{
if(!UpdateList(FileName))
exit(RETURN_ERROR);
}
exit(RETURN_OK);
}