/************************************************************************ xtc.c
**
**  XTC - X windows Tektronix Control program.
**
**  Copyright 1992  Jim Snyder
**                  Princeton Plasma Physics Laboratory, Princeton University
**
**  Last Edit:  24-JAN-1994   XTC V4.3
**
**  12-JAN-2012  CLF: use _SC_LOGIN_NAME_MAX
**                    getlogin()
*/

#define xtc_module 0
                                        /* Include files for all platforms */
#include <stdio.h>			/* Standard I/O */
#include <stdlib.h>
#include <Xm/Xm.h>			/* Motif toolkit */
#include <Xm/MainW.h>			/* Motif Main Window */
#include <Xm/BulletinB.h>		/* Motif Bulletin Board */
#include <Xm/DrawingA.h>		/* Motif Drawing Area */
#include <Xm/RowColumn.h>		/* Motif Row Column */
#include <Xm/PushB.h>			/* Motif Push Button */
#include <Xm/CascadeB.h>		/* Motif Cascade Button */
#include <Xm/ToggleB.h>			/* Motif Toggle Button */
#include <Xm/List.h>			/* Motif Scrolled List */
#include <Xm/Label.h>			/* Motif Label */
#include <Xm/Form.h>			/* Motif Form */
#include <Xm/FileSB.h>			/* Motif File Selection Box */
#include <Xm/Scale.h>			/* Motif Scale */
#include <Xm/Text.h>			/* Motif Text */
#include <Xm/Separator.h>		/* Motif Separator */
#include <Xm/MwmUtil.h>			/* mwm interface */
#include <X11/Xresource.h>		/* Xrm routines */
#include "body.h"			/* Pixmap for "About XTC" */
#include "icons.h"  			/* Pixmap for XTC icon */
#include "xtcwc.h"           		/* Widgets and callbacks */

#ifdef VMS				/* VMS-specific include files */
#include <jpidef.h>			/* JPI$ symbols */
#include <lnmdef.h>			/* LNM$ symbols */
#include <iodef.h>			/* IO$ symbols */
#include <clidef.h>			/* CLI$ symbols */
#include <dvidef.h>			/* DVI$ symbols */
#include <syidef.h>			/* SYI$ symbols */
#include <ssdef.h>			/* SS$ symbols */
#include <starlet.h>			/* System Services */
#include <lib$routines.h>		/* RTL LIB$ routines */
#include <descrip.h>			/* Descriptor definitions */
#include <rms.h>			/* RMS structures */
#else					/* UNIX-specific include files */
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#endif

					/* Routines local to this module */
static void mbx_gin_so_sc_init();
static void process_buffer();
static void dump_frame_buffer();
static void display_message();
static void ss_message();
static void clear_buffer();
static void dump_byte_stream();
static void get_xtc_id();
static void set_shell_icon();
static void check_mailbox_byte();
static void qiow_sysoutput();
static void remove_plot();
static void force_ERASE();
static void file_frame();
static void print_frame();
static void generate_exp_from_raw();
static void generate_print_filename();
static void save_current_settings();
static void get_settings();
static void parse_settings();
static void fill_widgets();
static void set_defaults();
static void implement_save_depth();
static void do_flex();
static void read_plotfile();
static void get_file_filter();
static void get_xy();
static void draw_frames();
static void set_color();
static void set_mixer();
static void size_lbox();
void create_tek_window();
void write_tek_window();
void get_tek_geometry();
void color_tek_window();
void get_tek_pixel();

static void handlerStructureNotify_shell();
static void handlerStructureNotify_shellLB();

#ifdef VMS
static void queue_mbx_read();
static void mbx_read_event();
static void write_rms_file();
static void printer_comp_event();
static void create_mailboxes();
#else
static void socket_mbx_accept();
static void socket_mbx_recv();
static void socket_gin_accept();
static void socket_gin_recv();
static void create_sockets();
#endif

					/* Routines called from TEKWINDOW */
void return_gin_bytes();
void draw_adj_frame();

					/* Routines called in XTCCREATE */
void xtccreate();

					/* Locally-defined structures */
#ifdef VMS
struct	item_list_3
	{
	short	buffer_length;
	short	item_code;
	char	*buffer_address;
	short	*return_length_address;
	}; 

struct	io_status_block
	{
	short	status;
	short	transfer;
	int	info;
	};
#endif 

					/* Toolkit structures */
static XtAppContext ctx;
static Arg arglist[15];
static XrmDatabase xrm_database;
static XrmValue xrm_value;
static Pixmap pixmap_arm1;
static Pixmap pixmap_arm2;
static Pixmap pixmap_arm3;
static Pixmap pixmap_body;

#ifdef VMS
static XtInputId xtinputid;
#else
static XtInputId xtinputid_mbx_accept;
static XtInputId xtinputid_mbx_recv;
static XtInputId xtinputid_gin_accept;
static XtInputId xtinputid_gin_recv;
#endif

					/* Other global data */
/*static char	username[L_cuserid]; */
static char	username[_SC_LOGIN_NAME_MAX];

static int	windows = FALSE;
static int	lb_state = 0;
static char	xrm_user_file[80];
static char	xrm_system_file[80];
static char	xrm_string[81];
static char	xrm_resource[81];
static char	*xrm_str_type[20];
static int	settings_key;
static char	nodename[61];
static char	window_name[80];
static char	xtc_id[41];
static char	*lbox_addr[100];
static char	*lbox_id[100];
static int	lbox_nbytes[100];
static int	lbox_alloc[100];
static int	lbox_id_length = 60;
static int	lbox_top = -1;
static int	lbox_index[2];
static int	lbox_flag[2] = { 0, 0 };       
static int	lbox_dump_index;
static int	lbox_current_index = -1;
static int	bmark = 0;
static int	redraw_flag;
static int	nbytes_buffer;
static char	*addr_buffer;
static int	snp_flag;
static char	mailbox_byte;
static int	append_byte;
static int	append_control_list;
static char	control_list[2][10];
static int	nbytes_control_list[2] = { 0, 0 };
static int	INITT_idx[2]           = { 0, 0 };
static int	FINITT_idx[2]          = { 0, 0 };
static int	SNP_idx[2]             = { 0, 0 };
static int	GIN_idx[2]             = { 0, 0 };
static int	save_depth;
static int	multi_order;
static int	dpn_list[100];
static int	dpn_num = 0;
static int	current_plot_number = 0;
static int	remove_index;
static int	keep;
static int	mbxno;
static int	idx_number;
static int  	byte_index = 0;
static char 	byte_stream_dump[3600];
static int	byte_stream_managed = 0;
static int	flex_position;
static int	flex_direction;
static int	flex_timeout = 400;
static char	message_string[400];
static int	nbytes_INITT_byte_stream;
static int	nbytes_FINITT_byte_stream;
static int	nbytes_SNP_byte_stream;
static int	nbytes_GIN_byte_stream = 2;
static char	INITT_byte_stream[8];
static char	FINITT_byte_stream[8];
static char	SNP_byte_stream[8];
static char	GIN_byte_stream[8] = { 0x1B, 0x1A };
static int	GIN_Bytes;
static int	startup_state;
static int	startup_x;
static int	startup_y;
static int	list_box_policy;
static int	display_MBX_data;
static int	display_plotfile_data;
static int	ctog;
static int	red_value[9];
static int	green_value[9];
static int	blue_value[9];
static char	raw_filename[255];
static char	frame_filename[255];
static char     ps_filename[258];
static int	file_flag;
static int	fn_list[100];
static int	fn_num = 0;
static int	auto_file;
static int	ps_file;
static int	append_frames;
static char	print_filename[255];
static int	auto_print;
static char 	scratch_area[81];
static char	*qiow_addr;
static int	qiow_nbytes;
static int	bytes_to_send;
static char	*frame_id;
static char	file_filter[255];
static char	plot_filename[255];
static char	plotfile_namepart[41];
static char     plotfile_buffer[512];
static char 	print_procedure[81];

#ifdef VMS
static char	print_queue[40];
static short	chan_mbx;
static short	chan_gin;
static int	event_flag_mbx = 10;
static int	maxmsg_mbx = 512;
static char	buffer_mbx[512];
static unsigned long printer_comp_status;
static int	event_flag_printer = 21;
static struct	RAB rab_frame;
static char	*default_file_type = ".PLT";
static char	rab_buffer[512];
static struct	io_status_block iosb_mbx;
static $DESCRIPTOR( lnm_temporary_mailbox_desc,  "LNM$TEMPORARY_MAILBOX" );
static $DESCRIPTOR( lnm_process_directory_desc,  "LNM$PROCESS_DIRECTORY" );
static $DESCRIPTOR( lnm_group_desc,              "LNM$GROUP" );
#else
static char	print_command[81];
static int	socket_mbx_desc, sd0_mbx;
static struct	sockaddr_un socket_mbx_name;
static char	socket_buffer_mbx[512];
static int	socket_mbx_flag = 0;
static int	socket_gin_desc, sd0_gin;
static struct	sockaddr_un socket_gin_name;
static char	socket_buffer_gin[6];
static int	socket_gin_flag = 0;
#endif

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

main(argc,argv)

	int argc;
	char *argv[];

	{

	int mwm_decorations;
#ifdef VMS
	char *xtc_resource = "xtc";
#else
	char *xtc_resource = "Xtc";
#endif

/*
**  Initialize xrm.
*/

	XrmInitialize();

/*
**  Create main shell widget.
*/

	wshell = XtAppInitialize( &ctx, xtc_resource, NULL, 0, 
					&argc, argv, NULL, NULL, 0);

	XtSetArg( arglist[0], XmNallowShellResize, TRUE );
	XtSetValues( wshell, arglist, 1 );

	set_shell_icon();

	XtAddEventHandler(wshell, StructureNotifyMask, FALSE, 
				handlerStructureNotify_shell, 0);

/*
**  Create list box shell widget.
*/


	wshellLB = XtAppCreateShell( 0, xtc_resource, 
				applicationShellWidgetClass,
                                XtDisplay(wshell), arglist, 0 );
 
	mwm_decorations = MWM_DECOR_BORDER + MWM_DECOR_RESIZEH +
	                  MWM_DECOR_TITLE  + MWM_DECOR_MENU;

	XtSetArg( arglist[0], XmNallowShellResize, TRUE );
	XtSetArg( arglist[1], XmNmwmDecorations, mwm_decorations );
	XtSetArg( arglist[2], XmNtitle, "XTC List Box" );
	XtSetValues( wshellLB, arglist, 3 );

	XtAddEventHandler(wshellLB, StructureNotifyMask, FALSE, 
				handlerStructureNotify_shellLB, 0);

/*
**  Create widgets
*/

	xtccreate();

/*
**  Manage the main window widget.
*/

	XtManageChild(wmain);

/*
**  Realize the shell widget.
*/

	XtRealizeWidget(wshell);

	windows = TRUE;

/*
**  Initialize the mailbox, GIN, SYS$OUTPUT, and SYS$COMMAND I/O channels.
*/

	mbx_gin_so_sc_init();

/*
**  Setup done; wait for input from the user.
*/

	XtAppMainLoop(ctx);

	} /* End main */

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

static void mbx_gin_so_sc_init()

	{

	int i;
	size_t ic ;
	char*  gname ;
	char icon_name[80];
#ifdef VMS
	unsigned long ss_status;
	short return_length;
 	struct item_list_3 itmlst[2];
	struct io_status_block iosb;
#endif

/*
**  Get nodename.
*/

#ifdef VMS
	itmlst[0].buffer_length = 15;
	itmlst[0].item_code = SYI$_NODENAME;
	itmlst[0].buffer_address = nodename;
	itmlst[0].return_length_address = &return_length;
	itmlst[1].buffer_length = 0;
	itmlst[1].item_code = 0;

	ss_status = sys$getsyiw( 0, 0, 0, itmlst, &iosb, 0, 0 );

	if (ss_status != SS$_NORMAL) 
		ss_message("Error getting data from $GETSYIW:", ss_status);
	if (iosb.status != SS$_NORMAL)
		{
		ss_status = iosb.status;
		ss_message("IOSB error getting data from $GETSYIW:",
				ss_status);
		}

	nodename[return_length] = '\0';
#else
	gethostname( nodename, 60 );
#endif

	sprintf( icon_name, "XTC on %s\0", nodename );
	sprintf( window_name, "XTC on %s\0", nodename );

	XtSetArg( arglist[0], XmNiconName, icon_name );
	XtSetArg( arglist[1], XmNtitle, window_name );
	XtSetValues( wshell, arglist, 2 );

/*
**  Get username of this process.

*/
	gname = getlogin() ;
	ic = strlen(gname) ;
	if (ic < _SC_LOGIN_NAME_MAX) {
		strcpy(username,gname) ;
	}
	else {
		strcpy(username, "dilbert") ;
	} ;


/*
**  Fill in resource file names.
*/

#ifdef VMS
	strcpy( xrm_user_file, "DECW$USER_DEFAULTS:XTC.DAT" );
	strcpy( xrm_system_file, "DECW$SYSTEM_DEFAULTS:XTC.DAT" );
#else
	sprintf( xrm_user_file, "%s/Xtc\0", (char *) getenv("HOME") );
	strcpy( xrm_system_file, "/usr/lib/X11/app-defaults/Xtc" );
#endif

/*
**  Create tek window.
*/

	create_tek_window( XtDisplay(wshell), wdraw );

/*
**  Fill necessary widgets with data available after creation.
*/

	fill_widgets();

/*
**  Set widget values into variables for quicker access.
*/

	set_defaults();

/*
**  Define LNM$TEMPORARY_MAILBOX to be LNM$GROUP in logical name table 
**  LNM$PROCESS_DIRECTORY.
*/

#ifdef VMS
	ss_status = lib$set_logical( &lnm_temporary_mailbox_desc, 
					&lnm_group_desc, 
					&lnm_process_directory_desc, 0, 0 );

	if (ss_status != SS$_NORMAL) 
		ss_message("Error setting temporary mailbox logical name:", 
				ss_status);
#endif

/*
**  Perform initialization setup on windows.
*/

	for (i = 0; i <= 8; i++) set_color(i);
	XmToggleButtonSetState( wtogGround[0], TRUE, TRUE );
	XmToggleButtonSetState( wtogGround[8], TRUE, TRUE );
	force_ERASE();

/*
**  Create mailboxes.
*/

#ifdef VMS
	create_mailboxes();
#else
	create_sockets();
#endif

/*
**  Reserve printer subprocess event flag.
*/

#ifdef VMS
	ss_status = lib$free_ef(&event_flag_printer);
	if (ss_status != SS$_NORMAL) 
		ss_message("Error freeing printer subprocess event flag:",
				ss_status);

	ss_status = lib$reserve_ef(&event_flag_printer);
	if (ss_status != SS$_NORMAL) 
		ss_message("Error reserving printer subprocess event flag:",
				ss_status);

	ss_status = sys$clref(event_flag_printer);
	if (ss_status != SS$_WASSET && ss_status != SS$_WASCLR) 
		ss_message("Error clearing printer subprocess event flag:",
				ss_status);

	XtAppAddInput( ctx, event_flag_printer, 0, printer_comp_event, 0);
#endif

	} /* End */

