home *** CD-ROM | disk | FTP | other *** search
- /*
- * WBStart-Handler.c V1.0
- *
- * Handler code
- *
- * (c) 1991 by Stefan Becker
- *
- */
- #include "WBStart.h"
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/icon_protos.h>
- #include <workbench/icon.h>
- #include <workbench/workbench.h>
- #include <stdlib.h>
- #include <string.h>
-
- /* Global data */
- void _waitwbmsg(void);
- struct Library *IconBase;
- static struct MsgPort *HandlerPort;
- static ULONG wbactive=0; /* Number of active WB processes */
- static char Version[]="$VER: WBStart-Handler V1.0 (24.11.1991)";
-
- /* Start tool as a WB process */
- static BOOL StartProgram(struct WBStartMsg *msg)
- {
- char *name=msg->wbsm_Name; /* Program name */
- BPTR fl; /* AmigaDOS file handle */
- register struct WBStartup *wbs; /* WBStartup message for tool */
- struct DiskObject *tdob; /* Tool icon */
- LONG ssize; /* StackSize, default */
- struct MsgPort *proc; /* Process descriptor for tool */
- struct WBArg *wbad,*wbas; /* Pointers to WB arguments */
- char *proname=NULL; /* Name of Project icon */
- int i;
-
- /* Allocate memory for WBStartup */
- if (!(wbs=calloc(sizeof(struct WBStartup)+
- sizeof(struct WBArg)*(msg->wbsm_NumArgs+2),1)))
- return (FALSE);
-
- /* Change to tool's directory */
- fl=CurrentDir(msg->wbsm_DirLock);
-
- /* Is it a project? */
- if (tdob=GetDiskObject(name))
- if (tdob->do_Type==WBPROJECT)
- {
- proname=name; /* Save original name */
- name=strdup(tdob->do_DefaultTool); /* Get name of default tool */
- FreeDiskObject(tdob);
- if (!name) goto se1; /* Enough memory? */
- tdob=GetDiskObject(name); /* Get icon of the default tool */
- }
-
- /* Is it a tool? */
- ssize=msg->wbsm_Stack;
- if (tdob)
- {
- if (tdob->do_Type==WBTOOL) /* Only tools supply this information */
- {
- if (tdob->do_ToolWindow) wbs->sm_ToolWindow=strdup(tdob->do_ToolWindow);
- if (tdob->do_StackSize>ssize) ssize=tdob->do_StackSize;
- }
-
- FreeDiskObject(tdob);
- }
- if (ssize<4096) ssize=4096; /* Minimum stack size is 4096 Bytes! */
- ssize=(ssize+3)&(~3); /* Stack size must be a multiple of 4! */
-
- /* Load tool code */
- if (!(wbs->sm_Segment=LoadSeg(name))) goto se2;
-
- /* Build WBStartup message */
- /* wbs->sm_Message.mn_Node.ln_Type=NT_MESSAGE; PutMsg() does this for us! */
- wbs->sm_Message.mn_ReplyPort=HandlerPort;
- wbs->sm_Message.mn_Length=sizeof(struct WBStartup);
- wbs->sm_NumArgs=msg->wbsm_NumArgs+1;
- wbs->sm_ArgList=wbs+1; /* WBArg array starts after WBStartup */
-
- /* Initialize WBArg pointers */
- wbas=msg->wbsm_ArgList;
- wbad=wbs->sm_ArgList;
-
- /* 1. argument is the tool itself! */
- if (!(wbad->wa_Lock=DupLock(msg->wbsm_DirLock))) goto se3;
- if (!(wbad->wa_Name=strdup(name))) goto se4;
- wbad++;
-
- /* If tool is a project, add it as 2. parameter to the WBArg list */
- if (proname)
- {
- if (!(wbad->wa_Lock=DupLock(msg->wbsm_DirLock))) goto se4;
- if (!(wbad->wa_Name=strdup(proname))) goto se4;
- wbad++;
- wbs->sm_NumArgs++;
- }
-
- /* Copy WB arguments */
- for (i=msg->wbsm_NumArgs; i; i--,wbas++,wbad++)
- {
- if (!(wbad->wa_Lock=DupLock(wbas->wa_Lock)))
- {
- wbad--; /* Skip parameters, which don't support a lock */
- wbs->sm_NumArgs--;
- continue; /* Next parameter */
- }
-
- /* Sanity check for name string... Enforcer is watching you! */
- if (!wbas->wa_Name || !(wbad->wa_Name=strdup(wbas->wa_Name))) goto se4;
- }
-
- /* Create process */
- if (!(wbs->sm_Process=CreateProc(wbs->sm_ArgList->wa_Name,msg->wbsm_Prio,
- wbs->sm_Segment,ssize)))
- goto se4;
-
- /* Send WBStartup message to tool */
- PutMsg(wbs->sm_Process,(struct Message *) wbs);
- if (proname) free(name); /* If project, then free default tool name */
- CurrentDir(fl); /* Change to old directory */
- wbactive++; /* Tool started! */
- return(TRUE);
-
- /* An error occurred. Free all resources */
- se4: wbas=wbs->sm_ArgList;
- for (i=wbs->sm_NumArgs; i; i--,wbas++)
- {
- UnLock(wbas->wa_Lock);
- if (wbas->wa_Name) free(wbas->wa_Name);
- }
- se3: UnLoadSeg(wbs->sm_Segment);
- se2: if (proname) free(name);
- se1: CurrentDir(fl);
- free(wbs);
- return(FALSE);
- }
-
- __stkargs void _main(int arglen, char *argptr)
- {
- ULONG gotsigs,wsig,psig;
- BOOL notend=TRUE;
-
- /* Open icon.library */
- if (!(IconBase=OpenLibrary(ICONNAME,0))) return;
-
- /* Create message port */
- if (!(HandlerPort=CreateMsgPort()))
- {
- CloseLibrary(IconBase);
- return;
- }
-
- /* Make port public */
- HandlerPort->mp_Node.ln_Pri=0;
- HandlerPort->mp_Node.ln_Name=WBS_PORTNAME;
- AddPort(HandlerPort);
-
- /* Init signal masks */
- psig=1L<<HandlerPort->mp_SigBit;
- wsig=psig|SIGBREAKF_CTRL_C;
-
- /* Main event loop */
- while (notend)
- {
- /* Wait on event */
- gotsigs=Wait(wsig);
-
- /* Got a message at our port? */
- if (gotsigs&psig)
- {
- struct WBStartMsg *msg;
-
- /* Process all messages */
- while (msg=GetMsg(HandlerPort))
- if (msg->wbsm_Msg.mn_Node.ln_Type==NT_REPLYMSG) /* Replied message? */
- {
- /* This is the death message from a tool we started some time ago */
- struct WBStartup *wbs=(struct WBStartup *) msg;
- struct WBArg *wa=wbs->sm_ArgList;
- int i=wbs->sm_NumArgs;
-
- while (i--)
- {
- UnLock(wa->wa_Lock); /* Free WB argument */
- if (wa->wa_Name) free(wa->wa_Name);
- wa++;
- }
-
- if (wbs->sm_ToolWindow) /* Free tool window specification */
- free(wbs->sm_ToolWindow);
-
- UnLoadSeg(wbs->sm_Segment); /* Unload code */
- free(wbs); /* Free WBStartup */
- wbactive--; /* One tool closed down */
- }
- else
- {
- /* We got a new message. Handle and reply it. */
- msg->wbsm_Stack=StartProgram(msg);
- ReplyMsg((struct Message *) msg);
- }
- }
-
- /* Received a CTRL-C? */
- if ((gotsigs&SIGBREAKF_CTRL_C) && !wbactive) notend=FALSE;
- }
-
- /* Exit handler */
- RemPort(HandlerPort);
- DeleteMsgPort(HandlerPort);
- CloseLibrary(IconBase);
- return;
-
- /* NOT REACHED */
- _waitwbmsg(); /* Force linking of WB startup code */
- }
-