/***************************************************************
 * vt100 - terminal emulator - initialization
 *				:ts=8
 *
 *	v2.9 ACS - Support new cmds EXT.  Use S and R for Send and Receive menu
 *		   items instead of ^ and V.  AREXX support.
 *	v2.8a 880331 ACS - Allow lines 0 in init file to *really* mean
 *			  "use all available lines".
 *	v2.7 870825 ACS - Allow execution of all script files specified on
 *			  command line (companion to changes in script.c).
 *			  Rolled menu init into one routine (do_menu_init()).
 *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
 *	v2.5 870214 DBW - more additions (see readme file)
 *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
 *	v2.3 861101 DBW - minor bug fixes
 *	v2.2 861012 DBW - more of the same
 *	v2.1 860915 DBW - new features (see README)
 *	     860901 ACS - Added Parity and Word Length and support code
 *	     860823 DBW - Integrated and rewrote lots of code
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW - First version released
 *
 ***************************************************************/

#include "vt100.h"

struct Device *ConsoleDevice = NULL;
struct IOStdReq ConReq;
extern APTR OrigWindowPtr;
extern int capture;		/* in vt100.c */

/*   Used by script.c for script file chaining. */
int script_files_todo = 0;
char **script_files = NULL;

char line[256];

/* Command key equivalences per menu.  Manipulated by script.c */

/*   Equivalences for the File menu... */
struct filecmd {
    char mo;	/* Mode			*/
    char se;	/* Send			*/
    char re;	/* Receive		*/
    char kg;	/* Kermit Get		*/
    char kb;	/* Kermit Bye		*/
    char ca;	/* Capture or Capturing */
    char nl;
} filecmd_chars = { ' ', 'S', 'R', 'G', 'B', ' ', '\0' };

/*   Equivalences for Mode sub-menu... */
struct mode_cmd {
    char as;	/* ascii mode		*/
    char xm;	/* xmodem mode		*/
    char xmc;	/* xmodemcrc mode	*/
    char ke;	/* kermit mode		*/
    char nl;
} modecmd_chars = { ' ', 'X', ' ', 'K', '\0' };

/*   Equivalences for the Comm menu... */
struct commcmd {
    char nl0;	/* Baud Sub-Item	*/
    char nl1;	/* Parity Sub-Item	*/
    char nl2;	/* Xfer mode Sub-Item	*/
    char sh;	/* Shared item		*/
    char nl;
} commcmd_chars = { ' ', ' ', ' ', ' ', '\0' };

/*   Equivalences for the Baud Rate sub-menu... */
struct baudcmd {
    char b03;	/* 0300			*/
    char b12;	/* 1200			*/
    char b24;	/* 2400			*/
    char b48;	/* 4800			*/
    char b96;	/* 9600			*/
    char bnl;
} baudcmd_chars = { ' ', 'L', 'H', ' ', ' ', '\0' };

/*   Equivalences for the Parity sub-menu... */
struct parcmd {
    char no;	/* NOne			*/
    char ma;	/* MArk			*/
    char sp;	/* SPace		*/
    char ev;	/* EVen			*/
    char od;	/* ODd			*/
    char nl;
} parcmd_chars = { 'N', ' ', ' ', 'E', 'O', '\0' };

/*   Equivalences for the Xfer Mode sub-menu... */
struct modcmd {
    char im;	/* IMage		*/
    char tx;	/* TeXt			*/
    char cn;	/* CoNvert		*/
    char ac;	/* AutoChop		*/
    char nl;
} modcmd_chars = { 'I', 'T', ' ', ' ', '\0' };

/*   Equivalences for the Script menu... */
struct scrcmd {
    char em;	/* Execute Macro	*/
    char ab;	/* Abort Macro		*/
    char rc;	/* AREXX Macro		*/
    char nl;
} scrcmd_chars = { 'M', 'A', ' ', '\0' };

/*   Equivalences for the Utility menu... */
struct utilcmd {
    char sb;	/* Send Break	*/
    char hu;	/* Hang Up	*/
    char cd;	/* Change Dir	*/
    char cs;	/* Clear Screen	*/
    char ec;	/* ECho		*/
    char wr;	/* WRap		*/
    char nk;	/* Num Key	*/
    char ac;	/* App Cur	*/
    char bs;	/* BS<->DEL	*/
    char xb;	/* Xfer beep	*/
    char mu;	/* Mouse up events	*/
    char md;	/* Mouse down events	*/
    char nl;
} utilcmd_chars = { '.', ' ', 'D', ' ', ' ', 'W', 'K', 'C', ' ', ' ', ' ', ' ', '\0' };

