home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 530b.lha / AMenu_v1.3 / AMenu-Handler.c < prev    next >
C/C++ Source or Header  |  1991-07-03  |  8KB  |  240 lines

  1. /*********************************************************************\
  2. **                               ________________________________    **
  3. **    A n t h o n y             |________    __    __    ________|   **
  4. **                                       |  |o_|  |o_|  |            **
  5. **            T h y s s e n            __|   __    __   |__          **
  6. **                                  __|   __|  |  |  |__   |__       **
  7. **   `` Dragon Computing ! ''    __|   __|     |  |     |__   |__    **
  8. **                              |_____|        |__|        |_____|   **
  9. **                                                                   **
  10. \*********************************************************************/
  11. /* This is the main process for AMenu.  This gets loaded and run in the
  12.  * background by AMenu.  When started, it finishes initializing itself,
  13.  * and starts monitoring the WorkBench IDCMP port.  If any messages show
  14.  * up that we are interested in, we run them as a CLI or WorkBench
  15.  * process.  We don't do any memory allocation or cleanup and leave that
  16.  * all to AMenu (in order to save some space).  Communication with
  17.  * AMenu is done via a public port - never used as a port, but it holds
  18.  * "global" variables.
  19.  */
  20.  
  21. #include "AMenu.h"
  22. #include <libraries/dosextens.h>   /* definition for struct Process */
  23.  
  24. static char *Copyright = COPYRIGHT;
  25.  
  26. struct ArpBase       *ArpBase = NULL;          /* Library Bases */
  27. struct IntuitionBase *IntuitionBase = NULL;    /* from ArpBase */
  28. struct GfxBase       *GfxBase = NULL;          /* from ArpBase */
  29. struct IconBase      *IconBase = NULL;         /* Opened normally */
  30.  
  31. struct MPort         *M = NULL;                /* Port & data from AMenu */
  32. struct MsgPort       *WBReplyPort = NULL;      /* WB processes replies */
  33. struct Process       *MyProc;                  /* This Process */
  34.  
  35. BPTR   WorkDirLock = NULL, OrigDirLock = NULL; /* Directory Locks */
  36. int    WBMenus, WBProcesses=0;                 /* Counts of things */
  37.  
  38.  
  39. extern BOOL   StartMonitor();
  40. extern void   Monitor(),FinishMonitor();
  41. extern void   WBFree(), Warn(char *);
  42.  
  43.  
  44. DB( BPTR   DBWindow = NULL; )     /* Debuging Output Window - Arp Closes */
  45.  
  46. /*------------------------------------------------*/
  47.  
  48. struct IntuiText     /* Exit while WB Processes still running requester */
  49.   WBOpen[] = {
  50.     { 3,1,JAM1,142,4,NULL, (UBYTE*)"WARNING!!", &WBOpen[1] },
  51.     { 0,1,JAM1, 7,12,NULL, (UBYTE*)"A WorkBench program started by AMenu may", &WBOpen[2] },
  52.     { 0,1,JAM1, 7,20,NULL, (UBYTE*)"still be open.  This can cause a crash if", &WBOpen[3] },
  53.     { 0,1,JAM1, 7,28,NULL, (UBYTE*)"the program finishes after AMenu.", &WBOpen[4] },
  54.     { 3,1,JAM1,24,36,NULL, (UBYTE*)"Do you REALLY want to quit now?", NULL },
  55.   },
  56.   TrueMsg  = { 0,1,JAM2, 7,3 ,NULL, (UBYTE*)"QUIT", NULL },
  57.   FalseMsg = { 0,1,JAM2, 7,3 ,NULL, (UBYTE*)"Cancel", NULL };
  58.  
  59.  
  60. void
  61. QuitHandler(Code)
  62.   short Code;
  63.   /* return error to AMenu during initialization */
  64. {
  65.   if( M ) {
  66.     M->ErrorCode = Code;
  67.     Signal(M->Parent, 1 << M->ParentSig);  /* Signal Parent */
  68.     Wait(SIGBREAKF_CTRL_C);                /* Wait for parent removal */
  69.     Signal(M->Parent, 1 << M->ParentSig);  /* Final Signal */
  70.   }
  71.  
  72.   if( WBReplyPort )  DeletePort( WBReplyPort );
  73.   if( OrigDirLock )  CurrentDir( OrigDirLock );
  74.   if( WorkDirLock )  UnLock( WorkDirLock );
  75.   if( IconBase )     CloseLibrary( (struct Library *)IconBase );
  76.  
  77.   if( ArpBase ) {
  78.     DB( if(DBWindow) FPrintf(DBWindow, "Handler Quit -- %d\n", Code); )
  79.     DB( Delay(600); )
  80.     ArpExit(20+Code,0);     /* OK as no true startup code used by handler */
  81.   } else
  82.     Exit(20+Code);
  83. }
  84.  
  85.  
  86. static struct Menu *
  87. SearchWBMenus()
  88. /*   Search the WB menus for either last menu or menu before AMenu
  89. ** This Routine also determines the number of WBMenus to determine
  90. ** if we recieve a WB menu or AMenu selection.
  91. */
  92. {
  93.   register struct Menu *Menu;
  94.   for( Menu = M->WBWindow->MenuStrip, WBMenus=1;
  95.          Menu->NextMenu && Menu->NextMenu != M->AMenu;
  96.            Menu = Menu->NextMenu, WBMenus++ );
  97.   return( Menu );
  98. }
  99.  
  100.  
  101. BOOL
  102. AddMenuStrip()
  103. /* add personalized menus to menustrip -- return true if menus added */
  104. {
  105.   register struct Menu  *Menu, *MenuStrip;
  106.   ULONG ILock;
  107.   BOOL Added;  /* did we attach the menus or were thay in place? */
  108.  
  109.   ILock = LockIBase(NULL);
  110.   Menu = SearchWBMenus();
  111.   MenuStrip = M->WBWindow->MenuStrip;
  112.   if( Added = !Menu->NextMenu ) {  /* insure AMenu is not already attached */
  113.     ClearMenuStrip(M->WBWindow);
  114.     Menu->NextMenu = M->AMenu;
  115.     SetMenuStrip(M->WBWindow, MenuStrip);
  116.   }
  117.   UnlockIBase(ILock);
  118.   return Added;   /* return TRUE if we added the menus */
  119. }
  120.  
  121.  
  122. void
  123. DelMenuStrip()
  124. /* remove our personalized menus from menustrip */
  125. {
  126.   register struct Menu *Menu, *MenuStrip;
  127.   ULONG ILock;
  128.  
  129.   ILock = LockIBase(0L);
  130.   Menu = SearchWBMenus();
  131.   MenuStrip = M->WBWindow->MenuStrip;
  132.   if( Menu->NextMenu ) {         /* insure AMenu is not already attached */
  133.     ClearMenuStrip(M->WBWindow);
  134.     Menu->NextMenu = NULL;
  135.     SetMenuStrip(M->WBWindow, MenuStrip);
  136.   }
  137.   UnlockIBase(ILock);
  138. }
  139.  
  140.  
  141. /* main program - initialize and start up monitor */
  142. void
  143. main() {
  144.  
  145.     /* find data set up by parent */
  146.   M = (struct MPort *)FindPort(AMENU_PORT);
  147.  
  148.     /* Open Libraries */
  149.   ArpBase  = (struct ArpBase *)  OpenLibrary("arp.library",0L);
  150.   IconBase = (struct IconBase *) OpenLibrary("icon.library",0L);
  151.   if( !ArpBase || !IconBase )
  152.     QuitHandler(ERR_LIB);
  153.    /* retrieve other library bases from Arp */
  154.   IntuitionBase = (struct IntuitionBase *) ArpBase->IntuiBase;
  155.   GfxBase       = (struct GfxBase *)       ArpBase->GfxBase;
  156.  
  157.     /* Check Handler */
  158.   if( !M || M->Handler ) { /* MPort dosn't exist or Handler already running */
  159.     Printf("%s is not an executable\n", AMENU_HANDLER);
  160.     ArpExit(20+ERR_MPORT, 0);    /* parent process not running */
  161.   }
  162.  
  163. #ifdef DBUG
  164.   if( !(DBWindow = ArpOpen(DBConsole, MODE_NEWFILE) ) ) {
  165.      Warn("Can't open DBWindow!");
  166.      QuitHandler(ERR_MON);
  167.   }
  168. #endif
  169.  
  170.  
  171.     /* Initialization */
  172.   DB( FPrintf(DBWindow, "Initializing\n"); )
  173.   M->Handler = FindTask(NULL);
  174.   MyProc = (struct Process *)M->Handler;
  175.   MyProc->pr_ConsoleTask = NULL;       /* no console */
  176.   MyProc->pr_CLI         = NULL;       /* not CLI */
  177.   MyProc->pr_WindowPtr   = (APTR)-1;   /* disable requesters for FindIt() */
  178.  
  179.     /* set Current Directory */
  180.   DB( FPrintf(DBWindow, "Locking Directory `%s'\n", M->Directory); )
  181.   if( !(WorkDirLock = Lock( M->Directory, ACCESS_READ )) ) {
  182.     DB( FPrintf(DBWindow, "Lock Failed (%ld)\n", IoErr()); )
  183.     QuitHandler(ERR_DIR);
  184.   }
  185.   OrigDirLock = CurrentDir( WorkDirLock );   /* save the old lock */
  186.  
  187.     /* set up Monitor */
  188.   DB( FPrintf(DBWindow, "Starting Monitor\n"); )
  189.   if( !StartMonitor())
  190.     QuitHandler(ERR_MON);
  191.  
  192.     /* Reply port for WB Processes */
  193.   if( !(WBReplyPort = CreatePort(AMENU_WBPORT, 0)) )
  194.     QuitHandler(ERR_REPLYPORT);
  195.  
  196.     /* Initialization Complete */
  197.   DB( FPrintf(DBWindow, "Signaling Parent\n"); )
  198.   M->ErrorCode = ERR_OK;
  199.   Signal(M->Parent, 1 << M->ParentSig);
  200.  
  201.     /* Add New Menus */
  202.   DB( FPrintf(DBWindow, "Adding Menus\n"); )
  203.   AddMenuStrip();   /* ignore return */
  204.  
  205.   DB( FPrintf(DBWindow, "Monitoring\n"); )
  206. restart:
  207.   Monitor();
  208.  
  209.     /* see if we can leave gracefully */
  210.     /* we don't want to terminate and then have a WB reply message */
  211.   DB( FPrintf(DBWindow, "Attempting to Exit\n"); )
  212.   if( (WBProcesses > 0) &&
  213.         !AutoRequest(NULL, WBOpen, &TrueMsg, &FalseMsg,0,0,370,80) ) {
  214.     M->ErrorCode = ERR_WBOPEN;
  215.     Signal(M->Parent, 1 << M->ParentSig);
  216.     goto restart;
  217.   }
  218.  
  219.     /* clean everything up */
  220.   DB( FPrintf(DBWindow, "Exit cleanup\n"); )
  221.   M->ErrorCode = ERR_OK;
  222.   FinishMonitor();
  223.   DelMenuStrip();
  224.   CloseLibrary((struct Library *)IconBase);
  225.   UnLock( CurrentDir( OrigDirLock ) );   /* return to original directory */
  226.  
  227.   DB( FPrintf(DBWindow, "Final Pause\n"); Delay(600); )
  228.   Forbid();               /* Disable Task switiching until we are done */
  229.  
  230.   { register struct Message *Msg;
  231.     while( Msg=GetMsg(WBReplyPort) )
  232.       WBFree(Msg);
  233.     DeletePort(WBReplyPort);
  234.   }
  235.  
  236.     /* signal parent that we are done */
  237.   Signal(M->Parent, 1 << M->ParentSig);
  238.   ArpExit(0,0);
  239. }
  240.