DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T d

⟦e68385a3b⟧ TextFile

    Length: 46027 (0xb3cb)
    Types: TextFile
    Names: »display.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« 
        └─⟦e5a54fb17⟧ 
            └─⟦this⟧ »pp-5.0/Src/MTAconsole/display.c« 

TextFile

/* display.c : display routines */

# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Src/MTAconsole/RCS/display.c,v 5.0 90/09/20 16:19:47 pp Exp Locker: pp $";
# endif

/*
 * $Header: /cs/research/pp/hubris/pp-beta/Src/MTAconsole/RCS/display.c,v 5.0 90/09/20 16:19:47 pp Exp Locker: pp $
 *
 * $Log:	display.c,v $
 * Revision 5.0  90/09/20  16:19:47  pp
 * rcsforce : 5.0 public release
 * 
 */



#include	"console.h"
extern Pixmap			backpixmap;
extern Mode			mode;
extern int			max_horiz_mtas;
extern State			connectState;
extern char			*time_t2RFC(),
				*vol2str(),
				*itoa(),
				*msginfo_args[3],
				*Qinformation,
				*Qversion;
extern time_t			time();
void				ChanToggle(),
				MtaToggle(),
				MsgToggle();
extern unsigned long		chancolourOf(),
				mtacolourOf(),
				msgcolourOf();
extern XFontStruct		*chanFont(),
				*mtaFont(),
				*msgFont(),
				*normalFont,
				*disabledFont;
/* \f

 */
/* channels */
extern void			Channel();
extern struct chan_struct	*currentchan,
				**globallist;
extern Widget			channel_all,
				channels,
				channel_info,
				channel_viewport,
				channel_label,
				monitor_form,
				monitor_viewport,
				switchform,
				qversion;
extern int 			max_vert_lines,
				read_currentchan,
				monitor_form_managed;
Widget				*channel_array = NULL;
int				actual_nchans_present = 0,
				num_channels,
				chan_info_shown = FALSE;
extern struct monitor_item	**display_list;

static void redisplay_channel();
static void monitor_display_channels();
static void undisplay_monitor();
static char *create_channel_display_string();
static char *create_channel_monitor_string();
static char *time_t2str();
static void resize_info_str();

extern int	total_volume, total_number_messages, total_number_reports;
extern Widget	total_number_label, total_volume_label;
extern unsigned long	volcolourOf(), numcolourOf();
static void	display_totals()
{
	char	buf[BUFSIZ];
	if (total_volume == 0
	    || (total_number_messages == 0
	    && total_number_reports == 0)) {
		MapVolume(False);
		return;
	}
	
	if (total_volume > 1000000)
		(void) sprintf(buf, "Volume = %d M", total_volume/1000000);
	else if (total_volume > 1000)
		(void) sprintf(buf, "Volume = %d k", total_volume / 1000);
	else
		(void) sprintf(buf, "Volume = %d", total_volume);
	WidgetSet(total_volume_label,
		  XtNlabel,	buf,
		  XtNborderColor,	volcolourOf(total_volume),
		  NULL);

	(void) sprintf(buf, "%d msg%s + %d report%s", 
		       total_number_messages,
		       (total_number_messages == 1) ? "" : "s",
		       total_number_reports,
		       (total_number_reports == 1) ? "" : "s");
	WidgetSet(total_number_label,	
		  XtNlabel,	buf,
		  XtNborderColor,	numcolourOf(total_number_messages+total_number_reports),
		  NULL);
	MapVolume(True);
}
	
char *create_channel_header()
{
	char	*str;

	if (currentchan == NULL)
		str = strdup("No current channel");
	else {
		str = (char *) malloc((unsigned) (strlen("Current channel : ") + 
				      strlen(currentchan->channelname) + 3 +
				      strlen(currentchan->channeldescrip)+1));

		sprintf(str, "Current channel : %s : %s", 
			currentchan->channelname, currentchan->channeldescrip);
	}
	return str;
}

#define ssformat	"%-*s %s"
#define sdformat	"%-*s %s"
#define	plus_ssformat	"%s\n%-*s %s"
#define plus_sdformat	"%s\n%-*s %d"

#define	tab		30
extern int	channel_info_strlen;

chan_display_info(chan)
struct chan_struct	*chan;
{
	XFontStruct	*font;
	char		*str,
			*info_str;
	int		info_strlen = BUFSIZ;
	info_str = calloc(1, (unsigned) info_strlen);

	sprintf(info_str, ssformat, tab, 
		chan->channelname, 
		chan->channeldescrip);
	if (chan->status->cachedUntil != 0)  {
		str = time_t2RFC(chan->status->cachedUntil);
		sprintf(info_str, plus_ssformat, info_str, tab,
			"delayed until",
			str);
		free(str);
	}
	if (chan->oldestMessage != 0 && 
	    (chan->numberMessages != 0 || chan->numberReports != 0)) {
		str = time_t2str(time((time_t *)0) - chan->oldestMessage);
		sprintf(info_str, plus_ssformat, info_str, tab,
			"oldest message",
			str);
		free(str);
	}
	if (chan->numberMessages != 0)
		sprintf(info_str, plus_sdformat, info_str, tab,
			"number of messages",
			chan->numberMessages);
	if (chan->numberReports != 0)
		sprintf(info_str, plus_sdformat, info_str, tab,
			"number of DRs",
			chan->numberReports);

	if (chan->volumeMessages != 0) {
		str = vol2str(chan->volumeMessages);
		sprintf(info_str, plus_ssformat, info_str, tab,
			"volume of messages",
			str);
		free(str);
	}
	if (chan->numberActiveProcesses != 0)
		sprintf(info_str, plus_sdformat, info_str, tab,
			"number of active processes",
			chan->numberActiveProcesses);
	sprintf(info_str, plus_ssformat, info_str, tab,
		"status",
		(chan->status->enabled == TRUE) ? "enabled" : "disabled");
	if (chan->status->lastAttempt != 0) {
		str = time_t2RFC(chan->status->lastAttempt);
		sprintf(info_str, plus_ssformat, info_str, tab,
			"last attempt",
			str);
		free(str);
	}
	if (chan->status->lastSuccess != 0) {
		str = time_t2RFC(chan->status->lastSuccess);
		sprintf(info_str, plus_ssformat, info_str, tab,
			"last success",
			str);
		free(str);
	}

	switch (chan->priority) {
	    case int_Qmgr_Priority_low:
		sprintf(info_str, plus_ssformat, info_str, tab,
			"priority",
			"low");
		break;
	    case int_Qmgr_Priority_normal:
		sprintf(info_str, plus_ssformat, info_str, tab,
			"priority",
			"normal");
		break;
	    case int_Qmgr_Priority_high:
		sprintf(info_str, plus_ssformat, info_str, tab,
			"priority",
			"high");
		break;
	    default:
		break;
	}
	if (chan->maxprocs == 0)
		sprintf(info_str, plus_ssformat, info_str, tab,
			"maximum processes",
			"unlimited");
	else
		sprintf(info_str, plus_sdformat, info_str, tab,
			"maximum processes",
			chan->maxprocs);