static char *filetext[] = {
    "Protocol",
    "Send",
    "Receive",
    "Kermit Get",
    "Kermit BYE",
    "Capture"
};

static char *modetext[] = {
    "  Ascii",
    "  Xmodem",
    "  XmodemCRC",
    "  Kermit"
};

static char *commtext[] = {
    "Baud Rate",
    "Parity   ",
    "Xfer Mode",
    "  Shared ",
};

static char *baudtext[] = {
    "   300",
    "  1200",
    "  2400",
    "  4800",
    "  9600"
};

static char *partext[] = {
    "  None ",
    "  Mark ",
    "  Space",
    "  Even ",
    "  Odd  "
};

static char *modtext[] = {
    "  Image  ",
    "  Text   ",
    "  Convert",
    "  AutoChop"
};

static char *scrtext[] = {
    "Execute Macro",
    "Abort Execution",
    "AREXX Macro"
};

static char *utiltext[] = {
    "Send Break",
    "Hang Up",
    "Change Dir",
    "Clear Scrn",
    "  Echo",
    "  Wrap",
    "  Num Key",
    "  App Cur",
    "  BS<->DEL",
    "  Xfer Beep",
    "  Mouse Up",
    "  Mouse Dn",
};

struct HowToInit {
    int LeftEdge;	/* in characters, NOT pixels	*/
    int Width;		/* 	ditto			*/
    ULONG Flags;
    char **text;
    char *cmdkeys;
};

static struct HowToInit menu_init[] = {
	{ 0, 20, ITEMTEXT | ITEMENABLED | HIGHCOMP,
	     filetext, (char *)(&filecmd_chars) },
	{10, 17, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE,
	     modetext, (char *)(&modecmd_chars) },
	{ 0, 11, ITEMTEXT | ITEMENABLED | HIGHCOMP,
	     commtext, (char *)(&commcmd_chars) },
	{ 10, 12, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE,
	       baudtext, (char *)(&baudcmd_chars) },
	{ 10, 12, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE,
	      partext, (char *)(&parcmd_chars) },
	{ 10, 15, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE,
	      modtext, (char *)(&modcmd_chars) },
	{ 0, 20, ITEMTEXT | ITEMENABLED | HIGHCOMP,
	     scrtext, (char *)(&scrcmd_chars) },
	{ 0, 16, ITEMTEXT | ITEMENABLED | HIGHCOMP,
	     utiltext, (char *)(&utilcmd_chars) }
};

#define FILE_INIT_ENTRY	(&(menu_init[0]))
#define MODE_INIT_ENTRY (&(menu_init[1]))
#define COMM_INIT_ENTRY	(&(menu_init[2]))
#define RS_INIT_ENTRY	(&(menu_init[3]))
#define PAR_INIT_ENTRY	(&(menu_init[4]))
#define XF_INIT_ENTRY	(&(menu_init[5]))
#define SCRIPT_INIT_ENTRY	(&(menu_init[6]))
#define UTIL_INIT_ENTRY	(&(menu_init[7]))

void do_menu_init();

#if AREXX
char *rexxerrmsgs[] = {
	"",
	"No AREXX library - AREXX unavailable.",
	"Can't contact AREXX server - AREXX unavailable.",
	"Can't create an AREXX msg - AREXX unavailable.",
	"Can't get memory for hostname.",
	"VT100 AREXX port already present - another VT100 up?",
	"Can't get memory for AREXX port."
};
#endif /* AREXX */

