/*
							-----------------------
								  PPMC_Main.c
								© 1992 REELSOFT
							-----------------------
*/

#include	"PPMC_Main.h"
#include	"PPMC_Proto.h"
#include	"PPMC.h"

VOID	main ( int argc, char *argv[] )
{
	Setup () ;
	MainLoop () ;
	Cleanup ( argc ? FROM_CLI : FROM_WB, RETURN_OK ) ;
}
#ifdef	_DCC
VOID	wbmain ( struct WBStartup * wbmsg )
{
	main ( 01, ( long * )wbmsg ) ;
}
#endif

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
VOID	About (VOID)
{
	rtEZRequestTags (	PPMC_TITLE" "PPMC_VER"\n"PPMC_CPRIGHT"\n\n"
						"Written by Reza ELGHAZI\nUsing...\n\n"
						"SAS/C Compiler v5.10b\n\n"
						"GadToolsBox v1.4\nCopyright Jaba Development\n\n"
						"powerpacker.library v35\n& reqtools.library v38\n"
						"Copyright Nico Francois\n\n"
						"This program is FREEWARE",
						"_Continue", NULL, NULL,
						RT_Window,		PPMCWnd,
						RT_ReqPos,		REQPOS_CENTERSCR,
						RT_LockWindow,	TRUE,
						RT_ShareIDCMP,	TRUE,
						RT_Underscore,	'_',
						RT_TextAttr,	&PPMCFnt,
						RTEZ_ReqTitle,	"About PPMC...",
						RTEZ_Flags,		EZREQF_CENTERTEXT,
						TAG_END	) ;
}

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
BOOL	Quit ( VOID )
{
	BOOL	exit ;	

	exit = (BOOL)rtEZRequestTags (	"Do you really\n""want to quit ?",
									"_Ok|_Cancel",
									NULL, NULL,
									RT_Window,		PPMCWnd,
									RT_ReqPos,		REQPOS_TOPLEFTWIN,
									RT_LockWindow,	TRUE,
									RT_ShareIDCMP,	TRUE,
									RT_Underscore,	'_',
	//								RT_TextAttr,	&PPMCFnt,
									RTEZ_ReqTitle,	PPMC_NAME,
									RTEZ_Flags,		EZREQF_CENTERTEXT,
									TAG_END	) ;
	FreeCrMem () ;
	return ( exit ) ;
}

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» Choosing the File to crunch..
BOOL	Load ( BOOL choose )
{
	struct	rtFileRequester	*filereq ;
	APTR	fr ;

	if ( choose ) {
		filereq = rtAllocRequestA ( RT_FILEREQ, NULL ) ;
		if ( filereq == NULL ) {
			DisplayWarning ( "Out of memory !" ) ;
			Cleanup ( 99, RETURN_WARN ) ;
		}

		fr = rtFileRequest (	filereq, oldname,
								"Select a file to powerpack..",
								RT_Window,		PPMCWnd,
								RT_ReqPos,		REQPOS_CENTERWIN,
								RT_LockWindow,	TRUE,
								RT_ShareIDCMP,	TRUE,
								RT_Underscore,	'_',
								RTFI_OkText,	"_Load",
								TAG_END
		) ;
		if ( fr == FALSE ) {
			rtFreeRequest ( filereq ) ;
			return FALSE ;
		}
		chdir ( filereq->Dir ) ;
		rtFreeRequest ( filereq ) ;
	}

	if ( AnalyseFile () == FALSE )
		return FALSE ;
	else
		sprintf ( newname, oldname ) ;

	//	...
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Save],   PPMCWnd, NULL, GA_Disabled, TRUE,  TAG_DONE ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Start],  PPMCWnd, NULL, GA_Disabled, FALSE, TAG_DONE ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Crunch], PPMCWnd, NULL, GTNM_Number, 0L, TAG_DONE ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Gained], PPMCWnd, NULL, GTNM_Number, 0L, TAG_DONE ) ;

	ClearMenus () ;
	PPMCNewMenu [NM_Save].nm_Flags		= NM_ITEMDISABLED ;
	PPMCNewMenu [NM_SaveAs].nm_Flags	= NM_ITEMDISABLED ;
	PPMCNewMenu [NM_Start].nm_Flags		= 0 ;
	SetupMenus () ;

	FillGauge (0) ;
	FreeCrMem () ;

	return TRUE ;
}

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» Analyse File to Load..
BOOL	AnalyseFile ( VOID )
{
	APTR	*fname = (APTR)&oldname ;
	BPTR	flock ;
	UBYTE	buffer [9] ;

	flock = Open ( oldname, MODE_OLDFILE ) ;
	if ( flock == NULL ) {
		rtEZRequestTags	(	"Unable to open \"%s\" !",
							"_Abort",
							NULL, &fname,
							RT_Window,		PPMCWnd,
							RT_ReqPos,		REQPOS_CENTERWIN,
							RT_LockWindow,	TRUE,
							RT_ShareIDCMP,	TRUE,
							RT_Underscore,	'_',
		//					RT_TextAttr,	&PPMCFnt,
							RTEZ_ReqTitle,	PPMC_WARN,
							RTEZ_Flags,		EZREQF_CENTERTEXT,
							TAG_END	) ;
		return FALSE ;
	}
	Read ( flock, buffer, 8 ) ;
	Close ( flock ) ;

	//	Check if oldname is an executable file...
	if (	buffer [0] == 0x00 && buffer [1] == 0x00 && buffer [2] == 0x03
		&&	buffer [3] == 0xf3 && buffer [4] == 0x00 && buffer [5] == 0x00
		&&	buffer [6] == 0x00 && buffer [7] == 0x00
		&&	rtEZRequestTags	(	"\"%s\"\nis an Executable File\nLoad it anyway ?",
								"_Ok|_Cancel",
								NULL, &fname,
								RT_Window,		PPMCWnd,
								RT_ReqPos,		REQPOS_CENTERWIN,
								RT_LockWindow,	TRUE,
								RT_ShareIDCMP,	TRUE,
								RT_Underscore,	'_',
			//					RT_TextAttr,	&PPMCFnt,
								RTEZ_ReqTitle,	PPMC_WARN,
								RTEZ_Flags,		EZREQF_CENTERTEXT,
								TAG_END ) == FALSE
	)
		return FALSE ;

	buffer [4] = 0x00 ;
	sprintf ( stmsg, "%s", oldname ) ;
	if ( !strcmp ( buffer, "PP20" ) )
		strcat ( stmsg, " (ppacked)" ) ;
	else if ( !strcmp ( buffer, "PX20" ) )
		strcat ( stmsg, " (ppacked & crypted)" ) ;
	strcat ( stmsg, " will be crunched..." ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Status], PPMCWnd, NULL, GTTX_Text, stmsg, TAG_DONE ) ;

	return TRUE ;
}

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» Choosing a Save File..
BOOL	Save ( ULONG cruneff, BOOL crypt, ULONG checksum, BOOL choose )
{
	struct	rtFileRequester	*filereq ;
	APTR	*fname, fr ;
	BPTR	flock ;

#ifdef	LATTICE
	strmfe ( newname, newname, "pp" ) ;
#else
	strcat ( newname, ".pp" ) ;
#endif
	
	fname = (APTR)&newname ;

	if ( choose ) {
		filereq = rtAllocRequestA ( RT_FILEREQ, NULL ) ;
		if ( filereq == NULL ) {
			DisplayWarning ( "Out of memory !" ) ;
			return FALSE ;
		}
		fr = rtFileRequest (	filereq, newname,
								"Select a file to save..",
								RT_Window,		PPMCWnd,
								RT_ReqPos,		REQPOS_CENTERWIN,
								RT_LockWindow,	TRUE,
								RT_ShareIDCMP,	TRUE,
								RT_Underscore,	'_',
								RTFI_OkText,	"_Save",
								RTFI_Flags,		FREQF_SAVE,
								TAG_END	) ;

		if ( fr == FALSE ) {
			rtFreeRequest ( filereq ) ;
			return FALSE ;
		}
		chdir ( filereq->Dir ) ;
		rtFreeRequest ( filereq ) ;
	}

//	Creating the Save File...
	flock = Open ( newname, MODE_NEWFILE ) ;
	if ( flock == NULL ) {
		rtEZRequestTags	(	"Unable to open \"%s\" !",
							"_Abort",
							NULL, &fname,
							RT_Window,		PPMCWnd,
							RT_ReqPos,		REQPOS_CENTERWIN,
							RT_LockWindow,	TRUE,
							RT_ShareIDCMP,	TRUE,
							RT_Underscore,	'_',
		//					RT_TextAttr,	&PPMCFnt,
							RTEZ_ReqTitle,	PPMC_WARN,
							RTEZ_Flags,		EZREQF_CENTERTEXT,
							TAG_END	) ;
		return FALSE ;
	}

//	Writing the Crunch Data Header...
	if ( ppWriteDataHeader ( flock, cruneff, crypt, checksum ) ) {
		//	Writing the Crunched File..
		if ( Write ( flock, cdata, clen ) != clen )
			DisplayWarning ( "Write Error !" ) ;
	}
	else
		DisplayWarning ( "Error writing data header !" ) ;

	Close ( flock ) ;

	sprintf ( stmsg, "%s is saved.", newname ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Status], PPMCWnd, NULL, GTTX_Text, stmsg, TAG_DONE ) ;

