head	1.4;
access;
symbols;
locks
	msbethke:1.4; strict;
comment	@ * @;


1.4
date	2000.03.30.23.17.52;	author msbethke;	state Exp;
branches;
next	1.3;

1.3
date	2000.02.16.18.25.42;	author msbethke;	state Exp;
branches;
next	1.2;

1.2
date	2000.01.25.17.28.05;	author msbethke;	state Exp;
branches;
next	1.1;

1.1
date	2000.01.25.16.43.18;	author msbethke;	state Exp;
branches;
next	;


desc
@MRQ - The MUI ReQuester improver
Started using RCS for V2.0
@


1.4
log
@Changed NewImage.mcc -> Guigfx.mcc
@
text
@/* mrq.c
** Main program source for MRQ, the MUI Requester Improver
**
** ©1997-2000 by Matthias.Bethke <Matthias.Bethke@@gmx.net>
** You are free to modify this source or use parts of it in your
** own programs as long as they are distributed as freeware.
*/

/* $Id: mrq.c 1.3 2000/02/16 18:25:42 msbethke Exp msbethke $
**
** $Log: mrq.c $
** Revision 1.3  2000/02/16 18:25:42  msbethke
** Disabled DOS requesters for MRQ's main process to avoid deadlocks
**
** Revision 1.2  2000/01/25 17:28:05  msbethke
** Adapted to new header names
**
** Revision 1.1  2000/01/25 16:43:18  msbethke
** Initial revision
**
*/

#include <proto/icon.h>
#include <proto/intuition.h>
#include <proto/rexxsyslib.h>
#include <proto/commodities.h>
#include <proto/datatypes.h>
#include <proto/wbstart.h>
#include <clib/debug_protos.h>
#include <libraries/reqtools.h>
#include <guigfx/guigfx.h>
#include <exec/memory.h>
#include <dos/dostags.h>
#include <lib/mb_utils.h>
#include <MUI/Guigfx_mcc.h>
#include <dos.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "mrq.h"
#include "config.h"
#include "mui_macros.h"
#include "muistuff.h"
#include "Requesters.h"
#include "MRQasm.h"
#include "mrqwindowclass.h"

#define RTEZREQUESTA_OFFSET (-66)
#define EASYREQUESTARGS_OFFSET (-588)

#define GUIGFXLIB_NAME "guigfx.library"
#define GUIGFXLIB_VMIN 15
#define REQTOOLSLIB_NAME "reqtools.library"
#define REQTOOLSLIB_VMIN 0
#define CGFXLIB_NAME "cybergraphics.library"
#define CGFXLIB_VMIN 0

/*************************************************************************/
/* local protos & dummy functions                                        */
/*************************************************************************/
static BOOL OpenLibs(void);
static void CloseLibs(void);
static BOOL BuildApp(void);
static void DisposeApp(APTR app);
static APTR ReadToolTypes(struct WBStartup*);
static APTR ReadShellParams(void);
static STRPTR FindConfigFile(void);
static BOOL CheckDir(STRPTR);
static BOOL AskQuit(void);
static BOOL CheckPatchManager(void);
static LONG DecodeQuality(STRPTR);
static void StartExternalProgram(STRPTR);
static BOOL ExistsIcon(STRPTR);
static BOOL CreateCustomClasses(void);
static void DeleteCustomClasses(void);
/* dummies */
void __regargs _CXBRK(void) {}
void chkabort(void) {}


/*************************************************************************/
/* global identifiers                                                    */
/*************************************************************************/
APTR OldEasyRequestArgs, OldrtEZRequestA, Application;
struct MUI_CustomClass *MUIMRQWindowClass;
struct IClass *MRQWindowClass;
UBYTE ProgName[80]={0};
struct TTVars ttVars = {0};
struct MRQConfig *Config;
const UBYTE VersionString[]="$VER: MRQ 2.0b5 by M.Bethke (30.03.2000)";
struct Library *MUIMasterBase, *GuiGFXBase, *CyberGfxBase;
struct ReqToolsBase *ReqToolsBase;
struct MsgPort *MainPort;
LONG AppActive=TRUE;
LONG __stack = 12288;
BPTR _debugfh=NULL;
STRPTR true_s="TRUE", false_s="FALSE",
		 none_s="<none>", unset_s="<unset>";	// take some work off the stringmerger