char *InitDefaults(argc,argv)
int	argc;
char	**argv;
    {
    FILE    *fd = NULL;
    char    *p = NULL, *ifile, temp[80];
    int     i, l, dont_init = 0, customfudge, maxrows, maxlines;

    for(l = 0; l < EXTMAX; l++)
	ExtXfer[l] = NULL;

    doing_init = 1;	/* make sure we only allow INIT script commands */
    if (argc > 1) {
	int start_of_script_files = 1;

	if(strcmp(argv[1], "-i") == 0) {	/* No init file */
	    dont_init = 1;
	    start_of_script_files = 2;
	}
	else if(strcmp(argv[1], "+i") == 0) {	/* Use specified init file */
	    start_of_script_files = 3;
    	    if((fd=fopen(argv[2],"r")) == NULL) {
		ifile = AllocMem((LONG)(strlen(argv[2])+3), MEMF_PUBLIC|MEMF_CLEAR);
		strcpy(ifile, "S:");
		strcat(ifile, argv[2]);
		fd = fopen(ifile, "r");
		FreeMem(ifile, (LONG)(strlen(argv[2])+3));
		ifile = NULL;
	    }
	}
	if(start_of_script_files > argc)
	    script_files_todo = 0;
	else
	    script_files_todo = argc - start_of_script_files; /* # of cmdline script files left */
	script_files = &(argv[start_of_script_files]);	  /* Ptr to first of 'em */
    }

    if((p_font == NULL) || (p_font[0] == '\0'))
	strcpy(myfontname, "topaz");
    else
	strcpy(myfontname, p_font);	/* Init font name */
    strcat(myfontname, ".font");

    if((p_device == NULL) || (p_device[0] == '\0'))
	strcpy(mysername, SERIALNAME);
    else
	strcpy(mysername, p_device);

#if AREXX
    /*   Setup the AREXX interface now so user can use it during init. */
    if( (RexxSysBase = (struct RxsLib *)OpenLibrary(RXSNAME, 0L))
       == NULL)
	puts("Can't open rexxsyslib.library - AREXX unavailable.");
    else if( (i = makerexxport()) != 0)
	cleanup(rexxerrmsgs[i], 256);
#endif /* AREXX */

    if(!dont_init)
	if((fd == NULL) && ((fd=fopen("vt100.init","r")) == NULL))
	    fd=fopen("s:vt100.init","r");

    if(fd != NULL) {
	while (fgets(line,256,fd) != 0) {
	    if(line[strlen(line)-1] == '\n')
		line[strlen(line)-1] = '\000';
	    p = next_wrd(&line[0],&l);
	    if (*p) {
		*p |= ' ';
		if (p[1]) p[1] |= ' ';
		if (*p == '#') continue;
		if (strncmp(p, "exi", 3) == 0) break;
		exe_cmd(p,l);
		}
	}
	fclose(fd);
    }
    doing_init = 0;

    IntuitionBase = (struct IntuitionBase *)
	OpenLibrary("intuition.library", INTUITION_REV);
    if( IntuitionBase == NULL )
	cleanup("can't open intuition",1);

    GfxBase = (struct GfxBase *)
	OpenLibrary("graphics.library",GRAPHICS_REV);
    if( GfxBase == NULL )
	cleanup("can't open graphics library",2);

    DiskfontBase = (struct Library *)OpenLibrary("diskfont.library", 0L);
    if(DiskfontBase == NULL)
	cleanup("can't open diskfont library", 2);

    if ( (myfont = (struct TextFont *)OpenFont(&myattr)) == NULL
      && (myfont = (struct TextFont *)OpenDiskFont(&myattr)) == NULL) {
	sprintf(temp, "Can't open font %s", myfontname);
	cleanup(temp, 4);
    }

    Xsize = myfont->tf_XSize;
    Ysize = myfont->tf_YSize;
    BaseLine = myfont->tf_Baseline;

    /* Now set up all the screen info as necessary */

    maxrows = GfxBase->NormalDisplayRows;

    /*   If user wants to use the current interlace setting then set p_interlace
    ** according to what the ViewLord says it is. */
    if(p_interlace == 2)
	p_interlace = ((IntuitionBase->ViewLord.Modes & LACE) == LACE) ? 1 : 0;
    else if((p_screen == 0) && ((IntuitionBase->ViewLord.Modes & LACE) == 0))
	p_interlace = 0;

    if(p_interlace)
	maxrows *= 2;

    customfudge = (p_screen == 1) ? 4 : 0;

    /*   See if user wants to use everything available (specified LINES 0).If
    ** so then set p_lines so we'll leave room for the window title.
    ** (Ysize + 1) is the size of the window title bar.
    ** (Ysize + 1 + customfudge) is used to allow us to account for the the 4
    ** scan-lines we'll allow in CUSTOM screen mode so that the user can pull
    ** the window down to expose the screen's depth arrangement gadgets.  Note
    ** that it's OK to overwrite the last 2 lines or so of the window-title bar
    ** (that's why we take the remainder first).
    **/
    if( ((maxrows - (Ysize + 1 - customfudge)) % Ysize) > (Ysize - 2) )
	maxlines = (maxrows - Ysize + customfudge) / Ysize;
    else
	maxlines = (maxrows - (Ysize + 1 + customfudge)) / Ysize;
    if(p_lines == 0)
	p_lines = maxlines;
    else if (p_lines > maxlines)
	p_lines = maxlines;

    /*   Set MINY.  MINY will be adjusted so we'll overwrite part of the
    ** window title bar if necessary to get the last line to end at the bottom
    ** of the window.
    ** Remember that MINY is the location of the BASELINE of the character. */
    {
	int end = (Ysize + 2) + (p_lines * Ysize);

	MINY = Ysize + 2;
	if(end > maxrows)
	    MINY -= (end - maxrows);
	MINY += BaseLine;
    }
    if(p_screen == 1 && p_interlace == 1)
	NewScreen.ViewModes |= LACE;

    MAXY = MINY + ((p_lines - 1) * Ysize);
    top  = MINY; bot  = MAXY;
    savx = MINX; savy = MINY;

    NewWindow.Height = MAXY + customfudge + (Ysize - BaseLine);
    NewWindow.MinHeight = NewWindow.Height;
    NewWindow.MaxHeight = NewWindow.Height;
    NewReqWindow.MaxHeight = NewWindow.Height;
    NewWindow.TopEdge	= 0L;

    if (p_screen == 1) {
	if (p_depth > 2)
	    p_depth = 2;
	else if (p_depth < 1)
	    p_depth = 1;
	NewScreen.Depth = (long)p_depth;
	NewScreen.Height = NewWindow.Height + customfudge;
	NewScreen.TopEdge = 0;
    } else {
	p_depth	= 2L;
	NewWindow.Screen = NULL;
	NewReqWindow.Screen = NULL;
	NewWindow.Type = WBENCHSCREEN;
	NewReqWindow.Type = WBENCHSCREEN;
    }

    /* see if we exit with a startup script */
    if (strncmp(p, "exi", 3) == 0) {
	p = next_wrd(p+l+1,&l);
	if (*p) return(p);
    }
    if (script_files_todo > 0) {
    	script_files_todo--;
    	return(*(script_files++));
    }
    return(NULL);
    }

