home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
576.lha
/
WBStart_v1.0
/
WBStart-Handler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-24
|
6KB
|
219 lines
/*
* 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 */
}