#ifdef VMS

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

static void queue_mbx_read()		/* VMS only */

	{

	unsigned long ss_status;
	unsigned long func;

	func = IO$_READVBLK;

	ss_status = sys$qio( event_flag_mbx, chan_mbx, 
				func, &iosb_mbx, 0, 0, 
				buffer_mbx, maxmsg_mbx, 0, 0, 0, 0 );

	if (ss_status != SS$_NORMAL) 
		ss_message("Error sending $QIO read to mbx mailbox:",
				ss_status);

	} /* End */

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

static void mbx_read_event()		/* VMS only */

	{

	unsigned long ss_status;

/*
**  Check the iosb status from the mailbox read.
*/

	if (iosb_mbx.status != SS$_NORMAL) 
		{
		ss_status = iosb_mbx.status;
		ss_message("IOSB error from $QIO read to mbx:", ss_status);
		}

/*
**  Save the number of bytes read from the mailbox and the address of the data,
**  and process the mailbox data.
*/

	if (iosb_mbx.transfer > 0)
		{
		nbytes_buffer = iosb_mbx.transfer;
		addr_buffer = buffer_mbx;
		mbxno = 0;
		process_buffer();
		}

/*
**  Queue another mailbox read.
*/

	queue_mbx_read();

	} /* End */

#else

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

static void socket_mbx_accept()		/* UNIX only */

	{

	if (socket_mbx_flag == 1) 
		{
		strcpy( message_string,	
			"socket_mbx connect refused - socket already in use");
		display_message();
		}

	else if ( (sd0_mbx = accept( socket_mbx_desc, 0, 0)) == -1 )
		ss_message( "accept() socket_mbx errno", errno );

	else
		{
		XtRemoveInput(xtinputid_mbx_accept);
	        xtinputid_mbx_recv = XtAppAddInput( ctx, sd0_mbx,
                                        XtInputReadMask, socket_mbx_recv, 0);
		socket_mbx_flag = 1;
		}

	} /* End */

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

static void socket_mbx_recv()		/* UNIX only */

	{

	int nchars;

	nchars = recv( sd0_mbx,socket_buffer_mbx,sizeof(socket_buffer_mbx),0 );

	if (nchars == 0)
		{
		XtRemoveInput(xtinputid_mbx_recv);
		close(sd0_mbx);
		xtinputid_mbx_accept = XtAppAddInput( ctx, socket_mbx_desc, 
					XtInputReadMask, socket_mbx_accept, 0);
		socket_mbx_flag = 0;
		}

	else if (nchars == -1)
		ss_message( "recv() socket_mbx errno", errno );

	else
		{
		nbytes_buffer = nchars;
		addr_buffer = socket_buffer_mbx;
		mbxno = 0;
		process_buffer();
		}

	} /* End */

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

static void socket_gin_accept()		/* UNIX only */

	{

	if (socket_gin_flag == 1) 
		{
		strcpy( message_string,	
			"socket_gin connect refused - socket already in use");
		display_message();
		}

	else if ( (sd0_gin = accept( socket_gin_desc, 0, 0)) == -1 )
		ss_message( "accept() socket_gin errno", errno );

	else
		{
		XtRemoveInput(xtinputid_gin_accept);
	        xtinputid_gin_recv = XtAppAddInput( ctx, sd0_gin,
                                        XtInputReadMask, socket_gin_recv, 0);
		socket_gin_flag = 1;
		}

	} /* End */

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

static void socket_gin_recv()		/* UNIX only */

	{

	int nchars;
	int i;

	nchars = recv( sd0_gin,socket_buffer_gin,sizeof(socket_buffer_gin),0 );

	if (nchars == 0)
		{
		XtRemoveInput(xtinputid_gin_recv);
		close(sd0_gin);
		xtinputid_gin_accept = XtAppAddInput( ctx, socket_gin_desc, 
					XtInputReadMask, socket_gin_accept, 0);
		socket_gin_flag = 0;
		}

	else if (nchars == -1)
		ss_message( "recv() socket_gin errno", errno );

	else
		{
		for (i = 0; i < nchars; i++)
			printf( "gin[%d] = %02X\n", i, socket_buffer_gin[i]);
		}

	} /* End */

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

#endif

static void process_buffer()

	{

	int i,j;
	unsigned long ss_status;
	char *vm_addr;
	int vm_start = 512;
	int vm_inc = 512;
	int vm_grab;

/*
**  Dump the buffer to the byte stream window.  
*/

	if (byte_stream_managed) dump_byte_stream();

/*
**  Trudge through the data, buffering this plot and looking for control bytes.
*/

	for (i = 0; i < nbytes_buffer; i++)
		{

/*
**  Check the next byte for a possible control-sequence byte.
*/

		mailbox_byte = addr_buffer[i];
		check_mailbox_byte();

/*
**  If a start-new-plot control-sequence was detected, and the current frame
**  already contains such a sequence, then end the current frame before
**  starting a new frame.
*/

		if (snp_flag == 1 && lbox_flag[mbxno] == 2)
			{
			lbox_dump_index = lbox_index[mbxno];
			redraw_flag = 0;
		        dump_frame_buffer();

			if (auto_file)
				{
				file_flag = 1;
				fn_list[0] = lbox_index[mbxno];
				fn_num = 1;
				file_frame();
				}

			if (auto_print)
				{
				fn_list[0] = lbox_index[mbxno];
				fn_num = 1;
				print_frame();
				}

			lbox_flag[mbxno] = 0;
			}

		if (lbox_flag[mbxno] == 0)
			{
			while (lbox_top + 1 >= save_depth)
				{
				remove_index = 0;
				remove_plot();
				}

			lbox_top++;

#ifdef VMS
			ss_status = lib$get_vm( &vm_start, 
						&lbox_addr[lbox_top], 0 );
			if (ss_status != SS$_NORMAL) 
				ss_message("Error allocating virtual memory:", 
						ss_status);

			ss_status = lib$get_vm( &lbox_id_length, 
						&lbox_id[lbox_top], 0 );
			if (ss_status != SS$_NORMAL) 
				ss_message("Error allocating virtual memory:",
						ss_status);
#else

			lbox_addr[lbox_top] = (char *)malloc(vm_start);
			lbox_id[lbox_top] = (char*)malloc(lbox_id_length);
#endif
 
			lbox_index[mbxno] = lbox_top;
			lbox_flag[mbxno] = 1;
			lbox_nbytes[lbox_top] = 0;
			lbox_alloc[lbox_top] = vm_start;

			get_xtc_id();
			current_plot_number++;
			sprintf( lbox_id[lbox_top], "%s [%d]\0", 
					xtc_id, current_plot_number );

			XmListSetHorizPos( wslBufferedFrames, 0 );

			XmListAddItem( wslBufferedFrames,
				XmStringCreate(lbox_id[lbox_top],""), 1 );
/*
			XmListSelectPos( wslBufferedFrames, 1, TRUE );
*/
			XmListSetPos( wslBufferedFrames, 1 );

			}

/*
**  Continue processing based on if this byte should be added to the current
**  plot byte stream or if a saved sequence of control bytes should be added.
*/

		if (append_byte || append_control_list > 0)
			{

/*
**  Allocate more space for this frame, if needed.
*/

			if (lbox_nbytes[lbox_index[mbxno]] >= 
			    lbox_alloc[lbox_index[mbxno]] - 
					nbytes_control_list[mbxno] - 5)
				{
				vm_grab = lbox_alloc[lbox_index[mbxno]] 
						+ vm_inc;
	
#ifdef VMS
				ss_status = lib$get_vm(	&vm_grab, 
							&vm_addr, 0 );
				if (ss_status != SS$_NORMAL) 
					ss_message(
					"Error allocating virtual memory:", 
						ss_status);
#else
				vm_addr = (char *)malloc(vm_grab);
#endif

				strncpy( vm_addr, 
					 lbox_addr[lbox_index[mbxno]],
					 lbox_alloc[lbox_index[mbxno]] );

#ifdef VMS
				ss_status = lib$free_vm( 
						&lbox_alloc[lbox_index[mbxno]],
						&lbox_addr[lbox_index[mbxno]],
						0 );
				if (ss_status != SS$_NORMAL) 
					ss_message(
					"Error freeing virtual memory:", 
						ss_status);
#else
				free(lbox_addr[lbox_index[mbxno]]);
#endif

				lbox_addr[lbox_index[mbxno]] = vm_addr;
				lbox_alloc[lbox_index[mbxno]] = vm_grab;
				}

/*
**  If the current saved control list (from the mailbox stream) is to be
**  added to the current plot, then do so.
*/

			if (append_control_list == 1 && 
			    nbytes_control_list[mbxno] > 0)
				{         
				for (j = 0; 
				     j < nbytes_control_list[mbxno]; j++)
					{
					lbox_nbytes[lbox_index[mbxno]]++; 
					lbox_addr[lbox_index[mbxno]]
					    [lbox_nbytes[lbox_index[mbxno]]-1] 
						= control_list[mbxno][j];
					}
				nbytes_control_list[mbxno] = 0;

				if (snp_flag == 1) lbox_flag[mbxno] = 2;
				}

/*
**  If the current saved control list (from the mailbox stream) is to be
**  passed but not added, then do so.
*/

			if (append_control_list == 2)
				{
				lbox_dump_index = lbox_index[mbxno];
				redraw_flag = 0;
			        dump_frame_buffer();

			    	if (nbytes_control_list[mbxno] > 0)
					{
				        if ((mbxno == 0 && 
					     display_MBX_data == 1) ||
				            (mbxno == 1 && 
					     display_plotfile_data == 1))
						{
						qiow_addr = 
						   &control_list[mbxno][0];
						qiow_nbytes = 
						   nbytes_control_list[mbxno];
						qiow_sysoutput();
						}

					nbytes_control_list[mbxno] = 0;
					}

				}

/*
**  If the current byte from the mailbox stream is to be added to the current
**  plot, then do so.
*/

			if (append_byte)
				{
				lbox_nbytes[lbox_index[mbxno]]++; 
				lbox_addr[lbox_index[mbxno]]
				         [lbox_nbytes[lbox_index[mbxno]]-1] 
						= mailbox_byte;
				}

			}

		}

/*
**  Dump the undumped part of the current plot buffer to the graphics screen.
*/

	lbox_dump_index = lbox_index[mbxno];
	redraw_flag = 0;
        dump_frame_buffer();

	} /* End */

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

static void dump_frame_buffer()

	{

	int pos;
	int nbytes_output;

	if ((redraw_flag == 1) ||
            (mbxno == 0 && display_MBX_data == 1) ||
            (mbxno == 1 && display_plotfile_data == 1))
		{
		if (lbox_dump_index != lbox_current_index)
			{
			lbox_current_index = lbox_dump_index;
			bmark = 0;
/*			title_tek_window(lbox_id[lbox_current_index]); */

			sprintf( window_name, "XTC on %s: %s\0", 
				nodename, lbox_id[lbox_current_index] );
			XtSetArg( arglist[0], XmNtitle, window_name );
			XtSetValues( wshell, arglist, 1 );
			}

		nbytes_output = lbox_nbytes[lbox_current_index] - bmark;

		if (nbytes_output > 0)
			{
			qiow_addr = &lbox_addr[lbox_current_index][bmark];
			qiow_nbytes = nbytes_output;
			qiow_sysoutput();

			bmark = lbox_nbytes[lbox_current_index];

			if ((redraw_flag == 0) &&
		    	   (dpn_num != 1 || dpn_list[0] != lbox_current_index))
				{				
				pos = lbox_top - lbox_current_index + 1;
				XmListSelectPos( wslBufferedFrames, 
							pos, TRUE );
				}
/*
			XmListSetPos( wslBufferedFrames, 1 );
*/
			}
		}

	} /* End */

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