//	...
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Save],  PPMCWnd, NULL, GA_Disabled, TRUE, TAG_DONE ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Start], PPMCWnd, NULL, GA_Disabled, TRUE, TAG_DONE ) ;

	ClearMenus () ;
	PPMCNewMenu [NM_Save].nm_Flags		= NM_ITEMDISABLED ;
	PPMCNewMenu [NM_SaveAs].nm_Flags	= NM_ITEMDISABLED ;
	PPMCNewMenu [NM_Start].nm_Flags		= NM_ITEMDISABLED ;
	SetupMenus () ;

	FillGauge (0) ;
	FreeCrMem () ;

	return TRUE ;
}

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
BOOL	Crunch ( ULONG cruneff, ULONG bufsize, ULONG decrcol, UBYTE *password  )
{
	WORD	err ;
	ULONG	errtags [] = {	RT_ShareIDCMP,	TRUE,
							RT_Underscore,	'_',
							RT_TextAttr,	&PPMCFnt,
							RTEZ_ReqTitle,	(UBYTE *)"PPMC Error",
							TAG_END
			} ;

	GT_SetGadgetAttrs ( PPMCGadgets [GD_Save],   PPMCWnd, NULL, GA_Disabled, TRUE,  TAG_DONE ) ;

	FillGauge (0) ;
	FreeCrMem () ;

//	Allocating the Crunching Informations...
	crin = ppAllocCrunchInfo ( cruneff, bufsize, CrStatus, NULL ) ;
	if ( crin == NULL )
		Cleanup ( 99, RETURN_WARN ) ;

//	Loading the File to Crunch...
	sprintf ( stmsg, "Loading %s...", newname ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Status], PPMCWnd, NULL, GTTX_Text, stmsg, TAG_DONE ) ;

	err = ppLoadData ( newname, decrcol, NULL, &cdata, &csize, NULL ) ;
	if ( err ) {
		rtEZRequest ( "%s !", "_Abort", NULL, (struct TagItem *)errtags, ppErrorMessage (err) ) ;
		ppFreeCrunchInfo ( crin ) ;
		strcpy ( stmsg, "Load or Drop another file to crunch..." ) ;
		GT_SetGadgetAttrs ( PPMCGadgets [GD_Status], PPMCWnd, NULL, GTTX_Text, stmsg, TAG_DONE ) ;
		return FALSE ;
	}