/*************************************************************************/
/* hooks                                                                 */
/*************************************************************************/
static void __saveds __asm __interrupt BrokerHookFunc(register __a1 CxMsg*, register __a2 APTR);
struct Hook BrokerHook = {{NULL,NULL},(void*)(&BrokerHookFunc),NULL,NULL};



/*************************************************************************/

LONG main(int argc, char *argv[])
{
LONG rcode = RETURN_OK;
APTR Args;
STRPTR ConfigName;
static const UBYTE MRQRendezvousPort[] = "MRQ.Rendezvous";
struct Process *MyProc;
APTR MyWindowPtr;

	if(!GetProgramName(ProgName,sizeof(ProgName))) strcpy(ProgName,"MRQ");

	MyProc = (struct Process*)FindTask(NULL);
	MyWindowPtr = MyProc->pr_WindowPtr;
	MyProc->pr_WindowPtr = (APTR)-1;

	if(FindPort((STRPTR)MRQRendezvousPort))
	{
		if(argc)
		{
			Printf("%s: already running!\n",*argv);
		} else
		{
		struct EasyStruct es={sizeof(struct EasyStruct),0,"MRQ Error","Please don't start me twice!","I won't!"};

			EasyRequestArgs(NULL,&es,NULL,NULL);
		}
		return RETURN_WARN;
	}

	if(argc)	Args = ReadShellParams();
	else Args = ReadToolTypes((struct WBStartup*)argv);

	if(!Args) return RETURN_FAIL;

	if(!(ConfigName = FindConfigFile()))
	{
	struct EasyStruct es={sizeof(struct EasyStruct),0,"MRQ Error","Can't find config file!","I see"};

		EasyRequestArgs(NULL,&es,NULL,NULL);
		if(argc) FreeArgs((struct RDArgs*)Args);
		else FreeDiskObject((struct DiskObject*)Args);
		return RETURN_ERROR;
	}

	if(ttVars.DefImageDir == NULL || (!CheckDir(ttVars.DefImageDir)))
	{
		if(!CheckDir(ttVars.DefImageDir="PROGDIR:MRQ-images"))
		{
			if(!CheckDir(ttVars.DefImageDir="s:MRQ-images"))
			{
			struct EasyStruct es={sizeof(struct EasyStruct),0,"MRQ Error","Can't find image directory!","I see"};

				EasyRequestArgs(NULL,&es,NULL,NULL);
				if(argc) FreeArgs((struct RDArgs*)Args);
				else FreeDiskObject((struct DiskObject*)Args);
				return RETURN_ERROR;
			}
		}
	}

	if(ttVars.Debug)									// debug info wanted
	{
		if(!argc || strlen(ttVars.Debug))		// WB-start or file specified
		{
			_debugfh=Open(strlen(ttVars.Debug) ?
								ttVars.Debug :				// file specified
								(STRPTR)"CON:40/80/640/180/MRQ_CONSOLE",MODE_NEWFILE);	// default
		} else
		{
			_debugfh = Output();						// use stdout
		}
	}

	prdebug(	"Started %s\n\n"
				"Parameters read:\n\tCONFIGFILE    : %s\n\tMOUSEREQ      : %s\n\t"
				"SAMEWIDTH     : %s\n\tFRONTSCREEN   : %s\n\tTRANSPARENCY  : %s\n\t"
				"SINGLEFRAME   : %s\n\tSIZEABLE      : %s\n\tCENTERTEXT    : %s\n\t"
				"NORTPATCH     : %s\n\tIMAGES        : %s\n\t"
				"QUALITY       : %s\n\tIMG_YES       : %s\n\tIMG_NO        : %s\n\t"
				"IMG_CANCEL    : %s\n\tIBUTTONSBYTEXT: %s\n\tAFTERPATCH    : %s\n\t"
				"AVOIDTASKS    : %s\n\n",
		VersionString+6,
		ConfigName,
		ttVars.MousedReq?true_s:false_s,
		ttVars.SameWidthButtons?true_s:false_s,
		ttVars.FrontmostScreen?true_s:false_s,
		ttVars.Transparency?true_s:false_s,
		ttVars.SingleFrame?true_s:false_s,
		ttVars.Sizeable?true_s:false_s,
		ttVars.Centered?true_s:false_s,
		ttVars.NoRTPatch?true_s:false_s,
		ttVars.DefImageDir,
		(ttVars.Quality==MUIV_Guigfx_Quality_Best)?"Best":
		(ttVars.Quality==MUIV_Guigfx_Quality_Medium)?"Medium":
		(ttVars.Quality==MUIV_Guigfx_Quality_High)?"High":
		"Low",
		ttVars.IB_Yes?ttVars.IB_Yes:none_s,
		ttVars.IB_No?ttVars.IB_No:none_s,
		ttVars.IB_Cancel?ttVars.IB_Cancel:none_s,
		ttVars.IButtonsByText?ttVars.IButtonsByText:unset_s,
		ttVars.AfterPatch?ttVars.AfterPatch:unset_s,
		ttVars.AvoidTasks?ttVars.AvoidTasks:unset_s
		);

	if(OpenLibs())
	{
		if(Config = ReadMRQConfig(ConfigName))
		{
			if(MainPort = CreateMsgPort())
			{
				MainPort->mp_Node.ln_Name = (STRPTR)MRQRendezvousPort;
				MainPort->mp_Node.ln_Pri = -128;
				AddPort(MainPort);

				if(BuildApp())
				{
				ULONG sigs, result;
				BOOL running=TRUE;
				struct MsgPort *RexxRPort;
		
					if(CreateCustomClasses())
					{
						if(RexxRPort = CreateMsgPort())
						{
						LONG RexxMPending=0,	RexxPortSignal, MainPortSignal;
			
							RexxPortSignal = 1<<(RexxRPort->mp_SigBit);
							MainPortSignal = 1<<(MainPort->mp_SigBit);

							OldEasyRequestArgs = SetFunction((struct Library*)IntuitionBase,EASYREQUESTARGS_OFFSET,(APTR)(&EasyRequestArgsPatch));
							prdebug("SetFunction() called on %s\n","intuition.library/EasyRequestArgs()");
							if(ReqToolsBase)				// obviously, only patch if RT found
							{
								if(ttVars.NoRTPatch)		// if no reqtools patching desired
								{
									CloseLibrary((struct Library*)ReqToolsBase);	// close early
									ReqToolsBase = NULL;
								} else
								{
									OldrtEZRequestA = SetFunction((struct Library*)ReqToolsBase,RTEZREQUESTA_OFFSET,(APTR)(&rtEZRequestA_Wedge));
									prdebug("SetFunction() called on %s\n","reqtools.library/rtEZRequestA()");
								}
							}

							if(ttVars.AfterPatch) StartExternalProgram(ttVars.AfterPatch);
							
							prdebug("Entering main loop\n\n");
							while(running)
							{
								result = DoMethod(Application,MUIM_Application_NewInput,&sigs);
			
								switch(result)
								{
									case MUIV_Application_ReturnID_Quit :
										running = !AskQuit();
										break;
			
									default :
										if(result && (!(result & 0x01)))
										{
										struct MRQReqMessage *msg;

											msg = (struct MRQReqMessage*)result;

											if(msg->mrm_EventHandler)
											{
												DoMethod(msg->mrm_WindowObject,
															MUIM_Window_RemEventHandler,
															msg->mrm_EventHandler);
											}
											DoMethod(Application,OM_REMMEMBER,msg->mrm_WindowObject);
											DisposeObject(msg->mrm_WindowObject);
											ReplyMsg((struct Message*)msg);
										}
								}
								if(sigs)
								{
									sigs = Wait(sigs | RexxPortSignal | MainPortSignal | SIGBREAKF_CTRL_C);

									if(sigs & SIGBREAKF_CTRL_C)	// got break signal
									{
										prdebug("Ctrl-C received\n");
										running = FALSE;
										continue;
									}

									if(sigs & MainPortSignal)		// have to set up a new requester
									{
									struct MRQReqMessage *msg;

										if(!(msg = (struct MRQReqMessage*)GetMsg(MainPort)))
										{
											DisplayBeep(NULL);
											continue;
										}

										MUI_EasyRequestArgs(msg);		// setup the entire requester

										if(msg->mrm_FatalError)			// handle errors
										{
											ReplyMsg((struct Message*)msg);
											continue;
										}

										if(msg->mrm_ARexxCmd)			// have to dispatch an ARexx command
										{
										struct RexxMsg *rmsg;

											prdebug("Sending ARexx message:\n\tPORT: '%s'\n\tCMND: '%s'...",msg->mrm_ARexxPort,msg->mrm_ARexxCmd);
		
											if(rmsg = CreateRexxMsg(RexxRPort,NULL,msg->mrm_ARexxPort))
											{
												rmsg->rm_Action	= RXCOMM;
												rmsg->rm_Args[0]	= msg->mrm_ARexxCmd;
												if(FillRexxMsg(rmsg,1,0))
												{
												struct MsgPort *RxDestPort;

													Forbid();
													if(RxDestPort = FindPort(msg->mrm_ARexxPort))
													{
														PutMsg(RxDestPort,(struct Message*)rmsg);
														RexxMPending++;
														Permit();
														prdebug("OK!\n");
													} else
													{
														Permit();
														prdebug("port not found!\n");
													}
												} else prdebug("FillRexxMsg() failed!\n");
											} else prdebug("can't create rexx message!\n");
										}
									}

									if(sigs & RexxPortSignal)		// got ARexx demon reply
									{
									struct RexxMsg *rmsg;
			
										while(rmsg = (struct RexxMsg*)GetMsg(RexxRPort))
										{
											ClearRexxMsg(rmsg,1);
											DeleteRexxMsg(rmsg);
											RexxMPending--;
											prdebug("Rexxhost reply received\n");
										}
									}
								}
							}

							if(ReqToolsBase)
							{
								SetFunction((struct Library*)ReqToolsBase,RTEZREQUESTA_OFFSET,OldrtEZRequestA);
								prdebug("rtEZRequestA()-patch removed\n");
							}
							SetFunction((struct Library*)IntuitionBase,EASYREQUESTARGS_OFFSET,OldEasyRequestArgs);
							prdebug("EasyRequestArgs()-patch removed\n");
							while(RexxMPending)
							{
								WaitPort(RexxRPort);
								GetMsg(RexxRPort);
							}
							DeleteMsgPort(RexxRPort);
						} else
						{
							prdebug("Can't create ARexx communication port!\n");
							rcode=RETURN_FAIL;
						}
						DeleteCustomClasses();
					} else
					{
						prdebug("Can't create custom classes!\n");
						rcode=RETURN_FAIL;
					}
					DisposeApp(Application);		
					prdebug("Disposed of MUI app\n");
				} else
				{
					prdebug("Can't build MUI application object!\n");
					rcode=RETURN_FAIL;
				}
				RemPort(MainPort);
				DeleteMsgPort(MainPort);
			}
			FreeMRQConfig(Config);
		} else rcode=RETURN_FAIL;
		CloseLibs();
	} else rcode=RETURN_FAIL;

	if(_debugfh)										// debug output being printed
	{
		if(strlen(ttVars.Debug) || !argc)		// file specified or WB-start
			Close(_debugfh);
	}

	if(argc) FreeArgs((struct RDArgs*)Args);
	else FreeDiskObject((struct DiskObject*)Args);

	MyProc->pr_WindowPtr = MyWindowPtr;

	return rcode;
}