static void check_mailbox_byte()

	{

	int i;
	int possible_control_byte;
	int got_INITT;
	int got_FINITT;
	int got_SNP;
	int got_GIN;

/*
**  Initialize flags that are used to detect relevant control sequences and
**  determine what to do with the current mailbox byte and the current saved
**  control list.
*/

	possible_control_byte = 0;
	got_INITT = 0;
	got_FINITT = 0;
	got_SNP = 0;
	got_GIN = 0;

/*
**  Check for INITT sequence.
*/

	if (nbytes_INITT_byte_stream > 0 &&
	    mailbox_byte == INITT_byte_stream[INITT_idx[mbxno]])
		{
		possible_control_byte = 1;
		INITT_idx[mbxno]++;
		if (INITT_idx[mbxno] >= nbytes_INITT_byte_stream) 
			got_INITT = 1;
		}
	else	
		{
		INITT_idx[mbxno] = 0;
		}

/*
**  Check for FINITT sequence.
*/

	if (nbytes_FINITT_byte_stream > 0 &&
	    mailbox_byte == FINITT_byte_stream[FINITT_idx[mbxno]])
		{
		possible_control_byte = 1;
		FINITT_idx[mbxno]++;
		if (FINITT_idx[mbxno] >= nbytes_FINITT_byte_stream) 
			got_FINITT = 1;
		}
	else	
		{
		FINITT_idx[mbxno] = 0;
		}

/*
**  Check for SNP sequence.
*/

	if (nbytes_SNP_byte_stream > 0 &&
	    mailbox_byte == SNP_byte_stream[SNP_idx[mbxno]])
		{
		possible_control_byte = 1;
		SNP_idx[mbxno]++;
		if (SNP_idx[mbxno] >= nbytes_SNP_byte_stream) got_SNP = 1;
		}
	else
		{
		SNP_idx[mbxno] = 0;
		}

/*
**  Check for GIN sequence.
*/

	if (nbytes_GIN_byte_stream > 0 &&
	    mailbox_byte == GIN_byte_stream[GIN_idx[mbxno]])
		{
		possible_control_byte = 1;
		GIN_idx[mbxno]++;
		if (GIN_idx[mbxno] >= nbytes_GIN_byte_stream) got_GIN = 1;
		}
	else
		{
		GIN_idx[mbxno] = 0;
		}

/*
**  If the current byte is a possible control sequence byte, then add it to
**  the control sequence list and set a flag to not append it to the current
**  plot byte stream.  If not, then set a flag to append the current control
**  list (which may be empty) to the current plot byte stream.
*/

	snp_flag = 0;
	append_byte = 1;
	append_control_list = 0;

	if (possible_control_byte)
		{
		nbytes_control_list[mbxno]++;
		control_list[mbxno][nbytes_control_list[mbxno]-1] 
			= mailbox_byte;
		append_byte = 0;
		}
	else
		append_control_list = 1;

/*
**  Continue processing based on if a control sequence has been detected.
*/

	if (got_INITT)
		{
		nbytes_control_list[mbxno] = 0;
		append_control_list = 1;
		INITT_idx[mbxno] = 0;
		}

	else if (got_FINITT)
		{
		nbytes_control_list[mbxno] = 0;
		FINITT_idx[mbxno] = 0;
		}

	else if (got_SNP)
		{
		snp_flag = 1;
		append_control_list = 1;
		SNP_idx[mbxno] = 0;
		}

	else if (got_GIN)
		{
		append_control_list = 2;
		GIN_idx[mbxno] = 0;
		}

	} /* End */

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

static void ss_message( string, status )

	char *string;
#ifdef VMS
	unsigned long status;
#else
	int status;
#endif

	{

#ifdef VMS
	short message_length;
	char message[257];
	struct dsc$descriptor message_desc;

/*
**  Get system message corresponding to the condition code.
*/

	message_desc.dsc$w_length  = 256;
        message_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
        message_desc.dsc$b_class   = DSC$K_CLASS_S;
        message_desc.dsc$a_pointer = message;

	sys$getmsg( status, &message_length, &message_desc, 0, 0 );
	message[message_length] = '\0';

/*
**  Append the system message to the input string that identifies the
**  nature of the error, and display the message string.
*/

	sprintf( message_string, "%s\n%s\0", string, message );
#else
	sprintf( message_string, "%s %d\0", string, status );
#endif

	display_message();

	} /* End */

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

static void display_message()

	{

	XmString old_message_string;
	int i;
#ifdef VMS
	char time_stamp[13];
	unsigned long ss_status;
	char timbuf[24];
	struct dsc$descriptor timbuf_desc;
#else
	char *time_stamp;
	long int tloc;
	time_t timet;
#endif

#ifdef VMS
	timbuf_desc.dsc$w_length  = 23;
        timbuf_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
        timbuf_desc.dsc$b_class   = DSC$K_CLASS_S;
        timbuf_desc.dsc$a_pointer = timbuf;

	ss_status = sys$asctim( 0, &timbuf_desc, 0, 0 );

	if (ss_status == SS$_NORMAL)
		{
		time_stamp[0] = ' ';
		time_stamp[1] = '(';
		for (i = 2; i < 10; i++) time_stamp[i] = timbuf[i+10];
		time_stamp[10] = ')';
		time_stamp[11] = '.';
		time_stamp[12] = '\0';
		}
	else
		{
		time_stamp[0] = '.';
		time_stamp[1] = '\0';
		}

	strcat( message_string, time_stamp );
#else
        tloc = NULL;
        timet = time(&tloc);
        time_stamp = (char *) ctime(&timet);
        time_stamp[24] = '\0';

        strcat( message_string, " (" );
        strcat( message_string, time_stamp );
        strcat( message_string, ")" );
#endif

	if (windows)
		{
		for (i = 0; i < 4; i++)
			{
			XtSetArg( arglist[0], XmNlabelString,
					&old_message_string );
			XtGetValues( wlabMessages[i+1], arglist, 1 );

			XtSetArg( arglist[0], XmNlabelString,
					old_message_string );
			XtSetValues( wlabMessages[i], arglist, 1 );
			}

		XtSetArg( arglist[0], XmNlabelString, 
				XmStringCreateLtoR(message_string,"") );
		XtSetValues( wlabMessages[4], arglist, 1 );

		XtManageChild( wformdMessages );
		}

	else
		printf( "%s", message_string );

	} /* End */

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

static void clear_buffer()

	{

	int i;
	int number_to_remove;

/*
**  If the number to remain is less than the current number of buffered plots, 
**  then get rid of the appropriate number of oldest saved plots.
*/

	number_to_remove = lbox_top + 1 - keep;
	remove_index = 0;

	if (number_to_remove > 0)
		{
		for (i = 0; i < number_to_remove; i++) remove_plot();

/*
		dpn_num = 0;
		XmListDeselectAllItems( wslBufferedFrames );
*/
		}

	} /* End */

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

static void dump_byte_stream()

	{

	int i;
	int idx;
	int blank_byte_index;
	char byte_string[3];

	for (i = 0; i < nbytes_buffer; i++)
		{
		byte_index++;
		if (byte_index > 1200) byte_index = 1;
		idx = 3 * ( byte_index - 1 );

		sprintf( byte_string, "%02X", addr_buffer[i] );

		byte_stream_dump[idx]   = byte_string[0];
		byte_stream_dump[idx+1] = byte_string[1];
		}

	blank_byte_index = byte_index + 1;
	if (blank_byte_index > 1200) blank_byte_index = 1;
	idx = 3 * ( blank_byte_index - 1 );

	byte_stream_dump[idx]   = '_';
	byte_stream_dump[idx+1] = '_';

	XtSetArg( arglist[0], XmNlabelString, 
			XmStringCreateLtoR(byte_stream_dump,"") );
	XtSetValues( wlabByteStreamDump, arglist, 1 );

	} /* End */

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

static void set_shell_icon()

	{

	Pixmap icon_pixmap;

/* 
**  Generate the icon pixmap.
*/

	icon_pixmap = XCreatePixmapFromBitmapData(
		XtDisplay(wshell),
		RootWindowOfScreen(XtScreen(wshell)),
		ICONXTC_bits, ICONXTC_width, ICONXTC_height, 1, 0,
		DefaultDepthOfScreen(XtScreen(wshell)));

/*                         
**  Set the pixmap on the shell widget.
*/

	XtSetArg(arglist[0], XtNiconPixmap, icon_pixmap);
	XtSetValues( wshell, arglist, 1 );

	} /* End */

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

static void get_xtc_id()

	{

#ifdef VMS
	unsigned long ss_status;
	short return_length;
 	struct item_list_3 itmlst[2];
	char lognam_xtc_id[31];
	struct dsc$descriptor lognam_xtc_id_desc;
#endif

	if (mbxno == 1)
		strcpy( xtc_id, plotfile_namepart );

	else
		{
#ifdef VMS
		sprintf( lognam_xtc_id, "XTC_ID_%d_%s\0", 
				idx_number, username );
		lognam_xtc_id_desc.dsc$w_length  = strlen(lognam_xtc_id);
	        lognam_xtc_id_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
	        lognam_xtc_id_desc.dsc$b_class   = DSC$K_CLASS_S;
	        lognam_xtc_id_desc.dsc$a_pointer = lognam_xtc_id;

		itmlst[0].buffer_length = 40;
		itmlst[0].item_code = LNM$_STRING;
		itmlst[0].buffer_address = xtc_id;
		itmlst[0].return_length_address = &return_length;
		itmlst[1].buffer_length = 0;
		itmlst[1].item_code = 0;

		ss_status = sys$trnlnm( 0, &lnm_group_desc, 
					&lognam_xtc_id_desc, 0, itmlst );

		if (ss_status == SS$_NOLOGNAM)       
			sprintf( xtc_id, "MBX_%d Frame\0", idx_number);

		else if (ss_status == SS$_BUFFEROVF) 
			xtc_id[40] = '\0';

		else if (ss_status != SS$_NORMAL) 
			ss_message("Error translating XTC_ID logical name:", 
					ss_status);

		else                                 
			xtc_id[return_length] = '\0';
#else
		sprintf( xtc_id, "MBX_%d Frame\0", idx_number);
#endif
		}

	} /* End */

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

static void qiow_sysoutput()

	{

/*
**  Queue the request in 512-byte increments.  This should prevent any
**  problems with MAXBUF being too small.
*/

	while (qiow_nbytes > 0)
		{
		bytes_to_send = qiow_nbytes;
		if (bytes_to_send > 512) bytes_to_send = 512;

		write_tek_window( qiow_addr, bytes_to_send );

		qiow_addr = qiow_addr + bytes_to_send;
		qiow_nbytes = qiow_nbytes - bytes_to_send;
		}

	} /* End */

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

static void remove_plot()

	{

	int i,j;
	unsigned long ss_status;

	XmListSetHorizPos( wslBufferedFrames, 0 );

	XmListDeleteItem( wslBufferedFrames,
				XmStringCreate(lbox_id[remove_index],"") );

#ifdef VMS
	ss_status = lib$free_vm( &lbox_alloc[remove_index],
				 &lbox_addr[remove_index], 0 );
	if (ss_status != SS$_NORMAL) 
		ss_message("Error freeing virtual memory:", ss_status);

	ss_status = lib$free_vm( &lbox_id_length,
				 &lbox_id[remove_index], 0 );
	if (ss_status != SS$_NORMAL) 
		ss_message("Error freeing virtual memory:", ss_status);
#else
	free(lbox_addr[remove_index]);
	free(lbox_id[remove_index]);
#endif

	for (i = remove_index; i < lbox_top; i++)
		{
		lbox_addr[i] = lbox_addr[i+1];
		lbox_id[i] = lbox_id[i+1];
		lbox_nbytes[i] = lbox_nbytes[i+1];
		lbox_alloc[i] = lbox_alloc[i+1];
		}

	lbox_top--;

	for (i = 0; i <= 1; i++)
		{
		if (lbox_flag[i] != 0 && lbox_index[i] == remove_index) 
			lbox_flag[i] = 0;
		if (lbox_flag[i] != 0 && lbox_index[i] >  remove_index) 
			lbox_index[i]--;
		}

	j = -1;
	for (i = 0; i < dpn_num; i++)
		{
		if (dpn_list[i] == remove_index) j = i;
		if (dpn_list[i] >  remove_index) dpn_list[i]--;
		}

	if (j >= 0)
		{
		for (i = j; i < dpn_num - 1; i++)
			{
			dpn_list[i] = dpn_list[i+1];
			}
		dpn_num--;
		}

	if (lbox_current_index == remove_index) lbox_current_index = -1;
	if (lbox_current_index >  remove_index) lbox_current_index--;

	} /* End */

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

static void force_ERASE()

	{

	int nbytes_ERASE_tek = 2;
	char ERASE_tek[2] = { 0x1B, 0x0C };

	qiow_addr = ERASE_tek;
	qiow_nbytes = nbytes_ERASE_tek;
	qiow_sysoutput();
	
	lbox_current_index = -1;

	dpn_num = 0;
	XmListDeselectAllItems( wslBufferedFrames );

	} /* End */

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

void callbackCommandsMenu( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	int i,j;
	int tek_width, tek_height;
	unsigned long ss_status;

	if (tag == 10)		/* Show List Box */
		{
		XtRealizeWidget( wshellLB );
		lb_state = 1;
		}

	else if (tag == 20)	/* Clear Plot Buffer */
		{
		XtManageChild( wformdClearFrameBuffer );
		}

	else if (tag == 30)	/* Show Byte Stream */
		{
		j = 0;

		for (i = 0; i < 3598; i = i + 3)
			{
			j++;
			byte_stream_dump[i] = '_';
			byte_stream_dump[i+1] = '_';
			if (j == 30) 
				{
				byte_stream_dump[i+2] = '\n';
				j = 0;
				}
			else
				byte_stream_dump[i+2] = ' ';
			}

		byte_stream_dump[3599] = '\0';

		XtSetArg( arglist[0], XmNlabelString, 
				XmStringCreateLtoR(byte_stream_dump,"") );
		XtSetValues( wlabByteStreamDump, arglist, 1 );

		XtManageChild( wformdByteStream );
		byte_stream_managed = 1;
		}

	else if (tag == 40)	/* Force ERASE */
		{
		force_ERASE();
		}

	else if (tag == 50)	/* Read Plot File */
		{
		XtManageChild( wfiledReadPlotFile );
		}

	else if (tag == 70)	/* Rename Frames */
		{
		XtManageChild( wformdRenameFrame );
		}

	else if (tag == 80 || tag == 90)	/* Fix Aspect Ratio */
		{
		get_tek_geometry( &tek_width, &tek_height );

		if (tag == 80)	tek_height = (780 * tek_width) / 1024;
		else            tek_width = (1024 * tek_height) / 780;

		XtSetArg( arglist[0], XmNwidth, tek_width );
		XtSetArg( arglist[1], XmNheight, tek_height );
		XtSetValues( wdraw, arglist, 2 );
		}

	else if (tag == 800)	/* About_XTC */
		{
		XtManageChild( wformdAboutXTC );

		XtAppAddTimeOut( 
			XtWidgetToApplicationContext(wformdAboutXTC),
			flex_timeout, do_flex, wformdAboutXTC );
		}

	else if (tag == 900)	/* Quit */
		{
		for (i = 0; i <= 1; i++)
			{
			if (lbox_flag[i] != 0)
				{
				if (auto_file)
					{
					file_flag = 1;
					fn_list[0] = lbox_index[i];
					fn_num = 1;
					file_frame();
					}

				if (auto_print)
					{
					fn_list[0] = lbox_index[i];
					fn_num = 1;
					print_frame();
					}
				}
			}

#ifdef VMS
		ss_status = lib$delete_logical( &lnm_temporary_mailbox_desc, 
						&lnm_process_directory_desc );
		if (ss_status != SS$_NORMAL) 
			ss_message(
			"Error deassigning temporary mailbox logical name:",
				ss_status);
#else
		if (socket_mbx_flag == 1)
			{
			XtRemoveInput(xtinputid_mbx_recv);
			close(sd0_mbx);
			}
		else
			XtRemoveInput(xtinputid_mbx_accept);

		close(socket_mbx_desc);
		unlink(socket_mbx_name.sun_path);


		if (socket_gin_flag == 1)
			{
			XtRemoveInput(xtinputid_gin_recv);
			close(sd0_gin);
			}
		else
			XtRemoveInput(xtinputid_gin_accept);

		close(socket_gin_desc);
		unlink(socket_gin_name.sun_path);
#endif

		exit(1);
		}

	} /* End */

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