//	Crunching...
	crunched = TRUE ;
	sprintf ( stmsg, "Crunching %s...", newname ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Status], PPMCWnd, NULL, GTTX_Text, stmsg, TAG_DONE ) ;

//	Enable the Abort gadget...
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Abort], PPMCWnd, NULL, GA_Disabled, FALSE, TAG_DONE ) ;

	SetAPen ( ppmcRP, 3 ) ;
	clen = ppCrunchBuffer ( crin, cdata, csize ) ;

//	Checking wether or not to crypt the file...
	if ( PPMCGadgets [GD_Crypt]->Flags & GFLG_SELECTED )
		ppDecrypt ( cdata, clen - 4, ppCalcPasskey ( password ) ) ;

//	Disable the Abort gadget...
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Abort], PPMCWnd, NULL, GA_Disabled, TRUE, TAG_DONE ) ;

	switch ( clen ) {
		default :
				GT_SetGadgetAttrs ( PPMCGadgets [GD_Save],  PPMCWnd, NULL, GA_Disabled, FALSE,  TAG_DONE ) ;
				sprintf ( stmsg, "%s crunched.", newname ) ;
				GT_SetGadgetAttrs ( PPMCGadgets [GD_Status], PPMCWnd, NULL, GTTX_Text, stmsg, TAG_DONE ) ;
				FillGauge (3) ;
				GT_SetGadgetAttrs ( PPMCGadgets [GD_Crunch], PPMCWnd, NULL, GTNM_Number, 100L, TAG_DONE ) ;

				ClearMenus () ;
				PPMCNewMenu [NM_Save].nm_Flags		= 0 ;
				PPMCNewMenu [NM_SaveAs].nm_Flags	= 0 ;
				SetupMenus () ;

				DisplayBeep (Scr) ;

				return TRUE ;

		case PP_CRUNCHABORTED :
				rtEZRequestTags	(	"Crunching aborted...",
									"_Resume",
									NULL, NULL,
									RT_Window,		PPMCWnd,
									RT_ReqPos,		REQPOS_POINTER,
									RT_LockWindow,	TRUE,
									RT_ShareIDCMP,	TRUE,
									RT_Underscore,	'_',
				//					RT_TextAttr,	&PPMCFnt,
									RTEZ_ReqTitle,	PPMC_WARN,
									TAG_END	) ;
				break ;

		case PP_BUFFEROVERFLOW :
				DisplayWarning ( "Buffer Overflow !" ) ;
				break ;
	}
	sprintf ( stmsg, "%s will be crunched...", newname ) ;
	GT_SetGadgetAttrs ( PPMCGadgets [GD_Status], PPMCWnd, NULL, GTTX_Text, stmsg, TAG_DONE ) ;

	FillGauge (0) ;
	FreeCrMem () ;

	return FALSE ;
}

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
BOOL	__stdargs __saveds CrStatus ( ULONG sofar, ULONG crunlen, ULONG totlen, APTR userdata )
{
	struct	IntuiMessage	*imsg ;
	ULONG	crunch, gained ;

	if ( sofar ) {
		crunch = ( sofar * 100L ) / totlen ;
		gained = 100L - ( 100L * crunlen) / sofar ;

		RectFill ( ppmcRP, 14, PPMCWnd->BorderTop + 85, 14 + 197 * sofar / totlen, PPMCWnd->BorderTop + 98 ) ;
		GT_SetGadgetAttrs ( PPMCGadgets [GD_Crunch], PPMCWnd, NULL, GTNM_Number, crunch, TAG_DONE ) ;
		GT_SetGadgetAttrs ( PPMCGadgets [GD_Gained], PPMCWnd, NULL, GTNM_Number, gained, TAG_DONE ) ;
	}
//	...
	if ( imsg = GT_GetIMsg ( PPMCWnd->UserPort ) ) {
		if ( imsg->Class == GADGETUP
			&& ((struct Gadget *)(imsg->IAddress))->GadgetID == GD_Abort )
			return FALSE ;
		else
			GT_ReplyIMsg ( imsg ) ;
	}

	return TRUE ;
}

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
VOID	FillGauge ( UBYTE pen )
{
	SetAPen ( ppmcRP, pen ) ;
	RectFill ( ppmcRP, 14,PPMCWnd->BorderTop + 85,210,PPMCWnd->BorderTop + 98 ) ;
}