	display_channelinfo_string(info_str);
	WidgetSet(channel_info,
		  XtNlabel, "all",
		  NULL);
	XtSetMappedWhenManaged(channel_all, True);
	XtSetMappedWhenManaged(channel_viewport, False);
	if ((font = chanFont(chan)) != NULL)
		WidgetSet(channel_all,
			  XtNfont, font,
			  NULL);
	chan_info_shown = TRUE;
	free(info_str);
}


chan_display_all()
{
	WidgetSet(channel_info,
		  XtNlabel, "info",
		  NULL);
	XtSetMappedWhenManaged(channel_viewport, True);
	XtSetMappedWhenManaged(channel_all, False);
	chan_info_shown = FALSE;
}


display_channels()
{
	clear_mta_refresh_list();
	control_display_channels();
	if (mode == monitor)
		monitor_display_channels();
	display_totals();
}

control_display_channels()
{
	int			i = 0;
	char			*str = NULL;
	XFontStruct		*font;
	for (i = 0; i < num_channels; i++)
		XtSetMappedWhenManaged(channel_array[i], False);
	i = 0;
	while (i < num_channels) {
		str = create_channel_display_string(globallist[i]);
		WidgetSet(channel_array[i],
			  XtNlabel, str,
			  XtNborderColor, chancolourOf(globallist[i]),
			  XtNborderWidth, chanborderOf(globallist[i]),
			  XtNbackgroundPixmap, 
			  (globallist[i]->status->enabled == FALSE) ? backpixmap : ParentRelative,
			  NULL);
		if ((font = chanFont(globallist[i])) != NULL)
			WidgetSet(channel_array[i],
				  XtNfont, font,
				  NULL);

		free(str);
		i++;
	}
	for (i = 0; i < num_channels; i++)
		XtSetMappedWhenManaged(channel_array[i], True);
	if (chan_info_shown == TRUE
	    && currentchan != NULL)
		chan_display_info(currentchan);
	if (currentchan != NULL && mode == control && read_currentchan != 0) {
		clear_mta_refresh_list();
		add_mta_refresh_list(currentchan->channelname);
		construct_event(mtaread);
	}
}

/* called when channel number of msgs gets out of step with total */
/* mtas number of msgs i.e. msgs go out or come in between chanread */
/* and subsequent mtareads */

redisplay_control_channel(num)
int	num;
{
	char	*str = NULL;

	XtSetMappedWhenManaged(channel_array[num], False);
	str = create_channel_display_string(globallist[num]);
	WidgetSet(channel_array[num],
		  XtNlabel, str,
		  XtNborderColor, chancolourOf(globallist[num]),
		  XtNborderWidth, chanborderOf(globallist[num]),
		  XtNbackgroundPixmap,(globallist[num]->status->enabled == FALSE) ? backpixmap : ParentRelative,
		  NULL);
	free(str);
	XtSetMappedWhenManaged(channel_array[num], True);
}

static void monitor_display_channels()
{
	int num_displayed = 0,
		i;

	order_display_channels();
	XtUnmanageChild(monitor_form);
	while ((num_displayed < num_channels) 
	       && (chanBadness(*(display_list[num_displayed]->channel)) != 0)) {
		monitor_channel(num_displayed);
		num_displayed++;
	}
	
	i = num_displayed;
	
	while (i < num_channels
	       && display_list[i]->chan != NULL) {
		undisplay_monitor(display_list[i]);
		i++;
	}
	XtManageChild(monitor_form);
	construct_event(mtaread);
}

static void undisplay_monitor(item)
struct monitor_item	*item;
{
	int	i = 0;
	if (item->form != NULL) {
		XtDestroyWidget(item->form);
		item -> chan = NULL;
		if (item->mtas != NULL) {
			while (item->mtas[i] != NULL) {
				item->mtas[i] = NULL;
				i++;
			}
		}
		item->box = NULL;
		item->form = NULL;
	}
}	

monitor_channel(num)
int	num;
{
	
	struct chan_struct	*actualchan;
	int			managed = TRUE;
	char			*str;
	XFontStruct		*font;
	/* display display_list[num] */
	actualchan = *(display_list[num]->channel);
	actualchan->display_num = num;

	XtFormDoLayout(monitor_form, False);

	if (connectState == connected) {
		if (display_list[num]->form == NULL) {
			/* need to create form */	
			display_list[num]->form = WidgetCreate("MonitorChannelForm",
							       formWidgetClass,
							       monitor_form,
							       XtNborderColor, chancolourOf(actualchan),
								   XtNmanaged, FALSE,
							       XtNfromVert, (num == 0) ? NULL : display_list[num-1]->form,
							       XtNfromHoriz, NULL,
							       XtNresizable, TRUE,
							       NULL);
			managed = FALSE;
		}
		if (display_list[num]->chan != NULL) {
			XtUnmanageChild(display_list[num]->chan);
			str = create_channel_monitor_string(actualchan);
			WidgetSet(display_list[num]->chan,
				  XtNborderColor, chancolourOf(actualchan),
				  XtNborderWidth, chanborderOf(actualchan),
				  XtNlabel, 	str,
				  XtNbackgroundPixmap, (actualchan->status->enabled == FALSE) 
				  ? backpixmap : ParentRelative,
				  NULL);
			if ((font = chanFont(actualchan)) != NULL)
				WidgetSet(display_list[num]->chan,
					  XtNfont,	font,
					  NULL);

			XtManageChild(display_list[num]->chan);
			free(str);
		} else {
			str = create_channel_monitor_string(actualchan);
			display_list[num]->chan = WidgetCreate("MonitorChannel",
							       labelWidgetClass,
							       display_list[num]->form,
							       XtNresizable, TRUE,
							       XtNborderColor, chancolourOf(actualchan),
							       XtNborderWidth, chanborderOf(actualchan),
							       XtNlabel, str,
							       XtNbackgroundPixmap, (actualchan->status->enabled == FALSE) 
							       ? backpixmap : ParentRelative,
							       XtNfromVert, NULL,
							       XtNfromHoriz, NULL,
							       XtNleft,	XtChainLeft,
							       XtNright,	XtChainLeft,
							       XtNtop,	XtChainTop,
							       XtNbottom,	XtChainTop,
							       NULL);
			if ((font = chanFont(actualchan)) != NULL)
				WidgetSet(display_list[num]->chan,
					  XtNfont,	font,
					  NULL);
			free(str);

		}
		if (managed == FALSE)
			XtManageChild(display_list[num]->form);
		XtFormDoLayout(display_list[num]->form, False);
		WidgetSet(display_list[num]->form,
			  XtNborderColor, chancolourOf(actualchan),
			  NULL);
		add_mta_refresh_list(actualchan->channelname);
	}
	if (display_list[num]->box != NULL)
		XtUnmanageChild(display_list[num]->box);
	XtFormDoLayout(display_list[num]->form, True);
	XtFormDoLayout(monitor_form, True);
}

static char *create_channel_display_string(chan)
struct chan_struct	*chan;
{
	char	str[BUFSIZ];

	sprintf(str,"%s : %d",chan->channelname,chan->numberMessages);
	if (chan->numberReports != 0)
	  sprintf(str,"%s + %d", str, chan->numberReports);
	return strdup(str);
}

static char *create_channel_monitor_string(chan)
struct chan_struct	*chan;
{
	char	str[BUFSIZ];

