/* * toolmanager.c V1.5 * * startup routines * * (c) 1991 by Stefan Becker * */ #include "ToolManager.h" /* Library pointers */ extern struct Library *SysBase,*IntuitionBase,*GfxBase; /* Autoinit Libs */ extern struct Library *LayersBase,*GadToolsBase; /* Autoinit Libs */ struct Library *WorkbenchBase,*IconBase,*CxBase; /* Tooltypes "YES" string */ static char YesString[]="YES"; /* ReadArgs() stuff */ static char Template[]="NOICON/S,ICONNAME/K,ICONFILE/K,CONFIG/K,OUTPUT/K,"\ "PATH/K,CX_POPUP/S,CX_POPKEY/K,CX_PRIORITY/K/N,"\ "NOREQ/S,DELAY/K/N,Tools/M"; static long defcxprio=0; static struct { /* All entries in this array MUST be longwords! */ long noicon; char *iconname; char *iconfile; char *config; char *output; char *path; long popup; char *popkey; long *cxprio; long noreq; long *delay; char **tools; } def={FALSE,NULL,NULL,NULL,NULL,NULL,FALSE,NULL,&defcxprio, FALSE,NULL,NULL}; /* miscellaneous */ extern char InternalConfigName[]; extern struct NewBroker nb; static struct DiskObject *dobj=NULL; static struct AppMenuItem *QTMAppMenuItem; static APTR OldConsoleTask=NULL; /* Open libraries and other stuff */ static BOOL openstuff(void) { long i; if (SysBase->lib_Version<36) /* Sanity check */ { puts("You need a Kickstart 2.0 or better to run " DEFPROGNAME "!"); exit(20); } /* Open libraries */ for (i=0; i<20; i++) /* Try it 20 times. Workbench can be sloooowwww.... */ { if (WorkbenchBase=OpenLibrary(WORKBENCH_NAME,36)) break; Delay(50); } if (!WorkbenchBase) cleanup(1); if (!(IconBase=OpenLibrary(ICONNAME,0))) cleanup(2); if (!(CxBase=OpenLibrary("commodities.library",36))) cleanup(3); Forbid(); /* Is "ToolManager" already running? */ MyMP=FindPort(MyName); Permit(); if (MyMP) return(TRUE); /* Yes, don't start again! */ if (!(MyMP=CreateMsgPort())) /* No, create message port */ cleanup(4); MyMP->mp_Node.ln_Pri=0; MyMP->mp_Node.ln_Name=MyName; /* Our name */ AddPort(MyMP); /* Announce our presence */ /* Create Commodities Broker port */ if (!(MyBrokerPort=CreateMsgPort())) cleanup(5); MyBrokerPort->mp_Node.ln_Pri=0; MyBrokerPort->mp_Node.ln_Name="TM Broker Port"; nb.nb_Port=MyBrokerPort; /* Create Broker */ if (!(MyBroker=CxBroker(&nb,NULL))) cleanup(6); SetConfigFileName(InternalConfigName); /* Copy config file name */ return(FALSE); /* No, start ToolManager */ } /* Init tool stuff */ static void inittool(void) { NewList(&ToolList); /* Initialize tool list */ /* Notify Workbench about special menu items. */ /* 1. If this item is selected, the program will quit */ if (!(QTMAppMenuItem=AddAppMenuItemA(0,NULL,"Quit ToolManager",MyMP,NULL))) cleanup(7); /* 2. If this item is selected, the status window will open */ if (!(OTWAppMenuItem=AddAppMenuItemA(1,NULL,"Open TM Window",MyMP,NULL))) cleanup(8); } /* Send an AppMessage with our parameters to a running ToolManager process */ static void SendParameters(LONG nargs, struct WBArg *arg) { struct MsgPort *sp,*rp; struct AppMessage *msg; /* Allocate memory for AppMessage */ if (!(msg=malloc(sizeof(struct AppMessage)))) goto e1; /* Create a reply port */ if (!(rp=CreateMsgPort())) goto e2; /* Build AppMessage */ msg->am_Message.mn_Node.ln_Type=NT_MESSAGE; msg->am_Message.mn_Node.ln_Pri=0; msg->am_Message.mn_ReplyPort=rp; msg->am_Type=MTYPE_APPICON; msg->am_NumArgs=nargs; msg->am_ArgList=arg; Forbid(); /* Find "ToolManager" message port */ sp=FindPort(MyName); if (sp) PutMsg(sp,(struct Message *) msg); /* Send AppMessage */ Permit(); if (sp) { /* We have send the message */ WaitPort(rp); /* Wait on the reply */ GetMsg(rp); /* Remove reply from port */ } DeleteMsgPort(rp); e2: free(msg); e1: return; } /* Workbench main entry point */ void wbmain(struct WBStartup *wbarg) { BPTR fl; ULONG delay=0; if (openstuff()) /* common startup code */ { /* ToolManager already running, send parameters */ if (wbarg->sm_NumArgs>1) SendParameters(wbarg->sm_NumArgs-1,wbarg->sm_ArgList+1); cleanup(4); /* All done */ } /* Set global startup current directory */ StartupCD=wbarg->sm_ArgList->wa_Lock; /* Get the program icon */ fl=CurrentDir(StartupCD); if (dobj=GetDiskObject(wbarg->sm_ArgList->wa_Name)) { char *cp1,*cp2,**ttp=dobj->do_ToolTypes; /* Retreive ToolTypes from icon */ /* 1. CONFIG= Set configuration file name */ if (cp1=FindToolType(ttp,"CONFIG")) SetConfigFileName(cp1); /* 2. CX_POPKEY= Set commodities HotKey */ if (cp1=FindToolType(ttp,"CX_POPKEY")) PopUpHotKey=strdup(cp1); /* 3. CX_POPUP=YES|NO Show status window on startup */ if (cp1=FindToolType(ttp,"CX_POPUP")) ShowStatusWindow=MatchToolValue(cp1,YesString); /* 4. CX_PRIORITY= Set broker priority */ if (cp1=FindToolType(ttp,"CX_PRIORITY")) nb.nb_Pri=strtol(cp1,&cp2,10); /* 5. NOREQ Don't show requester */ ShowQuitReq=!FindToolType(ttp,"NOREQ"); /* 6. DELAY= Wait "num" seconds before adding the tools */ if (cp1=FindToolType(ttp,"DELAY")) delay=50*strtol(cp1,&cp2,10); /* 7. OUTPUT= CLI Tool Output file */ if (cp1=FindToolType(ttp,"OUTPUT")) CLIOutputFile=strdup(cp1); /* 8. PATH= Global CLI Tool path string */ if (cp1=FindToolType(ttp,"PATH")) GlobalPath=strdup(cp1); /* 9. ICONNAME= Name of the AppIcon */ if (cp1=FindToolType(ttp,"ICONNAME")) IconName=strdup(cp1); /* 10. NOICON Show AppIcon */ ShowIcon=!FindToolType(ttp,"NOICON"); /* 11. INTERNALICON Use the internal icon as AppIcon */ if (ShowIcon && !FindToolType(ttp,"INTERNALICON")) MyIcon=dobj; /* Disk icon will be used as AppIcon */ else { /* No icon or the internal icon will be used */ FreeDiskObject(dobj); dobj=NULL; } } CurrentDir(fl); /* Set defaults if needed */ if (!PopUpHotKey) PopUpHotKey=DefaultPopUpHotKey; if (!CLIOutputFile) CLIOutputFile=DefaultCLIOutputFile; if (!IconName) IconName=MyName; /* Init tool stuff */ if (delay) Delay(delay); /* I hope this fixes ALL mysterious crashes... */ inittool(); /* Process WB startup parameters */ WBAddToolNode(wbarg->sm_ArgList+1,wbarg->sm_NumArgs-1); /* Read configuration file */ fl=CurrentDir(StartupCD); ReadConfigFile(ConfigName,TRUE); CurrentDir(fl); mainloop(); /* Go into main loop */ } /* CLI main entry point */ void main(int argc, char **argv) { struct RDArgs *rda; struct Process *pr=FindTask(NULL); /* Help requested? */ if ((argc>1) && (*argv[1]=='?')) { /* Print out usage, but DON'T start ToolManager */ puts(""); puts(CopyrightNote); fputs("\nUsage: " DEFPROGNAME " ",stdout); puts(Template); puts("\n Parameter Description Default"); puts(" NOICON Don't show the program icon Show icon"); puts(" ICONNAME Name of the program icon " DEFPROGNAME); puts(" ICONFILE File name for the program icon Internal icon"); puts(" CONFIG Name of configuration file " DEFCONFIGNAME); puts(" OUTPUT Name of the CLI output file (see docs)"); puts(" PATH List of directories for CLI path No path"); puts(" CX_POPUP Open status window after startup Don't open"); puts(" CX_POPKEY Commodities HotKey definition \"" DEFPOPUPHOTKEY "\""); puts(" CX_PRIORITY Commodities priority 0"); puts(" NOREQ Don't show quit requester Show requester"); puts(" DELAY Wait \"num\" seconds before startup Donīt wait"); puts(" Tools Name of programs to add to the menu"); puts("\nRequires Kickstart 2.0 or better!"); exit(0); } freopen("*","w",stderr); /* Reopen the stderr for banner line */ fputs(CopyrightNote,stderr); /* Put out banner line (only in CLI) */ fputc('\n',stderr); fclose(stderr); /* Set global startup current directory */ StartupCD=CurrentDir(NULL); CurrentDir(StartupCD); if (openstuff()) /* common startup code */ { /* ToolManager already running, send parameters */ struct WBArg *wa; if (argc<2) cleanup(4); /* No parameters to send */ /* Allocate memory for WB parameters */ if (!(wa=malloc(sizeof(struct WBArg)*(argc-1)))) cleanup(4); /* Process CLI startup parameters */ if (rda=ReadArgs(Template,(LONG *) &def,NULL)) { /* Build WBArgs */ if (argv=def.tools) { register struct WBArg *wat=wa; argc=0; while (*argv) /* Scan list of tools */ { wat->wa_Lock=StartupCD; /* Copy parameters */ wat->wa_Name=*argv++; wat++; argc++; } if (argc>0) SendParameters(argc,wa); /* Send parameters */ } FreeArgs(rda); /* Free RDArgs */ } free(wa); /* Free WB parameters */ cleanup(4); /* All done */ } /* Process CLI startup parameters */ rda=ReadArgs(Template,(LONG *) &def,NULL); /* Set internal values according to command line parameters */ ShowIcon=!def.noicon; if (def.iconname) IconName=strdup(def.iconname); if (!IconName) IconName=MyName; if (ShowIcon && def.iconfile && (dobj=GetDiskObject(def.iconfile))) MyIcon=dobj; if (def.config) SetConfigFileName(def.config); if (def.output) CLIOutputFile=strdup(def.output); if (!CLIOutputFile) CLIOutputFile=DefaultCLIOutputFile; if (def.path) GlobalPath=strdup(def.path); ShowStatusWindow=def.popup; if (def.popkey) PopUpHotKey=strdup(def.popkey); if (!PopUpHotKey) PopUpHotKey=DefaultPopUpHotKey; nb.nb_Pri=*def.cxprio; ShowQuitReq=!def.noreq; /* I hope this fixes ALL mysterious crashes... */ if (def.delay) Delay(*def.delay*50); /* Init tool stuff */ inittool(); /* Add every other parameter as CLI tool */ if (argv=def.tools) { struct ConfigBlock *cb; if (cb=malloc(sizeof(struct ConfigBlock))) /* Get memory */ { /* Init config block */ InitConfigBlock(cb); cb->cb_Type=TNTYPE_CLI; while (*argv) { strncpy(cb->cb_Alias,*argv++,BUFLEN-1); AddToolNode(cb,StartupCD); } free(cb); } } /* Free RDArgs */ if (rda) FreeArgs(rda); ReadConfigFile(ConfigName,TRUE); /* Read configuration file */ fclose(stdin); /* Detach from console window */ fclose(stdout); OldConsoleTask=pr->pr_ConsoleTask; pr->pr_ConsoleTask=NULL; mainloop(); /* Go into main loop */ } /* Final cleanup routine */ void cleanup(int i) { register struct Message *msg; switch(i) { case 99: case 10:if (MyAppIcon) RemoveAppIcon(MyAppIcon); if (dobj) FreeDiskObject(dobj); case 9:RemoveTools(); if (OTWAppMenuItem) RemoveAppMenuItem(OTWAppMenuItem); case 8:RemoveAppMenuItem(QTMAppMenuItem); case 7:DeleteCxObjAll(MyBroker); /* Remove CX Objects */ case 6:while (msg=GetMsg(MyBrokerPort)) ReplyMsg(msg); DeleteMsgPort(MyBrokerPort); case 5:RemPort(MyMP); /* Remove message port */ while (msg=GetMsg(MyMP)) ReplyMsg(msg); /* Reply all messages */ DeleteMsgPort(MyMP); case 4:CloseLibrary(CxBase); case 3:CloseLibrary(IconBase); case 2:CloseLibrary(WorkbenchBase); case 1:break; } /* Did we have a console window? */ if (OldConsoleTask) { struct Process *pr=FindTask(NULL); pr->pr_ConsoleTask=OldConsoleTask; /* Yes, restore old value */ } exit(RETURN_OK); /* all o.k. */ }