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 >
C/C++ Source or Header  |  1991-11-24  |  6KB  |  219 lines

  1. /*
  2.  * WBStart-Handler.c   V1.0
  3.  *
  4.  * Handler code
  5.  *
  6.  * (c) 1991 by Stefan Becker
  7.  *
  8.  */
  9. #include "WBStart.h"
  10. #include <clib/dos_protos.h>
  11. #include <clib/exec_protos.h>
  12. #include <clib/icon_protos.h>
  13. #include <workbench/icon.h>
  14. #include <workbench/workbench.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. /* Global data */
  19. void _waitwbmsg(void);
  20. struct Library *IconBase;
  21. static struct MsgPort *HandlerPort;
  22. static ULONG wbactive=0;            /* Number of active WB processes */
  23. static char Version[]="$VER: WBStart-Handler V1.0 (24.11.1991)";
  24.  
  25. /* Start tool as a WB process */
  26. static BOOL StartProgram(struct WBStartMsg *msg)
  27. {
  28.  char *name=msg->wbsm_Name;      /* Program name */
  29.  BPTR fl;                        /* AmigaDOS file handle */
  30.  register struct WBStartup *wbs; /* WBStartup message for tool */
  31.  struct DiskObject *tdob;        /* Tool icon */
  32.  LONG ssize;                     /* StackSize, default */
  33.  struct MsgPort *proc;           /* Process descriptor for tool */
  34.  struct WBArg *wbad,*wbas;       /* Pointers to WB arguments */
  35.  char *proname=NULL;             /* Name of Project icon */
  36.  int i;
  37.  
  38.  /* Allocate memory for WBStartup */
  39.  if (!(wbs=calloc(sizeof(struct WBStartup)+
  40.                   sizeof(struct WBArg)*(msg->wbsm_NumArgs+2),1)))
  41.   return (FALSE);
  42.  
  43.  /* Change to tool's directory */
  44.  fl=CurrentDir(msg->wbsm_DirLock);
  45.  
  46.  /* Is it a project? */
  47.  if (tdob=GetDiskObject(name))
  48.   if (tdob->do_Type==WBPROJECT)
  49.    {
  50.     proname=name;                      /* Save original name */
  51.     name=strdup(tdob->do_DefaultTool); /* Get name of default tool */
  52.     FreeDiskObject(tdob);
  53.     if (!name) goto se1;               /* Enough memory? */
  54.     tdob=GetDiskObject(name);          /* Get icon of the default tool */
  55.    }
  56.  
  57.  /* Is it a tool? */
  58.  ssize=msg->wbsm_Stack;
  59.  if (tdob)
  60.   {
  61.    if (tdob->do_Type==WBTOOL)          /* Only tools supply this information */
  62.     {
  63.      if (tdob->do_ToolWindow) wbs->sm_ToolWindow=strdup(tdob->do_ToolWindow);
  64.      if (tdob->do_StackSize>ssize) ssize=tdob->do_StackSize;
  65.     }
  66.  
  67.    FreeDiskObject(tdob);
  68.   }
  69.  if (ssize<4096) ssize=4096; /* Minimum stack size is 4096 Bytes! */
  70.  ssize=(ssize+3)&(~3);       /* Stack size must be a multiple of 4! */
  71.  
  72.  /* Load tool code */
  73.  if (!(wbs->sm_Segment=LoadSeg(name))) goto se2;
  74.  
  75.  /* Build WBStartup message */
  76.  /* wbs->sm_Message.mn_Node.ln_Type=NT_MESSAGE; PutMsg() does this for us! */
  77.  wbs->sm_Message.mn_ReplyPort=HandlerPort;
  78.  wbs->sm_Message.mn_Length=sizeof(struct WBStartup);
  79.  wbs->sm_NumArgs=msg->wbsm_NumArgs+1;
  80.  wbs->sm_ArgList=wbs+1;             /* WBArg array starts after WBStartup */
  81.  
  82.  /* Initialize WBArg pointers */
  83.  wbas=msg->wbsm_ArgList;
  84.  wbad=wbs->sm_ArgList;
  85.  
  86.  /* 1. argument is the tool itself! */
  87.  if (!(wbad->wa_Lock=DupLock(msg->wbsm_DirLock))) goto se3;
  88.  if (!(wbad->wa_Name=strdup(name))) goto se4;
  89.  wbad++;
  90.  
  91.  /* If tool is a project, add it as 2. parameter to the WBArg list */
  92.  if (proname)
  93.   {
  94.    if (!(wbad->wa_Lock=DupLock(msg->wbsm_DirLock))) goto se4;
  95.    if (!(wbad->wa_Name=strdup(proname))) goto se4;
  96.    wbad++;
  97.    wbs->sm_NumArgs++;
  98.   }
  99.  
  100.  /* Copy WB arguments */
  101.  for (i=msg->wbsm_NumArgs; i; i--,wbas++,wbad++)
  102.   {
  103.    if (!(wbad->wa_Lock=DupLock(wbas->wa_Lock)))
  104.     {
  105.      wbad--;             /* Skip parameters, which don't support a lock */
  106.      wbs->sm_NumArgs--;
  107.      continue;           /* Next parameter */
  108.     }
  109.  
  110.    /* Sanity check for name string... Enforcer is watching you! */
  111.    if (!wbas->wa_Name || !(wbad->wa_Name=strdup(wbas->wa_Name))) goto se4;
  112.   }
  113.  
  114.  /* Create process */
  115.  if (!(wbs->sm_Process=CreateProc(wbs->sm_ArgList->wa_Name,msg->wbsm_Prio,
  116.                                   wbs->sm_Segment,ssize)))
  117.   goto se4;
  118.  
  119.  /* Send WBStartup message to tool */
  120.  PutMsg(wbs->sm_Process,(struct Message *) wbs);
  121.  if (proname) free(name);       /* If project, then free default tool name */
  122.  CurrentDir(fl);                /* Change to old directory */
  123.  wbactive++;                    /* Tool started! */
  124.  return(TRUE);
  125.  
  126.  /* An error occurred. Free all resources */
  127. se4: wbas=wbs->sm_ArgList;
  128.      for (i=wbs->sm_NumArgs; i; i--,wbas++)
  129.       {
  130.        UnLock(wbas->wa_Lock);
  131.        if (wbas->wa_Name) free(wbas->wa_Name);
  132.       }
  133. se3: UnLoadSeg(wbs->sm_Segment);
  134. se2: if (proname) free(name);
  135. se1: CurrentDir(fl);
  136.      free(wbs);
  137.      return(FALSE);
  138. }
  139.  
  140. __stkargs void _main(int arglen, char *argptr)
  141. {
  142.  ULONG gotsigs,wsig,psig;
  143.  BOOL notend=TRUE;
  144.  
  145.  /* Open icon.library */
  146.  if (!(IconBase=OpenLibrary(ICONNAME,0))) return;
  147.  
  148.  /* Create message port */
  149.  if (!(HandlerPort=CreateMsgPort()))
  150.   {
  151.    CloseLibrary(IconBase);
  152.    return;
  153.   }
  154.  
  155.  /* Make port public */
  156.  HandlerPort->mp_Node.ln_Pri=0;
  157.  HandlerPort->mp_Node.ln_Name=WBS_PORTNAME;
  158.  AddPort(HandlerPort);
  159.  
  160.  /* Init signal masks */
  161.  psig=1L<<HandlerPort->mp_SigBit;
  162.  wsig=psig|SIGBREAKF_CTRL_C;
  163.  
  164.  /* Main event loop */
  165.  while (notend)
  166.   {
  167.    /* Wait on event */
  168.    gotsigs=Wait(wsig);
  169.  
  170.    /* Got a message at our port? */
  171.    if (gotsigs&psig)
  172.     {
  173.      struct WBStartMsg *msg;
  174.  
  175.      /* Process all messages */
  176.      while (msg=GetMsg(HandlerPort))
  177.       if (msg->wbsm_Msg.mn_Node.ln_Type==NT_REPLYMSG) /* Replied message? */
  178.        {
  179.         /* This is the death message from a tool we started some time ago */
  180.         struct WBStartup *wbs=(struct WBStartup *) msg;
  181.         struct WBArg *wa=wbs->sm_ArgList;
  182.         int i=wbs->sm_NumArgs;
  183.  
  184.         while (i--)
  185.          {
  186.           UnLock(wa->wa_Lock);      /* Free WB argument */
  187.           if (wa->wa_Name) free(wa->wa_Name);
  188.           wa++;
  189.          }
  190.  
  191.         if (wbs->sm_ToolWindow)     /* Free tool window specification */
  192.          free(wbs->sm_ToolWindow);
  193.  
  194.         UnLoadSeg(wbs->sm_Segment); /* Unload code */
  195.         free(wbs);                  /* Free WBStartup */
  196.         wbactive--;                 /* One tool closed down */
  197.        }
  198.       else
  199.        {
  200.         /* We got a new message. Handle and reply it. */
  201.         msg->wbsm_Stack=StartProgram(msg);
  202.         ReplyMsg((struct Message *) msg);
  203.        }
  204.     }
  205.  
  206.    /* Received a CTRL-C? */
  207.    if ((gotsigs&SIGBREAKF_CTRL_C) && !wbactive) notend=FALSE;
  208.   }
  209.  
  210.  /* Exit handler */
  211.  RemPort(HandlerPort);
  212.  DeleteMsgPort(HandlerPort);
  213.  CloseLibrary(IconBase);
  214.  return;
  215.  
  216.  /* NOT REACHED */
  217.  _waitwbmsg();    /* Force linking of WB startup code */
  218. }
  219.