	sprintf(str,"%s : %d %s",
		chan->channelname,
		chan->numberMessages,
		(chan->numberMessages == 1) ? "msg" : "msgs");

	if (chan->numberReports != 0)
	  sprintf(str, "%s and %d %s",
		  str,
		  chan->numberReports,
		  (chan->numberReports == 1) ? "DR" : "DRs");

	sprintf(str, "%s on %d %s",
		str,
		chan->num_mtas,
		(chan->num_mtas == 1) ? "mta" : "mtas");

	return strdup(str);
}

resize_chan_array(num)
int	num;	/* number of channels that will be displayed */
{
	int	i = num;
	char	*str;

	XtSetMappedWhenManaged(channels, False); 
	while (i < actual_nchans_present) {
		XtUnmanageChild(channel_array[i]);
		i++;
	}
	
	XSync(XtDisplay(channels), False);

	i = num;
	while (i < actual_nchans_present) {
		XtDestroyWidget(channel_array[i]);
		i++;
	}

	if (num == 0) {
		if (channel_array != NULL) {
			free ((char *) channel_array);
			channel_array = NULL;
		}
	} else if (actual_nchans_present == 0)
		/* haven't got any so malloc first lot */
		channel_array = (Widget *) calloc((unsigned) num, 
						  sizeof(Widget));
	else if (actual_nchans_present != num)
		/* need some more */
		channel_array = (Widget *) realloc((char *) channel_array, 
						   (unsigned) (num * sizeof(Widget)));
	while (actual_nchans_present < num) {
		str = itoa(actual_nchans_present);
		channel_array[actual_nchans_present] = 
			WidgetCreate(NULL,
				     labelWidgetClass,
				     channels,
				     XtNborderWidth,	2,
				     XtNlabel, str,
				     NULL);
		actual_nchans_present++;
		free(str);
	}
	actual_nchans_present = num;
	XtSetMappedWhenManaged(channels, True); 
}

/* \f

 */
/* mtas */
extern struct mta_struct	*currentmta;
extern int			read_currentmta;
extern int			max_mta_border;
extern void			Mta();
extern Widget			mtas,
				mta_all,
				mta_info,
				mta_viewport,
				mta_label;

struct mta_disp_struct		*mta_array = NULL;
int				actual_nmtas_present = 0,
				num_mtas_displayed = 0,
				mta_info_shown = FALSE;
static char			*create_mta_display_string();
extern int			mta_info_strlen;

mta_display_info(chan,mta)
struct chan_struct	*chan;
struct mta_struct	*mta;
{
	char		*str,
			*info_str;
	int		info_strlen = BUFSIZ;
	XFontStruct	*font;
	info_str = calloc(1, (unsigned) info_strlen);

	sprintf(info_str, ssformat, tab,
		mta->mta,
		"on channel ",
		chan->channelname);
	if (mta->status->cachedUntil != 0) {
		str = time_t2RFC(mta->status->cachedUntil);
		sprintf(info_str, plus_ssformat, info_str, tab,
			"delayed until",
			str);
		free(str);
	}
	if (mta->info != NULLCP)
		sprintf (info_str, plus_ssformat, info_str, tab,
			 "error info",
			 mta -> info);
	
	str = time_t2str(time((time_t *) 0) - mta->oldestMessage);
	sprintf(info_str, plus_ssformat, info_str, tab,
		"oldest message",
		str);
	free(str);

	str = itoa(mta->numberMessages);
	sprintf(info_str, plus_ssformat, info_str, tab,
		"number of messages",
		str);
	free(str);

	if (mta->numberReports != 0) {
	  str = itoa(mta->numberReports);
	  sprintf(info_str, plus_ssformat, info_str, tab,
		  "number of drs",
		  str);
	  free(str);
	}

	str = vol2str(mta->volumeMessages);
	sprintf(info_str, plus_ssformat, info_str, tab,
		"volume of messages",
		str);
	free(str);

	if (mta -> active) 
		sprintf(info_str, plus_ssformat, info_str, tab,
			"active",
			"processes running");

	sprintf(info_str, plus_ssformat, info_str, tab,
		"status",
		(mta->status->enabled == TRUE) ? "enabled" : "disabled");
	if (mta->status->lastAttempt != 0) {
		str = time_t2RFC(mta->status->lastAttempt);
		sprintf(info_str, plus_ssformat, info_str, tab,
			"last attempt",
			str);
		free(str);
	}
	if (mta->status->lastSuccess != 0) {
		str = time_t2RFC(mta->status->lastSuccess);
		sprintf(info_str, plus_ssformat, info_str, tab,
			"last success",
			str);
		free(str);
	}

	switch (mta->priority) {
	    case int_Qmgr_Priority_low:
		sprintf(info_str, plus_ssformat, info_str, tab,
			"priority",
			"low");
		break;
	    case int_Qmgr_Priority_normal:
		sprintf(info_str, plus_ssformat, info_str, tab,
			"priority",
			"normal");
		break;
	    case int_Qmgr_Priority_high:
		sprintf(info_str, plus_ssformat, info_str, tab,
			"priority",
			"high");
		break;
	    default:
		break;
	}

	display_mtainfo_string(info_str);
	WidgetSet(mta_info,
		  XtNlabel, "all",
		  NULL);
	XtSetMappedWhenManaged(mta_all, True);
	XtSetMappedWhenManaged(mta_viewport, False);
	if ((font = mtaFont(mta)) != NULL)
		WidgetSet(mta_all,
			  XtNfont, font,
			  NULL);
	mta_info_shown = TRUE;
	free(info_str);
}

mta_display_all()
{
	WidgetSet(mta_info,
		  XtNlabel, "info",
		  NULL);
	XtSetMappedWhenManaged(mta_viewport, True);
	XtSetMappedWhenManaged(mta_all, False);
	mta_info_shown = FALSE;
}

display_empty_mta_list(chan)
struct chan_struct	*chan;
{
	int	i;
	/* reset counters */
	if (chan != NULL && chan->mtalist != NULL)
		free_mta_list(&(chan->mtalist), &(chan->num_mtas));
	resize_mta_array(0);
	for (i = 0; i < actual_nmtas_present; i++) {
		mta_array[i].mta = NULL;
		XtSetMappedWhenManaged(mta_array[i].widget, False);
	}
	reset_label(mta_label);
	MtaToggle();
	MsgToggle();
}
	
display_mtas(chan)
struct chan_struct	*chan;
{
	if (mode == monitor)
		monitor_display_mtas(chan);
	else
		control_display_mtas(chan);
}

control_display_mtas(chan)
struct	chan_struct	*chan;
{
	int	i;
	char	*str;
	XFontStruct	*font;

	XtUnmanageChild(mtas);
	XtFormDoLayout(mtas, False);

	for (i = 0; i < num_mtas_displayed; i++)
		XtSetMappedWhenManaged(mta_array[i].widget, False);
	resize_mta_array(chan->num_mtas);

