home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 488.lha / modengine_v1.0 / modengine1.c < prev    next >
C/C++ Source or Header  |  1991-03-07  |  6KB  |  226 lines

  1. /* ModEngine1.c
  2.  * Copyright (C) 1990 Commodore-Amiga, Inc.
  3.  * written by David N. Junod
  4.  *
  5.  * Modular event processing shell for Intuition
  6.  *
  7.  */
  8.  
  9. #include "mod.h"
  10. #include "ModEngine1.h"
  11.  
  12. /* Required for Intuition processing */
  13. struct IntuitionBase *IntuitionBase = NULL;
  14.  
  15. /* Main processing loop */
  16. VOID main ()
  17. {
  18.     struct AppInfo *ai = NULL;
  19.     struct List *list = NULL;
  20.     struct Node *node = NULL;
  21.     struct MsgHandler *mh = NULL;
  22.     ULONG sig_rcvd;
  23.  
  24.     /* Obtain the needed resources */
  25.     ai = OpenAll ();
  26.     list = &(ai->MsgList);
  27.  
  28.     /* Process messages until user signals that they are done. */
  29.     /* loop until done and no messages outstanding */
  30.     while (!ai->Done || ai->numcmds)
  31.     {
  32.     /* wait for a message to come in */
  33.     sig_rcvd = Wait (ai->sigbits);
  34.  
  35.     /* process signals */
  36.     if (list->lh_TailPred != (struct Node *) list)
  37.     {
  38.         node = list->lh_Head;
  39.         while (node->ln_Succ)
  40.         {
  41.         mh = (struct MsgHandler *) node;
  42.         if (node->ln_Type==MH_HANDLER_T && (mh->mh_SigBits & sig_rcvd))
  43.             (*mh->mh_Func[MH_HANDLE]) (ai, mh);
  44.         node = node->ln_Succ;
  45.         }
  46.     }
  47.     }
  48.     /* Free up all the resources cleanly */
  49.     CloseAll (ai, RETURN_OK, NULL);
  50. }
  51.  
  52. /*--- Obtain the needed resources ---*/
  53. struct AppInfo *OpenAll ()
  54. {
  55.     struct AppInfo *ai = NULL;
  56.  
  57.     /* open required libraries here */
  58.     if (!(IntuitionBase = (struct IntuitionBase *)
  59.       OpenLibrary ("intuition.library", 33L)))
  60.     CloseAll (ai, RETURN_FAIL, "Could not open intuition.library");
  61.  
  62.     /* Allocate memory for all our variables */
  63.     if (!(ai = (struct AppInfo *)
  64.       AllocMem (sizeof (struct AppInfo), MEMF_CLEAR|MEMF_PUBLIC)))
  65.     CloseAll (ai, RETURN_FAIL, "Not enough memory");
  66.  
  67.     /* Initialize the message handler list */
  68.     NewList (&(ai->MsgList));
  69.  
  70.     /* set up the function table pointer */
  71.     ai->FuncTable = &FTable[0];
  72.  
  73.     /* set up ARexx message handler */
  74.     if (!(AddMsgHandler (ai,
  75.              setup_arexx (ai, "OURAPP", "mod", ACTIVE),
  76.              OPTIONAL))) /* handler optional */
  77.     CloseAll (ai, RETURN_FAIL, "Could not allocate ARexx resources");
  78.  
  79.     /* set up DOS command shell message handler */
  80.     if (!(AddMsgHandler (ai,
  81.              setup_dos (ai, "CON:0/150/600/50/Command Window",
  82.                     "Cmd>", "Waiting for message(s)\n",
  83.                     INACTIVE),
  84.              OPTIONAL))) /* handler optional */
  85.     CloseAll (ai, RETURN_FAIL, "Could not allocate DOS resources");
  86.  
  87.     /* set up IDCMP message handler */
  88.     if (!(AddMsgHandler (ai,
  89.              setup_idcmp (ai, &NewWindow, KeyArray, &Menu1,
  90.                           ACTIVE),
  91.              REQUIRED))) /* handler required */
  92.     CloseAll (ai, RETURN_FAIL, "Could not allocate IDCMP resources");
  93.  
  94.     return (ai);
  95. }
  96.  
  97. /*--- Free up all the resources that we obtained ---*/
  98. VOID CloseAll (struct AppInfo * ai, int value, UBYTE * fmsg)
  99. {
  100.     struct List *list = &(ai->MsgList);
  101.     struct Node *node = NULL, *nxtnode = NULL;
  102.     struct MsgHandler *mh = NULL;
  103.  
  104.     /* display error message, if there is one */
  105.     if (fmsg)
  106.     NotifyUser (NULL, fmsg);
  107.  
  108.     /* shutdown all the handlers */
  109.     if (list->lh_TailPred != (struct Node *) list)
  110.     {
  111.     node = list->lh_Head;
  112.     while (nxtnode = node->ln_Succ)
  113.     {
  114.         mh = (struct MsgHandler *) node;
  115.         (*mh->mh_Func[MH_SHUTDOWN]) (ai, mh);
  116.         node = nxtnode;
  117.     }
  118.     }
  119.  
  120.     /* free our variable space */
  121.     if (ai)
  122.     FreeMem (ai, sizeof (struct AppInfo));
  123.  
  124.     /* close down libraries now */
  125.     if (IntuitionBase)
  126.     CloseLibrary ((struct Library *) IntuitionBase);
  127.  
  128.     exit (value);
  129. }
  130.  
  131. /* add a message handler node to the handler list */
  132. BOOL AddMsgHandler (struct AppInfo * ai, struct MsgHandler * mh,
  133.             BOOL needed)
  134. {
  135.     BOOL retval = FALSE;
  136.  
  137.     if (mh)
  138.     {
  139.     Enqueue (&(ai->MsgList), (struct Node *) mh);
  140.     ai->sigbits |= mh->mh_SigBits;
  141.     retval = TRUE;
  142.     }
  143.     return ( (BOOL)((needed) ? retval : TRUE) );
  144. }
  145.  
  146. /* handle messages between function handlers */
  147. BOOL HandlerFunc (struct AppInfo * ai, UBYTE * name, WORD function)
  148. {
  149.     BOOL retval = FALSE;
  150.     struct MsgHandler * mh;
  151.  
  152.     if (mh = (struct MsgHandler *)FindName (&(ai->MsgList), name))
  153.     {
  154.     if (mh->mh_Func[function])
  155.         retval = (*mh->mh_Func[function])(ai, mh);
  156.     }
  157.     return (retval);
  158. }
  159.  
  160. /* get handler data */
  161. struct MsgHandler * HandlerData (struct AppInfo * ai, UBYTE * name)
  162. {
  163.     return ( (struct MsgHandler *)FindName (&(ai->MsgList), name) );
  164. }
  165.  
  166. /* First checks to see if the command is an internal function and if so,
  167.  * it executes the function.  Otherwise, it passes the command to ARexx. */
  168. BOOL PerfFunc (struct AppInfo * ai, struct Message * msg, UBYTE * anchor)
  169. {
  170.     extern BOOL send_rexx_command (UBYTE *, struct AppInfo *,
  171.                    struct MsgHandler *);
  172.     struct MsgHandler * mh = NULL;
  173.     register VOID (*func) (struct AppInfo *, struct Message *, UBYTE *);
  174.     register UBYTE *args = anchor;
  175.     register WORD cntr;
  176.     BOOL retval = FALSE;
  177.     UBYTE arg1[50];
  178.  
  179.     /* get the first word of the command string */
  180.     args = stptok (args, arg1, sizeof (arg1), " ,");
  181.  
  182.     /* increment past first space */
  183.     if (strlen (args) > 0)
  184.     ++args;
  185.  
  186.     /* check the array to see if it is a name that we understand */
  187.     for (cntr = 1, func = NO_FUNCTION;
  188.      (ai->FuncTable[cntr].name != NULL) && (func == NO_FUNCTION);
  189.      cntr++)
  190.     {
  191.     if ((strcmpi (arg1, ai->FuncTable[cntr].name)) == 0)
  192.         func = ai->FuncTable[cntr].func;
  193.     }
  194.  
  195.     /* preset the error return to zero */
  196.     ai->pri_ret = 0L;
  197.  
  198.     if (func != NO_FUNCTION)
  199.     {
  200.     /* valid internal function, let's execute it */
  201.  
  202.     /* execute the function */
  203.     (*(func)) (ai, (struct Message *) msg, args);
  204.  
  205.     /* successful command completion */
  206.     retval = TRUE;
  207.     }
  208.     else
  209.     {
  210.     /* see if we are using ARexx */
  211.     if (mh = HandlerData (ai, "AREXX"))
  212.     {
  213.         /* wasn't an internal function, so let's pass it to ARexx */
  214.         if (!send_rexx_command (anchor, ai, mh))
  215.         {
  216.         /* ARexx failed (not present) */
  217.         NotifyUser (NULL, "ARexx not present");
  218.         }
  219.         else
  220.         /* successful command completion */
  221.         retval = TRUE;
  222.     }
  223.     }
  224.     return (retval);
  225. }
  226.