/*************************************************************************/

static BOOL OpenLibs(void)
{
struct EasyStruct es={sizeof(struct EasyStruct),0,"MRQ Error","Can't open %s V%ld+!","Dammit!"};

	ReqToolsBase = (struct ReqToolsBase*)OpenLibrary(REQTOOLSLIB_NAME, REQTOOLSLIB_VMIN);	// optional
	CyberGfxBase = OpenLibrary(CGFXLIB_NAME,CGFXLIB_VMIN); 			// optional
	if(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN))
	{
		if(GuiGFXBase = OpenLibrary(GUIGFXLIB_NAME,GUIGFXLIB_VMIN))
		{
			return TRUE;
		} else
		{
			EasyRequest(NULL,&es,NULL,GUIGFXLIB_NAME,GUIGFXLIB_VMIN);
			CloseLibs();
		}
	} else
	{
		EasyRequest(NULL,&es,NULL,MUIMASTER_NAME,MUIMASTER_VMIN);
	}
	return FALSE;	
}

static void CloseLibs(void)
{
	if(MUIMasterBase) CloseLibrary(MUIMasterBase);
	if(ReqToolsBase) CloseLibrary((struct Library*)ReqToolsBase);
}

/*************************************************************************/

static BOOL BuildApp(void)
{
	Application = ApplicationObject,
		MUIA_Application_Title      , "MRQ",
		MUIA_Application_Version    , VersionString,
		MUIA_Application_Copyright  , "Matthias Bethke",
		MUIA_Application_Author     , "Matthias Bethke",
		MUIA_Application_Description, "A requester replacement using MUI",
		MUIA_Application_Base       , "MRQ",
		MUIA_Application_SingleTask , TRUE,
		MUIA_Application_BrokerHook , &BrokerHook,
		End;

	if(Application)
	{
		DoMethod(Application,MUIM_Notify,MUIA_Application_Active,MUIV_EveryTime,
					MUIV_Notify_Self,3,MUIM_WriteLong,MUIV_TriggerValue,&AppActive);
	}
	return (BOOL)Application;
}