	i = 0;
	while (i < num_mtas_displayed) {
		mta_array[i].mta = chan->mtalist[i];
		str = create_mta_display_string(mta_array[i].mta);
		XtSetMappedWhenManaged(mta_array[i].widget, True);
		XtUnmanageChild(mta_array[i].widget);
		WidgetSet(mta_array[i].widget,
			  XtNlabel, str,
			  XtNborderColor, mtacolourOf(mta_array[i].mta),
			  XtNborderWidth, mtaborderOf(mta_array[i].mta),
			  XtNfromVert, (i == 0) ? NULL : mta_array[i-1].widget,
			  XtNbackgroundPixmap,
			  (mta_array[i].mta->status->enabled == FALSE) ? backpixmap : ParentRelative,
			  NULL);
		if ((font = mtaFont(mta_array[i].mta)) != NULL)
			WidgetSet(mta_array[i].widget,
				  XtNfont, font,
				  NULL);

		XtManageChild(mta_array[i].widget);
		free(str);
		i++;
	}
	if (mta_info_shown == TRUE
	    && currentchan != NULL
	    && currentmta != NULL)
		mta_display_info(currentchan, currentmta);
	if (currentchan != NULL
	    && read_currentmta != 0
	    && currentmta != NULL) {
		msginfo_args[0] = currentchan->channelname;
		msginfo_args[1] = currentmta->mta;
		if (is_loc_chan(currentchan) == TRUE)
			/* local */
			msginfo_args[2] = (char *) 1;
		else
			msginfo_args[2] = (char *) 0;
		construct_event(readchannelmtamessage);
	} else 
		display_empty_msg_list();
	XtFormDoLayout(mtas, True);
	XtManageChild(mtas);
}

int	oldnum;
extern Heuristic heuristic;
extern int	percent,
		lower_bound_mtas;

static void resize_and_zero (pbuf, pnum, num, size)
char	**pbuf;
int	*pnum;
int	num;
unsigned size;
{
	if (*pbuf == NULLCP)
		*pbuf = calloc(num, size);
	else {
		*pbuf = realloc(*pbuf,
				(unsigned) (num * size));
		if (num > *pnum)
			bzero (((*pbuf) + (*pnum)*size), (num-(*pnum))*size);
	}
	*pnum = num;
}
			

		
monitor_display_mtas(chan)
struct chan_struct	*chan;
{
	int 	num_displayed = 0,
		line_num = 0,
		bigestBorderWidth = 0;
	int	max_allowed, num_alloced;
	int num_vert_lines = 0, max_num;

	Dimension	vp_len, chan_len, dist, longest_len,
			line_len = 0;
	Widget		abovewidget = NULL;
	int		temp;

	XtFormDoLayout(monitor_form, False);
	XtFormDoLayout(display_list[chan->display_num]->form, False);
	WidgetSet(monitor_form,
		  XtNleft,	XtRubber,
		  XtNright,	XtRubber,
		  XtNtop,	XtRubber,
		  XtNbottom,	XtRubber,
		  NULL);
	WidgetSet(display_list[chan->display_num]->form,
		  XtNleft,	XtRubber,
		  XtNright,	XtRubber,
		  XtNtop,	XtRubber,
		  XtNbottom,	XtRubber,
		  NULL);

	if (display_list[chan->display_num]->box == NULL) {
		display_list[chan->display_num]->box = WidgetCreate("MonitorMTAForm",
								    formWidgetClass,
								    display_list[chan->display_num]->form,
								    XtNmanaged,		FALSE,
								    XtNresizable,	TRUE,
								    XtNborderWidth,	0,
								    XtNfromHoriz,	display_list[chan->display_num]->chan,
								    XtNfromVert,	NULL,
								    XtNbackgroundPixmap, ParentRelative,
								    XtNvertDistance,	0,
								    XtNhorizDistance,	0,
								    NULL);
	} 
	WidgetSet(display_list[chan->display_num]->box,
		  XtNleft,	XtRubber,
		  XtNright,	XtRubber,
		  XtNtop,	XtRubber,
		  XtNbottom,	XtRubber,
		  NULL);

	XtFormDoLayout(display_list[chan->display_num]->box, False);

	WidgetGet(switchform,
		  XtNwidth,	&vp_len,
		  NULL);
	WidgetGet(display_list[chan->display_num]->chan,
		  XtNwidth,	&chan_len,
		  NULL);
	WidgetGet(display_list[chan->display_num]->form,
		  XtNdefaultDistance, &temp,
		  NULL);
	dist = (Dimension) temp;
	longest_len = vp_len-chan_len-3*dist-12;
/* -10 is fudge for scrollbar */

	switch (heuristic) {
	    case percentage:
		max_allowed = (chan->num_mtas * chanBadness(chan) * percent) / (max_bad_channel * 100);
		num_alloced = (max_allowed < lower_bound_mtas) ? lower_bound_mtas : max_allowed;

		if (display_list[chan->display_num]->num_allocd != num_alloced)
			resize_and_zero (&(display_list[chan->display_num]->mtas),
					 &display_list[chan->display_num]->num_allocd,
					 num_alloced,
					 sizeof(Mta_disp_struct *));
		       
		while (num_displayed < chan->num_mtas
		       && mtaBadness(chan->mtalist[num_displayed]) != 0
		       && (num_displayed < lower_bound_mtas
			   || num_displayed < max_allowed)) {
			if (monitor_mta(chan->display_num, 
					chan->mtalist[num_displayed], 
					num_displayed,
					&line_num,
					&line_len,
					&abovewidget,
					longest_len,
					dist,
					max_allowed,
					&bigestBorderWidth) == OK)
				num_displayed++;
		}
		break;
	    case line:
		num_vert_lines = NumVertLines(chan);
		if (num_vert_lines <= 0) num_vert_lines = 1;
		max_num = num_vert_lines * max_horiz_mtas;
		if (max_num == 0) max_num++;

		if (display_list[chan->display_num]->num_allocd != max_num) 
			resize_and_zero(&(display_list[chan->display_num]->mtas),
					&(display_list[chan->display_num]->num_allocd),
					max_num,
					sizeof(Mta_disp_struct *));

		while (num_displayed < max_num 
		       && line_num < num_vert_lines
		       && (num_displayed < chan->num_mtas)
		       && (mtaBadness(chan->mtalist[num_displayed]) != 0)) {
			if (monitor_mta(chan->display_num, 
					chan->mtalist[num_displayed], 
					num_displayed,
					&line_num,
					&line_len,

					&abovewidget,
					longest_len,
					dist,
					num_vert_lines, 
					&bigestBorderWidth) == OK)
				num_displayed++;
		}
		break;
	    case all:
		if (display_list[chan->display_num]->num_allocd != 
		    chan->num_mtas) 
			resize_and_zero(&(display_list[chan->display_num]->mtas),
					&(display_list[chan->display_num]->num_allocd),
					chan->num_mtas,
					sizeof(Mta_disp_struct *));

		while (num_displayed < chan->num_mtas
		       && mtaBadness(chan->mtalist[num_displayed]) != 0) {
			if (monitor_mta(chan->display_num, 
					chan->mtalist[num_displayed], 
					num_displayed,
					&line_num,
					&line_len,

					&abovewidget,
					longest_len,
					dist,
					num_vert_lines, 
					&bigestBorderWidth) == OK)
				num_displayed++;
		}
		break;
	}
			
							 
	oldnum = display_list[chan->display_num]->num_mtas;

	display_list[chan->display_num]->num_mtas = num_displayed;
	