void callbackCustomizeMenu( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	if (tag == 10)
		XtManageChild( wformdFrameBuffering );

	else if (tag == 20)
		XtManageChild( wformdFrameFiling );

	else if (tag == 30)
		XtManageChild( wformdFramePrinting );

	else if (tag == 40)
		XtManageChild( wformdControlSequences );

	else if (tag == 50)
		XtManageChild( wformdVisibility );

	else if (tag == 60)
		XtManageChild( wformdColors );

	else if (tag == 100)	/* Use Last Saved Settings */
		{
		settings_key = 1;
		get_settings();
		}

	else if (tag == 110)	/* Use System Defaults */
		{
		settings_key = 0;
		get_settings();
		}

	else if (tag == 120)	/* Save Current Settings */
		save_current_settings();

	} /* End */

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

void callbackDismiss( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	int i;

	if (tag == 10)
		{
		XtUnmanageChild( wformdByteStream );
		byte_stream_managed = 0;
		}

	else if (tag == 20)
		XtUnmanageChild( wformdAboutXTC );

	else if (tag == 30)
		XtUnmanageChild( wformdMessages );

	else if (tag == 40)
		XtUnmanageChild( wformdColors );

	else if (tag == 50)
		{
		XtUnrealizeWidget( wshellLB );
		lb_state = 0;
		}

	} /* End */

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

void callbackOKACFrameBuffering( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	if (tag == 10 || tag == 11)
		{
		XmScaleGetValue( wscaleBufferDepth, &save_depth );

		implement_save_depth();

		if ( XmToggleButtonGetState( wtogTopDown ) )
			multi_order = 0;
		else	multi_order = 1;
		}

	else if (tag == 12)
		{
		XmScaleSetValue( wscaleBufferDepth, save_depth );

		if (multi_order == 0)
			XmToggleButtonSetState( wtogTopDown, 
							TRUE, TRUE );
		else
			XmToggleButtonSetState( wtogBottomUp, 
							TRUE, TRUE );
		}

	if (tag == 10 || tag == 12)
		XtUnmanageChild( wformdFrameBuffering );

	} /* End */

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

void callbackOKACRenameFrame( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	int i,j,p,d;
	char *f;
	char num_part[10];
	char new_frame_id[60];
	XmString old_items[1], new_items[1];

	if (tag == 10 || tag == 11)
		{
		if (dpn_num > 0)
			{
			for (d = 0; d < dpn_num; d++)
				{
				frame_id = lbox_id[dpn_list[d]];

				p = strlen(frame_id) - 1;
				while (frame_id[p] != '[') p--;        

				j = 0;
				for (i = p-1; i < strlen(frame_id); i++) 
					num_part[j++] = frame_id[i];
				num_part[j] = '\0';

				f = XmTextGetString( wtextFrameID );

				strcpy( new_frame_id, f );
				strcat( new_frame_id, num_part );

				old_items[0] = XmStringCreate(frame_id,"");
				new_items[0] = XmStringCreate(new_frame_id,"");

				XmListSetHorizPos( wslBufferedFrames, 0 );

				XmListReplaceItems( wslBufferedFrames, 
						old_items, 1, new_items);

/*
				XmListSelectItem( wslBufferedFrames, 
						new_items[0], FALSE );
*/

				strcpy( lbox_id[dpn_list[d]], new_frame_id );
				}

			dpn_num = 0;
			XmListDeselectAllItems( wslBufferedFrames );
			}
		else
			{
			strcpy( message_string,	
				"Rename error: No frames are selected");
			display_message();
			}
		}

	else if (tag == 12)
		{
		}

	if (tag == 10 || tag == 12)
		XtUnmanageChild( wformdRenameFrame );

	} /* End */

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

void callbackOKACFrameFiling( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	char *r;

	if (tag == 10 || tag == 11)
		{
		r = XmTextGetString( wtextFrameFilename );
		strcpy( raw_filename, r );

		auto_file = XmToggleButtonGetState( wtogAutoFile );

		ps_file = XmToggleButtonGetState( wtogPsFile );

		append_frames = XmToggleButtonGetState( 
					wtogAppendFrames );
		}

	else if (tag == 12)
		{
		XmTextSetString( wtextFrameFilename, raw_filename );

		XmToggleButtonSetState( wtogAutoFile, 
						auto_file, FALSE );
		XmToggleButtonSetState( wtogPsFile, 
						ps_file, FALSE );

		XmToggleButtonSetState( wtogAppendFrames,
						 append_frames, FALSE );
		}

	if (tag == 10 || tag == 12)
		XtUnmanageChild( wformdFrameFiling );

	} /* End */

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

void callbackOKACFramePrinting( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	char *d, *p;

	if (tag == 10 || tag == 11)
		{
#ifdef VMS
		d = XmTextGetString( wtextQueue );
		strcpy( print_queue, d );

		d = XmTextGetString( wtextCommandFile );
		strcpy( print_procedure, d );
#else
		d = XmTextGetString( wtextPrintCommand );
		strcpy( print_command, d );

		d = XmTextGetString( wtextCommandFile );
		strcpy( print_procedure,d);
#endif
		auto_print = XmToggleButtonGetState( wtogAutoPrint );

		d = XmTextGetString( wtextScratchArea );
		strcpy( scratch_area, d );
		}

	else if (tag == 12)
		{
#ifdef VMS
		XmTextSetString( wtextQueue, print_queue );
		XmTextSetString( wtextCommandFile, print_procedure );
#else
                XmTextSetString( wtextPrintCommand, print_command );
		XmTextSetString( wtextCommandFile, print_procedure );
#endif
		XmToggleButtonSetState( wtogAutoPrint, auto_print, FALSE );
		XmTextSetString( wtextScratchArea, scratch_area );
		}

	if (tag == 10 || tag == 12)
		XtUnmanageChild( wformdFramePrinting );

	} /* End */

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

void callbackOKACVisibility( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	int i;
	char *string;
	char byte_string[5];

	if (tag == 10 || tag == 11)
		{
		if ( XmToggleButtonGetState( wtogStartupWindow ) )
			startup_state = 0;
		else	startup_state = 1;

		if ( XmToggleButtonGetState( wtogListBoxConstant ) )
			list_box_policy = 0;
		else	list_box_policy = 1;

		display_MBX_data = XmToggleButtonGetState( 
					wtogDisplayMBXData );

		display_plotfile_data = XmToggleButtonGetState( 
					wtogDisplayPlotfileData );
		}

	else if (tag == 12)
		{
		if (startup_state)
			XmToggleButtonSetState( wtogStartupIcon, 
							TRUE, TRUE );

		else
			XmToggleButtonSetState( wtogStartupWindow, 
							TRUE, TRUE );

		if (list_box_policy)
			XmToggleButtonSetState( wtogListBoxVariable, 
							TRUE, TRUE );

		else
			XmToggleButtonSetState( wtogListBoxConstant, 
							TRUE, TRUE );

		XmToggleButtonSetState( wtogDisplayMBXData, 
						display_MBX_data, FALSE );

		XmToggleButtonSetState( wtogDisplayPlotfileData, 
						display_plotfile_data, FALSE );

		}

	if (tag == 10 || tag == 12)
		XtUnmanageChild( wformdVisibility );

	} /* End */

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

void callbackOKACControlSeqs( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	int i;
	char *string;
	char byte_string[3];
	int sscanf_temp;

	if (tag == 10 || tag == 11)
		{
		nbytes_INITT_byte_stream = 0;
	
		for (i = 0; i < 8; i++)
			{
			string = XmTextGetString( wtextINITT[i] );
			if (strlen(string) == 0 || 
				strcmp( string, " ") == 0 ||
				strcmp( string, "  ") == 0)
				INITT_byte_stream[i] = 0;
			else
				{
				sscanf( string, "%x", &sscanf_temp );
				INITT_byte_stream[i] = sscanf_temp;
 				nbytes_INITT_byte_stream = i + 1;
				}
			}

		for (i = 0; i <= 1; i++) INITT_idx[i] = 0;


		nbytes_FINITT_byte_stream = 0;
	
		for (i = 0; i < 8; i++)
			{
			string = XmTextGetString( wtextFINITT[i] );
			if (strlen(string) == 0 || 
				strcmp( string, " ") == 0 ||
				strcmp( string, "  ") == 0)
				FINITT_byte_stream[i] = 0;
			else
				{
				sscanf( string, "%x", &sscanf_temp );
				FINITT_byte_stream[i] = sscanf_temp;
				nbytes_FINITT_byte_stream = i + 1;
				}
			}

		for (i = 0; i <= 1; i++) FINITT_idx[i] = 0;


		nbytes_SNP_byte_stream = 0;
	
		for (i = 0; i < 8; i++)
			{
			string = XmTextGetString( wtextSNP[i] );
			if (strlen(string) == 0 || 
				strcmp( string, " ") == 0 ||
				strcmp( string, "  ") == 0)
				SNP_byte_stream[i] = 0;
			else
				{
				sscanf( string, "%x", &sscanf_temp );
				SNP_byte_stream[i] = sscanf_temp;
				nbytes_SNP_byte_stream = i + 1;
				}
			}

		for (i = 0; i <= 1; i++) SNP_idx[i] = 0;

		if (nbytes_SNP_byte_stream == 0)
			{
			sprintf( message_string, "%s%s%s\0", 
				"Warning: You have entered an empty ``Start ",
				"Of Frame'' byte stream.\nThis will make ",
				"new frame recognition impossible" );
			display_message();
			}

		string = XmTextGetString( wtextGINBytes );
		sscanf( string, "%d", &GIN_Bytes );

		}

	else if (tag == 12)
		{
		for (i = 0; i < 8; i++)
			{
			if (i < nbytes_INITT_byte_stream)
				sprintf( byte_string, "%02X\0", 
						INITT_byte_stream[i] );
			else
				sprintf ( byte_string, "\0" );

			XmTextSetString( wtextINITT[i], byte_string );
			}

		for (i = 0; i < 8; i++)
			{
			if (i < nbytes_FINITT_byte_stream)
				sprintf( byte_string, "%02X\0", 
						FINITT_byte_stream[i] );
			else
				sprintf ( byte_string, "\0" );

			XmTextSetString( wtextFINITT[i], byte_string );
			}

		for (i = 0; i < 8; i++)
			{
			if (i < nbytes_SNP_byte_stream)
				sprintf( byte_string, "%02X\0", 
						SNP_byte_stream[i] );
			else
				sprintf ( byte_string, "\0" );

			XmTextSetString( wtextSNP[i], byte_string );
			}

		sprintf( byte_string, "%d\0", GIN_Bytes );

		XmTextSetString( wtextGINBytes, byte_string );
		}

	if (tag == 10 || tag == 12)
		XtUnmanageChild( wformdControlSequences );

	} /* End */

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

void callbackDrawFrame( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	draw_frames();

	} /* End */

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

static void draw_frames()

	{
	int d;

	if (dpn_num > 0)
		{
		for (d = 0; d < dpn_num; d++) 
			{
			if (multi_order == 1) lbox_dump_index = dpn_list[d];
			else lbox_dump_index = dpn_list[dpn_num-d-1];

			bmark = 0;
			redraw_flag = 1;
		        dump_frame_buffer();
			}
		}
	else
		{
		strcpy( message_string,	
			"Draw error: No frames are selected");
		display_message();
		}

	} /* End */

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