void InitDevs()
{
USHORT	colors[4];
int	i;
BYTE	*b,*c;
struct Process *mproc;

    if (p_screen == 1) {
	if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL)
	    cleanup("can't open screen",3);
	NewWindow.Screen = myscreen;
	NewReqWindow.Screen = myscreen;
    }

    if ((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
	cleanup("can't open window",4);

    if(OpenDevice("console.device", -1L, &ConReq, 0L))
	cleanup("can't open console", 4);
    ConsoleDevice = ConReq.io_Device;

    if(p_screen == 1) {	/* Cause system reqs to come to this screen */
	mproc = (struct Process *)FindTask(0L);
	OrigWindowPtr = mproc->pr_WindowPtr;
	mproc->pr_WindowPtr = (APTR)mywindow;
    }

    myviewport   = (struct ViewPort *)ViewPortAddress(mywindow);
    myrastport   = (struct RastPort *)mywindow->RPort;

    SetFont(myrastport,myfont);

    if (p_depth > 1) myrequest.BackFill = 2;
    if (p_screen != 0 && p_wbcolors == 0) {
	colors[0] = p_background;
	colors[1] = p_foreground;
	colors[2] = p_bold;
	colors[3] = p_cursor;
	if (p_depth == 1)
	    LoadRGB4(myviewport, colors, 2L);
	else
	    LoadRGB4(myviewport, colors, 4L);
    }

    Read_Request = (struct IOExtSer *)
	AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR);
    Read_Request->io_SerFlags = (p_shared ? SERF_SHARED : 0);
    Read_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
    if(OpenDevice(mysername, (LONG)p_unit, (struct IORequest *)Read_Request, NULL))
	cleanup("Can't open Read device",5);
    rs_in = malloc(p_buffer+1);
    Read_Request->io_SerFlags = 0L;
    Read_Request->io_Baud	  = p_baud;
    Read_Request->io_ReadLen  = 8L;
    Read_Request->io_WriteLen = 8L;
    Read_Request->io_CtlChar  = 0x11130000L;
    Read_Request->io_RBufLen  = p_buffer;
    Read_Request->io_BrkTime  = p_break;
    Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
    DoIO((struct IORequest *)Read_Request);
    Read_Request->IOSer.io_Command = CMD_READ;
    Read_Request->IOSer.io_Length  = 1;
    Read_Request->IOSer.io_Data    = (APTR) &rs_in[0];

    Write_Request = (struct IOExtSer *)
	AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR);
    b = (BYTE *)Read_Request;
    c = (BYTE *)Write_Request;
    for (i=0;i<sizeof(struct IOExtSer);i++)
	*c++ = *b++;
    Write_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
    Write_Request->IOSer.io_Command = CMD_WRITE;
    Write_Request->IOSer.io_Length = 1;
    Write_Request->IOSer.io_Data = (APTR) &rs_out[0];

    Timer_Port = CreatePort("Timer Port",0L);
    Script_Timer_Port = CreatePort("Timer Port",0L);

    if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)&Timer, NULL) ||
	OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)&Script_Timer, NULL))
	cleanup("can't open timer device",7);

    Timer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
    Timer.tr_node.io_Command = TR_ADDREQUEST;
    Timer.tr_node.io_Flags = 0;
    Timer.tr_node.io_Error = 0;

    Script_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port;
    Script_Timer.tr_node.io_Command = TR_ADDREQUEST;
    Script_Timer.tr_node.io_Flags = 0;
    Script_Timer.tr_node.io_Error = 0;

    BeepWave = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR));
    if (BeepWave != 0)
	BeepWave[0] = 100;

    Audio_Port = CreatePort("Audio Port",0L);

    Audio_Request.ioa_Request.io_Message.mn_ReplyPort = Audio_Port;
    Audio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85;
    Audio_Request.ioa_Data = Audio_AllocMap;
    Audio_Request.ioa_Length = (ULONG) sizeof(Audio_AllocMap);

    if (OpenDevice(AUDIONAME, NULL, (struct IORequest *)&Audio_Request, NULL))
	cleanup("can't open audio device",8);

    Audio_Request.ioa_Request.io_Command = CMD_WRITE;
    Audio_Request.ioa_Request.io_Flags = ADIOF_PERVOL;
    Audio_Request.ioa_Data = BeepWave;
    Audio_Request.ioa_Length = BEEPSIZE;
    Audio_Request.ioa_Period = COLORCLOCK / (BEEPSIZE * BEEPFREQ);
    Audio_Request.ioa_Volume = p_volume;
    Audio_Request.ioa_Cycles = 100;
}