	while (num_displayed < display_list[chan->display_num] -> num_allocd
	       && display_list[chan->display_num]->mtas[num_displayed] != NULL
	       && display_list[chan->display_num]->mtas[num_displayed]->widget != NULL) {
		undisplay_mta_monitor(&(display_list[chan->display_num]->mtas[num_displayed]->widget));
		num_displayed++;
	}

	if (display_list[chan->display_num]->num_mtas == 0) {
		undisplay_mta_monitor(&(display_list[chan->display_num]->box));
		XtFormDoLayout(display_list[chan->display_num]->form, True);
		WidgetSet(display_list[chan->display_num]->form,
			  XtNleft,	XtChainLeft,
			  XtNright,	XtChainLeft,
			  XtNtop,	XtChainTop,
			  XtNbottom,	XtChainTop,
			  NULL);
		XtFormDoLayout(monitor_form, True);
		WidgetSet(monitor_form,
			  XtNleft,	XtChainLeft,
			  XtNright,	XtChainLeft,
			  XtNtop,	XtChainTop,
			  XtNbottom,	XtChainTop,
			  NULL);
		return;
	}
/*	WidgetSet(display_list[chan->display_num]->box,
		  XtNdefaultDistance,	(1+2*bigestBorderWidth),
		  NULL);*/

	XtFormDoLayout(display_list[chan->display_num]->box, True);
	
	XtManageChild(display_list[chan->display_num]->box);
	WidgetSet(display_list[chan->display_num]->box,
		  XtNleft,	XtChainLeft,
		  XtNright,	XtChainLeft,
		  XtNtop,	XtChainTop,
		  XtNbottom,	XtChainTop,
		  NULL);
	XtFormDoLayout(display_list[chan->display_num]->form, True);
	WidgetSet(display_list[chan->display_num]->form,
		  XtNleft,	XtChainLeft,
		  XtNright,	XtChainLeft,
		  XtNtop,	XtChainTop,
		  XtNbottom,	XtChainTop,
		  NULL);
	XtFormDoLayout(monitor_form, True);
	WidgetSet(monitor_form,
		  XtNleft,	XtChainLeft,
		  XtNright,	XtChainLeft,
		  XtNtop,	XtChainTop,
		  XtNbottom,	XtChainTop,
		  NULL);
}

undisplay_mta_monitor(pwidget)
Widget	*pwidget;
{
	if (*pwidget != NULL) {
		XtDestroyWidget(*pwidget);
		*pwidget = NULL;
	}
}

monitor_mta(chan_display_num,
	    mta, 
	    num, 
	    pline_num,
	    pline_len,
	    pvert,
	    longest,
	    dist,
	    linesAllowed,
	    borderWidth_ub)
int			chan_display_num;
struct mta_struct	*mta;
int			num;
int			*pline_num;
Dimension		*pline_len;
Widget			*pvert;
Dimension		longest,
			dist;
int			linesAllowed;
int			*borderWidth_ub;
{
	char	*str;
	Widget	horiz = NULL;
	Dimension	widget_width;
	Dimension	borderWidth = mtaborderOf(mta);
	XFontStruct	*font;

	str = create_mta_display_string(mta);
	
	if (display_list[chan_display_num]->mtas[num] == NULL) 
		/* need to create widget */
		display_list[chan_display_num]->mtas[num] = 
			(Mta_disp_struct *) calloc(1, sizeof(Mta_disp_struct));

	if (display_list[chan_display_num]->mtas[num]->widget != NULL) {
		XtDestroyWidget(display_list[chan_display_num]->mtas[num]->widget);
		display_list[chan_display_num]->mtas[num]->widget = NULL;
	}

	display_list[chan_display_num]->mtas[num]->mta = mta;

	if (display_list[chan_display_num]->mtas[num]->widget == NULL) {
		display_list[chan_display_num]->mtas[num]->widget =
			WidgetCreate("MonitorMTA",
				     labelWidgetClass,
				     display_list[chan_display_num]->box,
				     XtNresizable,	TRUE,
				     XtNborderWidth,	borderWidth,
				     XtNlabel, str,
				     XtNborderColor, mtacolourOf(mta),
				     XtNbackgroundPixmap,
				     (mta->status->enabled == FALSE) ? backpixmap : ParentRelative,
				     XtNleft,	XtChainLeft,
				     XtNright,	XtChainLeft,
				     XtNtop,	XtChainTop,
				     XtNbottom,	XtChainTop,
				     NULL);
		if ((font = mtaFont(mta)) != NULL)
			WidgetSet(display_list[chan_display_num]->mtas[num]->widget,
				  XtNfont,  font,
				  NULL);

	} 
	free(str);
	
	WidgetGet(display_list[chan_display_num]->mtas[num]->widget,
		  XtNwidth,	&widget_width,
		  NULL);

	if (*pline_len+dist+widget_width > longest) {
		/* new line */
		(*pline_num)++;
		if (heuristic == line && (*pline_num) >= linesAllowed) {
			undisplay_mta_monitor(&(display_list[chan_display_num]->mtas[num]->widget));
			return NOTOK;
		}
		if (num == 0)
			/* problems ? */
			*pvert = NULL;
		else
			*pvert = display_list[chan_display_num]->mtas[num-1]->widget;
		horiz = NULL;
		(*pline_len) = dist+widget_width;
	} else {
		if (num == 0)
			horiz = NULL;
		else
			horiz = display_list[chan_display_num]->mtas[num-1]->widget;
		(*pline_len) += dist+widget_width;
	}

	WidgetSet(display_list[chan_display_num]->mtas[num]->widget,
		  XtNfromVert,	*pvert,
		  XtNfromHoriz,	horiz,
		  NULL);
/*	XtManageChild(display_list[chan_display_num]->mtas[num]->widget);*/
	if ((int) borderWidth > *borderWidth_ub)
		*borderWidth_ub = borderWidth;
	return OK;
}

char	*create_mta_header()
{
	/* takes from current channel and current mta */
	char	*str;
	if (currentmta == NULL
	    || currentchan == NULL)
		str = strdup("No current mta");
	else {
		str = (char *) malloc((unsigned) (strlen("Current mta : ") +
				      strlen(currentmta->mta) + 
				      strlen(" on ") +
				      strlen(currentchan->channelname) + 1));
		sprintf(str, "Current mta : %s on %s", 
			currentmta->mta, currentchan->channelname);
	}

	return str;
}

static char *create_mta_display_string(mta)
struct mta_struct	*mta;
{
	char	str[BUFSIZ];

	sprintf(str, "%s : %d",mta->mta, mta->numberMessages);
	if (mta->numberReports != 0)
	  sprintf(str, "%s + %d", str, mta->numberReports);
	return strdup(str);
}