void callbackFileFrame( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{
	int d;

	if (dpn_num > 0)
		{
		for (d = 0; d < dpn_num; d++)
			{
			if (multi_order == 1) fn_list[d] = dpn_list[d];
			else fn_list[d] = dpn_list[dpn_num-d-1];
			}

		fn_num = dpn_num;

		file_flag = 1;
		file_frame();
		}
	else
		{
		strcpy( message_string,	
			"File error: No frames are selected");
		display_message();
		}

	} /* End */

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

void callbackPrintFrame( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{
	int d;

	if (dpn_num > 0)
		{
		for (d = 0; d < dpn_num; d++)
			{
			if (multi_order == 1) fn_list[d] = dpn_list[d];
			else fn_list[d] = dpn_list[dpn_num-d-1];
			}

		fn_num = dpn_num;

		print_frame();
		}
	else
		{
		strcpy( message_string,	
			"Print error: No frames are selected");
		display_message();
		}

	} /* End */

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

void callbackDeleteFrame( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	int d;

	if (dpn_num > 0)
		{
/*
		for (d = 0; d < dpn_num; d++)
			{
			remove_index = dpn_list[d];
			remove_plot();
			}

		dpn_num = 0;
		XmListDeselectAllItems( wslBufferedFrames );
*/
		while( dpn_num > 0)
			{
			remove_index = dpn_list[0];
			remove_plot();
			}
		}
	else
		{
		strcpy( message_string,	
			"Delete error: No frames are selected");
		display_message();
		}

	} /* End */

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

void callbackListBoxSelect( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmListCallbackStruct *callback_data;

	{

	int i;
	int dpn;

	if (callback_data->reason == XmCR_EXTENDED_SELECT)
		{
		dpn_num = callback_data->selected_item_count;
		for (i = 0; i < dpn_num; i++)
			{
			dpn_list[dpn_num-i-1] = lbox_top
				- callback_data->selected_item_positions[i] 
				+ 1;                   
			}
		}

	else if (callback_data->reason == XmCR_DEFAULT_ACTION)
		{
/*
		dpn = lbox_top - callback_data->item_position + 1;

		bmark = 0;
		lbox_dump_index = dpn;
		redraw_flag = 1;
	        dump_frame_buffer();
*/
		draw_frames();
		}

	} /* End */

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

void callbackClearFrameBuffer( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	if (tag == 10 || tag == 20)
		{
		keep = 0;
		clear_buffer();
		if (tag == 10) current_plot_number = 0;
		}

	XtUnmanageChild( wformdClearFrameBuffer );

	} /* End */

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

void callbackGINBytes( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmPushButtonCallbackStruct *callback_data;

	{

	if (tag == 5)
		XmTextSetString( wtextGINBytes, "5" );

	else if (tag == 6)
		XmTextSetString( wtextGINBytes, "6" );

	} /* End */

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

void callbackReadPlotFile( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmFileSelectionBoxCallbackStruct *callback_data;

	{

	char *p;

	if (callback_data->reason == XmCR_OK)
		{
		XmStringGetLtoR( callback_data->value, "", &p );
		strcpy( plot_filename, p );

		read_plotfile();
		}

	else if (callback_data->reason == XmCR_CANCEL)
		{
		XtUnmanageChild( wfiledReadPlotFile );
		}

	} /* End */

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

#ifdef VMS

static void file_frame()		/* VMS version */

	{

	struct FAB fab_frame;
	int contin;
	int file_open;
	unsigned long ss_status;

	int spawn_flags;
	$DESCRIPTOR( nl_desc, "NL:" );
	char command_string[255];
	struct dsc$descriptor command_string_desc;

/*
**  Generate frame_filename.
*/

	if (file_flag == 1)
		generate_exp_from_raw();
	else
		generate_print_filename();

/*
**  Initialize the rms structures.
*/

	fab_frame           = cc$rms_fab;
	fab_frame.fab$l_dna = default_file_type;
	fab_frame.fab$b_dns = strlen(default_file_type);
	fab_frame.fab$b_fac = FAB$M_PUT;
	fab_frame.fab$l_fna = frame_filename;
	fab_frame.fab$b_fns = strlen(frame_filename);
	if (file_flag == 1)
		{
		if ( append_frames )	fab_frame.fab$l_fop = FAB$M_CIF;
		else			fab_frame.fab$l_fop = FAB$M_SUP;
		}
	else
		fab_frame.fab$l_fop = FAB$M_SUP;
	fab_frame.fab$w_mrs = 512;
	fab_frame.fab$b_org = FAB$C_SEQ;
	fab_frame.fab$b_rfm = FAB$C_FIX;
	fab_frame.fab$b_shr = FAB$M_NIL;

	rab_frame           = cc$rms_rab;
	rab_frame.rab$l_fab = &fab_frame;
	rab_frame.rab$l_rop = RAB$M_EOF;
	rab_frame.rab$l_rbf = rab_buffer;
	rab_frame.rab$w_rsz = 512;

/*
**  Create/open the output file.
*/

	contin = 1;
	file_open = 1;

	ss_status = sys$create(&fab_frame);

	if (ss_status != RMS$_NORMAL && 
	    ss_status != RMS$_CREATED &&
	    ss_status != RMS$_SUPERSEDE)
		{
		ss_message("Error creating/opening output file:", ss_status);
		contin = 0;
		file_open = 0;
		}

/*
**  Connect the record stream.
*/

	if (contin)
		{
		ss_status = sys$connect(&rab_frame);

		if (ss_status != RMS$_NORMAL)
			{
			ss_message("Error connecting to output file:",
						ss_status);
			contin = 0;
			}
		}

/*
**  Dump the specified frame to the output file.
*/

	if (contin) write_rms_file();

/*
**  Close the output file.
*/

	if (file_open)
		{
		ss_status = sys$close(&fab_frame);

		if (ss_status != RMS$_NORMAL) 
			ss_message("Error closing output file:", ss_status);
		}
/*
**  Convert to Post Script ?
*/
	if (ps_file)
	  {
	    sprintf( command_string, 
		     "@SOURCEROOT:[XTCTEK]TEK2PS_DCL.COM  %s\0",
		     frame_filename );

	    command_string_desc.dsc$w_length  = strlen(command_string);
	    command_string_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
	    command_string_desc.dsc$b_class   = DSC$K_CLASS_S;
	    command_string_desc.dsc$a_pointer = command_string;
	    
printf("command = %s\n",command_string);
	    spawn_flags = CLI$M_NOWAIT;

	    ss_status = lib$spawn( &command_string_desc,
				   &nl_desc,
				   &nl_desc,
				   &spawn_flags,
				   0, 0, 
				   &printer_comp_status, 
				   &event_flag_printer, 
				   0, 0, 0, 0 );

	    if (ss_status != SS$_NORMAL) 
	      ss_message("Error spawning printer subprocess:", ss_status);
	  }

	if (contin && file_flag == 1) 
		{
		XBell(XtDisplay(wmain), 20 );
		XBell(XtDisplay(wmain), 100 );
		}

	} /* End */

#else

static void file_frame()		/* UNIX version */

	{

	FILE *f;
	char amode[5];
	int c, c1;
	int fn,contin;
	char *frame_addr, *s;
	int frame_nbytes;

        char command_string[255];

	if (file_flag == 1) generate_exp_from_raw();
	else                generate_print_filename();

	if (file_flag == 1 && append_frames) strcpy(amode,"ab");
	else                                 strcpy(amode,"wb");

	if (!(f=fopen(frame_filename,amode)))
		{
		ss_message("fopen() error:", 0);
		}
	else
		{
		contin = 1;

		for (fn = 0; fn < fn_num; fn++)
			{
			frame_addr = lbox_addr[fn_list[fn]];
			frame_nbytes = lbox_nbytes[fn_list[fn]];

			while (frame_nbytes > 0 && contin == 1)
				{
				c = (int) *frame_addr;
	                        if ((c1 = fputc(c,f)) == EOF)
					{
					ss_message("fputc() error:", 0);
					contin = 0;
					}
				else
					{
					frame_addr++;
					frame_nbytes--;
					}
				}
			}

		fclose(f);
		if (ps_file) {
		  strcpy(ps_filename,frame_filename);
		  strcat(ps_filename,".ps");

		  s = XmTextGetString( wtextCommandFile );
		  if (strlen(s))
		    {
		      sprintf( command_string, "tek2ps -o %s -p %s/tek2ps.pro %s\0", ps_filename, s, frame_filename );
		      /* printf(" system: %s\n",command_string); */
		      system( command_string ); 
		    }
		  else
		    {
		      strcpy( message_string,
			"Supply Directory of tek2ps prolog in Frame Printing");
		      display_message();
		    }
		}

		if (file_flag == 1)
			{
			XBell(XtDisplay(wmain), 20 );
			XBell(XtDisplay(wmain), 100 );
			}
		}
	
	} /* End */

#endif

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

#ifdef VMS

static void print_frame()		/* VMS version */

	{

	int spawn_flags;
	unsigned long ss_status;
	$DESCRIPTOR( nl_desc, "NL:" );
	char command_string[121];
	struct dsc$descriptor command_string_desc;

	file_flag = 2;
	file_frame();

	sprintf( command_string, "@%s %s %s\0",
			print_procedure, frame_filename, print_queue );

	command_string_desc.dsc$w_length  = strlen(command_string);
        command_string_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
        command_string_desc.dsc$b_class   = DSC$K_CLASS_S;
        command_string_desc.dsc$a_pointer = command_string;

	spawn_flags = CLI$M_NOWAIT;

	ss_status = lib$spawn(	&command_string_desc,
				&nl_desc,
				&nl_desc,
				&spawn_flags,
				0, 0, 
				&printer_comp_status, 
				&event_flag_printer, 
				0, 0, 0, 0 );

	if (ss_status != SS$_NORMAL) 
		ss_message("Error spawning printer subprocess:", ss_status);

	} /* End */

#else

static void print_frame()		/* UNIX version */

	{

	char command_string[200];
        int  status;

	file_flag = 2;
	file_frame();

	if (strlen(ps_filename)) {
	  sprintf( command_string, "%s %s\0", print_command, ps_filename );
	}
	else if (strlen(print_procedure)) {
	  sprintf( command_string, "/bin/sh %s/xtc_print '%s' %s %s\0",
		  print_procedure,print_command, frame_filename,
		  print_procedure);
	}
	else {
	  sprintf( command_string, "%s %s\0", print_command, frame_filename );
	}
	/*	    printf("command_string: %s\n",command_string); */
	system( command_string );
        status = remove(frame_filename);	
	if (ps_file) {
	  status = remove(ps_filename);
	}	

	XBell(XtDisplay(wmain), 20 );
	XBell(XtDisplay(wmain), 100 );
    
	} /* End */

#endif

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

static void generate_exp_from_raw()

	{

	int i,j,k,p;

/*
**  Set frame_id to the list box entry for the first frame to be processed.
*/

	frame_id = lbox_id[fn_list[0]];

/*
**  Find the right-most left parenthesis.  This character is used as a
**  divider between the frame label and the frame number, which can be
**  used as substitution parameters in the filename.
*/

	p = strlen(frame_id) - 1;
	while (frame_id[p] != '[') p--;        

/*
**  Generate the expanded filename from the raw filename, substituting in
**  the frame label for '*', the frame number for '#', and '_' for any
**  blanks.
*/

	j = 0;

	for (i = 0; i < strlen(raw_filename); i++)
		{
		if (raw_filename[i] == '~')
			{
			strcpy (frame_filename, (char *) getenv("HOME") );
			j = strlen (frame_filename);
			}

		else if (raw_filename[i] == '*')
			{
			for (k = 0; k < p-1; k++)
				{
				if (frame_id[k] <= ' ')
					frame_filename[j++] = '_';
				else
					frame_filename[j++] = frame_id[k];
				}
			}

		else if (raw_filename[i] == '#')
			{
			for (k = p+1; k < strlen(frame_id)-1; k++)
				frame_filename[j++] = frame_id[k];
			}

		else if (raw_filename[i] <= ' ')
			{                
			frame_filename[j++] = '_';			
			}

		else
			{                
			frame_filename[j++] = raw_filename[i];			
			}
		}

	frame_filename[j] = '\0';

	} /* End */

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

#ifdef VMS

static void generate_print_filename()		/* VMS version */

	{

	char tdstring[18];
	unsigned long ss_status;
	char timbuf[24];
	struct dsc$descriptor timbuf_desc;

	timbuf_desc.dsc$w_length  = 23;
        timbuf_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
        timbuf_desc.dsc$b_class   = DSC$K_CLASS_S;
        timbuf_desc.dsc$a_pointer = timbuf;

	ss_status = sys$asctim( 0, &timbuf_desc, 0, 0 );

	if (ss_status != SS$_NORMAL) 
		ss_message("Error getting time from $ASCTIM:", ss_status);

	tdstring[0]  = timbuf[0];
	if (tdstring[0] == ' ') tdstring[0] = '0';
	tdstring[1]  = timbuf[1];
	tdstring[2]  = timbuf[3];
	tdstring[3]  = timbuf[4];
	tdstring[4]  = timbuf[5];
	tdstring[5]  = timbuf[7];
	tdstring[6]  = timbuf[8];
	tdstring[7]  = timbuf[9];
	tdstring[8]  = timbuf[10];
	tdstring[9]  = timbuf[12];
	tdstring[10] = timbuf[13];
	tdstring[11] = timbuf[15];
	tdstring[12] = timbuf[16];
	tdstring[13] = timbuf[18];
	tdstring[14] = timbuf[19];
	tdstring[15] = timbuf[21];
	tdstring[16] = timbuf[22];
	tdstring[17] = '\0';

	sprintf (frame_filename, "%sXTC_%s%s\0", 
			scratch_area, tdstring, default_file_type );

	} /* End */

#else

static void generate_print_filename()		/* UNIX version */

        {
        long int tloc;
        time_t timet;
        int temp_mon;
        int temp_year;
        struct tm *tmstruct;
        char tdstring[15];

        tloc = NULL;
        timet = time(&tloc);
        tmstruct = localtime(&timet);

        temp_mon = tmstruct->tm_mon + 1;
        temp_year = tmstruct->tm_year + 1900;

        sprintf( tdstring, "%02d%02d%04d%02d%02d%02d\0",
                        temp_mon,
                        tmstruct->tm_mday,
                        temp_year,
                        tmstruct->tm_hour,
                        tmstruct->tm_min,
                        tmstruct->tm_sec );

        sprintf( frame_filename, "%s/xtc_%s.plt\0",
                        scratch_area, tdstring );

        } /* End */

#endif

#ifdef VMS

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

static void write_rms_file()

	{

	int i,f;
	int contin;
	unsigned long ss_status;
	char *frame_addr;
	int frame_nbytes;

	contin = 1;

	for (f = 0; f < fn_num; f++)
		{
		frame_addr = lbox_addr[fn_list[f]];
		frame_nbytes = lbox_nbytes[fn_list[f]];

		while (frame_nbytes > 0 && contin == 1)
			{
			bytes_to_send = frame_nbytes;
			if (bytes_to_send > 512) bytes_to_send = 512;

			for (i = 0; i < bytes_to_send; i++)
				{
				rab_buffer[i] = *frame_addr;
				frame_addr++;
				frame_nbytes--;
				}

			if (bytes_to_send < 512)
				{
				for (i = bytes_to_send; i < 512; i++)
					rab_buffer[i] = 0x00;
				}

			ss_status = sys$put(&rab_frame);

			if (ss_status != RMS$_NORMAL) 
				{
				ss_message("Error writing output file:",
						ss_status);
				contin = 0;
				}
			}
		}

	} /* End */

#endif

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

static void save_current_settings()

	{
	int i;
	char *ft[2] = { "false", "true" };
	int tek_width, tek_height;

	xrm_database = XrmGetStringDatabase("");

	get_xy();

	sprintf( xrm_string, "%d\0", startup_x );
	XrmPutStringResource( &xrm_database, 
				"xtc.x", 
				xrm_string );

	sprintf( xrm_string, "%d\0", startup_y );
	XrmPutStringResource( &xrm_database, 
				"xtc.y", 
				xrm_string );

	XrmPutStringResource( &xrm_database, 
				"xtc.iconic", 
				ft[startup_state] );

	get_tek_geometry( &tek_width, &tek_height );
		
	sprintf( xrm_string, "%d\0", tek_width );
	XrmPutStringResource( &xrm_database, 
				"xtc*wdraw.width", 
				xrm_string );

	sprintf( xrm_string, "%d\0", tek_height );
	XrmPutStringResource( &xrm_database, 
				"xtc*wdraw.height", 
				xrm_string );

	sprintf( xrm_string, "%d\0", save_depth );
	XrmPutStringResource( &xrm_database, 
				"xtc*wscale_Buffer_Depth.value", 
				xrm_string );

	if (multi_order == 0)
		{
		XrmPutStringResource( &xrm_database, 
					"xtc*wtog_Top_Down.set", 
					"true" );

		XrmPutStringResource( &xrm_database, 
					"xtc*wtog_Bottom_Up.set", 
					"false" );
		}
	else
		{
		XrmPutStringResource( &xrm_database, 
					"xtc*wtog_Bottom_Up.set", 
					"true" );

		XrmPutStringResource( &xrm_database, 
					"xtc*wtog_Top_Down.set", 
					"false" );
		}

	XrmPutStringResource( &xrm_database, 
				"xtc*wtext_Frame_Filename.value", 
				raw_filename );

	XrmPutStringResource( &xrm_database, 
				"xtc*wtog_Auto_File.set", 
				ft[auto_file] );

	XrmPutStringResource( &xrm_database, 
				"xtc*wtog_Ps_File.set", 
				ft[ps_file] );

	XrmPutStringResource( &xrm_database, 
				"xtc*wtog_Append_Frames.set", 
				ft[append_frames] );

#ifdef VMS
	XrmPutStringResource( &xrm_database, 
				"xtc*wtext_Queue.value", 
				print_queue );

#else
        XrmPutStringResource( &xrm_database,
                                "xtc*wtext_Print_Command.value",
                                print_command );
#endif
	XrmPutStringResource( &xrm_database, 
				"xtc*wtext_Command_File.value", 
				print_procedure );

	XrmPutStringResource( &xrm_database, 
				"xtc*wtog_Auto_Print.set", 
				ft[auto_print] );

	XrmPutStringResource( &xrm_database, 
				"xtc*wtext_Scratch_Area.value", 
				scratch_area );

	for (i = 0; i < nbytes_INITT_byte_stream; i++)
		{
		sprintf( xrm_resource, "xtc*wtext_INITT_%d.value\0", i );
		sprintf( xrm_string, "%02X\0", INITT_byte_stream[i] );

		XrmPutStringResource( &xrm_database, 
					xrm_resource, 
					xrm_string );
		}

	for (i = 0; i < nbytes_FINITT_byte_stream; i++)
		{
		sprintf( xrm_resource, "xtc*wtext_FINITT_%d.value\0", i );
		sprintf( xrm_string, "%02X\0", FINITT_byte_stream[i] );

		XrmPutStringResource( &xrm_database, 
					xrm_resource, 
					xrm_string );
		}

	for (i = 0; i < nbytes_SNP_byte_stream; i++)
		{
		sprintf( xrm_resource, "xtc*wtext_SNP_%d.value\0", i );
		sprintf( xrm_string, "%02X\0", SNP_byte_stream[i] );

		XrmPutStringResource( &xrm_database, 
					xrm_resource, 
					xrm_string );
		}

	sprintf( xrm_string, "%d\0", GIN_Bytes );
	XrmPutStringResource( &xrm_database, 
				"xtc*wtext_GIN_Bytes.value", 
				xrm_string );

	if (startup_state)
		{
		XrmPutStringResource( &xrm_database, 
				"xtc*wtog_Startup_Icon.set", 
				"true" );

		XrmPutStringResource( &xrm_database, 
				"xtc*wtog_Startup_Window.set", 
				"false" );
		}
	else
		{
		XrmPutStringResource( &xrm_database, 
				"xtc*wtog_Startup_Window.set", 
				"true" );

		XrmPutStringResource( &xrm_database, 
				"xtc*wtog_Startup_Icon.set", 
				"false" );
		}

	if (list_box_policy)
		{
		XrmPutStringResource( &xrm_database, 
				"xtc*wtog_List_Box_Variable.set", 
				"true" );

		XrmPutStringResource( &xrm_database, 
				"xtc*wtog_List_Box_Constant.set", 
				"false" );

		XrmPutStringResource( &xrm_database, 
				"xtc*wsl_Buffered_Frames.listSizePolicy", 
				"XmVARIABLE" );
		}
	else
		{
		XrmPutStringResource( &xrm_database, 
				"xtc*wtog_List_Box_Constant.set", 
				"true" );

		XrmPutStringResource( &xrm_database, 
				"xtc*wtog_List_Box_Variable.set", 
				"false" );

		XrmPutStringResource( &xrm_database, 
				"xtc*wsl_Buffered_Frames.listSizePolicy", 
				"XmCONSTANT" );
		}

	XrmPutStringResource( &xrm_database, 
			"xtc*wtog_Display_MBX_Data.set", 
			ft[display_MBX_data] );

	XrmPutStringResource( &xrm_database, 
			"xtc*wtog_Display_Plotfile_Data.set", 
			ft[display_plotfile_data] );

	for (i = 0; i <= 8; i++)
		{
		if (i < 8)
			sprintf( xrm_resource, 
				"xtc*wscale_Foreground%d_Red_V4.value\0", i );
		else
			sprintf( xrm_resource, 
				"xtc*wscale_Background_Red_V4.value\0");

		sprintf( xrm_string, "%d\0", red_value[i] );
		XrmPutStringResource( &xrm_database, xrm_resource, xrm_string);

		if (i < 8)
			sprintf( xrm_resource, 
				"xtc*wscale_Foreground%d_Green_V4.value\0", i);
		else
			sprintf( xrm_resource, 
				"xtc*wscale_Background_Green_V4.value\0");

		sprintf( xrm_string, "%d\0", green_value[i] );
		XrmPutStringResource( &xrm_database, xrm_resource, xrm_string);

		if (i < 8)
			sprintf( xrm_resource, 
				"xtc*wscale_Foreground%d_Blue_V4.value\0", i );
		else
			sprintf( xrm_resource, 
				"xtc*wscale_Background_Blue_V4.value\0");

		sprintf( xrm_string, "%d\0", blue_value[i] );
		XrmPutStringResource( &xrm_database, xrm_resource, xrm_string);
		}

	get_file_filter();

	XrmPutStringResource( &xrm_database, 
				"xtc*wfiled_Read_Plot_File.dirMask", 
				file_filter );

	XrmPutFileDatabase( xrm_database, xrm_user_file );

/*
	XrmDestroyDatabase( xrm_database );
*/

	} /* End */

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

static void get_settings()

	{
	int i;

	if (settings_key)
		xrm_database = XrmGetFileDatabase( xrm_user_file );
	else
		xrm_database = XrmGetFileDatabase( xrm_system_file );

	if (xrm_database == NULL)
		{
		if (settings_key)
			sprintf( message_string,
			"Error: Cannot process xrm database file %s\0",
			xrm_user_file );
		else
			sprintf( message_string,
			"Error: Cannot process xrm database file %s\0",
			xrm_system_file );

		display_message();
		}

	else
		{
		parse_settings();

		set_defaults();

		implement_save_depth();
		for (i = 0; i <= 8; i++) set_color(i);
		XmToggleButtonSetState( wtogGround[0], TRUE, TRUE );
		XmToggleButtonSetState( wtogGround[8], TRUE, TRUE );
		}

	} /* End */

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

static void parse_settings()

	{

	int i, j;
	int tf_flag;

	strcpy( xrm_resource, "xtc.wdraw.width" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		sscanf( xrm_string, "%d", &i );

		XtSetArg( arglist[0], XmNwidth, i );
		XtSetValues( wdraw, arglist, 1 );
		}

	strcpy( xrm_resource, "xtc.wdraw.height" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		sscanf( xrm_string, "%d", &i );

		XtSetArg( arglist[0], XmNheight, i );
		XtSetValues( wdraw, arglist, 1 );
		}

	strcpy( xrm_resource, "xtc.wscale_Buffer_Depth.value" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		sscanf( xrm_string, "%d", &i );

		XmScaleSetValue( wscaleBufferDepth, i );
		}

	strcpy( xrm_resource, "xtc.wtog_Top_Down.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') tf_flag = 1;

		XmToggleButtonSetState( wtogTopDown, 
						tf_flag, TRUE );
		}

	strcpy( xrm_resource, "xtc.wtog_Bottom_Up.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') tf_flag = 1;

		XmToggleButtonSetState( wtogBottomUp, 
						tf_flag, TRUE );
		}

	strcpy( xrm_resource, "xtc.wtext_Frame_Filename.value" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		XmTextSetString( wtextFrameFilename, xrm_string );
		}

	strcpy( xrm_resource, "xtc.wtog_Auto_File.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') tf_flag = 1;

		XmToggleButtonSetState( wtogAutoFile, 
						tf_flag, FALSE );
		}

	strcpy( xrm_resource, "xtc.wtog_Ps_File.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') tf_flag = 1;

		XmToggleButtonSetState( wtogPsFile, 
						tf_flag, FALSE );
		}

	strcpy( xrm_resource, "xtc.wtog_Append_Frames.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') tf_flag = 1;

		XmToggleButtonSetState( wtogAppendFrames, 
						tf_flag, FALSE );
		}

#ifdef VMS
	strcpy( xrm_resource, "xtc.wtext_Queue.value" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		XmTextSetString( wtextQueue, xrm_string );
		}

#else
	strcpy( xrm_resource, "xtc.wtext_Print_Command.value" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		XmTextSetString( wtextPrintCommand, xrm_string );
		}
#endif

	strcpy( xrm_resource, "xtc.wtext_Command_File.value" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		XmTextSetString( wtextCommandFile, xrm_string );
		}

	strcpy( xrm_resource, "xtc.wtog_Auto_Print.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') tf_flag = 1;

		XmToggleButtonSetState( wtogAutoPrint, tf_flag, FALSE );
		}

	strcpy( xrm_resource, "xtc.wtext_Scratch_Area.value" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		XmTextSetString( wtextScratchArea, xrm_string );
		}

	for (i = 0; i < 8; i++)
		{
		sprintf( xrm_resource, "xtc.wtext_INITT_%d.value\0", i );
		if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
					xrm_str_type, &xrm_value ) )
			{
			strncpy( xrm_string, xrm_value.addr, xrm_value.size );
	
			XmTextSetString( wtextINITT[i], xrm_string );
			}
		else
			XmTextSetString( wtextINITT[i], "" );
		}

	for (i = 0; i < 8; i++)
		{
		sprintf( xrm_resource, "xtc.wtext_FINITT_%d.value\0", i );
		if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
					xrm_str_type, &xrm_value ) )
			{
			strncpy( xrm_string, xrm_value.addr, xrm_value.size );
	
			XmTextSetString( wtextFINITT[i], xrm_string );
			}
		else
			XmTextSetString( wtextFINITT[i], "" );
		}

	for (i = 0; i < 8; i++)
		{
		sprintf( xrm_resource, "xtc.wtext_SNP_%d.value\0", i );
		if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
					xrm_str_type, &xrm_value ) )
			{
			strncpy( xrm_string, xrm_value.addr, xrm_value.size );
	
			XmTextSetString( wtextSNP[i], xrm_string );
			}
		else
			XmTextSetString( wtextSNP[i], "" );
		}

	strcpy( xrm_resource, "xtc.wtext_GIN_Bytes.value" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		XmTextSetString( wtextGINBytes, xrm_string );
		}

	strcpy( xrm_resource, "xtc.wtog_Startup_Icon.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') 
			tf_flag = 1;

		XmToggleButtonSetState( wtogStartupIcon, 
						tf_flag, TRUE );
		}

	strcpy( xrm_resource, "xtc.wtog_Startup_Window.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') 
			tf_flag = 1;

		XmToggleButtonSetState( wtogStartupWindow, 
						tf_flag, TRUE );
		}

	strcpy( xrm_resource, "xtc.wtog_Display_MBX_Data.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') 
			tf_flag = 1;

		XmToggleButtonSetState( wtogDisplayMBXData, 
						tf_flag, FALSE );
		}

	strcpy( xrm_resource, "xtc.wtog_Display_Plotfile_Data.set" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		tf_flag = 0;
		if (xrm_string[0] == 't' || xrm_string[0] == 'T') 
			tf_flag = 1;

		XmToggleButtonSetState( wtogDisplayPlotfileData, 
					tf_flag, FALSE );
		}

	for (i = 0; i <= 8; i++)
		{
		if (i < 8)
			sprintf( xrm_resource, 
				"xtc.wscale_Foreground%d_Red_V4.value\0", i );
		else
			sprintf( xrm_resource, 
				"xtc.wscale_Background_Red_V4.value\0" );

		if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
					xrm_str_type, &xrm_value ) )
			{
			strncpy( xrm_string, xrm_value.addr, xrm_value.size );
			sscanf( xrm_string, "%d", &j );
			XmScaleSetValue( wscaleRed[i], j );
			}

		if (i < 8)
			sprintf( xrm_resource, 
				"xtc.wscale_Foreground%d_Green_V4.value\0", i);
		else
			sprintf( xrm_resource, 
				"xtc.wscale_Background_Green_V4.value\0" );

		if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
					xrm_str_type, &xrm_value ) )
			{
			strncpy( xrm_string, xrm_value.addr, xrm_value.size );
			sscanf( xrm_string, "%d", &j );
			XmScaleSetValue( wscaleGreen[i], j );
			}

		if (i < 8)
			sprintf( xrm_resource, 
				"xtc.wscale_Foreground%d_Blue_V4.value\0", i );
		else
			sprintf( xrm_resource, 
				"xtc.wscale_Background_Blue_V4.value\0" );

		if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
					xrm_str_type, &xrm_value ) )
			{
			strncpy( xrm_string, xrm_value.addr, xrm_value.size );
			sscanf( xrm_string, "%d", &j );
			XmScaleSetValue( wscaleBlue[i], j );
			}

		}

	strcpy( xrm_resource, "xtc.wfiled_Read_Plot_File.dirMask" );
	if (XrmGetResource( xrm_database, xrm_resource, xrm_resource,
				xrm_str_type, &xrm_value ) )
		{
		strncpy( xrm_string, xrm_value.addr, xrm_value.size );

		XtSetArg( arglist[0], XmNdirMask, 
				XmStringCreateLtoR(xrm_string,"") );
		XtSetValues( wfiledReadPlotFile, arglist, 1 );
		}

	} /* End */

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