static void DisposeApp(APTR app)
{
	if(app) MUI_DisposeObject(app);
}

/*************************************************************************/

static APTR ReadToolTypes(struct WBStartup *msg)
{
struct DiskObject *dob;
BPTR olddir=0, homedir;

	if(!(msg->sm_NumArgs)) return NULL;
	homedir = msg->sm_ArgList[0].wa_Lock;
	if(homedir) olddir = CurrentDir(homedir);

	if(dob = GetDiskObject(msg->sm_ArgList[0].wa_Name))
	{
		ttVars.ConfigName			= FindToolType(dob->do_ToolTypes,"CONFIGFILE");
		ttVars.Debug				= FindToolType(dob->do_ToolTypes,"DEBUG");
		ttVars.MousedReq			= (LONG)FindToolType(dob->do_ToolTypes,"MOUSEREQ");
		ttVars.SameWidthButtons	= (LONG)FindToolType(dob->do_ToolTypes,"SAMEWIDTH");
		ttVars.FrontmostScreen	= (LONG)FindToolType(dob->do_ToolTypes,"FRONTSCREEN");
		ttVars.SingleFrame		= (LONG)FindToolType(dob->do_ToolTypes,"SINGLEFRAME");
		ttVars.Transparency		= (LONG)FindToolType(dob->do_ToolTypes,"TRANSPARENCY");
		ttVars.Sizeable			= (LONG)FindToolType(dob->do_ToolTypes,"SIZEABLE");
		ttVars.Centered			= (LONG)FindToolType(dob->do_ToolTypes,"CENTERTEXT");
		ttVars.NoRTPatch			= (LONG)FindToolType(dob->do_ToolTypes,"NORTPATCH");
		ttVars.DefaultIcon		= (LONG)FindToolType(dob->do_ToolTypes,"DEFAULTICON");
		ttVars.DefImageDir		= FindToolType(dob->do_ToolTypes,"IMAGES");
		ttVars.IButtonsByText	= FindToolType(dob->do_ToolTypes,"IBUTTONSBYTEXT");
		ttVars.IB_Yes				= FindToolType(dob->do_ToolTypes,"IMG_YES");
		ttVars.IB_No				= FindToolType(dob->do_ToolTypes,"IMG_NO");
		ttVars.IB_Cancel			= FindToolType(dob->do_ToolTypes,"IMG_CANCEL");
		ttVars.AfterPatch			= FindToolType(dob->do_ToolTypes,"AFTERPATCH");
		ttVars.AvoidTasks			= FindToolType(dob->do_ToolTypes,"AVOIDTASKS");

		ttVars.Quality				= DecodeQuality(FindToolType(dob->do_ToolTypes,"QUALITY"));
	} else PrintFault(IoErr(),ProgName);
	if(olddir) CurrentDir(olddir);
	return (APTR)dob;
}

