home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * 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.
- *
- ****************************************************************************/
-
- #include <libraries/arpbase.h>
-
- /* Function prototypes. */
-
- VOID * SendMacroMsg(struct MacroMessage *);
- UBYTE * GetToken(UBYTE *,LONG *);
- struct MacroKey * AddMacroKey(struct MacroKey *);
- LONG Interprete(UBYTE *,LONG);
- LONG UpdateList(char *);
-
- VOID main(LONG,char **);
-
- /* The Arp CLI-Interface data. */
-
- char *CLI_Template = "STARTUP/K,QUIT/S,INFO/S";
- char *CLI_Help = "\nUsage: \33[1mKeyMacro\33[0m [STARTUP <File>] [QUIT] [INFO]\n";
-
- #define ARG_STARTUP 1
- #define ARG_QUIT 2
- #define ARG_INFO 3
- #define ARG_UPDATE 4
-
- /* Easy macro. */
-
- #define From_CLI (ThatsMe -> pr_CLI)
-
- /* Global and shared data structures. */
-
- struct MXMBase *MXMBase;
- extern struct ArpBase *ArpBase;
- struct MSeg *MSeg;
- struct MacroKey *KeyList;
- extern struct ExecBase *SysBase;
-
- /* 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}
- };
-
- /* SendMacroMsg(scm_Msg,scm_Port):
- *
- * Post a cloned macro message to a MsgPort.
- */
-
- VOID *
- SendMacroMsg(struct MacroMessage *scm_Msg)
- {
- struct MacroMessage *scm_TempMsg = (struct MacroMessage *)AllocRem(sizeof(struct MacroMessage),MEMF_PUBLIC | MEMF_CLEAR);
-
- if(scm_TempMsg)
- {
- 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(&MSeg -> Port,(struct Message *)scm_TempMsg);
- }
-
- return((VOID *)scm_TempMsg);
- }
-
- /* 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);
- char 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 *MacroKey)
- {
- struct MacroKey *TheKey = NULL;
- LONG i;
-
- for(i = 0 ; i < MSeg -> NumMacros ; i++)
- {
- if(KeyList[i] . mk_Type == MK_UNUSED)
- {
- TheKey = &KeyList[i];
- break;
- }
- }
-
- if(!TheKey)
- return(NULL);
-
- CopyMem(MacroKey,TheKey,sizeof(struct MacroKey));
-
- return(TheKey);
- }
-
- /* Interprete(String,Line):
- *
- * Interprete a command line from the config file.
- */
-
- LONG
- 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 MessBuff[256],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)
- {
- SPrintf(MessBuff,"Line %ld: Unknown keyword:\n\n'%s'",Line,String);
-
- PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
- 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)
- {
- SPrintf(MessBuff,"Line %ld: Didn't recognize qualifier:\n\n'%s'",Line,String);
-
- PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
- 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(InvertKey(Token[0],&FakeEvent,IK_USEIKM,NULL))
- Code = FakeEvent . ie_Code;
- }
-
- if(Code == -1)
- {
- SPrintf(MessBuff,"Line %ld: Didn't recognize key:\n\n'%s'",Line,String);
-
- PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
- return(FALSE);
- }
-
- Next: FOREVER
- {
- if(Token = GetToken(String,&Start))
- {
- if(!UStrCmp("=",Token))
- break;
- }
- else
- {
- SPrintf(MessBuff,"Line %ld: Statement '=' missing:\n\n'%s'",Line,String);
-
- PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
- return(FALSE);
- }
- }
-
- if(Token = GetToken(String,&Start))
- strcpy(KeyBuff1,Token);
- else
- {
- SPrintf(MessBuff,"Line %ld: Didn't find macro:\n\n'%s'",Line,String);
-
- PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
- return(FALSE);
- }
-
- if(Key)
- goto AddIt;
-
- if(!(Token = GetToken(String,&Start)))
- goto AddIt;
-
- if(UStrCmp("WINDOW",Token))
- {
- SPrintf(MessBuff,"Line %ld: Didn't recognize 'WINDOW' statement:\n\n'%s'",Line,String);
-
- PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
- return(FALSE);
- }
-
- if(!(Token = GetToken(String,&Start)))
- {
- SPrintf(MessBuff,"Line %ld: Didn't find window title:\n\n'%s'",Line,String);
-
- PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
- return(FALSE);
- }
-
- if(!(WindowName = (UBYTE *)AllocRem(strlen(Token) + 1,MEMF_PUBLIC)))
- {
- PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
- 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)))
- {
- PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
- 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);
-
- SPrintf(MessBuff,"Line %ld: Key macro table full.",Line);
-
- PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
- return(FALSE);
- }
-
- /* UpdateList(Name):
- *
- * Update the big macro key list.
- */
-
- LONG
- UpdateList(char *Name)
- {
- char LineBuff[256];
- LONG LineNum = 1;
- FILE *ConfigFile;
-
- if(!Name)
- Name = "S:KeyMacro.config";
-
- if(!(KeyList = (struct MacroKey *)AllocRem(sizeof(struct MacroKey) * MAXMACROS,MEMF_PUBLIC | MEMF_CLEAR)))
- {
- PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
- return(FALSE);
- }
-
- MSeg -> NumMacros = MAXMACROS;
-
- if(ConfigFile = fopen(Name,"r"))
- {
- while(fgets(LineBuff,256,ConfigFile))
- {
- if(!Interprete(LineBuff,LineNum++))
- {
- fclose(ConfigFile);
-
- FreeRem(KeyList);
-
- return(FALSE);
- }
- }
-
- fclose(ConfigFile);
- }
- else
- {
- PopRequest(NULL,"KeyMacro Problem:","Couldn't open configuration file!",NULL,"Continue?",FALSE,NULL);
- return(FALSE);
- }
-
- return(TRUE);
- }
-
- /* main(argc,argv):
- *
- * The entry point to this program.
- */
-
- VOID
- main(LONG argc,char **argv)
- {
- struct Process *ThatsMe = (struct Process *)SysBase -> ThisTask;
- LONG Created = FALSE;
- char *FileName = argv[ARG_STARTUP];
- LONG i;
-
- /* No ^C trapping, please. */
-
- Enable_Abort = FALSE;
-
- /* Started from Workbench? */
-
- if(!From_CLI)
- FileName = NULL;
-
- /* Try to open mxm.library. */
-
- if(!(MXMBase = (struct MXMBase *)OpenLibrary("mxm.library",34)))
- {
- if(From_CLI)
- Puts("\33[1mKeyMacro:\33[0m You need \33[1mmxm.library\33[0m 34.12 or higher to run this program.");
-
- exit(RETURN_FAIL);
- }
-
- /* 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");
-
- CloseLibrary((struct Library *)MXMBase);
-
- exit(RETURN_OK);
- }
-
- /* Remove the handler? */
-
- if(argv[ARG_QUIT])
- {
- Printf("Removing \33[1m\33[33mKeyMacro\33[31m\33[0m, ");
-
- if(!MSeg)
- {
- Printf("failed!\7\n");
-
- CloseLibrary((struct Library *)MXMBase);
-
- exit(RETURN_OK);
- }
-
- MSeg -> Father = (struct Task *)SysBase -> ThisTask;
-
- if(MSeg -> Child)
- {
- Signal(MSeg -> Child,SIG_CLOSE);
- Wait(SIG_CLOSE);
- }
-
- RemPort((struct MsgPort *)MSeg);
- FreeMem(MSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME));
-
- if(MSeg -> Segment)
- UnLoadPrg(MSeg -> Segment);
-
- if(MSeg -> MacroList)
- {
- for(i = 0 ; i < MSeg -> NumMacros ; i++)
- {
- if(MSeg -> MacroList[i] . mk_Type == MK_UNUSED)
- continue;
-
- 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);
- }
-
- FreeRem(MSeg);
-
- Printf("OK.\n");
-
- CloseLibrary((struct Library *)MXMBase);
-
- 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;
-
- NewList(&MSeg -> Port . mp_MsgList);
-
- if(From_CLI)
- {
- Printf("\33[1m\33[33mKeyMacro v1.%ld \33[31m\33[0m(C) Copyright 1989, 1990 by \33[4mMXM\33[0m.\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
- {
- if(From_CLI)
- Printf("failed!\n");
-
- CloseLibrary((struct Library *)MXMBase);
-
- exit(RETURN_FAIL);
- }
-
- MSeg -> Segment = LoadPrg("KeyMacro-Handler");
-
- if(!MSeg -> Segment)
- MSeg -> Segment = LoadPrg("L:KeyMacro-Handler");
-
- if(!MSeg -> Segment)
- {
- if(From_CLI)
- Printf("unable to find \33[33mL:KeyMacro-Handler\33[31m\7!\n");
-
- FreeRem(MSeg -> Port . mp_Node . ln_Name);
- FreeRem(MSeg);
- }
- else
- {
- AddPort((struct MsgPort *)MSeg);
-
- 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((struct MsgPort *)MSeg);
- FreeRem(MSeg -> Port . mp_Node . ln_Name);
-
- if(MSeg -> Segment)
- UnLoadPrg(MSeg -> Segment);
-
- FreeRem(MSeg);
-
- CloseLibrary((struct Library *)MXMBase);
-
- exit(RETURN_FAIL);
- }
- else
- {
- if(From_CLI)
- Printf("initializing, ");
-
- InvertKey(NULL,NULL,IK_USEIKM | IK_BUILDLIST,NULL);
-
- if(From_CLI)
- Puts("Okay.");
- else
- PopRequest(NULL,"KeyMacro Info:","\33[1mKeyMacro\33[0m installed.",NULL,"Continue?",FALSE,NULL);
-
- Created = TRUE;
- }
- }
- }
- }
-
- /* Update the macro key list. */
-
- if(UpdateList(FileName))
- {
- if(Created)
- {
- MSeg -> NumMacros = MAXMACROS;
- MSeg -> MacroList = KeyList;
- }
- else
- {
- struct MacroMessage UpdateMsg;
-
- UpdateMsg . mm_Type = MM_UPDATE;
- UpdateMsg . mm_NumMacros= MAXMACROS;
- UpdateMsg . mm_MacroList= KeyList;
-
- SendMacroMsg(&UpdateMsg);
-
- if(From_CLI)
- Printf("\33[1mKeyMacro:\33[0m Updating macro keys...\n");
- }
- }
- else
- {
- CloseLibrary((struct Library *)MXMBase);
- exit(RETURN_ERROR);
- }
-
- CloseLibrary((struct Library *)MXMBase);
-
- exit(RETURN_OK);
- }
-