home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
530b.lha
/
AMenu_v1.3
/
AMenu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-03
|
7KB
|
240 lines
/*********************************************************************\
** ________________________________ **
** A n t h o n y |________ __ __ ________| **
** | |o_| |o_| | **
** T h y s s e n __| __ __ |__ **
** __| __| | | |__ |__ **
** `` Dragon Computing ! '' __| __| | | |__ |__ **
** |_____| |__| |_____| **
** **
\*********************************************************************/
/* This program puts customized menus into the WorkBench menubar.
* The program is split up into two parts, AMenu and AMenu-Handler.
* This section is AMenu and it initializes and starts up a process
* to run AMenu-Handler, and then terminates. AMenu also terminates
* and cleans up after the suprocess. AMenu will parse the users
* menus, initialize data to be passed to AMenu-Handler, and start
* up AMenu-Handler. AMenu-Handler does very little memory
* allocation in order to save space, so AMenu does allocation and
* freeing for it.
*/
#include "AMenu.h" /* Handler Message Port definition */
#include "AllocStr.h" /* String Allocation macros */
#include "ArpC.h" /* Header for ArpC startup code */
struct MPort *M; /* Externel Handler Port (Named Port) */
extern void FreeMenus(); /* External Routines called */
extern BOOL ParseMenus();
/*---------------------------------------------------*/
void
ExitAMenu(Str,Ret)
char *Str;
int Ret;
/* Print string and exit. The Arp, Graphics, and Intuition
** libraries are automatically closed by ArpC startup code
*/
{
Puts(Str); exit(Ret);
}
void
RemoveHandler()
/* shutdown and clean up after handler */
{
if (!M)
return;
Printf("Removing -- ", VERSION);
DB( Puts(""); )
if( M->Segment ) {
DB( Puts("Signaling Handler to Exit - Waiting"); )
M->Parent = (struct Task *)Process; /* from ArpC startup code */
M->ParentSig = AllocSignal(-1L);
Signal( M->Handler, SIGBREAKF_CTRL_C); /* don't advertize use of ^C */
Wait(1 << M->ParentSig);
FreeSignal(M->ParentSig);
DB( Puts("Handler has reported in"); )
switch( M->ErrorCode ) {
case ERR_OK:
break;
case ERR_WBOPEN: /* WB process still active */
ExitAMenu("Leaving handler in place...\n", 0);
default: /* some strange error */
Printf("Handler reports error (%ld)", (LONG)M->ErrorCode);
ExitAMenu("",0);
}
DB( Puts("Unloading Port/Handler"); )
RemPort( &M->Port );
UnLoadSeg( M->Segment );
}
/* this is done here, not in handler... */
DB( Puts("Freeing Menus/Port"); )
FreeMenus();
if( M->Port.mp_Node.ln_Name )
FreeStr(M->Port.mp_Node.ln_Name);
if( M->Directory )
FreeStr(M->Directory);
if( M->Console )
FreeStr(M->Console);
FreeMem(M, sizeof(struct MPort));
ExitAMenu("Done", 0);
}
void
HandlerReport()
/* report the result from load or update of handler */
{
switch( M->ErrorCode ) {
case ERR_OK:
ExitAMenu("OK", 0);
case ERR_DIR:
Puts("Bad Global Directory - Can't Lock\n");
break;
case ERR_LIB:
Puts("Handler unable to open Libraries\n");
break;
default:
Printf("Handler returned error (%ld)\n", (LONG)M->ErrorCode);
}
RemoveHandler();
}
void
UpdateHandler()
/* The Handler already exists so just replace the menus */
{
Printf("Updating %s -- ", VERSION);
DB( Puts("\nSignaling Handler for Update - Waiting"); )
M->Parent = (struct Task *)Process; /* from ArpC startup code */
M->ParentSig = AllocSignal(-1L);
Signal(M->Handler, SIGBREAKF_CTRL_D);
Wait(1 << M->ParentSig);
FreeSignal(M->ParentSig);
FreeMenus();
DB( Puts("Handler Waiting -- Updating Menus"); )
if( ParseMenus() )
RemoveHandler();
DB( Puts("Signaling Handler to Continue"); )
Signal(M->Handler, SIGBREAKF_CTRL_D);
HandlerReport();
}
void
LoadHandler()
/* Load, Read config and Start Handler */
{
struct Screen *Scr;
ULONG ILock;
Printf("Installing %s -- ", VERSION);
DB( Puts("\nCreating Port"); ) /* do NOT use ArpAlloc() */
M = (struct MPort *)AllocMem( sizeof(struct MPort), MEMF_PUBLIC|MEMF_CLEAR);
DB( Puts("Locating WB Window"); )
Scr = (struct Screen *)OpenWorkBench(); /* this returns workbench */
if( !Scr ) {
FreeMem( M, sizeof(struct MPort) );
ExitAMenu("Unable to locate Workbench screen!",24);
}
ILock = LockIBase(NULL);
for( M->WBWindow=Scr->FirstWindow; M->WBWindow;
M->WBWindow = M->WBWindow->NextWindow )
if( M->WBWindow->Flags & WBENCHWINDOW ) break;
UnlockIBase(ILock);
if( !M->WBWindow ) {
FreeMem( M, sizeof(struct MPort) );
ExitAMenu("Unable to locate Workbench Window!",25);
}
if( ParseMenus() )
RemoveHandler();
DB( Puts("Adding Port"); )
M->Port.mp_Flags = PA_IGNORE;
M->Port.mp_Node.ln_Pri = 0;
M->Port.mp_Node.ln_Type = NT_MSGPORT;
M->Port.mp_Node.ln_Name = AllocStr(AMENU_PORT);
AddPort(&M->Port);
DB( Puts("Loading Handler"); )
M->Segment = LoadPrg(AMENU_HANDLER);
if (!M->Segment)
M->Segment = LoadPrg(AMENU_HANDLER2);
if (!M->Segment) {
Printf("Can't find %s", AMENU_HANDLER);
RemoveHandler();
}
DB( Puts("Starting Handler"); )
if( !CreateProc(AMENU_HANDLER2, 0, M->Segment, DEF_STACK) ) {
Puts("Can't Create Process!");
RemoveHandler();
}
/* handshake so that we know it got started ok */
DB( Puts("Waiting for Handler Signal"); )
M->Parent = (struct Task *)Process; /* from ArpC startup code */
M->ParentSig = AllocSignal(-1L);
Wait(1 << M->ParentSig);
FreeSignal(M->ParentSig);
DB( Puts("Handler Signal recieved"); )
HandlerReport();
}
/*-----------------------------------------------------------------*/
/* These globals are for ArpC the startup code used */
char *CLI_Args[2]; /* the argc array -- in line with template below */
char *CLI_Template = "Q=QUIT/s,V=VERSION/s";
char *CLI_Help = "Amenu [QUIT] -- AMenu by Anthony Thyssen";
void
main(argc,argv) /* called from ArpC */
int argc;
char *argv[];
{
/* the Arp library (thus Graphics and Intuition libraries) are
** opened in the ArpC startup code. Any CLI arguments given in
** the template is also parsed and placed in correct position.
*/
/* Locate Named Port -- see if handler is running */
M = (struct MPort *)FindPort(AMENU_PORT);
if( CLI_Args[0] ) /* Was QUIT was given? */
RemoveHandler(); /* no return */
if( CLI_Args[1] ) /* Was VERSION asked for? */
ExitAMenu(COPYRIGHT,0); /* no return */
if( M )
UpdateHandler(); /* no return */
LoadHandler(); /* no return */
/* should never be reached */
}