static APTR ReadShellParams(void)
{
struct RDArgs *Args;
struct MRQShellArguments args={0};

	if(Args = ReadArgs(
		"Configfile,IMD=ImageDir/K,BY=Button_Yes/K,BN=Button_No/K,BC=Button_Cancel/K,"
		"IBBT=IButtonsByText/K,QU=Quality/K,AT=AvoidTasks/K,DI=DefaultIcon/S"
		"MR=MouseReq/S,SW=SameWidth/S,FS=FrontScreen/S,"
		"SF=SingleFrame/S,TR=Transparency/S,SI=Sizeable/S,CT=CenterText/S,NRTP=NoRTPatch/S,"
		"AP=AfterPatch/K,Debug/K",(LONG*)&args,NULL))
	{
		ttVars.ConfigName		= args.ConfigName;	// may be NULL!

		ttVars.DefImageDir	= args.DefImageDir	? args.DefImageDir	: NULL;
		ttVars.IB_Yes			= args.IB_Yes			? args.IB_Yes			: NULL;
		ttVars.IB_No			= args.IB_No			? args.IB_No			: NULL;
		ttVars.IB_Cancel		= args.IB_Cancel		? args.IB_Cancel		: NULL;
		ttVars.IButtonsByText= args.IButtonsByText? args.IButtonsByText: NULL;

		ttVars.Quality		= DecodeQuality(args.Quality);

		ttVars.MousedReq			= args.MousedReq;
		ttVars.SameWidthButtons	= args.SameWidth;
		ttVars.FrontmostScreen	= args.FrontScreen;
		ttVars.SingleFrame		= args.SingleFrame;
		ttVars.Transparency		= args.Transparency;
		ttVars.Sizeable			= args.Sizeable;
		ttVars.Centered			= args.Centered;
		ttVars.NoRTPatch			= args.NoRTPatch;
		ttVars.AfterPatch			= args.AfterPatch;
		ttVars.Debug				= args.Debug;
		ttVars.AvoidTasks			= args.AvoidTasks;
		ttVars.DefaultIcon		= args.DefaultIcon;
	} else PrintFault(IoErr(),ProgName);
	return (APTR)Args;
}

