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 >
Wrap
C/C++ Source or Header
|
1991-07-03
|
8KB
|
240 lines
/*********************************************************************\
** ________________________________ **
** A n t h o n y |________ __ __ ________| **
** | |o_| |o_| | **
** T h y s s e n __| __ __ |__ **
** __| __| | | |__ |__ **
** `` Dragon Computing ! '' __| __| | | |__ |__ **
** |_____| |__| |_____| **
** **
\*********************************************************************/
/* This is the main process for AMenu. This gets loaded and run in the
* background by AMenu. When started, it finishes initializing itself,
* and starts monitoring the WorkBench IDCMP port. If any messages show
* up that we are interested in, we run them as a CLI or WorkBench
* process. We don't do any memory allocation or cleanup and leave that
* all to AMenu (in order to save some space). Communication with
* AMenu is done via a public port - never used as a port, but it holds
* "global" variables.
*/
#include "AMenu.h"
#include <libraries/dosextens.h> /* definition for struct Process */
static char *Copyright = COPYRIGHT;
struct ArpBase *ArpBase = NULL; /* Library Bases */
struct IntuitionBase *IntuitionBase = NULL; /* from ArpBase */
struct GfxBase *GfxBase = NULL; /* from ArpBase */
struct IconBase *IconBase = NULL; /* Opened normally */
struct MPort *M = NULL; /* Port & data from AMenu */
struct MsgPort *WBReplyPort = NULL; /* WB processes replies */
struct Process *MyProc; /* This Process */
BPTR WorkDirLock = NULL, OrigDirLock = NULL; /* Directory Locks */
int WBMenus, WBProcesses=0; /* Counts of things */
extern BOOL StartMonitor();
extern void Monitor(),FinishMonitor();
extern void WBFree(), Warn(char *);
DB( BPTR DBWindow = NULL; ) /* Debuging Output Window - Arp Closes */
/*------------------------------------------------*/
struct IntuiText /* Exit while WB Processes still running requester */
WBOpen[] = {
{ 3,1,JAM1,142,4,NULL, (UBYTE*)"WARNING!!", &WBOpen[1] },
{ 0,1,JAM1, 7,12,NULL, (UBYTE*)"A WorkBench program started by AMenu may", &WBOpen[2] },
{ 0,1,JAM1, 7,20,NULL, (UBYTE*)"still be open. This can cause a crash if", &WBOpen[3] },
{ 0,1,JAM1, 7,28,NULL, (UBYTE*)"the program finishes after AMenu.", &WBOpen[4] },
{ 3,1,JAM1,24,36,NULL, (UBYTE*)"Do you REALLY want to quit now?", NULL },
},
TrueMsg = { 0,1,JAM2, 7,3 ,NULL, (UBYTE*)"QUIT", NULL },
FalseMsg = { 0,1,JAM2, 7,3 ,NULL, (UBYTE*)"Cancel", NULL };
void
QuitHandler(Code)
short Code;
/* return error to AMenu during initialization */
{
if( M ) {
M->ErrorCode = Code;
Signal(M->Parent, 1 << M->ParentSig); /* Signal Parent */
Wait(SIGBREAKF_CTRL_C); /* Wait for parent removal */
Signal(M->Parent, 1 << M->ParentSig); /* Final Signal */
}
if( WBReplyPort ) DeletePort( WBReplyPort );
if( OrigDirLock ) CurrentDir( OrigDirLock );
if( WorkDirLock ) UnLock( WorkDirLock );
if( IconBase ) CloseLibrary( (struct Library *)IconBase );
if( ArpBase ) {
DB( if(DBWindow) FPrintf(DBWindow, "Handler Quit -- %d\n", Code); )
DB( Delay(600); )
ArpExit(20+Code,0); /* OK as no true startup code used by handler */
} else
Exit(20+Code);
}
static struct Menu *
SearchWBMenus()
/* Search the WB menus for either last menu or menu before AMenu
** This Routine also determines the number of WBMenus to determine
** if we recieve a WB menu or AMenu selection.
*/
{
register struct Menu *Menu;
for( Menu = M->WBWindow->MenuStrip, WBMenus=1;
Menu->NextMenu && Menu->NextMenu != M->AMenu;
Menu = Menu->NextMenu, WBMenus++ );
return( Menu );
}
BOOL
AddMenuStrip()
/* add personalized menus to menustrip -- return true if menus added */
{
register struct Menu *Menu, *MenuStrip;
ULONG ILock;
BOOL Added; /* did we attach the menus or were thay in place? */
ILock = LockIBase(NULL);
Menu = SearchWBMenus();
MenuStrip = M->WBWindow->MenuStrip;
if( Added = !Menu->NextMenu ) { /* insure AMenu is not already attached */
ClearMenuStrip(M->WBWindow);
Menu->NextMenu = M->AMenu;
SetMenuStrip(M->WBWindow, MenuStrip);
}
UnlockIBase(ILock);
return Added; /* return TRUE if we added the menus */
}
void
DelMenuStrip()
/* remove our personalized menus from menustrip */
{
register struct Menu *Menu, *MenuStrip;
ULONG ILock;
ILock = LockIBase(0L);
Menu = SearchWBMenus();
MenuStrip = M->WBWindow->MenuStrip;
if( Menu->NextMenu ) { /* insure AMenu is not already attached */
ClearMenuStrip(M->WBWindow);
Menu->NextMenu = NULL;
SetMenuStrip(M->WBWindow, MenuStrip);
}
UnlockIBase(ILock);
}
/* main program - initialize and start up monitor */
void
main() {
/* find data set up by parent */
M = (struct MPort *)FindPort(AMENU_PORT);
/* Open Libraries */
ArpBase = (struct ArpBase *) OpenLibrary("arp.library",0L);
IconBase = (struct IconBase *) OpenLibrary("icon.library",0L);
if( !ArpBase || !IconBase )
QuitHandler(ERR_LIB);
/* retrieve other library bases from Arp */
IntuitionBase = (struct IntuitionBase *) ArpBase->IntuiBase;
GfxBase = (struct GfxBase *) ArpBase->GfxBase;
/* Check Handler */
if( !M || M->Handler ) { /* MPort dosn't exist or Handler already running */
Printf("%s is not an executable\n", AMENU_HANDLER);
ArpExit(20+ERR_MPORT, 0); /* parent process not running */
}
#ifdef DBUG
if( !(DBWindow = ArpOpen(DBConsole, MODE_NEWFILE) ) ) {
Warn("Can't open DBWindow!");
QuitHandler(ERR_MON);
}
#endif
/* Initialization */
DB( FPrintf(DBWindow, "Initializing\n"); )
M->Handler = FindTask(NULL);
MyProc = (struct Process *)M->Handler;
MyProc->pr_ConsoleTask = NULL; /* no console */
MyProc->pr_CLI = NULL; /* not CLI */
MyProc->pr_WindowPtr = (APTR)-1; /* disable requesters for FindIt() */
/* set Current Directory */
DB( FPrintf(DBWindow, "Locking Directory `%s'\n", M->Directory); )
if( !(WorkDirLock = Lock( M->Directory, ACCESS_READ )) ) {
DB( FPrintf(DBWindow, "Lock Failed (%ld)\n", IoErr()); )
QuitHandler(ERR_DIR);
}
OrigDirLock = CurrentDir( WorkDirLock ); /* save the old lock */
/* set up Monitor */
DB( FPrintf(DBWindow, "Starting Monitor\n"); )
if( !StartMonitor())
QuitHandler(ERR_MON);
/* Reply port for WB Processes */
if( !(WBReplyPort = CreatePort(AMENU_WBPORT, 0)) )
QuitHandler(ERR_REPLYPORT);
/* Initialization Complete */
DB( FPrintf(DBWindow, "Signaling Parent\n"); )
M->ErrorCode = ERR_OK;
Signal(M->Parent, 1 << M->ParentSig);
/* Add New Menus */
DB( FPrintf(DBWindow, "Adding Menus\n"); )
AddMenuStrip(); /* ignore return */
DB( FPrintf(DBWindow, "Monitoring\n"); )
restart:
Monitor();
/* see if we can leave gracefully */
/* we don't want to terminate and then have a WB reply message */
DB( FPrintf(DBWindow, "Attempting to Exit\n"); )
if( (WBProcesses > 0) &&
!AutoRequest(NULL, WBOpen, &TrueMsg, &FalseMsg,0,0,370,80) ) {
M->ErrorCode = ERR_WBOPEN;
Signal(M->Parent, 1 << M->ParentSig);
goto restart;
}
/* clean everything up */
DB( FPrintf(DBWindow, "Exit cleanup\n"); )
M->ErrorCode = ERR_OK;
FinishMonitor();
DelMenuStrip();
CloseLibrary((struct Library *)IconBase);
UnLock( CurrentDir( OrigDirLock ) ); /* return to original directory */
DB( FPrintf(DBWindow, "Final Pause\n"); Delay(600); )
Forbid(); /* Disable Task switiching until we are done */
{ register struct Message *Msg;
while( Msg=GetMsg(WBReplyPort) )
WBFree(Msg);
DeletePort(WBReplyPort);
}
/* signal parent that we are done */
Signal(M->Parent, 1 << M->ParentSig);
ArpExit(0,0);
}