resize_mta_array(num)
int	num;	/* new number of mtas */
{

	int	i = num;

	while (i < actual_nmtas_present) {
		XtSetMappedWhenManaged(mta_array[i].widget, False);
		XtDestroyWidget(mta_array[i].widget);
		i++;
	}
	if (num == 0) {
		if (mta_array != NULL) {
			free((char *) mta_array);
			mta_array = NULL;
		}
	} else if (actual_nmtas_present == 0)
		mta_array = (struct mta_disp_struct *)
			calloc((unsigned int) num,
			       sizeof(struct mta_disp_struct));
	else if (num != actual_nmtas_present)
		mta_array = (struct mta_disp_struct *)
			realloc((char *) mta_array,
				(unsigned int) (num * sizeof(struct mta_disp_struct)));
	while (actual_nmtas_present < num) {
		mta_array[actual_nmtas_present].mta = NULL;
		mta_array[actual_nmtas_present].widget =
			WidgetCreate(NULL,
				     labelWidgetClass,
				     mtas,
				     XtNfromVert, (actual_nmtas_present == 0) ? NULL : mta_array[actual_nmtas_present-1].widget,
				     XtNfromHoriz,	NULL,
				     XtNresizable,	TRUE,
				     XtNleft,	XtChainLeft,
				     XtNright,	XtChainLeft,
				     XtNtop,	XtChainTop,
				     XtNbottom,	XtChainTop,
				     XtNborderWidth,	2,
				     NULL);
		actual_nmtas_present++;
	}
	actual_nmtas_present = num;
	num_mtas_displayed = num;
}

/* \f

 */
/* msgs */
extern struct msg_struct	*currentmsg,
				**global_msg_list;
extern int			max_msg_border;
extern void			Msg();
extern Widget			msg_all,
				msgs,
				msg_info,
				msg_viewport,
				msg_label;
extern int		       	number_msgs,
				msg_info_strlen;

struct msg_disp_struct		*msg_array = NULL;
int				actual_nmsgs_present = 0,
				num_msgs_displayed = 0,
				msg_info_shown = FALSE;
static char			*create_msg_display_string();

msg_display_info(msg)
struct msg_struct	*msg;
{
	struct recip	*ix;
	char		*str,
			*info_str,
			temp[BUFSIZ];
	int		info_strlen = BUFSIZ;
	XFontStruct	*font;
	info_str = calloc(1, BUFSIZ);

	sprintf(temp, "%s", msg->msginfo->queueid);
	resize_info_str(&info_str, &info_strlen, strlen(temp)+1);
	sprintf(info_str, "%s\n", temp);

	sprintf(temp, ssformat, tab, "originator ", msg->msginfo->originator);
	resize_info_str(&info_str, &info_strlen, strlen(temp+1));
	sprintf(info_str, "%s%s\n", info_str, temp);

	if (msg->msginfo->uaContentId != NULLCP) {
		sprintf(temp, ssformat, tab,
			"ua content id",
			msg->msginfo->uaContentId);
		resize_info_str(&info_str, &info_strlen, strlen(temp)+1);
		sprintf(info_str, "%s%s\n", info_str, temp);
	}

	if (msg->msginfo->inChannel != NULLCP) {
		sprintf(temp, ssformat, tab,
			"inbound channel",
			msg->msginfo->inChannel);
		resize_info_str(&info_str, &info_strlen, strlen(temp)+1);
		sprintf(info_str, "%s%s\n", info_str, temp);
	}
	
	ix = msg->reciplist;
	if (ix != NULL) ix = ix->next;
	while (ix != NULL) {
		sprintf(info_str, "%s\n", info_str);
		sprintf(temp, ssformat, tab,
			"to",
			ix->recipient);
		sprintf(temp, "%s(id %d)", temp, ix->id);

		if (ix->info != NULLCP)
			sprintf(temp, plus_ssformat, temp, tab,
				"error info",
				ix -> info);

		if (ix->chansOutstanding == NULL)
			sprintf(temp, plus_ssformat, temp, tab,
				"",
				"awaiting DRs");
		else
			sprintf(temp, plus_ssformat, temp, tab,
				"remaining channels",
				ix->chansOutstanding);
		if (ix->status->cachedUntil != 0) {
			str = time_t2RFC(ix->status->cachedUntil);
			sprintf(temp, plus_ssformat, temp, tab,
				"delayed until",
				str);
			free(str);
		}
		sprintf(temp, plus_ssformat, temp, tab,
			"status",
			(ix->status->enabled == TRUE) ? "enabled" : "disabled");
		
		if (ix->status->lastAttempt != 0) {
			str = time_t2RFC(ix->status->lastAttempt);
			sprintf(temp, plus_ssformat, temp, tab,
				"last attempt",
				str);
			free(str);
		}

		if (ix->status->lastSuccess != 0) {
			str = time_t2RFC(ix->status->lastSuccess);
			sprintf(temp, plus_ssformat, temp, tab,
				"last success",
				str);
			free(str);
		}
		resize_info_str(&info_str, &info_strlen, strlen(temp)+1);
		sprintf(info_str, "%s%s\n", info_str, temp);
		ix = ix->next;
	}
	sprintf(info_str, "%s\n", info_str);

	temp[0] = '\0';
	if (msg->msginfo->contenttype != NULLCP) 
		sprintf(temp, plus_ssformat, temp, tab,
			"content type",
			msg->msginfo->contenttype);

	if (msg->msginfo->eit != NULL)
		sprintf(temp, plus_ssformat, temp, tab,
			"eits",
			msg->msginfo->eit);
	str = time_t2str(time((time_t *) 0) - msg->msginfo->age);
	sprintf(temp, plus_ssformat, temp, tab,
		"Age",
		str);
	free(str);
	if (msg->msginfo->expiryTime != 0) {
		str = time_t2RFC(msg->msginfo->expiryTime);
		sprintf(temp, plus_ssformat, temp, tab,
			"Expiry time",
			str);
		free(str);
	}
	if (msg->msginfo->deferredTime != 0) {
		str = time_t2RFC(msg->msginfo->deferredTime);
		sprintf(temp, plus_ssformat, temp, tab,
			"Deferred until",
			str);
		free(str);
	}
	switch (msg->msginfo->priority) {
	    case int_Qmgr_Priority_low:
		sprintf(temp, plus_ssformat, temp, tab,
			"priority",
			"low");
		break;
	    case int_Qmgr_Priority_normal:
		sprintf(temp, plus_ssformat, temp, tab,
			"priority",
			"normal");
		break;
	    case int_Qmgr_Priority_high:
		sprintf(temp, plus_ssformat, temp, tab,
			"priority",
			"high");
		break;
	    default:
		break;
	}
	if (msg->msginfo->errorCount != 0)
		sprintf(temp, plus_sdformat, temp, tab,
			"number of errors",
			msg->msginfo->errorCount);
	resize_info_str(&info_str, &info_strlen, strlen(temp));
	sprintf(info_str, "%s%s", info_str, temp);

	display_msginfo_string(info_str);
	WidgetSet(msg_info,
		  XtNlabel, "all",
		  NULL);
	XtSetMappedWhenManaged(msg_all, True);
	XtSetMappedWhenManaged(msg_viewport, False);
	if ((font = msgFont(msg)) != NULL)
		WidgetSet(msg_all,
			  XtNfont, font,
			  NULL);
	msg_info_shown = TRUE;
	free(info_str);
}

msg_display_all()
{
	WidgetSet(msg_info,
		  XtNlabel, "info",
		  NULL);
	XtSetMappedWhenManaged(msg_viewport, True);
	XtSetMappedWhenManaged(msg_all, False);
	msg_info_shown = FALSE;
}

display_msgs()
{
	if (mode == control)
		control_display_msgs();
}

int display_empty_msg_list()
{
	int	i;

	for (i = 0; i < actual_nmsgs_present; i++) {
		msg_array[i].msg = NULL;
		XtSetMappedWhenManaged(msg_array[i].widget, False);
	}
	currentmsg = NULL;
	reset_label(msg_label);
	MtaToggle();
	MsgToggle();
}