/*************************************************************************/

static void __saveds __asm __interrupt BrokerHookFunc(register __a1 CxMsg *cxm, register __a2 APTR app)
{
	if(CxMsgType(cxm) == CXM_COMMAND)
	{
		if(CxMsgID(cxm) == CXCMD_APPEAR)
		{
			if(MUI_RequestA(Application,NULL,0,"MRQ Request","*_MUIprefs|_Configfile",
									"Edit MUI settings for MRQ\nor edit the configfile?",
									NULL))
			{
				DoMethod(app,MUIM_Application_OpenConfigWindow,0);
			} else prdebug("Configfile editing not yet implemented!\n");
		}
	}
}

/*************************************************************************/


static LONG DecodeQuality(STRPTR s)
{
	if(s)
	{
		if(!stricmp(s,"best")) return MUIV_Guigfx_Quality_Best;
		if(!stricmp(s,"high")) return MUIV_Guigfx_Quality_High;
		if(!stricmp(s,"low")) return MUIV_Guigfx_Quality_Low;
	}
	return MUIV_Guigfx_Quality_Medium;		// default
}


/*************************************************************************/

static void StartExternalProgram(STRPTR ttype)
{
BPTR FileLock;
BOOL WBStarted=FALSE;

	if(FileLock = Lock(ttype,ACCESS_READ))
	{
	BPTR DirLock;

		DirLock = ParentDir(FileLock);
		UnLock(FileLock);
		if(ExistsIcon(ttype))
		{
		struct Library *WBStartBase;

			if(WBStartBase = OpenLibrary("wbstart.library",0))
			{
				prdebug("Starting Workbench program '%s'\n",ttype);

				if(WBStartTags(WBStart_Name, ttype,
									WBStart_DirectoryLock, DirLock,
									TAG_DONE) == RETURN_OK)
				{
					WBStarted = TRUE;
				} else
				{
					prdebug("Error starting program!\n");
				}
				CloseLibrary(WBStartBase);
			} else prdebug("Starting Workbench programs requires %s\n","wbstart.library");
		}
	}

	if(!WBStarted)
	{
	STRPTR tt,prog,args;

		if(tt = AllocVecPooled(Config->mc_MemPool,strlen(ttype)+1))
		{
			strcpy(tt,ttype);

			prog = strtok(tt," ");
			args = strtok(NULL," ");

			prdebug("Starting shell program \"%s\" (parameters: \"%s\")\n",prog,args?args:(STRPTR)"<none>");

			if(SystemTags(prog,
								NP_Arguments,args,
								SYS_Asynch,TRUE,
								TAG_DONE) != RETURN_OK)
			{
				prdebug("Error starting program!\n");
			}
			FreeVecPooled(Config->mc_MemPool,tt);
		}
	}
}