static void fill_widgets()

	{

/*
**  "About XTC" arm label widget.
*/

	pixmap_arm1 = XCreatePixmapFromBitmapData(
		XtDisplay(wlabAboutXTCArm),
		RootWindowOfScreen(XtScreen(wlabAboutXTCArm)),
		ARM1_bits, ARM1_width, ARM1_height, 0, 1,
		DefaultDepthOfScreen(XtScreen(wlabAboutXTCArm)));

	pixmap_arm2 = XCreatePixmapFromBitmapData(
		XtDisplay(wlabAboutXTCArm),
		RootWindowOfScreen(XtScreen(wlabAboutXTCArm)),
		ARM2_bits, ARM2_width, ARM2_height, 0, 1,
		DefaultDepthOfScreen(XtScreen(wlabAboutXTCArm)));

	pixmap_arm3 = XCreatePixmapFromBitmapData(
		XtDisplay(wlabAboutXTCArm),
		RootWindowOfScreen(XtScreen(wlabAboutXTCArm)),
		ARM3_bits, ARM3_width, ARM3_height, 0, 1,
		DefaultDepthOfScreen(XtScreen(wlabAboutXTCArm)));

	XtSetArg( arglist[0], XmNlabelPixmap, pixmap_arm1 );
	XtSetValues( wlabAboutXTCArm, arglist, 1 );

	flex_position = 1;
	flex_direction = 1;

/*
**  "About XTC" body label widget.
*/

	pixmap_body = XCreatePixmapFromBitmapData(
		XtDisplay(wlabAboutXTCBody),
		RootWindowOfScreen(XtScreen(wlabAboutXTCBody)),
		BODY_bits, BODY_width, BODY_height, 0, 1,
		DefaultDepthOfScreen(XtScreen(wlabAboutXTCBody)));

	XtSetArg( arglist[0], XmNlabelPixmap, pixmap_body );
	XtSetValues( wlabAboutXTCBody, arglist, 1 );

	} /* End */

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