/*****************************************************************/
/*    The following function initializes the structure arrays	 */
/*   needed to provide the File menu topic.			 */
/*****************************************************************/
void InitFileItems()
{
    int n, nxfer;
    struct HowToInit Externs;	/* for the external xfer pgms */
    char *p, *p1;

    if(capture == TRUE)
	filetext[FILEMAX-1] = "Capturing";
    else
	filetext[FILEMAX-1] = "Capture";
    do_menu_init(FileItem, FileText, FILE_INIT_ENTRY, FILEMAX);
    FileItem[0].SubItem = ModeItem;
    do_menu_init(ModeItem, ModeText, MODE_INIT_ENTRY, MODEMAX);

    p = (char *)&Externs; p1 = (char *)MODE_INIT_ENTRY;
    for(n = 0; n < sizeof(struct HowToInit); n++)
	*(p++) = *(p1++);

    nxfer = MODEMAX;
    for(n = 0; n < NumExts; n++) {
	struct ExternalXfer *exp = ExtXfer[n];

	nxfer = n + MODEMAX;
	ModeItem[nxfer-1].NextItem = &ModeItem[nxfer];
	Externs.text = &exp->dispname;
	*Externs.cmdkeys = exp->cmdkey;
	do_menu_init(&ModeItem[nxfer], &ModeText[nxfer], &Externs, 1);
	ModeItem[nxfer].TopEdge = 10 * nxfer;
    }

    for(n = 0; n <= nxfer; n++ ) {
	ModeItem[n].MutualExclude = (~(1 << n));
    }
    if(p_xproto > nxfer) {
	p_xproto = MODEMAX - 1;
    }
    ModeItem[p_xproto].Flags |= CHECKED;
}