static BOOL ExistsIcon(STRPTR prog)
{
STRPTR icon;
ULONG proglen;
BOOL ret = FALSE;

	proglen = strlen(prog);
	if(icon = AllocVecPooled(Config->mc_MemPool,proglen+6))
	{
	BPTR lock;

		strcpy(icon,prog);
		strcpy(icon+proglen,".info");
		if(lock = Lock(icon,ACCESS_READ))
		{
			UnLock(lock);
			ret = TRUE;
		}
		FreeVecPooled(Config->mc_MemPool,icon);
	}
	return ret;
}

/*************************************************************************/

static STRPTR FindConfigFile(void)
{
static STRPTR CfgAlts[3] = {NULL,"PROGDIR:MRQ.config","s:MRQ.config"};
BPTR lock;
int i;

	i = (CfgAlts[0] = ttVars.ConfigName) ? 0 : 1;
	for(; i<(sizeof(CfgAlts)/sizeof(STRPTR)); i++)
	{
		if(lock=Lock(CfgAlts[i],ACCESS_READ))
		{
			UnLock(lock);
			return CfgAlts[i];
		}
	}
	return NULL;
}

static BOOL CheckDir(STRPTR dir)
{
BPTR lock;
BOOL ret=FALSE;

	if(lock=Lock(dir,ACCESS_READ))
	{
	struct FileInfoBlock *fib;
		if(fib = AllocDosObjectTagList(DOS_FIB,NULL))
		{
			if(Examine(lock,fib))
			{
				if(fib->fib_DirEntryType > 0) ret=TRUE;	// entry is directory
			}
			FreeDosObject(DOS_FIB,fib);
		}
		UnLock(lock);
	}
	return ret;
}