static void set_defaults()

	{

	int i;
	char *s;
	int sscanf_temp;

	XmScaleGetValue( wscaleBufferDepth, &save_depth );

	multi_order = XmToggleButtonGetState( wtogBottomUp );

	s = XmTextGetString( wtextFrameFilename );
	strcpy( raw_filename, s );


	auto_file = XmToggleButtonGetState( wtogAutoFile );

	if (auto_file)
		{
		strcpy( message_string, "Warning: Auto File toggle is on");
		display_message();
		}

	ps_file = XmToggleButtonGetState( wtogPsFile );

	if (ps_file)
		{
		strcpy( message_string, "Warning: PostScript File toggle is on");
		display_message();
		}


	append_frames = XmToggleButtonGetState( wtogAppendFrames );


#ifdef VMS
	s = XmTextGetString( wtextQueue );
	strcpy( print_queue, s );

#else
	s = XmTextGetString( wtextPrintCommand );
	strcpy( print_command, s );
#endif

	s = XmTextGetString( wtextCommandFile );
	strcpy( print_procedure, s );

	auto_print = XmToggleButtonGetState( wtogAutoPrint );

	if (auto_print)
		{
		strcpy( message_string, "Warning: Auto Print toggle is on");
		display_message();
		}


	s = XmTextGetString( wtextScratchArea );
	strcpy( scratch_area, s );


	nbytes_INITT_byte_stream = 0;
	
	for (i = 0; i < 8; i++)
		{
		s = XmTextGetString( wtextINITT[i] );
		if (strlen(s) == 0 || 
			strcmp( s, " ") == 0 ||
			strcmp( s, "  ") == 0)
			INITT_byte_stream[i] = 0;
		else
			{
			sscanf( s, "%x", &sscanf_temp );
			INITT_byte_stream[i] = sscanf_temp;
			nbytes_INITT_byte_stream = i + 1;
			}
		}

	for (i = 0; i <= 1; i++) INITT_idx[i] = 0;


	nbytes_FINITT_byte_stream = 0;
	
	for (i = 0; i < 8; i++)
		{
		s = XmTextGetString( wtextFINITT[i] );
		if (strlen(s) == 0 || 
			strcmp( s, " ") == 0 ||
			strcmp( s, "  ") == 0)
			FINITT_byte_stream[i] = 0;
		else
			{
			sscanf( s, "%x", &sscanf_temp );
			FINITT_byte_stream[i] = sscanf_temp;
			nbytes_FINITT_byte_stream = i + 1;
			}
		}

	for (i = 0; i <= 1; i++) FINITT_idx[i] = 0;


	nbytes_SNP_byte_stream = 0;
	
	for (i = 0; i < 8; i++)
		{
		s = XmTextGetString( wtextSNP[i] );
		if (strlen(s) == 0 || 
			strcmp( s, " ") == 0 ||
			strcmp( s, "  ") == 0)
			SNP_byte_stream[i] = 0;
		else
			{
			sscanf( s, "%x", &sscanf_temp );
			SNP_byte_stream[i] = sscanf_temp;
			nbytes_SNP_byte_stream = i + 1;
			}
		}

	for (i = 0; i <= 1; i++) SNP_idx[i] = 0;


	s = XmTextGetString( wtextGINBytes );
	sscanf( s, "%d", &GIN_Bytes );


	startup_state = XmToggleButtonGetState( wtogStartupIcon );

	list_box_policy = XmToggleButtonGetState(wtogListBoxVariable);

	display_MBX_data = XmToggleButtonGetState( 
					wtogDisplayMBXData );

	display_plotfile_data = XmToggleButtonGetState( 
					wtogDisplayPlotfileData );


	for (i = 0; i <= 8; i++)
		{
		XmScaleGetValue( wscaleRed[i],   &red_value[i]);
		XmScaleGetValue( wscaleGreen[i], &green_value[i]);
		XmScaleGetValue( wscaleBlue[i],  &blue_value[i]);
		}

	} /* End */

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

static void implement_save_depth()

	{

	keep = save_depth;
	clear_buffer();

	} /* End */

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

static void do_flex( w, t )

	Widget w;
	XtIntervalId *t;

	{

	if (flex_position == 1)
		{
		XtSetArg( arglist[0], XmNlabelPixmap, pixmap_arm2 );
		XtSetValues( wlabAboutXTCArm, arglist, 1 );

		flex_position = 2;
		flex_direction = 1;
		}

	else if (flex_position == 2)
		{
		if (flex_direction == 0)
			{
			XtSetArg( arglist[0], XmNlabelPixmap, pixmap_arm1 );
			XtSetValues( wlabAboutXTCArm, arglist, 1 );

			flex_position = 1;
			}
		else
			{
			XtSetArg( arglist[0], XmNlabelPixmap, pixmap_arm3 );
			XtSetValues( wlabAboutXTCArm, arglist, 1 );

			flex_position = 3;
			}
		}

	else
		{
		XtSetArg( arglist[0], XmNlabelPixmap, pixmap_arm2 );
		XtSetValues( wlabAboutXTCArm, arglist, 1 );

		flex_position = 2;
		flex_direction = 0;
		}

	if (XtIsManaged(wformdAboutXTC))
		XtAppAddTimeOut( 
		XtWidgetToApplicationContext(wformdAboutXTC),
		flex_timeout, do_flex, wformdAboutXTC );

	} /* End */

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

#ifdef VMS

static void read_plotfile()		/* VMS version */

	{

	struct FAB fab_plotfile;
	struct RAB rab_plotfile;
	struct NAM nam_plotfile;
	int contin;
	char resultant_filename[255];
	unsigned long ss_status;

/*
**  Initialize RMS structures.
*/

	fab_plotfile           = cc$rms_fab;
	fab_plotfile.fab$b_fac = FAB$M_GET;
	fab_plotfile.fab$l_fna = plot_filename;
	fab_plotfile.fab$b_fns = strlen(plot_filename);
	fab_plotfile.fab$l_nam = &nam_plotfile;
	fab_plotfile.fab$b_shr = FAB$M_SHRGET | FAB$M_SHRPUT;

	rab_plotfile           = cc$rms_rab;
	rab_plotfile.rab$l_fab = &fab_plotfile;
	rab_plotfile.rab$l_ubf = plotfile_buffer;
	rab_plotfile.rab$w_usz = 512;

	nam_plotfile           = cc$rms_nam;
	nam_plotfile.nam$l_rsa = resultant_filename;
	nam_plotfile.nam$b_rss = 255;

/*
**  Open plot file.
*/

	contin = 1;

	ss_status = sys$open(&fab_plotfile);

	if (ss_status != RMS$_NORMAL)
		{
		ss_message("Error opening plot file:", ss_status);
		contin = 0;
		}

/*
**  Extract the name part of the filename.
*/

	if (contin)
		{
		strncpy( plotfile_namepart, nam_plotfile.nam$l_name,
				nam_plotfile.nam$b_name );
		plotfile_namepart[nam_plotfile.nam$b_name] = '\0';
		}

/*
**  Connect the record stream.
*/

	if (contin)
		{
		ss_status = sys$connect(&rab_plotfile);
	
		if (ss_status != RMS$_NORMAL)
			{
			ss_message("Error connecting to plot file:",
					ss_status);
			contin = 0;
			}
		}

/*
**  Read records.
*/

	while (contin)
		{
		ss_status = sys$get(&rab_plotfile);

		if (ss_status == RMS$_EOF)
			{
			contin = 0;
			}

		else if (ss_status != RMS$_NORMAL)
			{
			ss_message("Error reading plot file:", ss_status);
			contin = 0;
			}

		else if (rab_plotfile.rab$w_rsz > 0)
			{
			nbytes_buffer = rab_plotfile.rab$w_rsz;
			addr_buffer = plotfile_buffer;
			mbxno = 1;
			process_buffer();
			}
		}

/*
**  Close file.
*/

	ss_status = sys$close(&fab_plotfile);

/*
	if (ss_status != RMS$_NORMAL) 
		ss_message("Error closing plot file:", ss_status);
*/

	} /* End */

#else

static void read_plotfile()		/* UNIX version */

	{

	FILE *f;
	int c;
	int i, m;
	int contin;

	i = strlen( plot_filename ) - 1;
	m = 0;
	contin = 1;

	while (contin)
		{
		if (plot_filename[i] == '/')
			{
			m = i+1;
			contin = 0;
			}
		else
			{		
			i--;
			if (i < 0) contin = 0;
			}
		}

	strcpy( plotfile_namepart, &plot_filename[m] );

	if (!(f=fopen(plot_filename,"rb")))
		{
		printf ("open error\n");
		}
	else
		{
		while ((c = getc(f)) != EOF)
			{
			plotfile_buffer[0] = (char) c;
			nbytes_buffer = 1;
			addr_buffer = plotfile_buffer;
			mbxno = 1;
			process_buffer();
			}
		fclose(f);
		}

	} /* End */

#endif

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

static void get_file_filter()

	{

	XmString file_filter_cs;
	char *d;

	XtSetArg( arglist[0], XmNdirMask, &file_filter_cs );
	XtGetValues( wfiledReadPlotFile, arglist, 1 );

	XmStringGetLtoR( file_filter_cs, "", &d );
	strcpy( file_filter, d );

	} /* End */

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

static void get_xy()

	{

	Window child_return;

	XTranslateCoordinates( XtDisplay(wshell),
				XtWindow(wshell),
				RootWindowOfScreen(XtScreen(wshell)),
				0, 0, &startup_x, &startup_y, &child_return );

	} /* End */

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

#ifdef VMS