/******************************************************************
**			Main Comm menu
**		set up for Baud & Parity submenus
*******************************************************************/
void InitCommItems()
{
    int n;

    do_menu_init(CommItem, CommText, COMM_INIT_ENTRY, COMMAX);
    CommItem[0].SubItem = RSItem;
    CommItem[1].SubItem = ParItem;
    CommItem[2].SubItem = XFItem;
    CommItem[3].Flags |= CHECKIT | MENUTOGGLE;
    if(p_shared)
	CommItem[3].Flags |= CHECKED;
    else
	CommItem[3].Flags &= (-1L ^ CHECKED);

/*****************************************************************/
/*    The following initializes the structure arrays		 */
/*   needed to provide the BaudRate Submenu topic.		 */
/*****************************************************************/

    do_menu_init(RSItem, RSText, RS_INIT_ENTRY, RSMAX);
    for( n=0; n<RSMAX; n++ ) {
	RSItem[n].MutualExclude = (~(1 << n));
    }

    /* select baud item chekced */
    switch (p_baud) {
	case 300:	n = 0; break;
	case 1200:	n = 1; break;
	case 2400:	n = 2; break;
	case 4800:	n = 3; break;
	case 9600:	n = 4; break;
	default:	n = 2; p_baud = 2400;
    }
    RSItem[n].Flags |= CHECKED;

/* initialize text for specific menu items */

/*****************************************************************/
/*    The following initializes the structure arrays		 */
/*   needed to provide the Parity   Submenu topic.		 */
/*****************************************************************/

    do_menu_init(ParItem, ParText, PAR_INIT_ENTRY, PARMAX);
    for( n=0; n<PARMAX; n++ ) {
	ParItem[n].MutualExclude = (~(1 << n));
    }

    /* select parity item chekced */
    ParItem[p_parity].Flags |= CHECKED;

/*****************************************************************/
/*    The following initializes the structure arrays		 */
/* initialize text for specific menu items */
/*    needed to provide the Transfer Mode menu topic.		 */
/*****************************************************************/

    do_menu_init(XFItem, XFText, XF_INIT_ENTRY, XFMAX);
    
    /* initialize each menu item and IntuiText with loop */
    for(n = 0; n < 2; n++)
	XFItem[n].MutualExclude = 2 - n;

    /* mode checked */
    XFItem[p_mode].Flags |= CHECKED;
    if (p_convert)
	XFItem[2].Flags |= CHECKED;

    if (p_autochop)
	XFItem[3].Flags |= CHECKED;
    
} /* end of InitCommItems() */


/*****************************************************************/
/*    The following function initializes the structure arrays	 */
/*   needed to provide the Script menu topic.			 */
/*****************************************************************/
void InitScriptItems()
{
    do_menu_init(ScriptItem, ScriptText, SCRIPT_INIT_ENTRY, SCRIPTMAX);
}

/*****************************************************************/
/*    The following function initializes the structure arrays	 */
/*   needed to provide the Util menu topic.		       */
/*****************************************************************/
void InitUtilItems()
{
    int	n;

    do_menu_init(UtilItem, UtilText, UTIL_INIT_ENTRY, UTILMAX);
    /* initialize each menu item and IntuiText with loop */
    for( n=0; n<UTILMAX; n++ ) {
	if (n > 3)
	    UtilItem[n].Flags |= CHECKIT | MENUTOGGLE;
    }

    if (p_echo)
	UtilItem[4].Flags |= CHECKED;
    if (p_wrap)
	UtilItem[5].Flags |= CHECKED;
    if (p_keyapp == 0)
	UtilItem[6].Flags |= CHECKED;
    if (p_curapp)
	UtilItem[7].Flags |= CHECKED;
    if (p_bs_del)
	UtilItem[8].Flags |= CHECKED;
    if (p_xbeep)
	UtilItem[9].Flags |= CHECKED;
    if(p_mouse_up)
	UtilItem[10].Flags |= CHECKED;
    if(p_mouse_down)
	UtilItem[11].Flags |= CHECKED;

    swap_bs_del();	/* Setup keys[] properly... */
    swap_bs_del();	/* ...for mode		    */
}