int	control_msgs_ub = 10, 
	msgs_ub = True;
extern	Widget	msgs_showall;

control_display_msgs()
{
	int	i;
	char	*str;
	XFontStruct	*font;
	XtUnmanageChild(msgs);
	XtFormDoLayout(msgs, False);

	for (i = 0; i < actual_nmsgs_present; i++)
		XtSetMappedWhenManaged(msg_array[i].widget, False);
	resize_msg_array((msgs_ub == True && number_msgs > control_msgs_ub) ? control_msgs_ub : number_msgs);

	i = 0;
	while (i < num_msgs_displayed) {
		msg_array[i].msg = global_msg_list[i];
		str = create_msg_display_string(global_msg_list[i]);
		XtSetMappedWhenManaged(msg_array[i].widget, True);
		XtUnmanageChild(msg_array[i].widget);
		font = msgFont(msg_array[i].msg);
		WidgetSet(msg_array[i].widget,
			  XtNlabel, str,
			  XtNbackgroundPixmap,
			  (font != NULL && font == disabledFont) ? backpixmap : ParentRelative,
			  XtNborderColor, msgcolourOf(msg_array[i].msg),
			  XtNborderWidth, msgborderOf(msg_array[i].msg),
			  NULL);
		if (font != NULL)
			WidgetSet(msg_array[i].widget,
				  XtNfont, font,
				  NULL);

		XtManageChild(msg_array[i].widget);
		free(str);
		i++;
	}
	if (msgs_ub == True && num_msgs_displayed < number_msgs)
		XtSetMappedWhenManaged(msgs_showall, True);
	else
		XtSetMappedWhenManaged(msgs_showall, False);

	if (msg_info_shown == TRUE
	    && currentmsg != NULL)
		msg_display_info(currentmsg);
	XtFormDoLayout(msgs, True);
	XtManageChild(msgs);
}

monitor_display_msgs()
{
}

char	*create_msg_header()
{
	/* takes from current msg */
	char	*str;
	if (currentmsg == NULL)
		str = strdup("No current message");
	else {
		str = (char *) malloc((unsigned) (strlen("Current msg : ") +
				      strlen(currentmsg->msginfo->queueid) + 1));
		sprintf(str, "Current msg : %s", 
			currentmsg->msginfo->queueid);
	}

	return str;
}

resize_msg_array(num)
int	num;	/* new number of msgs */
{
	int	i = num;
/*	if (control_msgs_ub < actual_nmsgs_present)*/
		
	while (i < actual_nmsgs_present) {
		XtSetMappedWhenManaged(msg_array[i].widget, False);
		XtDestroyWidget(msg_array[i].widget);
		i++;
	}

	if (num == 0) {
		if (msg_array != NULL) {
			free ((char *) msg_array);
			msg_array = NULL;
		}
	} else if (actual_nmsgs_present == 0)
		msg_array = (struct msg_disp_struct *)
			calloc((unsigned int) num,
			       sizeof(struct msg_disp_struct));
	else if (actual_nmsgs_present != num)
		msg_array = (struct msg_disp_struct *)
			realloc((char *) msg_array,
				 (unsigned int) (num * sizeof(struct msg_disp_struct)));

	while (actual_nmsgs_present < num) {
		msg_array[actual_nmsgs_present].msg = NULL;
		msg_array[actual_nmsgs_present].widget =
			WidgetCreate(NULL,
				     labelWidgetClass,
				     msgs,
				     XtNfromVert, (actual_nmsgs_present == 0) ? NULL : msg_array[actual_nmsgs_present-1].widget,
				     XtNfromHoriz,	NULL,
				     XtNresizable,	TRUE,
				     XtNborderWidth,	2,
				     XtNleft,	XtChainLeft,
				     XtNright,	XtChainLeft,
				     XtNtop,	XtChainTop,
				     XtNbottom,	XtChainTop,
				     NULL);
		actual_nmsgs_present++;
	}
	actual_nmsgs_present = num;
	num_msgs_displayed = num;
}

static char	*create_msg_display_string(msg)
struct msg_struct	*msg;
{
	char	str[BUFSIZ];

	if (msg->reciplist == NULL
	    || msg->reciplist->next == NULL)
		/* delivery report */
		sprintf(str,"dr (%s) to %s",
			msg->msginfo->queueid,
			msg->msginfo->originator);
	else {
		struct recip	*ix = msg->reciplist;
		int		found = 0;

		while (ix != NULL && found == 0) {
			if (ix->actChan != NULL 
			    && currentchan != NULL 
			    && strcmp(ix->actChan, 
				      currentchan->channelname) == 0) {
				/* channel matches */
				if (is_loc_chan(currentchan) == TRUE) { 
					if (ix->recipient && currentmta
					    && strcmp(ix->recipient, currentmta->mta) == 0)
						found = 1;
				} else if (ix->mta != NULL 
					   && currentmta != NULL
					   && strcmp(ix->mta, 
						     currentmta->mta) == 0)
					/* mta matches */
					found = 1;
			}
			if (found == 0)
				ix = ix->next;
		}
		if (ix != NULL && ix->id == 0) 
			/* delivery report ? */
			sprintf(str, "dr (%s) to %s",
				msg->msginfo->queueid,
				ix->recipient);
		else {
			if (ix == NULL) ix = msg->reciplist->next;

			sprintf(str, "%s to %s from %s",
				msg->msginfo->queueid,
				ix->recipient,
				msg->msginfo->originator);
		}
	}
	return strdup(str);
}

reset_label(hdr)
Widget	hdr;
{
	char *str = NULL;
	XFontStruct	*font = normalFont;
	if (hdr == channel_label) {
		str = create_channel_header();
		font = chanFont(currentchan);
	} else if (hdr == mta_label) {
		str = create_mta_header();
		font = mtaFont(currentmta);
	} else if (hdr == msg_label) {
		str = create_msg_header();
		font = msgFont(currentmsg);
	}
	WidgetSet(hdr,
		  XtNlabel, str,
		  NULL);
	if (font != NULL)
		WidgetSet(hdr,
			  XtNfont, font,
			  NULL);

	if (str) free(str);
}	

/* \f

 */
extern Widget	connect_command,
		refresh_command;
extern struct tailor *tailors;
extern void	tailor_free();

ResetForDisconnect()
{
	/* change disconnect to connect */
	WidgetSet(connect_command,
		  XtNlabel, "connect",
		  NULL);
	WidgetSet(refresh_command,
		  XtNlabel, "refresh",
		  NULL);
	if (tailors) {
		tailor_free(tailors);
		tailors = NULL;
	}
	MapButtons(False);
	MapVolume(False);
	undisplay_time_label();

	if (connectState == connected)
		clear_displays();
	if (Qinformation != NULLCP) {
		free(Qinformation);
		Qinformation = NULLCP;
	}
	if (Qversion != NULLCP) {
		free(Qversion);
		Qversion = NULLCP;
		WidgetSet(qversion,
			  XtNlabel,	"???",
			  NULL);
	}
}

clear_displays()
{
	/* unmap all displays */
	/* deal with channel display */
	clear_monitor();
	clear_channel_display();
	clear_control();
	
}