static void create_mailboxes()		/* VMS version */

	{

	int i;
	int idx;
	int logname_flag;
	unsigned long ss_status;
	unsigned long mbx_ss_status, gin_ss_status;
	short return_length;
 	struct item_list_3 itmlst[2];
	char lognam_xtc_mbx[31];
	struct dsc$descriptor lognam_xtc_mbx_desc;
	char lognam_xtc_gin[21];
	struct dsc$descriptor lognam_xtc_gin_desc;
	char xtc_mbx_tran[16];
	char xtc_gin_tran[16];
	int bufquo_mbx;
	int promsk_mbx;
	int maxmsg_gin;
	int bufquo_gin;
	int promsk_gin;

	logname_flag = 0;
	idx = 0;
	while (logname_flag == 0)
		{

/*
**  First, find unused logical names for the mailboxes.  Set the test string 
**  for the new mailbox logical name to be XTC_***_idx_username, where idx is 
**  the next integer to test.
*/

		sprintf( lognam_xtc_mbx, "XTC_MBX_%d_%s\0", idx, username );
		lognam_xtc_mbx_desc.dsc$w_length  = strlen(lognam_xtc_mbx);
	        lognam_xtc_mbx_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
	        lognam_xtc_mbx_desc.dsc$b_class   = DSC$K_CLASS_S;
	        lognam_xtc_mbx_desc.dsc$a_pointer = lognam_xtc_mbx;

		sprintf( lognam_xtc_gin, "XTC_GIN_%d_%s\0", idx, username );
		lognam_xtc_gin_desc.dsc$w_length  = strlen(lognam_xtc_gin);
	        lognam_xtc_gin_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
	        lognam_xtc_gin_desc.dsc$b_class   = DSC$K_CLASS_S;
	        lognam_xtc_gin_desc.dsc$a_pointer = lognam_xtc_gin;

/*
**  Check for this logical name currently in use.
*/

		itmlst[0].buffer_length = 15;
		itmlst[0].item_code = LNM$_STRING;
		itmlst[0].buffer_address = xtc_mbx_tran;
		itmlst[0].return_length_address = &return_length;
		itmlst[1].buffer_length = 0;
		itmlst[1].item_code = 0;

		mbx_ss_status = sys$trnlnm( 0, &lnm_group_desc, 
					&lognam_xtc_mbx_desc, 0, itmlst );

		itmlst[0].buffer_length = 15;
		itmlst[0].item_code = LNM$_STRING;
		itmlst[0].buffer_address = xtc_gin_tran;
		itmlst[0].return_length_address = &return_length;
		itmlst[1].buffer_length = 0;
		itmlst[1].item_code = 0;

		gin_ss_status = sys$trnlnm( 0, &lnm_group_desc, 
					&lognam_xtc_gin_desc, 0, itmlst );

/*
**  If this logical name is not in use, then grab it.
*/

		if (mbx_ss_status == SS$_NOLOGNAM &&
		    gin_ss_status == SS$_NOLOGNAM) logname_flag = 1;

/*
**  Create mailboxes.
*/

		if (logname_flag == 1)
			{
			bufquo_mbx = 10 * maxmsg_mbx;
			promsk_mbx = 0x00001F0F;

			mbx_ss_status = sys$crembx( 0, &chan_mbx, 
				maxmsg_mbx, bufquo_mbx, 
				promsk_mbx, 0, &lognam_xtc_mbx_desc ); 

			maxmsg_gin = 80;
			bufquo_gin = 10 * maxmsg_gin;
			promsk_gin = 0x0000FF0F;

			gin_ss_status = sys$crembx( 0, &chan_gin, 
				maxmsg_gin, bufquo_gin, 
				promsk_gin, 0, &lognam_xtc_gin_desc ); 

			if (mbx_ss_status != SS$_NORMAL ||
			    gin_ss_status != SS$_NORMAL)
				{
				ss_message("XTC_MBX mailbox creation status:", 
						mbx_ss_status);
				ss_message("XTC_GIN mailbox creation status:", 
						gin_ss_status);
				ss_status = sys$dassgn( chan_mbx ); 
				ss_status = sys$dassgn( chan_gin ); 
				logname_flag = 2;
				}
			}


/*
**  If applicable, increment idx to try another mailbox logical name.
*/

		if (logname_flag == 0)
			{
			idx++;
			if (idx > 99)
				{
				strcpy( message_string, 
					"Error: Maximum mailbox idx reached");
				display_message();
				logname_flag = 2;
				}
			}

		}

/*
**  If the mailboxes were successfully created, then set parameters.
*/

	if (logname_flag == 1)
		{
		idx_number = idx;

/*
**  Reserve event flag for mailbox read completion, and add that event
**  flag to the list of X events.  This is done because the toolkit calls
**  needed in the mailbox read processing cannot be done at AST level.  
**  When the mailbox read completes (and the event flag is set), an X event 
**  is generated for the mbx_read_event routine.
*/

		ss_status = lib$free_ef(&event_flag_mbx);
		if (ss_status != SS$_NORMAL) 
			ss_message("Error freeing mailbox event flag:",
					ss_status);

		ss_status = lib$reserve_ef(&event_flag_mbx);
		if (ss_status != SS$_NORMAL) 
			ss_message("Error reserving mailbox event flag:",
					ss_status);

		ss_status = sys$clref(event_flag_mbx);
		if (ss_status != SS$_WASSET && ss_status != SS$_WASCLR) 
			ss_message("Error clearing mailbox event flag:",
					ss_status);

		xtinputid = XtAppAddInput( ctx, event_flag_mbx, 0, 
						mbx_read_event, 0);
		queue_mbx_read();

/*
**  Display mailbox names on XTC main window.
*/

		XtSetArg( arglist[0], XmNlabelString, 
				XmStringCreateLtoR(lognam_xtc_mbx,"") );
		XtSetValues( wlabGraphicsOut, arglist, 1 );

		XtSetArg( arglist[0], XmNlabelString, 
				XmStringCreateLtoR(lognam_xtc_gin,"") );
		XtSetValues( wlabGraphicsIn, arglist, 1 );

		size_lbox();
		}

	} /* End */

#else

static void create_sockets()

	{

	int i, idx;
	int sockflag;
	int mbx_estat, gin_estat;
	int mbx_errno, gin_errno;
	char sname_mbx[31];
	char sname_gin[31];

	sockflag = 0;
	idx = 0;
	while (sockflag == 0)
		{

/*
**  First, find unused names for the sockets.  
*/

		sprintf( sname_mbx, "/tmp/xtc_mbx_%d_%s\0", idx, username );
		sprintf( sname_gin, "/tmp/xtc_gin_%d_%s\0", idx, username );

/*
**  Check for these socket names currently in use.
*/

		mbx_estat = access( sname_mbx, F_OK );
		gin_estat = access( sname_gin, F_OK );

		if (mbx_estat != 0 && gin_estat != 0) sockflag = 1;

/*
**  Create sockets.
*/

		if (sockflag == 1)
			{
        	        socket_mbx_name.sun_family = AF_UNIX; /* TGC 14-Mar-94 */
        	        socket_gin_name.sun_family = AF_UNIX; /* TGC 14-Mar-94 */
			socket_mbx_desc = socket(AF_UNIX, SOCK_STREAM, 0);
			mbx_errno = errno;
			socket_gin_desc = socket(AF_UNIX, SOCK_STREAM, 0);
			gin_errno = errno;

			if (socket_mbx_desc == -1 || socket_gin_desc == -1)
				{
				ss_message("socket() socket_mbx error:", 
						mbx_errno);
				ss_message("socket() socket_gin error:",
						gin_errno);
				close(socket_mbx_desc);
				close(socket_gin_desc);
				sockflag = 2;
				}
			}

/*
**  Bind sockets.
*/

		if (sockflag == 1)
			{
			strcpy( socket_mbx_name.sun_path, sname_mbx );
			strcpy( socket_gin_name.sun_path, sname_gin );

			mbx_estat = bind( socket_mbx_desc, 
						&socket_mbx_name,
						sizeof(socket_mbx_name) );
			mbx_errno = errno;

			gin_estat = bind( socket_gin_desc, 
						&socket_gin_name,
						sizeof(socket_gin_name) );
			gin_errno = errno;
						
			if (mbx_estat == -1 || gin_estat == -1)
				{
				ss_message("bind() socket_mbx error:", 
						mbx_errno);
				ss_message("bind() socket_gin error:", 
						gin_errno);
				close(socket_mbx_desc);
				unlink(socket_mbx_name.sun_path);
				close(socket_gin_desc);
				unlink(socket_gin_name.sun_path);
				sockflag = 2;
				}
			}

/*
**  Listen for connections.
*/

		if (sockflag == 1)
			{
			mbx_estat = listen( socket_mbx_desc, 1 );
			mbx_errno = errno;

			gin_estat = listen( socket_gin_desc, 1 );
			gin_errno = errno;
						
			if (mbx_estat == -1 || gin_estat == -1)
				{
				ss_message("listen() socket_mbx error:", 
						mbx_errno);
				ss_message("listen() socket_gin error:", 
						gin_errno);
				close(socket_mbx_desc);
				unlink(socket_mbx_name.sun_path);
				close(socket_gin_desc);
				unlink(socket_gin_name.sun_path);
				sockflag = 2;
				}
			}

/*
**  If applicable, increment idx to try another socket name.
*/

		if (sockflag == 0)
			{
			idx++;
			if (idx > 99)
				{
				strcpy( message_string, 
					"Error: Maximum socket index reached");
				display_message();
				sockflag = 2;
				}
			}

		}

/*
**  If a socket was successfully created, then set parameters.
*/

	if (sockflag == 1)
		{
		idx_number = idx;
			
/*
**  Add input events for socket accept.
*/

		xtinputid_mbx_accept = XtAppAddInput( ctx, socket_mbx_desc, 
					XtInputReadMask, socket_mbx_accept, 0);
		socket_mbx_flag = 0;

		xtinputid_gin_accept = XtAppAddInput( ctx, socket_gin_desc, 
					XtInputReadMask, socket_gin_accept, 0);
		socket_gin_flag = 0;


/*
**  Display mailbox names on XTC main window.
*/

		XtSetArg( arglist[0], XmNlabelString,
				XmStringCreateLtoR(&sname_mbx[5],"") );
		XtSetValues( wlabGraphicsOut, arglist, 1 );

		XtSetArg( arglist[0], XmNlabelString,
				XmStringCreateLtoR(&sname_gin[5],"") );
		XtSetValues( wlabGraphicsIn, arglist, 1 );

		size_lbox();
		}

	} /* End */

#endif

#ifdef VMS

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

static void printer_comp_event()

	{

	unsigned long ss_status;

	if (printer_comp_status == SS$_NORMAL ||
	    printer_comp_status == 0x10000001) 
		{
		XBell(XtDisplay(wmain), 20 );
		XBell(XtDisplay(wmain), 100 );
		}

	else
		{
		ss_message("Printer subprocess completion status:", 
				printer_comp_status);
		}

	ss_status = sys$clref(event_flag_printer);
	if (ss_status != SS$_WASSET && ss_status != SS$_WASCLR) 
		ss_message("Error clearing printer subprocess event flag:",
				ss_status);

	} /* End */

#endif

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

#ifdef VMS

void return_gin_bytes( bytes, nbytes )

        char bytes[];
        int nbytes;

        {

	int i;
	unsigned long ss_status;
	unsigned long func;
	struct io_status_block iosb;

	for (i = 0; i < nbytes; i++)
		{
		func = IO$_WRITEVBLK | IO$M_NOW | IO$M_NORSWAIT;

		ss_status = sys$qiow( 0, chan_gin, func, &iosb, 
					0, 0, &bytes[i], 1, 
					0, 0, 0, 0 );

		if (ss_status != SS$_NORMAL) 
			ss_message("Error on $QIOW write to XTC_GIN:", 
					ss_status);
		if (iosb.status != SS$_NORMAL) 
			{
			ss_status = iosb.status;
			ss_message("IOSB error on $QIOW write to XTC_GIN:", 
					ss_status);
			}
		}

	} /* End */

#else

void return_gin_bytes( bytes, nbytes )

	char bytes[];
	int nbytes;

	{

	int i;
	int send_status;

	if (socket_gin_flag == 1)
		{
		for (i = 0; i < nbytes; i++)
			{
			send_status = send( sd0_gin, &bytes[i], 1, 0 );

			if (send_status == -1)
				ss_message("socket_gin send() error:", errno);
			}
		}

	} /* End */

#endif

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

void draw_adj_frame( adj )

        int adj;

        {

	int d, pos;

	if (dpn_num > 0)
		{

		if (adj == 0)
			{
			d = dpn_list[0] - 1;
			if (d >= 0)
				{
				pos = lbox_top - d + 1;
				XmListSelectPos( wslBufferedFrames, 
							pos, TRUE );
				draw_frames();
				}
			}

		else if (adj == 1)
			{
			d = dpn_list[dpn_num-1] + 1;
			if (d <= lbox_top)
				{
				pos = lbox_top - d + 1;
				XmListSelectPos( wslBufferedFrames, 
							pos, TRUE );
				draw_frames();
				}
			}

		}

	} /* End */

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

void callbackColorFB( widget, tag, callback_data )

        Widget widget;
        int tag;
        XmToggleButtonCallbackStruct *callback_data;

        {
	int i;

	if (callback_data->set)
		{
		ctog = tag;

		for (i = 0; i <= 8; i++)
			{
			if (i == ctog)
				{
	                        XtManageChild(wscaleRed[i]);
	                        XtManageChild(wscaleGreen[i]);
	                        XtManageChild(wscaleBlue[i]);
				}
			else
				{
	                        XtUnmanageChild(wscaleRed[i]);
	                        XtUnmanageChild(wscaleGreen[i]);
	                        XtUnmanageChild(wscaleBlue[i]);
				}
			}

		set_mixer();
		}
        }

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

void callbackColorMix( widget, tag, callback_data )

	Widget widget;
	int tag;
	XmScaleCallbackStruct *callback_data;

	{

	if (tag == 10)      red_value[ctog]   = callback_data->value;
	else if (tag == 20) green_value[ctog] = callback_data->value;
	else if (tag == 30) blue_value[ctog]  = callback_data->value;

	set_color(ctog);
	set_mixer();

	}

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

static void set_color(fb)
	int fb;
	{

	color_tek_window( fb, red_value[fb], green_value[fb], blue_value[fb] );

	}

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

static void set_mixer()
	{
	unsigned long pixel;

	get_tek_pixel( ctog, &pixel );

	XtSetArg( arglist[0], XmNbackground, pixel);
        XtSetValues( wlabMixer, arglist, 1 );
	}

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

static void size_lbox()
	{
	Widget vsb;
	short width_vsb, width_GO, width_Graphics_Out, height_current;
	float fheight_current, fheight_desired;
	int lbox_width, lbox_vic;

	XtSetArg( arglist[0], XmNverticalScrollBar, &vsb );
	XtGetValues( wslBufferedFrames, arglist, 1 );

	XtSetArg( arglist[0], XmNwidth, &width_vsb );
	XtGetValues( vsb, arglist, 1 );

	XtSetArg( arglist[0], XmNwidth, &width_GO );
	XtGetValues( wlabGO, arglist, 1 );

	XtSetArg( arglist[0], XmNwidth, &width_Graphics_Out );
	XtGetValues( wlabGraphicsOut, arglist, 1 );

	XtSetArg( arglist[0], XmNheight, &height_current );
	XtGetValues( wslBufferedFrames, arglist, 1 );
	
	lbox_width = width_GO + 5 + width_Graphics_Out 
	             - 4 - width_vsb - 7 - 100;
	if (lbox_width < 180) lbox_width = 180;

	fheight_current = height_current;
	fheight_desired = (4 * 55) + (3 * 8);
	lbox_vic = ((12.0 * fheight_desired) / fheight_current) + 0.99;

	XtSetArg( arglist[0], XmNwidth, lbox_width);
	XtSetArg( arglist[1], XmNvisibleItemCount, lbox_vic);
        XtSetValues( wslBufferedFrames, arglist, 2 );
	}

static void handlerStructureNotify_shell( widget, client_data, 
					xevent, condispatch )
	Widget widget;
	XtPointer client_data;
	XEvent *xevent;
	Boolean *condispatch;
	{
	if (xevent->type == MapNotify)
		{
		if (lb_state == 1) XtRealizeWidget( wshellLB );
		}

	else if (xevent->type == UnmapNotify)
		{
		if (lb_state == 1) XtUnrealizeWidget( wshellLB );
		}
	}

static void handlerStructureNotify_shellLB( widget, client_data, 
					xevent, condispatch )
	Widget widget;
	XtPointer client_data;
	XEvent *xevent;
	Boolean *condispatch;
	{
	if (xevent->type == UnmapNotify)
		{
		XtUnrealizeWidget( wshellLB );
		XtRealizeWidget( wshellLB );
		}
	}