static BOOL AskQuit(void)
{

	if(CheckPatchManager()) return TRUE;	// don't ask if it's safe to remove patches

	if(ttVars.AfterPatch)
	{
		MUI_RequestA(Application,NULL,0,"MRQ Error","*:-(",
			"MRQ has started another program after patching!\n"
			"Therefore it can't be unloaded without causing\n"
			"a certain crash on the next call to a patched function.",NULL);
		return FALSE;
	}
	return (BOOL)MUI_RequestA(Application,NULL,0,"MRQ Warning","_I am sure|*_Not really",
						"Are you sure you want to quit MRQ?\n"
						"This is not safe if other programs have\n"
						"patched the same functions!",NULL);
}

static BOOL CheckPatchManager(void)
{
BOOL ret;

	Forbid();
	ret = (BOOL)(FindPort("SetMan"));
	Permit();
	return ret;
}

static BOOL CreateCustomClasses(void)
{
	if(MUIMRQWindowClass = NewMRQWindowClass())
	{
		MRQWindowClass = MUIMRQWindowClass->mcc_Class;
		return TRUE;
	}
	DeleteCustomClasses();
	return FALSE;
}

static void DeleteCustomClasses(void)
{
	if(MUIMRQWindowClass)	MUI_DeleteCustomClass(MUIMRQWindowClass);
}



void prdebug(char *fmt, ...)
{
va_list arglist;
char tbuf[768];

	if(ttVars.Debug)
	{
		memset(tbuf,0,sizeof(tbuf));
		va_start(arglist,fmt);
		mb_VNSPrintf(tbuf,fmt,sizeof(tbuf),(LONG*)arglist);
		FPuts(_debugfh,tbuf);
		va_end(arglist);
	}
}
@


1.3
log
@Disabled DOS requesters for MRQ's main process to avoid deadlocks
@
text
@d9 1
a9 1
/* $Id: mrq.c 1.2 2000/01/25 17:28:05 msbethke Exp msbethke $
d12 3
d35 1
a35 1
#include <MUI/NewImage_mcc.h>
d91 1
a91 1
const UBYTE VersionString[]="$VER: MRQ 2.0b3 by M.Bethke (16.02.2000)";
d202 3
a204 3
		(ttVars.Quality==MUIV_NewImage_Quality_Best)?"Best":
		(ttVars.Quality==MUIV_NewImage_Quality_Medium)?"Medium":
		(ttVars.Quality==MUIV_NewImage_Quality_High)?"High":
d574 3
a576 3
		if(!stricmp(s,"best")) return MUIV_NewImage_Quality_Best;
		if(!stricmp(s,"high")) return MUIV_NewImage_Quality_High;
		if(!stricmp(s,"low")) return MUIV_NewImage_Quality_Low;
d578 1
a578 1
	return MUIV_NewImage_Quality_Medium;		// default
d608 1
a608 1
				}
@


1.2
log
@Adapted to new header names
@
text
@d9 1
a9 1
/* $Id: mrq.c 1.1 2000/01/25 16:43:18 msbethke Exp msbethke $
d12 3
d88 1
a88 1
const UBYTE VersionString[]="$VER: MRQ 1.13 by M.Bethke (25.01.2000)";
d112 3
a114 1
static UBYTE MRQRendezvousPort[] = "MRQ.Rendezvous";
a115 1
 
d118 5
a122 1
	if(FindPort(MRQRendezvousPort))
d217 1
a217 1
				MainPort->mp_Node.ln_Name = MRQRendezvousPort;
d404 3
@


1.1
log
@Initial revision
@
text
@d9 5
a13 1
/* $Id:$
a14 1
** $Log:$
d36 1
a36 1
#include "mrq_config.h"
d39 1
a39 1
#include "MUI_ERA.h"
@