/****************************************************************/
/*   The following function inits the Menu structure array with */
/*  appropriate values for our simple menu.  Review the manual	*/
/*  if you need to know what each value means.			*/
/****************************************************************/
void InitMenu()
{
    menu[0].NextMenu = &menu[1];
    menu[0].LeftEdge = 5;
    menu[0].TopEdge = 0;
    menu[0].Width = 40;
    menu[0].Height = 10;
    menu[0].Flags = MENUENABLED;
    menu[0].MenuName = "File";	  /* text for menu-bar display */
    menu[0].FirstItem = &FileItem[0]; /* pointer to first item in list */

    menu[1].NextMenu = &menu[2];
    menu[1].LeftEdge = 55;
    menu[1].TopEdge = 0;
    menu[1].Width = 88;
    menu[1].Height = 10;
    menu[1].Flags = MENUENABLED;
    menu[1].MenuName = "Comm Setup";	/* text for menu-bar display */
    menu[1].FirstItem = &CommItem[0];	/* pointer to first item in list */

    menu[2].NextMenu = &menu[3];
    menu[2].LeftEdge = 153;
    menu[2].TopEdge = 0;
    menu[2].Width = 56;
    menu[2].Height = 10;
    menu[2].Flags = MENUENABLED;
    menu[2].MenuName = "Script";	/* text for menu-bar display */
    menu[2].FirstItem = &ScriptItem[0];	/* pointer to first item in list*/

    menu[3].NextMenu = NULL;
    menu[3].LeftEdge = 225;
    menu[3].TopEdge = 0;
    menu[3].Width = 64;
    menu[3].Height = 10;
    menu[3].Flags = MENUENABLED;
    menu[3].MenuName = "Utility";	   /* text for menu-bar display */
    menu[3].FirstItem = &UtilItem[0];  /* pointer to first item in list*/
}

void do_menu_init(menuitem, menutext, initentry, max)
struct MenuItem menuitem[];
struct IntuiText menutext[];
struct HowToInit *initentry;
int max;
{
    int n, nplus1;
    char **temp;

    /* initialize each menu item and IntuiText with loop */
    for( n=0; n < max; n++ ) {
	nplus1 = n + 1;
	temp = initentry->text;
	menutext[n].IText = (UBYTE *)temp[n];
	menuitem[n].NextItem = &menuitem[nplus1];
	menuitem[n].LeftEdge = initentry->LeftEdge * Ysize;
	menuitem[n].TopEdge = 10 * n;
	menuitem[n].Width = initentry->Width * Ysize;
	menuitem[n].Height = 10;
	menuitem[n].Flags = initentry->Flags;
	menuitem[n].MutualExclude = 0;
	menuitem[n].ItemFill = (APTR)&menutext[n];
	menuitem[n].SelectFill = NULL;
	if((initentry->cmdkeys != NULL)
	&& (initentry->cmdkeys[n])
	&& (initentry->cmdkeys[n] != ' ')) {
	    menuitem[n].Command  = initentry->cmdkeys[n];
	    menuitem[n].Flags   |= COMMSEQ;
	}
	else menuitem[n].Command = 0;
	menuitem[n].SubItem = NULL;
	menuitem[n].NextSelect = 0;
    
	menutext[n].FrontPen = 0;
	menutext[n].BackPen = 1;
	menutext[n].DrawMode = JAM2;/* render in fore and background */
	menutext[n].LeftEdge = 0;
	menutext[n].TopEdge = 1;
	menutext[n].ITextFont = NULL;
	menutext[n].NextText = NULL;
    }
    menuitem[max-1].NextItem = NULL;
}

#if AREXX
makerexxport()
{
    int i,
	ret = 0;
    long hostlen = strlen(HOSTNAMEROOT) + strlen(mysername) + 1 + 2 + 1;
			/* "VT100-"            name          "-" "xx" \0 */

    if(HostName) {
	FreeMem(HostName, (ULONG)(strlen(HostName)+1));
	HostName = NULL;
    }

    if( (HostName = AllocMem(hostlen, MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
	return NOHOSTMEM;

    sprintf(HostName, "%s%s-%02d", HOSTNAMEROOT, mysername, p_unit);

    Forbid();
    
    if(FindPort(HostName) != NULL)
	ret = HAVEVT100PORT;
    else if( (FromRexxPort = (struct MsgPort *)AllocMem((LONG)sizeof(struct MsgPort),
			     MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
	ret = NOPORTMEM;
    else {
	InitPort(FromRexxPort, HostName);
	AddPort(FromRexxPort);
    }

    Permit();
    if(ret && RexxSysBase) {
	CloseLibrary((struct Library *)RexxSysBase);
	RexxSysBase = NULL;
    }
    return ret;
}
#endif /* AREXX */