clear_monitor()
{
	int 	i = 0,
		j = 0;
	XtFormDoLayout(monitor_form, False);
	if (display_list != NULL) {
		while (i < num_channels) {
			if (display_list[i] != NULL) {
				if (display_list[i]->form)
					XtFormDoLayout(display_list[i]->form, False);		
				if (display_list[i]->box)
					XtFormDoLayout(display_list[i]->box, False);
				if (display_list[i]->chan != NULL) {
					XtDestroyWidget(display_list[i]->chan);
					j = 0;
					while (j < display_list[i] -> num_allocd
					       && display_list[i]->mtas[j] != NULL) {
						if (display_list[i]->mtas[j]->widget != NULL)
							XtDestroyWidget(display_list[i]->mtas[j]->widget);
						free((char *) display_list[i]->mtas[j]);
						j++;
					}
					free((char *) display_list[i]->mtas);
				}
				if (display_list[i]->box != NULL)
					XtDestroyWidget(display_list[i]->box);
				if (display_list[i]->form != NULL)
					XtDestroyWidget(display_list[i]->form);
			}
		free((char *) display_list[i]);
		i++;
		}
		free((char *) display_list);
		display_list = NULL;
	}
	XtFormDoLayout(monitor_form, True);
}

clear_control()
{
	/* destructive clear removing channel, mta, msg displays */
	/* and freeing globallist */
	clear_mta_display();
	clear_msg_display();
}

clear_channel_display()
{
	int	i;
	free_channel_list();
	currentchan = NULL;
	resize_chan_array(0);
	reset_label(channel_label);
	ChanToggle();
	for (i = 0; i < actual_nchans_present; i++) {
		if (channel_array[i] != NULL) 
			XtSetMappedWhenManaged(channel_array[i], False);
	}
}

clear_mta_display()
{
	int	i;
	resize_mta_array(0);
	currentmta = NULL;
	read_currentmta = 0;
	reset_label(mta_label);
	MtaToggle();
	for (i = 0; i < actual_nmtas_present; i++) {
		if (mta_array[i].widget != NULL) 
			XtSetMappedWhenManaged(mta_array[i].widget, False);
	}
}

clear_msg_display()
{
	int	i;

	resize_msg_array(0);
	currentmsg = NULL;
	reset_label(msg_label);
	MsgToggle();
	if (msg_info_shown == TRUE)
		msg_display_all();
	for (i = 0; i < actual_nmsgs_present; i++) {
		if (msg_array[i].widget != NULL)
			XtSetMappedWhenManaged(msg_array[i].widget, False);
	}
}

void ChanToggle()
{
	if (chan_info_shown == TRUE)
		chan_display_all();
}

void MtaToggle()
{
	if (mta_info_shown == TRUE)
		mta_display_all();
}

void MsgToggle()
{
	if (msg_info_shown == TRUE)
		msg_display_all();
}

toggle_info_displays()
{
	ChanToggle();
	MtaToggle();
	MsgToggle();
}

/* \f

 */
textdisplay(tuple, str)
Popup_tuple	*tuple;
char	*str;
{
	XtTextBlock	txtblock;

	txtblock.ptr = str;
	txtblock.firstPos = 0;
	txtblock.format = FMT8BIT;
	txtblock.length = strlen(str);
	/* pad with blanks */
	XtTextReplace(tuple->text,
		      (XtTextPosition) 0,
		      (XtTextPosition) (tuple->str != NULLCP) ? strlen(tuple->str) : 0,
/*MAX_EDIT_STRING, */
		      &txtblock);
}

extern Widget	top;
terminate_display()
{
	XtDestroyWidget(top);
/*	XtDestroyWidget(popup);*/
}

update_channel_from_mtas(chan, nmsgs, ndrs, nmtas, volume)
struct chan_struct	*chan;
int			nmsgs,
  			ndrs,
			nmtas,
			volume;
{
	int	changed = FALSE;
	
	if (chan -> numberMessages != nmsgs) {
		total_number_messages += nmsgs - chan -> numberMessages;
		chan -> numberMessages = nmsgs;
		changed = TRUE;
	}
	
	if (chan -> numberReports != ndrs) {
		total_number_reports += ndrs - chan -> numberReports;
	  chan -> numberReports = ndrs;
	  changed = TRUE;
	}

	if (chan -> num_mtas != nmtas) {
		chan -> num_mtas = nmtas;
		changed = TRUE;
	}
	if (chan -> volumeMessages != volume) {
		total_volume += volume - chan -> volumeMessages;
		chan -> volumeMessages = volume;
		changed = TRUE;
	}	
	if (changed == TRUE) {
		redisplay_channel(chan);
		display_totals();
	}
}

static void redisplay_channel(chan)
struct chan_struct	*chan;
{
	int	i = 0;
	char	*str;

	/* do control display */
	while (i < num_channels && globallist[i] != chan)
		i++;

	if (i < num_channels) {
		str = create_channel_display_string(globallist[i]);
		WidgetSet(channel_array[i],
			  XtNlabel, str,
			  XtNborderColor, chancolourOf(globallist[i]),
			  XtNborderWidth, chanborderOf(globallist[i]),
			  XtNbackgroundPixmap,
			  (globallist[i]->status->enabled == FALSE) ? backpixmap : ParentRelative,
			  NULL);
		free(str);
	}

	if (mode == monitor) {
		/* do monitor display */
		str = create_channel_monitor_string(chan);
		WidgetSet(display_list[chan->display_num] ->  chan,
			  XtNlabel, str,
			  XtNborderColor, chancolourOf(chan),
			  XtNborderWidth, chanborderOf(chan),
			  XtNbackgroundPixmap, (chan->status->enabled == FALSE) ? backpixmap : ParentRelative,
			  NULL);
		free(str);
	}
}

static char	*time_t2str(in)
time_t  in;
{
	char	buf[BUFSIZ];
	time_t	result;
	buf[0] = '\0';
	
	if (in < 0)
		return strdup("still in the womb");

	if ((result = in / (60 * 60 * 24)) != 0) {
		sprintf(buf, "%d day%s",
			result,
			(result == 1) ? "" : "s");
		in = in % (60 * 60 * 24);
	}

	if ((result = in / (60 * 60)) != 0) {
		sprintf(buf, 
			(buf[0] == '\0') ? "%s%d hr%s" : "%s %d hr%s",
			buf, 
			result,
			(result == 1) ? "" : "s");
		in = in % (60 * 60);
	}
	if ((result = in / 60) != 0) {
		sprintf(buf, 
			(buf[0] == '\0') ? "%s%d min%s" : "%s %d min%s",
			buf, 
			result,
			(result == 1) ? "" : "s");
		in = in % 60;
	}

	if (buf[0] == '\0' && in != 0)
		sprintf(buf, "%d sec%s", 
			in,
			(in == 1) ? "" : "s");
	if (buf[0] == '\0')
		sprintf(buf, "just born");
	return strdup(buf);
}

static void	resize_info_str(pold, poldlen, inc)
char		**pold;
int		*poldlen,
		inc;
{
	if (strlen(*pold) + inc >= *poldlen) {
		*poldlen += BUFSIZ;
		*pold = realloc(*pold, (unsigned) *poldlen);
	}
}