/* * WBStart-Handler.c V1.0 * * Handler code * * (c) 1991 by Stefan Becker * */ #include "WBStart.h" #include #include #include #include #include #include #include /* 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<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 */ }