VOID	FreeCrMem ( VOID )
{
	if ( crunched == TRUE ) {
		FreeMem ( cdata, csize ) ;
		ppFreeCrunchInfo (crin) ;
		crunched = FALSE ;
	}
}

//	»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
VOID	MainLoop (VOID)
{
#ifdef	PPMC_CX
	ULONG	cxsig ;
#endif
	ULONG	globalsig, winsig, appwinsig,
			cruneff		= 4L,	bufsize		= 0L,
			decrcol		= 4L,	checksum	= 0L ;
	UBYTE	password [17] ;
	BOOL	quit	= FALSE,
			crypt	= FALSE ;

	password [0] = newname [0] = oldname [0] = 0x00 ;

	appwinsig	= 1L << msgport->mp_SigBit ;
	winsig		= 1L << PPMCWnd->UserPort->mp_SigBit ;
#ifdef	PPMC_CX
	cxsig		= 1L << BrokerMP->mp_SigBit ;
#endif

	globalsig	= (	appwinsig | winsig
#ifdef	PPMC_CX
					| SIGBREAKF_CTRL_C | cxsig
#endif
	) ;

	do {
		if ( Wait (globalsig) ) {
			if ( msgport && appwinsig ) {
				struct	AppMessage	*amsg ;
				UBYTE	filepath [256] ;

				while ( amsg = (struct AppMessage *)GetMsg (msgport) ) {
#ifdef	LATTICE
					getpath ( amsg->am_ArgList->wa_Lock, filepath ) ;
#else
					NameFromLock ( amsg->am_ArgList->wa_Lock, filepath, 256 ) ;
#endif
					chdir ( filepath ) ;
					strcpy ( oldname, amsg->am_ArgList->wa_Name ) ;
					Load ( FALSE ) ;

					ReplyMsg ( (struct Message *)amsg ) ;
				}
			}
			//	...
			if ( winsig ) {
				struct	IntuiMessage	*imsg ;
				struct	Gadget			*object ;
				struct	MenuItem		*item ;
				UWORD	code ;
				BOOL	loop ;

				while ( imsg = GT_GetIMsg ( PPMCWnd->UserPort ) ) {
					object	= imsg->IAddress;
					code	= imsg->Code ;
					loop	= TRUE ;

					switch ( imsg->Class ) {
						case REFRESHWINDOW :
							GT_BeginRefresh ( PPMCWnd ) ;
							PPMCRender () ;
							if ( crunched == TRUE )
								FillGauge (3) ;
							GT_EndRefresh ( PPMCWnd, TRUE ) ;
							break ;

						case CLOSEWINDOW :
							quit = Quit () ;
							break ;

						case GADGETUP :
							switch ( object->GadgetID ) {
								case GD_About :
									About () ;
									break ;

								case GD_Load :
									Load ( TRUE ) ;
									break ;

								case GD_Save :
									Save ( cruneff, crypt, checksum, TRUE ) ;
									break ;

								case GD_Start :
									if ( crypt == TRUE && ppEnterPassword ( Scr, password ) == TRUE )
										checksum = ppCalcChecksum ( password ) ;
									Crunch ( cruneff, bufsize, decrcol, password ) ;
									break ;

								case GD_Crypt :
									crypt = !crypt ;

									ClearMenus () ;
									if ( crypt == TRUE )
										PPMCNewMenu [NM_Password].nm_Flags = CHECKIT|CHECKED|MENUTOGGLE ;
									else
										PPMCNewMenu [NM_Password].nm_Flags = CHECKIT|MENUTOGGLE ;
									SetupMenus () ;

									break ;
							}
							break ;

						case GADGETDOWN :
							switch ( object->GadgetID ) {
								case GD_CrunEff :
									cruneff = code ;
									break ;

								case GD_BufSize :
									bufsize = code ;
									break ;

								case GD_DecrCol :
									decrcol = code ;
									break ;
							}
							break ;

						case MENUPICK :
							while ( loop == TRUE && code != MENUNULL ) {
								item = ItemAddress ( PPMCMenus, code ) ;

								switch ( MENUNUM (code) ) {
									case 0 :		//	Project Menu
										switch ( ITEMNUM (code) ) {
											case 0 :	//	About...
												About () ;
												break ;

											case 2 :	//	Load...
												Load ( TRUE ) == TRUE ;
												loop = FALSE ;
												break ;

											case 3 :	//	Save
											case 4 :	//	Save As...
												loop = !Save ( cruneff, crypt, checksum, (BOOL)(ITEMNUM(code)-3) ) ;
												break ;

											case 6 :	//	Quit...
												quit = Quit () ;
												break ;
										}
										break ;

									case 1 :		//	Parameters Menu
										switch ( ITEMNUM (code) ) {
											case 0 :	//	Efficiency
												cruneff = SUBNUM (code) ;
												GT_SetGadgetAttrs ( PPMCGadgets [GD_CrunEff], PPMCWnd, NULL, GTMX_Active, cruneff, TAG_DONE ) ;
												break ;

											case 1 :	//	Speedup Buffer
												bufsize = SUBNUM (code) ;
												GT_SetGadgetAttrs ( PPMCGadgets [GD_BufSize], PPMCWnd, NULL, GTMX_Active, bufsize, TAG_DONE ) ;
												break ;

											case 2 :	//	Decrunching Effect
												decrcol = SUBNUM (code) ;
												GT_SetGadgetAttrs ( PPMCGadgets [GD_DecrCol], PPMCWnd, NULL, GTMX_Active, decrcol, TAG_DONE ) ;
												break ;

											case 3 :	//	Password
												crypt = !crypt ;
												GT_SetGadgetAttrs ( PPMCGadgets [GD_Crypt], PPMCWnd, NULL, GTCB_Checked, crypt, TAG_DONE ) ;
												break ;
										}
										break ;

									case 2 :	//	Crunching Menu
										if ( ITEMNUM (code) == 0 ) {	//	Start
											if ( crypt == TRUE && ppEnterPassword ( Scr, password ) == TRUE )
												checksum = ppCalcChecksum ( password ) ;
											Crunch ( cruneff, bufsize, decrcol, password ) ;
											loop = FALSE ;
										}
										break ;
								}
								code = item->NextSelect ;
							}
							break ;
					}
					GT_ReplyIMsg (imsg) ;
				}
			}
#ifdef	PPMC_CX
			if ( SIGBREAKF_CTRL_C ) {
				FreeCrMem () ;
				quit = TRUE ;
			}
			if ( msgport && cxsig ) {
				CxMsg	*cxmsg ;
				ULONG	msgid, msgtype ;

				while ( cxmsg = (CxMsg *)GetMsg ( BrokerMP ) ) {
					msgid	= CxMsgID	(cxmsg) ;
					msgtype	= CxMsgType	(cxmsg) ;
					ReplyMsg ( (struct Message *)cxmsg ) ;

					switch ( msgtype ) {
						case CXM_IEVENT :
							break ;

						case CXM_COMMAND :
							switch ( msgid ) {
								case CXCMD_ENABLE :
									ActivateCxObj ( broker, 0L ) ;
									if ( OpenPPMCWindow () ) {
										DisplayWarning ( "Unable to reopen PPMC Window !" ) ;
										quit = TRUE ;
										break ;
									}
									appwin = AddAppWindow ( 1,0, PPMCWnd, msgport, NULL ) ;
									if ( appwin == NULL ) {
										DisplayWarning ( "Unable to add an AppWindow !" ) ;
										quit = TRUE ;
									}
									break ;

								case CXCMD_DISABLE :
									ActivateCxObj ( broker, 1L ) ;
									FreeCrMem () ;
									ClosePPMCWindow () ;
									if (appwin)
										RemoveAppWindow (appwin) ;
									break ;

								case CXCMD_KILL :
									FreeCrMem () ;
									quit = TRUE ;
									break ;
							}
							break ;
					}
				}
			}
#endif
		}
	} while ( quit == FALSE ) ;
}

VOID	DisplayWarning ( UBYTE *message )
{
	rtEZRequestTags	(	message,
						"_Abort",
						NULL, NULL,
						RT_Window,		PPMCWnd,
						RT_ReqPos,		REQPOS_CENTERWIN,
						RT_LockWindow,	TRUE,
						RT_ShareIDCMP,	TRUE,
						RT_Underscore,	'_',
						RT_TextAttr,	&PPMCFnt,
						RTEZ_ReqTitle,	PPMC_WARN,
						TAG_END	) ;
}

//	...