/* * toolmanager.c V1.4 * * startup routines * * (c) 1991 by Stefan Becker * */ #include "ToolManager.h" /* Library pointers */ extern struct Library *SysBase,*IntuitionBase,*GfxBase; /* Autoinit Libs */ extern struct Library *GadToolsBase; /* Autoinit Libs */ struct Library *WorkbenchBase,*IconBase,*CxBase; /* Tooltypes "YES" string */ static char YesString[]="YES"; /* ReadArgs() stuff */ static char Template[]= "NOICON/S,CONFIG/K,POPUP/S,POPKEY/K,CXPRIO/K/N,NOREQ/S,Tools/M"; static long defcxprio=0; static struct { /* All entries in this array MUST be longwords! */ long noicon; char *config; long popup; char *popkey; long *cxprio; long noreq; char **tools; } def={FALSE,NULL,FALSE,NULL,&defcxprio,FALSE,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) { if (SysBase->lib_Version<36) /* Sanity check */ { puts("You need a Kickstart 2.0 or better to run " DEFPROGNAME "!"); exit(20); } /* Open libraries */ if (!(WorkbenchBase=OpenLibrary(WORKBENCH_NAME,36))) 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); return(FALSE); /* No, start ToolManager */ } /* Init tool stuff */ static void inittool(void) { SetConfigFileName(InternalConfigName); /* Copy config file name */ NewList(&ToolList); /* Initialize tool list */ /* Notify Workbench about special menu items. */ /* 1. If this item is selected, the program will quit */ if (!(QTMAppMenuItem=AddAppMenuItem(0,NULL,"Quit ToolManager",MyMP,TAG_DONE))) cleanup(7); /* 2. If this item is selected, the status window will open */ if (!(OTWAppMenuItem=AddAppMenuItem(1,NULL,"Open TM Window",MyMP,TAG_DONE))) 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; 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 */ } inittool(); /* Init tool stuff */ /* Process WB startup parameters */ WBAddToolNode(wbarg->sm_ArgList+1,wbarg->sm_NumArgs-1); /* 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); if (!PopUpHotKey) PopUpHotKey=DefaultPopUpHotKey; /* 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. SHOWREQ=YES|NO Show requester */ if (cp1=FindToolType(ttp,"SHOWREQ")) ShowQuitReq=MatchToolValue(cp1,YesString); /* 6. INTERNALICON Use the internal icon as AppIcon */ if (!FindToolType(ttp,"INTERNALICON")) MyIcon=dobj; /* 7. SHOWICON=YES|NO Show AppIcon */ if (cp1=FindToolType(ttp,"SHOWICON")) if (!(ShowIcon=MatchToolValue(cp1,YesString))) { FreeDiskObject(dobj); dobj=NULL; } } CurrentDir(fl); /* Read configuration file */ ReadConfigFile(); 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: ToolManager ",stdout); puts(Template); puts("\n Parameter Description Default"); puts(" NOICON : Don't show the program icon Show icon"); puts(" CONFIG : Name of configuration file " DEFCONFIGNAME); puts(" POPUP : Open status window after startup Don't open"); puts(" POPKEY : Commodities HotKey definition \"" DEFPOPUPHOTKEY "\""); puts(" CXPRIO : Commodities priority 0"); puts(" NOREQ : Don't display quit requester Show requester"); 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 */ } inittool(); /* Init tool stuff */ /* Process CLI startup parameters */ rda=ReadArgs(Template,(LONG *) &def,NULL); /* Set internal values according to command line parameters */ ShowIcon=!def.noicon; if (def.config) SetConfigFileName(def.config); ShowStatusWindow=def.popup; if (def.popkey) PopUpHotKey=strdup(def.popkey); if (!PopUpHotKey) PopUpHotKey=DefaultPopUpHotKey; nb.nb_Pri=*def.cxprio; ShowQuitReq=!def.noreq; /* 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(); /* 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 (ShowIcon) RemoveAppIcon(MyAppIcon); if (dobj) FreeDiskObject(dobj); case 9:RemoveTools(); if (!ShowIcon) 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. */ }