#define	    ident	"1A11"
#ifdef __DECC
#pragma	    module	    EL737	ident
#endif
/*
** +--------------------------------------------------------------+
** |                  Paul Scherrer Institute                     |
** |                     SINQ Project				  |
** |                                                              |
** | This software may be used freely by non-profit organizations.|
** | It may be copied provided that the name of P.S.I. and of the |
** | author is included. Neither P.S.I. nor the author assume any |
** | responsibility for the use of this software outside of P.S.I.|
** +--------------------------------------------------------------+
**
** Link_options - Here is the Linker Option File
**!$	if p1 .eqs. "DEBUG" then dbg1 := /debug
**!$	if p1 .eqs. "DEBUG" then dbg2 := _dbg
**!$	link 'dbg1'/exe=el737'dbg2'.exe sys$input/options
**!	    el737
**!	    sinq_olb/lib
**!	    sys$share:decw$xmlibshr12.exe/share
**!	    sys$share:decw$xtlibshrr5.exe/share
**!$	purge/nolog el737'dbg2'.exe
**!$	exit
**!$!
**!$! To build on LNSA09 ...
**!$!	$ build_cc_select :== decc
**!$!	$ import tasmad
**!$!	$ define/job deltat_c_tlb sinq_c_tlb
**!$!	$ set default ud0:[maden.scratch]
**!$!	$ bui tas_src:[utils]el737 debug
**!$!
** Link_options_end
**
**	Building on Alpha Digital Unix:
**
**	    setenv TAS_BASE ~maden/tasmad
**	    source $TAS_BASE/tasmad.setup
**	    rcp -p "lnsa09:tas_src:[utils]el737.c" $TAS_SRC/utils/el737.c
**	    cc -std1 -g -o $TAS_BIN/el737	\
**		    -I$TAS_INC			\
**		    $TAS_SRC/utils/el737.c	\
**		    -L$TAS_LIB -lsinq -lm -lrt -lXm -lXt -lX11
**
** Resource File:	    decw$user_defaults:SinQ_rc.dat
** -------------     or	    $HOME/SinQ_rc
**
**	*rs232cSrvHost:		lnsw02	<-- the name of the RS232C server
**	*rs232cSrvInetPort:	4000	<-- the TCP/IP port of the server
**	*rs232cSrvEL737Chan:	2	<-- the RS232C channel number of the
**						EL737 VME counter on the server
**  plus
**	*vmeCntrMsecPoll:	500	<-- 0.5 sec updates
**	*vmeCntrMode:		Count	<-- "Count" or "Time"
**	*vmeCntrPresetCount:	0	<-- The preset count
**	*vmeCntrPresetTime:	0	<-- The preset time (secs or hh:mm:ss.t)
**	    if *vmeCntrPresetCount is zero, the value is read from the cntr.
**	    Ditto for *vmeCntrPresetTime.
**+
**---------------------------------------------------------------------------
** Module Name  . . . . . . . . : [...MOTIF]EL737.C
**
** Author   . . . . . . . . . . : D. Maden
** Date of creation . . . . . . : Nov 1994
**
** Purpose
** =======
**    EL737 is a program which was written to learn about OSF/Motif
**    programming and, maybe, to generate a useful tool for the SINQ
**    VME/RS-232-C Neutron Counter.
**
** Use:
** ===
**   1)	Ensure that VME_MOTOR_SRV is running on the appropriate computer.
**
**   2)	Define the foreign command and the workstation where the display
**	is to appear via the commands:
**
**	    $ cntr :== $cpt:[exe]el737
**	    $ set display /create /transport=tcpip /node=pswxxx
**
**   3)	Check the resource file DECW$USER_DEFAULTS:SinQ_rc.dat on VMS or
**				$HOME/SinQ_rc on Digital-UNIX for the
**	required resources (or specify them as options - see below).
**
**   4) Ensure that the Session Manager security is set up to allow windows
**	to be created on one's workstation.
**
**   5)	Issue the command:
**				    $ cntr [-options]
**
**	Options are:			Equivalent Resource Name   Default
**	-----------			------------------------   -------
**	    -host  <server-name>	  *rs232cSrvHost	      Undefined
**	    -port  <port-number>	  *rs232cSrvInetPort	      4000
**	    -chan  <chan-number>	  *rs232cSrvEL737Chan	      0
**	    -mode  <counter-mode>	  *vmeCntrMode		      ???
**	    -count <preset-count>	  *vmeCntrPresetCount	      0
**	    -time  <preset-time>	  *vmeCntrPresetTime	      0
**	    -poll  <poll-delay-in-msec>	  *vmeCntrMsecPoll	      1000
**	    -tmo   <time-out-in-msecs>	  *vmeCntrTmo		      5000
**	    -persist   	                  *vmeCntrPersist             False
**	where
**	    <chan-number>  is the number of the RS-232-C channel on the
**			    server which is connected to the EL737 VME counter.
**			    For example, on a Macintosh, the 4 channels of the
**			    first Hurdler board are usually channels 2 - 5 incl.
**	    <counter-mode> may be "Count" or "Time".
**	    <preset-count> must be an integer.
**	    <preset-time>  may be a fixed point number, e.g. 10.5, in which case
**			    it is assumed to be seconds, or "hh:mm:ss.t".
**	If specified, a flag takes precedence over the resource file.
**
** Updates:
**  1A01 11-Nov-1994 DM.	Initial version.
**  1A10  3-Apr-2000 DM.        Add fortify.h
**-
**====================================================================
*/
#include    <stdlib.h>
#include    <stdio.h>
#include    <stdarg.h>
#include    <netdb.h>
#include    <errno.h>
#include    <ctype.h>

#ifdef	__VMS
  #include    <signal.h>
  #include    <unixio.h>
#else
  #include    <unistd.h>
  #ifdef FORTIFY
    #include    <fortify/fortify.h>
  #endif
#endif

#include    <netinet/in.h>
#include    <arpa/inet.h>
#include    <math.h>
#include    <sys/socket.h>
#include    <sys/time.h>

#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/ArrowB.h>
#include <Xm/BulletinB.h>
#include <Xm/CascadeB.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/MainW.h>
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/PanedW.h>
#include <Xm/Scale.h>
#include <Xm/ScrolledW.h>
#include <Xm/SelectioB.h>
#include <Xm/Separator.h>
/*
**--------------------------------------------------------------------------
**			Define global structures and constants.
*/
#include    <el737_def.h>
#include    <sinq_prototypes.h>

#define MAX_ARGS	20
#define SCALE_RUN_MAX	1000

  enum	Menu_Type {CASCADE, PULL_DOWN, SEPARATOR};

  typedef struct {
    char* rs232c_srv_host;	    /* Name of Host running the RS232C Server */
    int   rs232c_srv_inet_port;	    /* TCP/IP Port Number of    RS232C Server */
    int   v24_chan;		    /* Channel # of VME counter on Server */
    char* mode;			    /* Default Mode of Neutron Counter */
    int   preset_count;		    /* Value for preset counter */
    char* preset_time;		    /* Value for preset timer */
    int   msec_poll;		    /* Poll rate in msec */
    int   msec_tmo;		    /* Time-out in msec */
    int   persist;		    /* If non-zero, keep going on error */
  } ApplicationData;
/*
**-------------------------------------------------------------
**	Global Variables
*/
  void		    *Hndl = NULL;
  struct EL737info  *InfoHndl;

  ApplicationData    AppData;

  XtAppContext	     App_context;	/* application context;	*/

  static XtResource	Resources[] = {
       {"rs232cSrvHost", "Rs232cSrvHost", XmRString, sizeof(String),
			XtOffsetOf (ApplicationData, rs232c_srv_host),
			XmRString, "Undefined"},
       {"rs232cSrvInetPort", "Rs232cSrvInetPort", XmRInt, sizeof(int),
			XtOffsetOf (ApplicationData, rs232c_srv_inet_port),
			XmRImmediate, (XtPointer) 4000},
       {"rs232cSrvEL737Chan", "Rs232cSrvEL737Chan", XmRInt, sizeof(int),
			XtOffsetOf (ApplicationData, v24_chan),
			XmRImmediate, (XtPointer) 0},
       {"vmeCntrMode", "VmeCntrMode", XmRString, sizeof(String),
			XtOffsetOf (ApplicationData, mode),
			XmRString, "???"},
       {"vmeCntrMsecPoll", "VmeCntrMsecPoll", XmRInt, sizeof(int),
			XtOffsetOf (ApplicationData, msec_poll),
			XmRImmediate, (XtPointer) 1000},
       {"vmeCntrTmo", "VmeCntrTmo", XmRInt, sizeof(int),
			XtOffsetOf (ApplicationData, msec_tmo),
			XmRImmediate, (XtPointer) 5000},
       {"vmeCntrPresetCount", "VmeCntrPresetCount", XmRInt, sizeof(int),
			XtOffsetOf (ApplicationData, preset_count),
			XmRImmediate, (XtPointer) 0},
       {"vmeCntrPresetTime", "VmeCntrPresetTime", XmRString, sizeof(String),
			XtOffsetOf (ApplicationData, preset_time),
			XmRString, "0"},
       {"vmeCntrPersist", "VmeCntrPersist", XmRInt, sizeof(int),
			XtOffsetOf (ApplicationData, persist),
			XmRImmediate, (XtPointer) 0},
  };
  static XrmOptionDescRec	OpTable[] = {
       {"-host",    ".rs232cSrvHost",	   XrmoptionSepArg, (XPointer) NULL},
       {"-port",    ".rs232cSrvInetPort",  XrmoptionSepArg, (XPointer) NULL},
       {"-chan",    ".rs232cSrvEL737Chan", XrmoptionSepArg, (XPointer) NULL},
       {"-mode",    ".vmeCntrMode",	   XrmoptionSepArg, (XPointer) NULL},
       {"-count",   ".vmeCntrPresetCount", XrmoptionSepArg, (XPointer) NULL},
       {"-time",    ".vmeCntrPresetTime",  XrmoptionSepArg, (XPointer) NULL},
       {"-poll",    ".vmeCntrMsecPoll",	   XrmoptionSepArg, (XPointer) NULL},
       {"-tmo",     ".vmeCntrMsecTmo",	   XrmoptionSepArg, (XPointer) NULL},
       {"-persist", ".vmeCntrPersist",	   XrmoptionNoArg,  (XPointer) "1"},
    };
  static struct Counter_State	Cntr_state;
  static struct Counter_State	Old_Cntr_state;
  static int			Cntr_state_mode;
  static int			Cntr_state_mon_preset = 100;
  static char			Cntr_state_timer_preset[32] = "10.00";

  static int			Cntr_state_mode_in_window;
  static int			Cntr_state_mon_preset_in_window;
  static char			Cntr_state_timer_preset_in_window[32];

  static struct RS__RespStruct	Respon_buff;

  static int	    Msg_seq = 9876;
  static int	    Scale_is_khz;
  static int	    Scale_max;
  static float	    Thresh_cntr_thresh;	/* This is threshold of th'hold cntr */
  static float	    Thresh_cntr_rate;	/* This is its rate */
  static Pixel	    Dflt_foreground;
  static Pixel	    Dflt_background;

  static XtIntervalId		Timer_id = 0;
  static char			Err_text[80];

  static Widget    Top_level;		/* Shell widget	*/

  static Widget    File_cascade;	/*  File  CascadeButton	*/
  static Widget    Setup_cascade;	/*  Setup CascadeButton	*/
  static Widget    Help_cascade;	/*  Help  CascadeButton	*/
  static Widget    Mode_cascade;	/*  Mode  CascadeButton	*/

  static Widget    Updt_button;		/*  Update   Push Button */
  static Widget    Go_button;		/*  Go	     Push Button */
  static Widget    Stop_button;		/*  Stop     Push Button */
  static Widget    Pause_button;	/*  Pause    Push Button */
  static Widget    Cont_button;		/*  Continue Push Button */

  static Widget    Swch_mode_button;	/* Switch Preset Mode Push Button */
  static Widget    Pre_cnt_button;	/* Preset Count Push Button */
  static Widget    Pre_time_button;	/* Preset Time  Push Button */

  static Widget    Lbl_counter_mode;
  static Widget    Lbl_counter_state;

  static Widget    Lbl_timer;
  static Widget    Lbl_mon, Lbl_mon_rate;
  static Widget    Lbl_det, Lbl_det_rate;
  static Widget    Lbl_c3,  Lbl_c3_rate;
  static Widget    Lbl_c4,  Lbl_c4_rate;
  static Widget    Lbl_c5,  Lbl_c5_rate;
  static Widget    Lbl_c6,  Lbl_c6_rate;
  static Widget    Lbl_c7,  Lbl_c7_rate;
  static Widget    Lbl_c8,  Lbl_c8_rate;

  static Widget    Lbl_thresh_scales;
  static Widget    Scale_thresh;
  static Widget    Scale_rate;
  static Widget    Lbl_rate_scale_max;
  static Widget    Lbl_thr_scale_val;
  static Widget    Lbl_rate_scale_val;
  static Widget    Btn_scale_up;
  static Widget    Btn_scale_down;
  static Widget    Scale_run_progress;

  static int	Nargs;		/* Argument list variables - these must ..  */
  static Arg	Args[MAX_ARGS];	/* .. only be used as temporary variables.  */
/*
**---------------------------------------------------------------------------
**			StrnTrim	- copy text, trimming whitespace.
*/
  char	*StrnTrim (
/*	 ========
*/		    char *dest,	/* Destination string */
		    char *src,	/* Source string */
		    int  max) {	/* Length of dest (incl terminating null) */
    char    *pntr;
    int	    prfx, cntr, last_non_space = 0;

    dest[0] = '\0';
    if (strlen (src) == 0) return dest;

    prfx = strspn (src, " \t\n\r\v\f");
    pntr = src + prfx;
    cntr = 0;
    while ((cntr < max) && (*pntr != '\0')) {
      dest[cntr] = *pntr;
      if (strcspn (pntr, " \t\n\r\v\f") >= 1) last_non_space = cntr;
      cntr++;
      pntr++;
    }
    dest[cntr] = '\0';
    dest[last_non_space+1] = '\0';
    return dest;
  }
/*
**---------------------------------------------------------------------------
**		CheckTimeSyntax	- check syntax of a time string
*/
  char	*CheckTimeSyntax (	/* Return NULL if not valid */
/*	 ===============
*/		char	    *str,	/* The string to be checked */
		char	    *secs) {	/* If valid, returned string of equiv
					**  duration in seconds
					*/
    static char	    text[50];
    char	    *pntr, *h_pntr, *m_pntr, *s_pntr;
    int		    len, hh, mm, ss, deci_secs;
    float	    f_ss;
    Boolean			    sep;
	    /*
	    ** Carefully check the syntax. Only whitespace, digits, ",", ":",
	    ** "." and "'" are allowed. Simply squeeze out "," and "'", i.e. no
	    ** check that exactly 3 chars occur between them!!
	    */
    StrnTrim (text, str, sizeof (text) - 1);	/* Make local copy to work on */
    len = strlen (text);
    if (len <= 0) return NULL;

    if (strspn (text, "0123456789,\':.") != len) return NULL;

    while ((pntr = strpbrk (text, ",\'")) != NULL) { /* Remove primes and */
      do {					      /*  commas */
        pntr[0] = pntr[1];
        pntr++;
      } while (pntr[0] != '\0');
    }
    if (strchr (text, ':') != NULL) {	/* hh:mm:ss.t or seconds?? */
					/* It seems to be hh:mm:ss.t */
      hh = mm = ss = deci_secs = 0;
      h_pntr = strtok (text, ":");  /* Split into tokens */
      m_pntr = strtok (NULL, ":");
      s_pntr = strtok (NULL, ":");
      if ((h_pntr == NULL) || (m_pntr == NULL) || (s_pntr == NULL)) return NULL;
      if (sscanf (h_pntr, "%d", &hh) != 1) return NULL;
      if (sscanf (m_pntr, "%d", &mm) != 1) return NULL;
      if (sscanf (s_pntr, "%f", &f_ss) != 1) return NULL;
      ss = (int) f_ss;
      if (hh >= 555) return NULL;
      if (mm >= 60) return NULL;
      if (ss >= 60) return NULL;
      deci_secs = (int) ((f_ss - (float) ss) * 10.0 + 0.001);
      ss = ((hh * 60 + mm) * 60) + ss;
      sprintf (text, "%d:%02d:%02d.%d", hh, mm, ss, deci_secs);
      sprintf (secs, "%d.%d", ss, deci_secs);
    }else {				/* Must be secs */
      if (sscanf (text, "%f", &f_ss) != 1) return NULL;
      if (f_ss <= 0.1) return NULL;
      deci_secs = (int) (f_ss * 10 + 0.1);
      hh = deci_secs/36000; deci_secs = deci_secs - (36000 * hh);
      mm = deci_secs/600;   deci_secs = deci_secs - (  600 * mm);
      ss = deci_secs/10;    deci_secs = deci_secs - (   10 * ss);
      sprintf (text, "%d:%02d:%02d.%d", hh, mm, ss, deci_secs);
      sprintf (secs, "%d.%d", (hh * 3600) + (mm * 60) + ss, deci_secs);
    }
    return text;
  }
/*
**---------------------------------------------------------------------------
**			TimeString	- set up time as a string.
*/
  void	 TimeString (
/*	 ==========
*/		    char    *dest,	/* Destination string */
		    char    *prfx,	/* Prefix string */
		    char    *secs) {	/* The time in seconds */

    float   time = 0.0;
    int	    hh, mm, ss, ticks;

    sscanf (secs, "%f", &time);
    ticks = (int) (time * 10.0 + 0.001);
    ss = ticks/10; ticks = ticks - (ss * 10);
    mm = ss/60; ss = ss - (mm * 60);
    hh = mm/60; mm = mm - (hh * 60);
    if (hh > 99) {
        sprintf (dest, "%s%d:%02d:%02d.%01d", prfx, hh, mm, ss, ticks);
    }else {
        sprintf (dest, "%s%02d:%02d:%02d.%01d", prfx, hh, mm, ss, ticks);
    }
  }
/*
**---------------------------------------------------------------------------
**			HelpCB		- callback for help buttons
*/
  void	HelpCB (
/*	======
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    static Widget   my_hlp = NULL;
    char	    *button_name, text[60];
    XmString	    my_cmpStr, my_cmpStr1;

    if (my_hlp == NULL) {
      my_cmpStr = XmStringCreateLtoR ("H E L P ! !",
				XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdialogTitle, my_cmpStr); Nargs++;
      my_hlp = XmCreateMessageDialog (Top_level, "Help", Args, Nargs);
      XmStringFree (my_cmpStr);
      XtUnmanageChild (XmMessageBoxGetChild (my_hlp, XmDIALOG_OK_BUTTON));
      XtUnmanageChild (XmMessageBoxGetChild (my_hlp, XmDIALOG_HELP_BUTTON));
    }
    sprintf (text, "\"%s\" not yet available", XtName (w));
    my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtVaSetValues (my_hlp, XmNmessageString, my_cmpStr, NULL);
    XtManageChild (my_hlp);
    XmStringFree (my_cmpStr);
  }
/*

**---------------------------------------------------------------------------
**			SetStateInWindows - update State fields in Windows to
**					    match Cntr_state.state.
*/
  void	SetStateInWindows () {
/*	=================
*/
    enum    {GO = 1, STOP = 2, PAUSE = 4, CONT = 8, MODE = 16};

    XmString	    tmp_cmpStr, my_cmpStr;
    int		    i, sens_mask, hh, mm, ss;
    float	    thresh, thresh1, rate, rate1, f_tmp, f_tmp_max;
    int		    i_tmp, scale_val;
    int		    updt_cntr_mode, mill, thou, units;
    char	    *buff, *title, text[80], r_text[40], t_text[40];

    if (memcmp (&Cntr_state, &Old_Cntr_state, sizeof (Cntr_state)) == 0) return;

    if (Cntr_state.state != Old_Cntr_state.state) {
		/*
		** State has changed. Adjust sensitivity of buttons.
		*/
      switch (Cntr_state.state) {
        case OFFLINE:    sens_mask = 0;
		    buff = "Off-line";
		    break;
        case MS:    sens_mask =	(GO | MODE);
		    buff = "Stopped";
		    break;
        case PTS:   sens_mask = (STOP | PAUSE);
		    buff = "Active";
		    Cntr_state_mode = VMECNT__PRESET_TIME;
		    break;
        case PCS:   sens_mask = (STOP | PAUSE);
		    buff = "Active";
		    Cntr_state_mode = VMECNT__PRESET_COUNT;
		    break;
        case LRTS:  sens_mask = (STOP | PAUSE);
		    buff = "Rate low";
		    Cntr_state_mode = VMECNT__PRESET_TIME;
		    break;
        case LRCS:  sens_mask = (STOP | PAUSE);
		    buff = "Rate low";
		    Cntr_state_mode = VMECNT__PRESET_COUNT;
		    break;
        case PTSP:  sens_mask = (STOP | CONT);
		    buff = "Paused";
		    Cntr_state_mode = VMECNT__PRESET_TIME;
		    break;
        case PCSP:  sens_mask = (STOP | CONT);
		    buff = "Paused";
		    Cntr_state_mode = VMECNT__PRESET_COUNT;
		    break;
        case LRTSP: sens_mask = (STOP | CONT);
		    buff = "Rate low and Paused";
		    Cntr_state_mode = VMECNT__PRESET_TIME;
		    break;
        case LRCSP: sens_mask = (STOP | CONT);
		    buff = "Rate low and Paused";
		    Cntr_state_mode = VMECNT__PRESET_COUNT;
		    break;
        default:    sens_mask = 0;
		    buff = "Illegal";
      }
		/*
		** Desensitise.
		*/
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNsensitive, False); Nargs++;
      if ((sens_mask & GO)    == 0) XtSetValues (Go_button,    Args, Nargs);
      if ((sens_mask & STOP)  == 0) XtSetValues (Stop_button,  Args, Nargs);
      if ((sens_mask & PAUSE) == 0) XtSetValues (Pause_button, Args, Nargs);
      if ((sens_mask & CONT)  == 0) XtSetValues (Cont_button,  Args, Nargs);
      if ((sens_mask & MODE)  == 0) XtSetValues (Mode_cascade, Args, Nargs);
		/*
		** Sensitise.
		*/
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNsensitive, True); Nargs++;
      if ((sens_mask & GO)    != 0) XtSetValues (Go_button,    Args, Nargs);
      if ((sens_mask & STOP)  != 0) XtSetValues (Stop_button,  Args, Nargs);
      if ((sens_mask & PAUSE) != 0) XtSetValues (Pause_button, Args, Nargs);
      if ((sens_mask & CONT)  != 0) XtSetValues (Cont_button,  Args, Nargs);
      if ((sens_mask & MODE)  != 0) XtSetValues (Mode_cascade, Args, Nargs);
		/*
		** Adjust Status Label Text to match state.
		*/
      tmp_cmpStr = XmStringCreateLtoR (buff, XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
      XtSetValues (Lbl_counter_state, Args, Nargs);
      XmStringFree (tmp_cmpStr);
    }
    if (strcmp (Cntr_state.timer, Old_Cntr_state.timer) != 0) {
      sscanf (Cntr_state.timer, "%f", &f_tmp);
      if (f_tmp < 10.0) {
        sprintf (text, "%.3f sec", f_tmp);
      } else if (f_tmp < 60.0) {
        sprintf (text, "%.2f sec", f_tmp);
      } else {
        ss = (int) f_tmp;
        mm = ss/60; ss = ss - (mm * 60);
        hh = mm/60; mm = mm - (hh * 60);
        sprintf (text, "%d:%02d:%02d", hh, mm, ss);
      }
      tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
      XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
      XtSetValues (Lbl_timer, Args, 1);
      XmStringFree (tmp_cmpStr);
      if (Cntr_state_mode == VMECNT__PRESET_TIME) {
        sscanf (Cntr_state_timer_preset, "%f", &f_tmp_max);
	scale_val = (int) ((f_tmp/f_tmp_max) * SCALE_RUN_MAX);
	if (scale_val > SCALE_RUN_MAX) scale_val = SCALE_RUN_MAX;
	XmScaleSetValue (Scale_run_progress, scale_val);
      }
    }
    for (i = 0; i < 8; i++) {
      if (Cntr_state.cntrs[i] != Old_Cntr_state.cntrs[i]) {
	sprintf (text, "%d", Cntr_state.cntrs[i]);
	tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
	XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
	switch (i) {
	 case 0: XtSetValues (Lbl_mon, Args, 1); break;
	 case 1: XtSetValues (Lbl_det, Args, 1); break;
	 case 2: XtSetValues (Lbl_c3,  Args, 1); break;
	 case 3: XtSetValues (Lbl_c4,  Args, 1); break;
	 case 4: XtSetValues (Lbl_c5,  Args, 1); break;
	 case 5: XtSetValues (Lbl_c6,  Args, 1); break;
	 case 6: XtSetValues (Lbl_c7,  Args, 1); break;
	 case 7: XtSetValues (Lbl_c8,  Args, 1);
	}
	XmStringFree (tmp_cmpStr);
	if ((Cntr_state_mode == VMECNT__PRESET_COUNT) &&
	    (i == 0)) {
	  f_tmp = ((float) Cntr_state.cntrs[0])/((float) Cntr_state_mon_preset);
	  scale_val = (int) (f_tmp * SCALE_RUN_MAX);
	  if (scale_val > SCALE_RUN_MAX) scale_val = SCALE_RUN_MAX;
	  XmScaleSetValue (Scale_run_progress, scale_val);
	}
      }
    }

    for (i = 0; i < 8; i++) {
      if (strcmp (Cntr_state.rates[i], Old_Cntr_state.rates[i]) != 0) {
	sscanf (Cntr_state.rates[i], "%f", &f_tmp);
        if (f_tmp > 999.0) {
          sprintf (text, "%.1f kHz", f_tmp/1000.0);
        }else if (f_tmp > 0.01) {
          sprintf (text, "%.1f Hz", f_tmp);
	}else {
          sprintf (text, "%.0f Hz", f_tmp);
        }
	tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
	XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
	switch (i) {
	 case 0: XtSetValues (Lbl_mon_rate, Args, 1); break;
	 case 1: XtSetValues (Lbl_det_rate, Args, 1); break;
	 case 2: XtSetValues (Lbl_c3_rate,  Args, 1); break;
	 case 3: XtSetValues (Lbl_c4_rate,  Args, 1); break;
	 case 4: XtSetValues (Lbl_c5_rate,  Args, 1); break;
	 case 5: XtSetValues (Lbl_c6_rate,  Args, 1); break;
	 case 6: XtSetValues (Lbl_c7_rate,  Args, 1); break;
	 case 7: XtSetValues (Lbl_c8_rate,  Args, 1);
	}
	XmStringFree (tmp_cmpStr);
      }
    }

    if (Cntr_state.analog_indx != Old_Cntr_state.analog_indx) {
      Nargs = 0;	    /* Prepare arguments to undo reverse-video */
      XtSetArg (Args[Nargs], XmNforeground, Dflt_foreground); Nargs++;
      XtSetArg (Args[Nargs], XmNbackground, Dflt_background); Nargs++;
      switch (Old_Cntr_state.analog_indx) {	/* Then do it */
       case 0: XtSetValues (Lbl_mon_rate, Args, Nargs); break;
       case 1: XtSetValues (Lbl_det_rate, Args, Nargs); break;
       case 2: XtSetValues (Lbl_c3_rate,  Args, Nargs); break;
       case 3: XtSetValues (Lbl_c4_rate,  Args, Nargs); break;
       case 4: XtSetValues (Lbl_c5_rate,  Args, Nargs); break;
       case 5: XtSetValues (Lbl_c6_rate,  Args, Nargs); break;
       case 6: XtSetValues (Lbl_c7_rate,  Args, Nargs); break;
       case 7: XtSetValues (Lbl_c8_rate,  Args, Nargs);
      }
      Nargs = 0;	    /* Then prepare arguments to do reverse-video */
      XtSetArg (Args[Nargs], XmNforeground, Dflt_background); Nargs++;
      XtSetArg (Args[Nargs], XmNbackground, Dflt_foreground); Nargs++;
      switch (Cntr_state.analog_indx) {	/* Then do it */
       case 0: XtSetValues (Lbl_mon_rate, Args, Nargs); break;
       case 1: XtSetValues (Lbl_det_rate, Args, Nargs); break;
       case 2: XtSetValues (Lbl_c3_rate,  Args, Nargs); break;
       case 3: XtSetValues (Lbl_c4_rate,  Args, Nargs); break;
       case 4: XtSetValues (Lbl_c5_rate,  Args, Nargs); break;
       case 5: XtSetValues (Lbl_c6_rate,  Args, Nargs); break;
       case 6: XtSetValues (Lbl_c7_rate,  Args, Nargs); break;
       case 7: XtSetValues (Lbl_c8_rate,  Args, Nargs);
      }
    }

    switch (Cntr_state.thresh_indx) {
     case -1:	title = "Threshold Check disabled";	break;
     case  0:	title = "\"Monitor\" Threshold/Rate";	break;
     case  1:	title = "\"Detector\" Threshold/Rate";	break;
     case  2:	title = "\"C3\" Threshold/Rate";	break;
     case  3:	title = "\"C4\" Threshold/Rate";	break;
     case  4:	title = "\"C5\" Threshold/Rate";	break;
     case  5:	title = "\"C6\" Threshold/Rate";	break;
     case  6:	title = "\"C7\" Threshold/Rate";	break;
     case  7:	title = "\"C8\" Threshold/Rate";
    }
    if (Cntr_state.thresh_indx < 0) {
      thresh = rate = 0.0;
    }else {
      sscanf (Cntr_state.threshes[Cntr_state.thresh_indx], "%f", &thresh);
      sscanf (Cntr_state.rates[Cntr_state.thresh_indx],    "%f", &rate);
    }

    if (Cntr_state.thresh_indx != Old_Cntr_state.thresh_indx) {
      tmp_cmpStr = XmStringCreateLtoR (title, XmSTRING_DEFAULT_CHARSET);
      XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
      XtSetValues (Lbl_thresh_scales, Args, 1);
/*
**      if (Cntr_state.thresh_indx < 0) {
**	XtSetArg (Args[0], XmNsensitive, False);
**      }else {
**	XtSetArg (Args[0], XmNsensitive, True);
**      }
**      XtSetValues (Scale_thresh, Args, 1);
*/
      XmStringFree (tmp_cmpStr);
      Thresh_cntr_thresh = thresh + 0.1;    /* Ensure thresh is updated */
      Thresh_cntr_rate = rate + 0.1;	    /* Ensure cntr rate is updated */
    }

    if (Scale_is_khz) {
      thresh1 = thresh/100.0;
      rate1   = rate/100.0;
    }else {
      thresh1 = thresh;
      rate1   = rate;
    }
    if (thresh > 999.0) {
      sprintf (t_text, "Thresh = %.1f kHz", thresh/1000.0);
    }else {
      sprintf (t_text, "Thresh = %.1f Hz", thresh);
    }
    if (rate > 999.0) {
      sprintf (r_text, "Rate   = %.1f kHz", rate/1000.0);
    }else {
      sprintf (r_text, "Rate   = %.1f Hz", rate);
    }

    if (thresh != Thresh_cntr_thresh) {    
      if ((int) thresh1 > Scale_max) {
        XmScaleSetValue (Scale_thresh, Scale_max);
      }else {
        XmScaleSetValue (Scale_thresh, (int) thresh1);
      }
      tmp_cmpStr = XmStringCreateLtoR (t_text, XmSTRING_DEFAULT_CHARSET);
      XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
      XtSetValues (Lbl_thr_scale_val, Args, 1);
      XmStringFree (tmp_cmpStr);

      Thresh_cntr_thresh = thresh;
    }
    if (rate != Thresh_cntr_rate) {
      if ((int) rate1 > Scale_max) {
        XmScaleSetValue (Scale_rate, Scale_max);
      }else {
        XmScaleSetValue (Scale_rate, (int) rate1);
      }
      tmp_cmpStr = XmStringCreateLtoR (r_text, XmSTRING_DEFAULT_CHARSET);
      XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
      XtSetValues (Lbl_rate_scale_val, Args, 1);
      XmStringFree (tmp_cmpStr);

      Thresh_cntr_rate = rate;
    }

    updt_cntr_mode = False;
    if (Cntr_state_mode != Cntr_state_mode_in_window) updt_cntr_mode = True;

    if ((Cntr_state_mode == VMECNT__PRESET_COUNT) &&
	(Cntr_state.mon_preset != Cntr_state_mon_preset_in_window))
	    updt_cntr_mode = True;

    if ((Cntr_state_mode == VMECNT__PRESET_TIME) &&
	(strcmp (Cntr_state.timer_preset,
		 Cntr_state_timer_preset_in_window) != 0))
		    updt_cntr_mode = True;

    if (updt_cntr_mode) {
      if (Cntr_state_mode == VMECNT__PRESET_COUNT) {
	units = Cntr_state.mon_preset;
	thou  = units/1000; units = units - (1000 * thou);
	mill  = thou/1000;  thou  = thou  - (1000 * mill);
	if (mill > 0) {
	  sprintf (text, "Preset Count Mode: %d'%03d'%03d", mill, thou, units);
	}else if (thou > 0) {
	  sprintf (text, "Preset Count Mode: %d'%03d", thou, units);
	}else {
	  sprintf (text, "Preset Count Mode: %d", units);
	}
	Cntr_state_mon_preset_in_window = Cntr_state.mon_preset;
      }else {
	TimeString (text, "Preset Time Mode: ", Cntr_state.timer_preset);
	strcpy (Cntr_state_timer_preset, Cntr_state.timer_preset);
	strcpy (Cntr_state_timer_preset_in_window, Cntr_state.timer_preset);
	strcpy (Cntr_state_timer_preset_in_window, Cntr_state.timer_preset);
      }
      my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
      XtSetArg (Args[0], XmNlabelString, my_cmpStr);
      XtSetValues (Lbl_counter_mode, Args, 1);
      XmStringFree (my_cmpStr);
      Cntr_state_mode_in_window = Cntr_state_mode;
    }

    memcpy (&Old_Cntr_state, &Cntr_state, sizeof (Cntr_state));
  }
/*
**---------------------------------------------------------------------------
**                      setupTime       - get the current time in ASCII
*/
  char  *setupTime (char *buff, int buff_size) {
/*      ==========
*/
    time_t          time_now;

    time_now = time (NULL);     /* Get the current time */
    StrJoin (buff, buff_size,   /* Convert to ASCII and copy to buffer */
                asctime (localtime (&time_now)), "");
    strtok (buff, "\n");        /* Remove the trailing "\n" character. */
    return buff;
  }
/*
**---------------------------------------------------------------------------
**			GetCounterStatus	- get counter status from srvr
*/
  int	GetCounterStatus (
/*	================
*/			int type) {	/* VMECNT__FULL  or 
					** VMECNT__INCR  or
					** VMECNT__SHORT
					*/
    int			status, size, max_size, errcode, my_errno, vaxc_errno;
    float		my_flt;
    char		text[20], buff[80], *err_pntr;
    char		*cmnd;
    char		*fmt;
    char		*pntr;
    char		*rply;

    static char *cmnd_list[] = {"rr 1\r", "rr 2\r", "rr 3\r", "rr 4\r",
				"rr 5\r", "rr 6\r", "rr 7\r", "rr 8\r",

				"di 1\r", "di 2\r", "di 3\r", "di 4\r",
				"di 5\r", "di 6\r", "di 7\r", "di 8\r",

				"dt\r", "da\r", "dr\r",

				"dl 1\r", "dl 2\r", "dl 3\r", "dl 4\r",
				"dl 5\r", "dl 6\r", "dl 7\r", "dl 8\r",

				"mp\r", "tp\r", NULL};

    static char *cmnd_fmt[]  = {"%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s",
				"%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s",
				"%s", "%d", "%d",
				"%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s",
				"%d", "%s"};
    static char *cmnd_pntr[]  = {	Cntr_state.rates[0],
					Cntr_state.rates[1],
					Cntr_state.rates[2],
					Cntr_state.rates[3],
					Cntr_state.rates[4],
					Cntr_state.rates[5],
					Cntr_state.rates[6],
					Cntr_state.rates[7],
					Cntr_state.thresh_integ_time[0],
					Cntr_state.thresh_integ_time[1],
					Cntr_state.thresh_integ_time[2],
					Cntr_state.thresh_integ_time[3],
					Cntr_state.thresh_integ_time[4],
					Cntr_state.thresh_integ_time[5],
					Cntr_state.thresh_integ_time[6],
					Cntr_state.thresh_integ_time[7],
					Cntr_state.rate_integ_time,
			      (char *) &Cntr_state.analog_indx,
			      (char *) &Cntr_state.thresh_indx,
					Cntr_state.threshes[0],
					Cntr_state.threshes[1],
					Cntr_state.threshes[2],
					Cntr_state.threshes[3],
					Cntr_state.threshes[4],
					Cntr_state.threshes[5],
					Cntr_state.threshes[6],
					Cntr_state.threshes[7],
			      (char *) &Cntr_state.mon_preset,
					Cntr_state.timer_preset};
    static int  cmnd_indx = 0;
		    /*
		    ** Send an appropriate list of commands
		    ** to the server and get a response.
		    */
    switch (type) {
     case VMECNT__SHORT:	/* Short (quick) status.
				*/
      status = AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			"rs\r", "ra\r", NULL);
      break;
     case VMECNT__INCR:		/* Incremental status - this slowly updates
				**  the status information of the counter.
				*/
      cmnd = cmnd_list[cmnd_indx];
      fmt  = cmnd_fmt[cmnd_indx];
      pntr = cmnd_pntr[cmnd_indx];
      status = AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			"rs\r", "ra\r", cmnd, NULL);
      cmnd_indx++;
      if (cmnd_list[cmnd_indx] == NULL) cmnd_indx = 0;
      break;
     case VMECNT__FULL:		/* Full status.
				*/
      status = AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			"rs\r", "ra\r",
			cmnd_list[ 0], cmnd_list[ 1], cmnd_list[ 2],
			cmnd_list[ 3], cmnd_list[ 4], cmnd_list[ 5],
			cmnd_list[ 6], cmnd_list[ 7], cmnd_list[ 8],
			cmnd_list[ 9], cmnd_list[10], cmnd_list[11],
			cmnd_list[12], cmnd_list[13], cmnd_list[14],
			cmnd_list[15], cmnd_list[16], cmnd_list[17],
			cmnd_list[18], cmnd_list[19], cmnd_list[20],
			cmnd_list[21], cmnd_list[22], cmnd_list[23],
			cmnd_list[24], cmnd_list[25], cmnd_list[26],
			cmnd_list[27], cmnd_list[28], cmnd_list[29],
			NULL);
    }
	    /*--------------------------------------------------------------
	    ** Now analyse the response. All responses start with the same
	    ** 2 commands so do these in common.
	    */
    if (status) {
      rply = AsynSrv_GetReply (
		    &InfoHndl->asyn_info, &InfoHndl->from_host, NULL);
      if (rply != NULL) {
        if (sscanf (rply, "%d", &Cntr_state.state) != 1) {
	  if (strncmp (rply, "?OF", 3) != 0) {
	    printf ("%s\n", setupTime (buff, sizeof (buff)));
	    printf ("GetCounterStatus -- bad response to RS command.\n");
	    printf ("         Response = \"%s\"\n", rply);
	  }
	  Cntr_state.state = (AppData.persist) ? UNKNOWN : OFFLINE;
	  return FALSE;
	}
	if ((Cntr_state.state & PTS) != 0) Cntr_state_mode=VMECNT__PRESET_TIME;
	if ((Cntr_state.state & PCS) != 0) Cntr_state_mode=VMECNT__PRESET_COUNT;

        rply = AsynSrv_GetReply (
		    &InfoHndl->asyn_info, &InfoHndl->from_host, rply);
	if (rply != NULL) {
	  if ((sscanf (rply, "%s %d %d %d %d %d %d %d %d",
		Cntr_state.timer,
		&Cntr_state.cntrs[0], &Cntr_state.cntrs[1],
		&Cntr_state.cntrs[2], &Cntr_state.cntrs[3],
		&Cntr_state.cntrs[4], &Cntr_state.cntrs[5],
		&Cntr_state.cntrs[6], &Cntr_state.cntrs[7]) != 9) ||
              (sscanf (rply, "%f %d", &my_flt, &status) != 2)) {
	    if (strncmp (rply, "?OF", 3) != 0) {
	      printf ("%s\n", setupTime (buff, sizeof (buff)));
	      printf ("GetCounterStatus -- bad response to RA command.\n");
	      printf ("         Response = \"%s\"\n", rply);
	    }
	    Cntr_state.state = (AppData.persist) ? UNKNOWN : OFFLINE;
	    return FALSE;
	  }
	}else {
          printf ("%s\n", setupTime (buff, sizeof (buff)));
	  printf ("GetCounterStatus -- Bad reply packet format!\n");
	  Cntr_state.state = (AppData.persist) ? UNKNOWN : OFFLINE;
	  return FALSE;
	}
      }else {
        printf ("%s\n", setupTime (buff, sizeof (buff)));
        printf ("GetCounterStatus -- Bad reply packet format!\n");
	Cntr_state.state = (AppData.persist) ? UNKNOWN : OFFLINE;
        return FALSE;
      }
      switch (type) {		/* Now switch to handle rest of reply */
       case VMECNT__SHORT:	/* Short status - nothing more to do */
	break;
       case VMECNT__INCR:	/* Incremental status - just one reply to
				** analyse */
        rply = AsynSrv_GetReply (
		    &InfoHndl->asyn_info, &InfoHndl->from_host, rply);
	if (rply != NULL) {
	  if ((sscanf (rply, fmt, pntr) != 1) ||
	      (sscanf (rply, "%f", &my_flt) != 1)) {
	    if (strncmp (rply, "?OF", 3) != 0) {
	      strcpy (text, cmnd);
	      text[strlen (cmnd) - 1] = '\0';	/* Remove trailing "\r" */
              printf ("%s\n", setupTime (buff, sizeof (buff)));
	      printf ("GetCounterStatus -- bad response to command.\n");
	      printf ("         Command  = \"%s\"\n", text);
	      printf ("         Response = \"%s\"\n", rply);
	    }
	    Cntr_state.state = (AppData.persist) ? UNKNOWN : OFFLINE;
	    return FALSE;
	  }else {
	    if (strncmp (cmnd, "da", 2) == 0) {
	      Cntr_state.analog_indx--;
	      if (Cntr_state.analog_indx < 0) Cntr_state.analog_indx = 0;
	      if (Cntr_state.analog_indx > 7) Cntr_state.analog_indx = 0;
	    }
	    if (strncmp (cmnd, "dr", 2) == 0) {
	      Cntr_state.thresh_indx--;
	      if (Cntr_state.thresh_indx < -1) Cntr_state.thresh_indx = -1;
	      if (Cntr_state.thresh_indx >  7) Cntr_state.thresh_indx = -1;
	    }
	  }
	}else {
          printf ("%s\n", setupTime (buff, sizeof (buff)));
	  printf ("GetCounterStatus -- Bad reply packet format!\n");
	  Cntr_state.state = (AppData.persist) ? UNKNOWN : OFFLINE;
	  return FALSE;
	}
	break;
       case VMECNT__FULL:	/* Full status - loop to analyse reply */
	for (cmnd_indx = 0; cmnd_list[cmnd_indx] != NULL; cmnd_indx++) {
	  cmnd = cmnd_list[cmnd_indx];
	  fmt  = cmnd_fmt[cmnd_indx];
	  pntr = cmnd_pntr[cmnd_indx];
	  rply = AsynSrv_GetReply (
		    &InfoHndl->asyn_info, &InfoHndl->from_host, rply);
	  if (rply != NULL) {
	    if ((sscanf (rply, fmt, pntr) != 1) ||
	        (sscanf (rply, "%f", &my_flt) != 1)) {
	      if (strncmp (rply, "?OF", 3) != 0) {
                strcpy (text, cmnd);
                text[strlen (cmnd) - 1] = '\0';	/* Remove trailing "\r" */
                printf ("%s\n", setupTime (buff, sizeof (buff)));
                printf ("GetCounterStatus -- bad response to command.\n");
                printf ("         Command  = \"%s\"\n", text);
                printf ("         Response = \"%s\"\n", rply);
              }
	      Cntr_state.state = (AppData.persist) ? UNKNOWN : OFFLINE;
              return FALSE;
	    }else if (strncmp (cmnd, "da", 2) == 0) {
	      Cntr_state.analog_indx--;
	      if (Cntr_state.analog_indx < 0) Cntr_state.analog_indx = 0;
	      if (Cntr_state.analog_indx > 7) Cntr_state.analog_indx = 0;
	    }else if (strncmp (cmnd, "dr", 2) == 0) {
	      Cntr_state.thresh_indx--;
	      if (Cntr_state.thresh_indx < -1) Cntr_state.thresh_indx = -1;
	      if (Cntr_state.thresh_indx >  7) Cntr_state.thresh_indx = -1;
	    }
	  }else {
            printf ("%s\n", setupTime (buff, sizeof (buff)));
	    printf ("GetCounterStatus -- Bad reply packet format!\n");
	    Cntr_state.state = (AppData.persist) ? UNKNOWN : OFFLINE;
	    return FALSE;
	  }
        }
	cmnd_indx = 0;
      }
    }else {
      printf ("%s\n", setupTime (buff, sizeof (buff)));
      printf ("GetCounterStatus:\n");
      printf ("       Bad status from AsynSrv_SendCmnds: %d\n", status);
      EL737_ErrInfo (&err_pntr, &errcode, &my_errno, &vaxc_errno);
      if (err_pntr != NULL) printf ("%s\n", err_pntr);
    }
    return TRUE;
  }
/*
**---------------------------------------------------------------------------
**			PutOnLine	- try to turn counter on-line.
*/
  int	PutOnLine () {
/*	=========
**		    Return value is True if counter is on-line.
*/
    int			    status;
    char		    text[32];
		    /*
		    ** Send commands to get the counter on-line. Use a
		    ** short time-out.
		    */
    EL737_Config (&Hndl, "msecTmo", 500, NULL);

    status = EL737_SendCmnd (&Hndl, "rmt 1\r", text, sizeof (text));

    status = EL737_SendCmnd (&Hndl, "rmt 1\r", text, sizeof (text));
    if ((!status) || (text[0] == '?')) goto offline;

    status = EL737_SendCmnd (&Hndl, "echo 2\r", text, sizeof (text));
    if ((!status) || (text[0] == '?')) goto offline;

    status = EL737_SendCmnd (&Hndl, "id\r", text, sizeof (text));
    if ((!status) || (strncmp (text, "EL737", 5) != 0)) goto offline;

    EL737_Config (&Hndl, "msecTmo", AppData.msec_tmo, NULL);
    return True;

offline:
    printf ("\007PutOnLine:\n"
		"      Device is not an EL737!\n");
    return False;
  }
/*
**---------------------------------------------------------------------------
**		PresetCntCB	- callback for setting preset count
*/
  void	PresetCntCB (
/*	===========
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    static Widget   my_err = NULL;
    char	    text[32], *token, *pntr;
    int		    limit = 0, len;
    int		    mill, thou, units;
    XmString			    my_cmpStr;
    XmSelectionBoxCallbackStruct   *my_call_data;
    XmStringContext		    ctxt;
    XmStringCharSet		    charset;
    XmStringDirection		    dir;
    Boolean			    sep;
	    /*
	    **	Do the work to find the result of the user's input
	    */
    my_call_data = (XmSelectionBoxCallbackStruct *) call_data;
    XmStringInitContext (&ctxt, my_call_data->value);
    XmStringGetNextSegment(ctxt, &token, &charset, &dir, &sep);
    XmStringFreeContext(ctxt);
    XtFree ((char *) dir);
    XtFree ((char *) sep);
    XtFree ((char *) charset);
	    /*
	    ** Carefully check the syntax. Only whitespace, digits, "," and "'"
	    ** are allowed. Simply squeeze out "," and "'", i.e. no check that
	    ** exactly 3 chars occur between them!!
	    */
    StrnTrim (text, token, sizeof (text) - 1);
    len = strlen (text);
    if (len <= 0) goto pc_error;
    if (strspn (text, "0123456789,\'") != len) goto pc_error;
    while ((pntr = strpbrk (text, ",\'")) != NULL) { /* Remove primes and */
      do {					      /*  commas */
        pntr[0] = pntr[1];
        pntr++;
      } while (pntr[0] != '\0');
    }
    if (sscanf (text, "%d", &limit) != 1) {
      goto pc_error;
    }else {
      if ((limit < 1) || (limit >= 2000e6)) {
        goto pc_error;
      }else {
        Cntr_state_mon_preset = limit;
      }
    }
    units = Cntr_state_mon_preset;
    thou  = units/1000; units = units - (1000 * thou);
    mill  = thou/1000;  thou  = thou  - (1000 * mill);
    if (mill > 0) {
      sprintf (text, "Preset Count Mode: %d'%03d'%03d", mill, thou, units);
    }else if (thou > 0) {
      sprintf (text, "Preset Count Mode: %d'%03d", thou, units);
    }else {
      sprintf (text, "Preset Count Mode: %d", units);
    }
    my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtSetArg (Args[0], XmNlabelString, my_cmpStr);
    XtSetValues (Lbl_counter_mode, Args, 1);
    XmStringFree (my_cmpStr);
    return;

  pc_error:
/*========
*/  if (my_err == 0) {
      my_cmpStr = XmStringCreateLtoR (
			"Illegal Value. Value must be an integer\n"
			"in the range 0 < Value < 2000e6",
			XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);
					Nargs++;
      XtSetArg (Args[Nargs], XmNmessageAlignment, XmALIGNMENT_CENTER); Nargs++;
      XtSetArg (Args[Nargs], XmNmessageString, my_cmpStr); Nargs++;
      my_err = XmCreateErrorDialog (Top_level, "Error", Args, Nargs);
      XmStringFree (my_cmpStr);
      XtUnmanageChild (XmMessageBoxGetChild (my_err, XmDIALOG_OK_BUTTON));
      XtUnmanageChild (XmMessageBoxGetChild (my_err, XmDIALOG_HELP_BUTTON));
    }
    XtManageChild (my_err);
    return;
  }
/*
**---------------------------------------------------------------------------
**		PresetTimeCB	- callback for setting preset time
*/
  void	PresetTimeCB (
/*	============
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    static Widget   my_err = NULL;
    char	    *token;
    char	    *pntr, secs_text[50], text[50];

    XmString			    my_cmpStr;
    XmSelectionBoxCallbackStruct   *my_call_data;
    XmStringContext		    ctxt;
    XmStringCharSet		    charset;
    XmStringDirection		    dir;
    Boolean			    sep;
	    /*
	    **	Do the work to find the result of the user's input
	    */
    my_call_data = (XmSelectionBoxCallbackStruct *) call_data;
    XmStringInitContext (&ctxt, my_call_data->value);
    XmStringGetNextSegment(ctxt, &token, &charset, &dir, &sep);
    XmStringFreeContext(ctxt);
    XtFree ((char *) dir);
    XtFree ((char *) sep);
    XtFree ((char *) charset);
	    /*
	    ** Carefully check the syntax.
	    */
    pntr = CheckTimeSyntax (token, secs_text);
    if (pntr == NULL) goto pt_error;

    strcpy (Cntr_state_timer_preset, secs_text);
    strcpy (Cntr_state_timer_preset_in_window, secs_text);

    TimeString (text, "Preset Time Mode: ", Cntr_state_timer_preset);
    my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtSetArg (Args[0], XmNlabelString, my_cmpStr);
    XtSetValues (Lbl_counter_mode, Args, 1);
    XmStringFree (my_cmpStr);
    return;

  pt_error:
/*========
*/  if (my_err == NULL) {
      my_cmpStr = XmStringCreateLtoR (
			"Illegal Value. Value must be hh:mm:ss.t\n"
			"or a floating point value. The allowed\n"
			"range is 0.1 secs to 555 hours.",
			XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);
					Nargs++;
      XtSetArg (Args[Nargs], XmNmessageAlignment, XmALIGNMENT_CENTER); Nargs++;
      XtSetArg (Args[Nargs], XmNmessageString, my_cmpStr); Nargs++;
      my_err = XmCreateErrorDialog (Top_level, "Error", Args, Nargs);
      XmStringFree (my_cmpStr);
      XtUnmanageChild (XmMessageBoxGetChild (my_err, XmDIALOG_OK_BUTTON));
      XtUnmanageChild (XmMessageBoxGetChild (my_err, XmDIALOG_HELP_BUTTON));
    }
    XtManageChild (my_err);
    return;
  }
/*
**---------------------------------------------------------------------------
**		ThreshActiveCB	- callback for Threshold .../Active Counter ...
*/
  void	ThreshActiveCB (
/*	==============
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    char	*button_name, text[16];
    int		cntr, status;
    float	my_val;
	    /*
	    **	print message to prove we got activated
	    */
    button_name = XtName (w);
    if ((sscanf (button_name, "C%d", &cntr) == 1) &&
	(cntr > 0) &&
	(cntr <= 8)) {
      printf (" Setting \"%s\" as Threshold Counter.\n", button_name);
    }else {
      cntr = 0;
      printf (" Disabling threshold monitoring.\n");
    }

    status = EL737_EnableThresh (&Hndl, cntr);
    if (status) {
      status = EL737_GetThresh (&Hndl, &Cntr_state.thresh_indx, &my_val);
      if (status) {
	Cntr_state.thresh_indx--;
	if (Cntr_state.thresh_indx < -1) Cntr_state.thresh_indx = -1;
	if (Cntr_state.thresh_indx >  7) Cntr_state.thresh_indx = -1;
	Thresh_cntr_thresh = my_val;
      }
    }
    SetStateInWindows ();   /* Update window display. */
  }
/*
**---------------------------------------------------------------------------
**		ThreshThreshCB	- callback for Threshold slider change.
*/
  void	ThreshThreshCB (
/*	==============
*/	    Widget	    w,			/*  widget id	*/
	    XtPointer	    client_data,	/*  data from application   */
	    XtPointer	    call_data) {	/*  data from widget class  */

    XmScaleCallbackStruct  *my_call_data;
    char		    text[32], text1[32];
    int			    cntr, my_value, status;
    char		   *rply_ptr;
    float		    my_flt;
	    /*
	    **	Find new value of slider
	    */
    my_call_data = (XmScaleCallbackStruct *) call_data;
    my_value = my_call_data->value;
    if (Scale_is_khz) my_value = my_value * 100;

    cntr = Cntr_state.thresh_indx + 1;
    if ((cntr >= 1) && (cntr <= 8)) {
      my_flt = my_value;
      status = EL737_SetThresh (&Hndl, cntr, my_flt);
      if (status) {
	status = EL737_GetThresh (&Hndl, &cntr, &my_flt);
	if (status) Thresh_cntr_thresh = my_flt;
      }
      SetStateInWindows ();   /* Update window display. */
    }else {
      printf (" Threshold monitoring is disabled. Slider ignored.\n");
    }
  }
/*
**---------------------------------------------------------------------------
**		ThreshIntValCB	- callback for setting threshold integ time
*/
  void  ThreshIntValCB (
/*	==============
*/		Widget	    w,			/*  widget id	*/
		XtPointer   client_data,	/*  data from application   */
		XtPointer   call_data) {	/*  data from widget class  */

    int				    status, len, cntr;
    static Widget		    my_err = NULL;
    char			    text[32], *token, *pntr;
    char			    cmnd0[32], cmnd1[32];
    float			    f_time = 0.5;
    char			   *rply_ptr;
    XmString			    my_cmpStr;
    XmSelectionBoxCallbackStruct   *my_call_data;
    XmStringContext		    ctxt;
    XmStringCharSet		    charset;
    XmStringDirection		    dir;
    Boolean			    sep;
	    /*
	    **	Do the work to find the result of the user's input
	    */
    my_call_data = (XmSelectionBoxCallbackStruct *) call_data;
    XmStringInitContext (&ctxt, my_call_data->value);
    XmStringGetNextSegment(ctxt, &token, &charset, &dir, &sep);
    XmStringFreeContext(ctxt);
    XtFree ((char *) dir);
    XtFree ((char *) sep);
    XtFree ((char *) charset);
	    /*
	    ** Carefully check the syntax. Only whitespace, digits and "."
	    ** are allowed.
	    */
    StrnTrim (text, token, sizeof (text) - 1);
    len = strlen (text);
    if (len <= 0) goto it_error;
    if (strspn (text, "0123456789.") != len) goto it_error;
    if (sscanf (text, "%f", &f_time) != 1)   goto it_error;
    if ((f_time < 0.1) || (f_time >= 30.0))  goto it_error;
	    /*
	    ** Finally, check for at most 1 "." (%f is not clever enough)
	    */
    pntr = strchr (text, '.');
    if (pntr != NULL) {
      pntr++;
      pntr = strchr (pntr, '.');
    }
    if (pntr != NULL) goto it_error;
	    /*
	    ** Everything seems to be ship-shape.
	    */
    cntr = Cntr_state.thresh_indx + 1;
    sprintf (cmnd0, "di %d %.1f\r", cntr, f_time);
    sprintf (cmnd1, "di %d\r", cntr);
    status = AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			cmnd0, cmnd1, NULL);
    if (status) {
      rply_ptr = AsynSrv_GetReply (&InfoHndl->asyn_info,
			&InfoHndl->from_host, NULL);
      if (rply_ptr != NULL) rply_ptr = AsynSrv_GetReply (&InfoHndl->asyn_info,
					    &InfoHndl->from_host, rply_ptr);
      if ((rply_ptr != NULL) && (rply_ptr[0] != '?')) {
	strcpy (Cntr_state.thresh_integ_time[Cntr_state.thresh_indx],
		rply_ptr);
      }
    }
    return;

  it_error:
/*========
*/  if (my_err == 0) {
      my_cmpStr = XmStringCreateLtoR (
			"Illegal Value. Value must be \n"
			"in the range 0.1 < Value < 30.0",
			XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);
					Nargs++;
      XtSetArg (Args[Nargs], XmNmessageAlignment, XmALIGNMENT_CENTER); Nargs++;
      XtSetArg (Args[Nargs], XmNmessageString, my_cmpStr); Nargs++;
      my_err = XmCreateErrorDialog (Top_level, "Error", Args, Nargs);
      XmStringFree (my_cmpStr);
      XtUnmanageChild (XmMessageBoxGetChild (my_err, XmDIALOG_OK_BUTTON));
      XtUnmanageChild (XmMessageBoxGetChild (my_err, XmDIALOG_HELP_BUTTON));
    }
    XtManageChild (my_err);
    return;
  }
/*
**---------------------------------------------------------------------------
**		ThreshIntegCB  - callback for Threshold .../Integration Time ...
*/
  void	ThreshIntegCB (
/*	=============
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    static Widget   my_it = NULL;
    char	    *button_name, text[40];
    int		    mill, thou, units;
    int		    hh, mm, ss;
    int		    cnts = 0;
    float	    f_tmp = 0.0;
    XmString	    my_cmpStr, my_cmpStr1;

    if (my_it == NULL) {
      my_cmpStr = XmStringCreateLtoR ("Threshold Integration Time",
				XmSTRING_DEFAULT_CHARSET);
      my_cmpStr1 = XmStringCreateLtoR ("Specify time in seconds\n"
				       "0.1 < Integration Time < 30",
				XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdialogStyle,
				XmDIALOG_PRIMARY_APPLICATION_MODAL); Nargs++;
      XtSetArg (Args[Nargs], XmNdialogTitle, my_cmpStr); Nargs++;
      XtSetArg (Args[Nargs], XmNselectionLabelString, my_cmpStr1); Nargs++;
      my_it = XmCreatePromptDialog (Top_level, "Integ_Time", Args, Nargs);
      XmStringFree (my_cmpStr);
      XmStringFree (my_cmpStr1);
      XtAddCallback (my_it, XmNokCallback, ThreshIntValCB, NULL);
      XtUnmanageChild (XmSelectionBoxGetChild (my_it, XmDIALOG_HELP_BUTTON));
    }
    sscanf (Cntr_state.thresh_integ_time[Cntr_state.thresh_indx], "%f", &f_tmp);
    if (f_tmp <= 0.1 || f_tmp >= 30.0) f_tmp = 0.5;
    sprintf (text, "%.1f", f_tmp);
    my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtVaSetValues (my_it, XmNtextString, my_cmpStr, NULL);
    XmStringFree (my_cmpStr);
    XtManageChild (my_it);
  }
/*
**---------------------------------------------------------------------------
**			TimerCB		- callback for timer
*/
  void	TimerCB (
/*	=======
*/		XtPointer	client_data,	/*  data from application   */
		XtIntervalId	*id) {		/*  data from widget class  */

    GetCounterStatus (VMECNT__INCR);
    if (Cntr_state.state == OFFLINE) {
      Old_Cntr_state.state = UNKNOWN; /* Force screen update if gone off-line */
    }
    SetStateInWindows ();		    /* Update window display. */

    if ((Cntr_state.state != OFFLINE) && (AppData.msec_poll > 0)) {
      Timer_id = XtAppAddTimeOut (App_context, AppData.msec_poll,
					TimerCB, NULL);
    }else {
      Timer_id = 0;
    }
  }
/*
**---------------------------------------------------------------------------
**		PollRateValCB	- callback for setting polling rate
*/
  void	PollRateValCB (
/*	=============
*/		Widget	    w,		/*  widget id	*/
		XtPointer   client_data,	/*  data from application   */
		XtPointer   call_data) {	/*  data from widget class  */

    static Widget   my_err = NULL;
    char	    text[32], *token, *pntr;
    int		    timer = 1000, len;
    XmString			    my_cmpStr;
    XmSelectionBoxCallbackStruct   *my_call_data;
    XmStringContext		    ctxt;
    XmStringCharSet		    charset;
    XmStringDirection		    dir;
    Boolean			    sep;
	    /*
	    **	Do the work to find the result of the user's input
	    */
    my_call_data = (XmSelectionBoxCallbackStruct *) call_data;
    XmStringInitContext (&ctxt, my_call_data->value);
    XmStringGetNextSegment(ctxt, &token, &charset, &dir, &sep);
    XmStringFreeContext(ctxt);
    XtFree ((char *) dir);
    XtFree ((char *) sep);
    XtFree ((char *) charset);
	    /*
	    ** Carefully check the syntax. Only whitespace, digits, "," and "'"
	    ** are allowed. Simply squeeze out "," and "'", i.e. no check that
	    ** exactly 3 chars occur between them!!
	    */
    StrnTrim (text, token, sizeof (text) - 1);
    len = strlen (text);
    if (len <= 0) goto pt_error;
    if (strspn (text, "0123456789,\'") != len) goto pt_error;
    while ((pntr = strpbrk (text, ",\'")) != NULL) { /* Remove primes and */
      do {					      /*  commas */
        pntr[0] = pntr[1];
        pntr++;
      } while (pntr[0] != '\0');
    }
    if (sscanf (text, "%d", &timer) != 1) goto pt_error;
    if ((timer < 0) || (timer > 10000)) goto pt_error;
		/* 
		** Now enable the new polling interval.
		*/
    if (Timer_id != 0) XtRemoveTimeOut (Timer_id);
    Timer_id = 0;
    if (timer != 0) {
      Timer_id = XtAppAddTimeOut (App_context, AppData.msec_poll,
					TimerCB, NULL);
    }
    AppData.msec_poll = timer;
    return;

  pt_error:
/*========
*/  if (my_err == 0) {
      my_cmpStr = XmStringCreateLtoR (
			"Illegal Value. Value must be an integer\n"
			"in the range 0 < Value < 2000e6",
			XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdefaultButtonType, XmDIALOG_CANCEL_BUTTON);
					Nargs++;
      XtSetArg (Args[Nargs], XmNmessageAlignment, XmALIGNMENT_CENTER); Nargs++;
      XtSetArg (Args[Nargs], XmNmessageString, my_cmpStr); Nargs++;
      my_err = XmCreateErrorDialog (Top_level, "Error", Args, Nargs);
      XmStringFree (my_cmpStr);
      XtUnmanageChild (XmMessageBoxGetChild (my_err, XmDIALOG_OK_BUTTON));
      XtUnmanageChild (XmMessageBoxGetChild (my_err, XmDIALOG_HELP_BUTTON));
    }
    XtManageChild (my_err);
    return;
  }
/*
**---------------------------------------------------------------------------
**		PollRateCB  - callback for Basic Timing/Polling Rate ...
*/
  void	PollRateCB (
/*	==========
*/		Widget	    w,		/*  widget id	*/
		XtPointer   client_data,	/*  data from application   */
		XtPointer   call_data) {	/*  data from widget class  */

    static Widget   my_pr = NULL;
    char	    *button_name, text[40];
    int		    thou, units;
    XmString	    my_cmpStr, my_cmpStr1;

    if (my_pr == NULL) {
      my_cmpStr = XmStringCreateLtoR ("Polling Rate",
				XmSTRING_DEFAULT_CHARSET);
      my_cmpStr1 = XmStringCreateLtoR ("Specify polling delay in milliseconds\n"
				       "Specifying 0 disables Polling\n"
				       "0 <= delay <= 10'000",
				XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdialogStyle,
				XmDIALOG_PRIMARY_APPLICATION_MODAL); Nargs++;
      XtSetArg (Args[Nargs], XmNdialogTitle, my_cmpStr); Nargs++;
      XtSetArg (Args[Nargs], XmNselectionLabelString, my_cmpStr1); Nargs++;
      my_pr = XmCreatePromptDialog (Top_level, "Integ_Time", Args, Nargs);
      XmStringFree (my_cmpStr);
      XmStringFree (my_cmpStr1);
      XtAddCallback (my_pr, XmNokCallback, PollRateValCB, NULL);
      XtUnmanageChild (XmSelectionBoxGetChild (my_pr, XmDIALOG_HELP_BUTTON));
    }
    units = AppData.msec_poll;
    thou  = units/1000; units = units - (1000 * thou);
    if (thou > 0) {
      sprintf (text, "%d'%03d", thou, units);
    }else {
      sprintf (text, "%d", units);
    }
    my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtVaSetValues (my_pr, XmNtextString, my_cmpStr, NULL);
    XmStringFree (my_cmpStr);
    XtManageChild (my_pr);
  }
/*
**---------------------------------------------------------------------------
**		IntegTimeCB  - callback for "Basic Timing/Integration Time ..."
*/
  void	IntegTimeCB (
/*	=============
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    static Widget   my_it = NULL;
    char	    *button_name, text[60];
    XmString	    my_cmpStr, my_cmpStr1;

    if (my_it == NULL) {
      my_cmpStr = XmStringCreateLtoR ("Integration Time",
				XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdialogTitle, my_cmpStr); Nargs++;
      my_it = XmCreateMessageDialog (Top_level, "IntTime", Args, Nargs);
      XmStringFree (my_cmpStr);
      XtUnmanageChild (XmMessageBoxGetChild (my_it, XmDIALOG_OK_BUTTON));
      XtUnmanageChild (XmMessageBoxGetChild (my_it, XmDIALOG_HELP_BUTTON));
    }
    sprintf (text, "Integration times can not yet be set", XtName (w));
    my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtVaSetValues (my_it, XmNmessageString, my_cmpStr, NULL);
    XtManageChild (my_it);
    XmStringFree (my_cmpStr);
  }
/*
**---------------------------------------------------------------------------
**		AnalSelectCB	- callback for Analogue .../Cn
*/
  void	AnalSelectCB (
/*	============
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    char	*button_name, text[16];
    char	*rply_ptr;
    int		status;
	    /*
	    **	print message to prove we got activated
	    */
    button_name = XtName (w);
    printf (" Routing Counter \"%s\" to Analogue Display.\n", button_name);

    sprintf (text, "da %c\r", button_name[1]);

    status = AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			text, "da\r", NULL);
    if (status) {
      rply_ptr = AsynSrv_GetReply (&InfoHndl->asyn_info,
			&InfoHndl->from_host, NULL);
      rply_ptr = AsynSrv_GetReply (&InfoHndl->asyn_info,
			&InfoHndl->from_host, rply_ptr);
      if ((rply_ptr != NULL) && (rply_ptr[0] != '?')) {
	sscanf (rply_ptr, "%d", &Cntr_state.analog_indx);
	Cntr_state.analog_indx--;
      }
    }
    SetStateInWindows ();   /* Update window display. */
  }
/*
**---------------------------------------------------------------------------
**			RunCB		- callback for Command menu
*/
  void	RunCB (
/*	=====
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    int		status_type, i_tmp;
    float	f_tmp;
    char	*button_name, text[32];
    XmString	tmp_cmpStr;
	    /*
	    **	print message to prove we got activated
	    */
    button_name = XtName (w);

    status_type = VMECNT__SHORT;   /* Get short (and quick) status by default */
    if (strcmp (button_name, "Update") == 0) {
      status_type = VMECNT__FULL;
      if ((Cntr_state.state == OFFLINE) ||	/* Must we go on-line? */
	  (Cntr_state.state == UNKNOWN)) {
	tmp_cmpStr = XmStringCreateLtoR ("Trying ..",XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues (Lbl_counter_state, XmNlabelString, tmp_cmpStr, NULL);
        XmUpdateDisplay (Top_level);
	if (!PutOnLine ()) {
	  tmp_cmpStr = XmStringCreateLtoR ("Off-line",XmSTRING_DEFAULT_CHARSET);
	  XtVaSetValues (Lbl_counter_state, XmNlabelString, tmp_cmpStr, NULL);
          XmUpdateDisplay (Top_level);
	  XmStringFree (tmp_cmpStr);
	  return;
	}
	if ((Timer_id == 0) && (AppData.msec_poll > 0)) {  /*
							   ** Re-enable polling.
							   */
	  Timer_id = XtAppAddTimeOut (App_context, AppData.msec_poll,
					TimerCB, NULL);
	}
      }
      tmp_cmpStr = XmStringCreateLtoR ("Updating", XmSTRING_DEFAULT_CHARSET);
    }else if (strcmp (button_name, "Go") == 0) {
      tmp_cmpStr = XmStringCreateLtoR ("Starting", XmSTRING_DEFAULT_CHARSET);
      if (Cntr_state_mode == VMECNT__PRESET_TIME) {
	sprintf (text, "tp %s\r", Cntr_state_timer_preset);
	AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			text, NULL);
      }else {
	sprintf (text, "mp %d\r", Cntr_state_mon_preset);
	AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			text, NULL);
      }
      XmScaleSetValue (Scale_run_progress, 0);
    }else if (strcmp (button_name, "Stop") == 0) {
      tmp_cmpStr = XmStringCreateLtoR ("Stopping", XmSTRING_DEFAULT_CHARSET);
      AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			"stop\r", NULL);
    }else if (strcmp (button_name, "Pause") == 0) {
      tmp_cmpStr = XmStringCreateLtoR ("Pausing", XmSTRING_DEFAULT_CHARSET);
      AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			"ps\r", NULL);
    }else if (strcmp (button_name, "Cont") == 0) {
      tmp_cmpStr = XmStringCreateLtoR ("Continuing", XmSTRING_DEFAULT_CHARSET);
      AsynSrv_SendCmnds (&InfoHndl->asyn_info,
			&InfoHndl->to_host, &InfoHndl->from_host,
			"co\r", NULL);
    }else {
      printf ("\007Unknown push button \"%s\" selected.\n", button_name);
      return;
    }
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
    XtSetValues (Lbl_counter_state, Args, Nargs);
    XmStringFree (tmp_cmpStr);
    XmUpdateDisplay (Top_level);
    Old_Cntr_state.state = -1;

    GetCounterStatus (status_type);
    SetStateInWindows ();   /* Update window display. */
  }
/*
**---------------------------------------------------------------------------
**			ScaleCB		- callback for Command menu
*/
  void	ScaleCB (
/*	=======
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    char	*button_name, text[40];
    XmString	tmp_cmpStr;
    int		tmp_max, dec_points;
    int		tmp_thresh, tmp_rate;
	    /*
	    **	print message to prove we got activated
	    */
    button_name = XtName (w);

    tmp_max = (Scale_is_khz) ? (Scale_max * 100) : Scale_max;

    if (strcmp (button_name, "Scale_up") == 0) {
      if (tmp_max >= 10000000) {
	printf ("Push button \"%s\" ignored.\n", button_name);
      }else {
        tmp_max = tmp_max * 10;
      }
    }else {
      if (tmp_max <= 100) {
	printf ("Push button \"%s\" ignored.\n", button_name);
      }else {
        tmp_max = tmp_max/10;
      }
    }
    if (tmp_max > 1000) {
      Scale_is_khz = TRUE;
      Scale_max = tmp_max/100;
      dec_points = 1;
      tmp_thresh = Thresh_cntr_thresh/100.0;
      tmp_rate   = Thresh_cntr_rate/100.0;
    }else {
      Scale_is_khz = FALSE;
      Scale_max = tmp_max;
      dec_points = 0;
      tmp_thresh = Thresh_cntr_thresh;
      tmp_rate   = Thresh_cntr_rate;
    }
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNdecimalPoints, dec_points); Nargs++;
    XtSetArg (Args[Nargs], XmNmaximum, (int) Scale_max); Nargs++;
    XtSetArg (Args[Nargs], XmNvalue, 0); Nargs++;
    XtSetValues (Scale_thresh, Args, Nargs);
    XtSetValues (Scale_rate, Args, Nargs);

    if ((int) tmp_thresh > Scale_max) {
      XmScaleSetValue (Scale_thresh, Scale_max);
    }else {
      XmScaleSetValue (Scale_thresh, tmp_thresh); Nargs++;
    }

    if ((int) tmp_rate > Scale_max) {
      XmScaleSetValue (Scale_rate, Scale_max);
    }else {
      XmScaleSetValue (Scale_rate, tmp_rate);
    }

    if (Scale_is_khz) {
      sprintf (text, "<-- %d kHz", Scale_max/10);
    }else {
      sprintf (text, "<-- %d Hz", Scale_max);
    }
    tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
    XtSetValues (Lbl_rate_scale_max, Args, 1);
    XmStringFree (tmp_cmpStr);

    if (Thresh_cntr_thresh > 999.0) {
      sprintf (text, "Thresh = %.1f kHz", Thresh_cntr_thresh/1000.0);
    }else {
      sprintf (text, "Thresh = %.0f Hz", Thresh_cntr_thresh);
    }
    tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
    XtSetValues (Lbl_thr_scale_val, Args, 1);
    XmStringFree (tmp_cmpStr);


    if (Thresh_cntr_rate > 999.0) {
      sprintf (text, "Rate   = %.1f kHz", Thresh_cntr_rate/1000.0);
    }else {
      sprintf (text, "Rate   = %.1f Hz", Thresh_cntr_rate);
    }
    tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    XtSetArg (Args[0], XmNlabelString, tmp_cmpStr);
    XtSetValues (Lbl_rate_scale_val, Args, 1);
    XmStringFree (tmp_cmpStr);

    if (Scale_is_khz && (Scale_max >= 100000)) {
      XtSetArg (Args[0], XmNsensitive, False);
      XtUnmanageChild (Btn_scale_up);
    }else {
      XtSetArg (Args[0], XmNsensitive, True);
      XtManageChild (Btn_scale_up);
    }
    XtSetValues (Btn_scale_up, Args, 1);

    if (!Scale_is_khz && (Scale_max <= 100)) {
      XtSetArg (Args[0], XmNsensitive, False);
      XtUnmanageChild (Btn_scale_down);
    }else {
      XtSetArg (Args[0], XmNsensitive, True);
      XtManageChild (Btn_scale_down);
    }
    XtSetValues (Btn_scale_down, Args, 1);
  }
/*

**---------------------------------------------------------------------------
**			SetPresetModeCB	- callback routine
*/
  void	SetPresetModeCB (
/*	===============
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    static Widget   my_pc = NULL;
    static Widget   my_pt = NULL;
    char	    *button_name, text[40];
    int		    mill, thou, units;
    int		    hh, mm, ss;
    int		    cnts = 0;
    float	    f_tmp = 0.0;
    XmString	    my_cmpStr, my_cmpStr1;

    if (my_pc == NULL) {
      my_cmpStr = XmStringCreateLtoR ("Preset Count",
				XmSTRING_DEFAULT_CHARSET);
      my_cmpStr1 = XmStringCreateLtoR ("0 < Preset Count < 2000e6",
				XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdialogStyle,
				XmDIALOG_PRIMARY_APPLICATION_MODAL); Nargs++;
      XtSetArg (Args[Nargs], XmNdialogTitle, my_cmpStr); Nargs++;
      XtSetArg (Args[Nargs], XmNselectionLabelString, my_cmpStr1); Nargs++;
      my_pc = XmCreatePromptDialog (Top_level, "Preset_Count", Args, Nargs);
      XmStringFree (my_cmpStr);
      XmStringFree (my_cmpStr1);
      XtAddCallback (my_pc, XmNokCallback, PresetCntCB, NULL);
      XtUnmanageChild (XmSelectionBoxGetChild (my_pc, XmDIALOG_HELP_BUTTON));

      my_cmpStr = XmStringCreateLtoR ("Preset Time",
				XmSTRING_DEFAULT_CHARSET);
      my_cmpStr1 = XmStringCreateLtoR ("Seconds or hh:mm:ss.t\n"
				       "0.1 secs < Time < 555 hours",
				XmSTRING_DEFAULT_CHARSET);
      Nargs = 0;
      XtSetArg (Args[Nargs], XmNdialogStyle,
				XmDIALOG_PRIMARY_APPLICATION_MODAL); Nargs++;
      XtSetArg (Args[Nargs], XmNdialogTitle, my_cmpStr); Nargs++;
      XtSetArg (Args[Nargs], XmNselectionLabelString, my_cmpStr1); Nargs++;
      my_pt = XmCreatePromptDialog (Top_level, "Preset_Time", Args, Nargs);
      XmStringFree (my_cmpStr);
      XmStringFree (my_cmpStr1);
      XtAddCallback (my_pt, XmNokCallback, PresetTimeCB, NULL);
      XtUnmanageChild (XmSelectionBoxGetChild (my_pt, XmDIALOG_HELP_BUTTON));
    }
    button_name = XtName (w);
    if (strcmp (button_name, "Switch Mode") == 0) {
      if (Cntr_state_mode == VMECNT__PRESET_TIME) {
        Cntr_state_mode = VMECNT__PRESET_COUNT;
        units = Cntr_state_mon_preset;
        thou  = units/1000; units = units - (1000 * thou);
        mill  = thou/1000;  thou  = thou  - (1000 * mill);
        if (mill > 0) {
          sprintf (text, "Preset Count Mode: %d'%03d'%03d", mill, thou, units);
        }else if (thou > 0) {
          sprintf (text, "Preset Count Mode: %d'%03d", thou, units);
        }else {
          sprintf (text, "Preset Count Mode: %d", units);
        }
      }else {
        Cntr_state_mode = VMECNT__PRESET_TIME;
	TimeString (text, "Preset Time Mode: ", Cntr_state_timer_preset);
      }
      my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
      XtVaSetValues (Lbl_counter_mode, XmNlabelString, my_cmpStr, NULL);
      XmStringFree (my_cmpStr);
    }else if (strcmp (button_name, "Set Preset Count Limit ...") == 0) {
      units = Cntr_state_mon_preset;
      thou  = units/1000; units = units - (1000 * thou);
      mill  = thou/1000;  thou  = thou  - (1000 * mill);
      if (mill > 0) {
        sprintf (text, "%d'%03d'%03d", mill, thou, units);
      }else if (thou > 0) {
        sprintf (text, "%d'%03d", thou, units);
      }else {
        sprintf (text, "%d", units);
      }
      my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
      XtVaSetValues (my_pc, XmNtextString, my_cmpStr, NULL);
      XmStringFree (my_cmpStr);
      XtManageChild (my_pc);
    }else if (strcmp (button_name, "Set Preset Time Limit ...") == 0) {
      TimeString (text, "", Cntr_state_timer_preset);
      my_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
      XtVaSetValues (my_pt, XmNtextString, my_cmpStr, NULL);
      XmStringFree (my_cmpStr);
      XtManageChild (my_pt);
    }else {
	    /*
	    **	print message to prove we got activated
	    */
      printf ("\007Unrecognised push button \"%s\" ignored.\n", button_name);
      return;
    }
    switch (Cntr_state_mode) {	    /* Ensure everything is up-to-date. */
     case VMECNT__PRESET_COUNT:
      XtSetArg (Args[0], XmNsensitive, True);	/* Sensitise relevant buttons */
      XtSetValues (Pre_cnt_button,  Args, 1);

      XtSetArg (Args[0], XmNsensitive, False);	/* De-sensitise the others */
      XtSetValues (Pre_time_button, Args, 1);
      break;

     case VMECNT__PRESET_TIME:
      XtSetArg (Args[0], XmNsensitive, True);	/* Sensitise relevant buttons */
      XtSetValues (Pre_time_button, Args, 1);

      XtSetArg (Args[0], XmNsensitive, False);	/* De-sensitise the others */
      XtSetValues (Pre_cnt_button, Args, 1);
    }
  }
/*
**---------------------------------------------------------------------------
**			AddMenuItem		- add item into menu
*/
  Widget AddMenuItem (
/*	 ===========
*/		Widget		parent,		/* The parent menu	    */
		char		*name,		/* Name of menu item	    */
		char		accelerator,	/* Accelerator character    */
		int		menu_type,	/* Menu type		    */
		Widget		casc_pane,    /* Pane to link to button ..
					      ** .. (menu_type = CASCADE only */
		XtCallbackProc	callback) {	/* Callback procedure	    */

    Widget	my_menu_item;

    Nargs = 0;
    if (accelerator != 0)
      XtSetArg (Args[Nargs], XmNmnemonic, accelerator);  Nargs++;
    XtSetArg (Args[Nargs], XmNnavigationType, XmTAB_GROUP);  Nargs++;

    switch (menu_type) {
      case CASCADE:
	XtSetArg (Args[Nargs], XmNsubMenuId, casc_pane);  Nargs++;
        my_menu_item = XmCreateCascadeButton (parent, name, Args, Nargs);
        break;
      case PULL_DOWN:
	my_menu_item = XmCreatePushButton (parent, name, Args, Nargs);
        break;
      case SEPARATOR:
	my_menu_item = XmCreateSeparator (parent, NULL, Args, Nargs);
        break;
      default:
        printf ("\007Illegal menu_type in call to AddMenuItem\n");
    }
    XtManageChild (my_menu_item);

    if (callback != NULL)
      XtAddCallback (my_menu_item, XmNactivateCallback, callback, NULL);

    return my_menu_item;
  }
/*
**---------------------------------------------------------------------------
**			MakeLabel		- make a simple label
*/
  Widget MakeLabel (
/*	 =========
*/		Widget		w,	    /*  widget id of parent of label */
		char		*text,	    /*  The text for the label */
		unsigned char	align) {    /*  The alignment for the label */

    Widget	my_label;
    XmString	my_compString;

    my_compString = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNlabelString, my_compString); Nargs++;
    XtSetArg (Args[Nargs], XmNentryAlignment, align); Nargs++;
    XtSetArg (Args[Nargs], XmNrecomputeSize, False); Nargs++;
    my_label = XmCreateLabel (w, NULL, Args, Nargs);
    XtManageChild (my_label);
    XmStringFree (my_compString);

    return my_label;
  }
/*
**---------------------------------------------------------------------------
**			QuitCB		- callback for quit button
*/
  void	QuitCB (
/*	======
*/		Widget	    w,		/*  widget id	*/
		XtPointer    client_data,	/*  data from application   */
		XtPointer    call_data) {	/*  data from widget class  */

    AsynSrv_Close (&InfoHndl->asyn_info, False);    /* Close the connection */
    exit (EXIT_SUCCESS);	    /* Terminate the application. */
  }
/*
**---------------------------------------------------------------------------
**			CreateMenuBar - Create menu bar for main window.
*/
  Widget CreateMenuBar (Widget window) {
/* 	 =============
*/
    Widget my_menu_bar;		/*  MenuBar		*/

    Widget file_menu_pane;	/*  File    MenuPane	*/
    Widget cmnd_menu_pane;	/*  Command MenuPane	*/
    Widget setup_menu_pane;	/*  Setup MenuPane	*/
    Widget help_menu_pane;	/*  Help  MenuPane	*/
    Widget mode_menu_pane;	/*  Mode  MenuPane	*/
    Widget thr_menu_pane;	/*  Threshold MenuPane	*/
    Widget anal_menu_pane;	/*  Analogue MenuPane	*/
    Widget time_menu_pane;	/*  Basic Timing MenuPane */
    Widget thr_cntr_menu_pane;	/*  Threshold Counter MenuPane	*/

    Widget my_button;
	    /*-------------------------------------------------------------
	    **	Create MenuBar in MainWindow.
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNadjustLast, True);  Nargs++;
    my_menu_bar = XmCreateMenuBar (window, "menu_bar", Args, Nargs); 
    XtManageChild (my_menu_bar);
		/*---------------------------------------------------------
		**    Create panes for the Menu Bar Pulldown Menus.
		*/
    Nargs = 0;
    file_menu_pane  = XmCreatePulldownMenu (my_menu_bar, "File_Menu",
								Args, Nargs);
    setup_menu_pane = XmCreatePulldownMenu (my_menu_bar, "Setup_Menu",
								Args, Nargs);
    help_menu_pane  = XmCreatePulldownMenu (my_menu_bar, "Help_Menu",
								Args, Nargs);

    mode_menu_pane  = XmCreatePulldownMenu (setup_menu_pane, "Mode_Menu",
								Args, Nargs);
    thr_menu_pane   = XmCreatePulldownMenu (setup_menu_pane, "Thresh_Menu",
						    Args, Nargs);
    anal_menu_pane   = XmCreatePulldownMenu (setup_menu_pane, "Analog_Menu",
						    Args, Nargs);
    time_menu_pane  = XmCreatePulldownMenu (setup_menu_pane, "Timing_Menu",
						    Args, Nargs);
    thr_cntr_menu_pane = XmCreatePulldownMenu (thr_menu_pane, "Thr_Cntr_Menu",
						    Args, Nargs);
		/*-------------------------------------------------------------
		**	    Create buttons on menu bar and specify afterwards
		**	    which one is the Help item.
		*/
    File_cascade  = AddMenuItem (my_menu_bar, "File",  'F',
						CASCADE, file_menu_pane, NULL);
    Setup_cascade = AddMenuItem (my_menu_bar, "Setup", 'S',
						CASCADE, setup_menu_pane, NULL);
    Help_cascade  = AddMenuItem (my_menu_bar, "Help",  'H',
						CASCADE, help_menu_pane, NULL);

    XtSetArg (Args[0], XmNmenuHelpWidget, Help_cascade);
    XtSetValues (my_menu_bar, Args, 1);
		/*---------------------------------------------------------
		**    Put items into the menu bar menu panes. Start with File.
		*/
    AddMenuItem (file_menu_pane,  "Quit/Finish", 'F', PULL_DOWN, NULL, QuitCB);
		/*---------------------------------------------------------
		**    Now do Setup.
		*/
    Mode_cascade = AddMenuItem (setup_menu_pane, "Mode",      'M',
						CASCADE, mode_menu_pane, NULL);
    AddMenuItem (setup_menu_pane, "Threshold", 'T',
						CASCADE, thr_menu_pane, NULL);
    AddMenuItem (setup_menu_pane, "Analogue", 'A',
						CASCADE, anal_menu_pane, NULL);
    AddMenuItem (setup_menu_pane, "Basic Timing", 'B',
						CASCADE, time_menu_pane, NULL);
		/*---------------------------------------------------------
		**    Now do Help.
		*/
    AddMenuItem (help_menu_pane, "Context-sensitive Help", 'C',
						PULL_DOWN, NULL, HelpCB);
    AddMenuItem (help_menu_pane, NULL, '\0', SEPARATOR, NULL, NULL);
    AddMenuItem (help_menu_pane, "Overview", 'O',
						PULL_DOWN, NULL, HelpCB);
		/*---------------------------------------------------------
		**    Now do Mode.
		*/
    Swch_mode_button = AddMenuItem (mode_menu_pane, "Switch Mode",
				    'M',  PULL_DOWN, NULL, SetPresetModeCB);
		       AddMenuItem (mode_menu_pane, NULL,
				    '\0', SEPARATOR, NULL, NULL);
    Pre_cnt_button  = AddMenuItem (mode_menu_pane, "Set Preset Count Limit ...",
				    'C', PULL_DOWN, NULL, SetPresetModeCB);
    Pre_time_button  = AddMenuItem (mode_menu_pane, "Set Preset Time Limit ...",
				    'T', PULL_DOWN, NULL, SetPresetModeCB);

    XtSetArg (Args[0], XmNsensitive, False); Nargs++;	/* Desensitise */
    switch (Cntr_state_mode) {
     case VMECNT__PRESET_COUNT:
      XtSetValues (Pre_time_button, Args, 1);
      break;
     case VMECNT__PRESET_TIME:
      XtSetValues (Pre_cnt_button,  Args, 1);
      break;
    }
		/*---------------------------------------------------------
		**    Now do Threshold.
		*/
    AddMenuItem (thr_menu_pane, "Active counter", 'A',
					CASCADE, thr_cntr_menu_pane, NULL);
    AddMenuItem (thr_menu_pane, "Integration Time ...",  'I',
					PULL_DOWN, NULL, ThreshIntegCB);
		/*---------------------------------------------------------
		**    Now do "Active counter" menu pane.
		*/
    AddMenuItem (thr_cntr_menu_pane, "Disable Threshold Monitoring", '1',
					PULL_DOWN, NULL, ThreshActiveCB);
    AddMenuItem (thr_cntr_menu_pane, "C1 (Monitor)", '1',
					PULL_DOWN, NULL, ThreshActiveCB);
    AddMenuItem (thr_cntr_menu_pane, "C2 (Detector)", '2',
					PULL_DOWN, NULL, ThreshActiveCB);
    AddMenuItem (thr_cntr_menu_pane, "C3", '3',
					PULL_DOWN, NULL, ThreshActiveCB);
    AddMenuItem (thr_cntr_menu_pane, "C4", '4',
					PULL_DOWN, NULL, ThreshActiveCB);
    AddMenuItem (thr_cntr_menu_pane, "C5", '5',
					PULL_DOWN, NULL, ThreshActiveCB);
    AddMenuItem (thr_cntr_menu_pane, "C6", '6',
					PULL_DOWN, NULL, ThreshActiveCB);
    AddMenuItem (thr_cntr_menu_pane, "C7", '7',
					PULL_DOWN, NULL, ThreshActiveCB);
    AddMenuItem (thr_cntr_menu_pane, "C8", '8',
					PULL_DOWN, NULL, ThreshActiveCB);
		/*---------------------------------------------------------
		**    Now do Analogue.
		*/
    AddMenuItem (anal_menu_pane, "C1 (Monitor)", '1',
					PULL_DOWN, NULL, AnalSelectCB);
    AddMenuItem (anal_menu_pane, "C2 (Detector)", '2',
					PULL_DOWN, NULL, AnalSelectCB);
    AddMenuItem (anal_menu_pane, "C3", '3',
					PULL_DOWN, NULL, AnalSelectCB);
    AddMenuItem (anal_menu_pane, "C4", '4',
					PULL_DOWN, NULL, AnalSelectCB);
    AddMenuItem (anal_menu_pane, "C5", '5',
					PULL_DOWN, NULL, AnalSelectCB);
    AddMenuItem (anal_menu_pane, "C6", '6',
					PULL_DOWN, NULL, AnalSelectCB);
    AddMenuItem (anal_menu_pane, "C7", '7',
					PULL_DOWN, NULL, AnalSelectCB);
    AddMenuItem (anal_menu_pane, "C8", '8',
					PULL_DOWN, NULL, AnalSelectCB);
		/*---------------------------------------------------------
		**    Now do Basic Timing.
		*/
    AddMenuItem (time_menu_pane, "Polling Rate ...", 'P',
						PULL_DOWN, NULL, PollRateCB);
    AddMenuItem (time_menu_pane, "Integration Time ...", 'I',
						PULL_DOWN, NULL, IntegTimeCB);

    return my_menu_bar;
  }
/*
**---------------------------------------------------------------------------
**			CreateApplication - set up main window.
*/
  Widget CreateApplication (Widget parent) {
/*	 =================
*/
    Widget main_window;		/*  MainWindow		*/
    Widget form_0;		/*  Form Widget	*/

    Widget frame_00;		/*  Frame Widget	*/
    Widget frame_01;		/*  Frame Widget	*/
    Widget frame_02;		/*  Frame Widget	*/
    Widget form_03;		/*  Form Widget	*/
    Widget rc_window_04;	/*  RowColumn Window	*/

    Widget rc_window_1;		/*  RowColumn Window	*/
    Widget w_tmp;

    XmString	    tmp_cmpStr;
    char	    text[80];
    int		    i, hh, mm, ss, dec_points, indx, i_tmp;
    int		    mill, thou, units;
    float	    f_tmp, f_max;
    char	    *title;
	    /*-------------------------------------------------------------
	    **	Create MainWindow.
	    */
    Nargs = 0;
    main_window = XmCreateMainWindow (parent, "main_window", Args, Nargs);
    XtManageChild (main_window);

    CreateMenuBar (main_window);
	    /*    
	    **      Create Form Widget to hold the various items
	    **	    in the Main Window
	    */
    Nargs = 0;
    form_0 = XmCreateForm (main_window, "form_0", Args, Nargs);
    XtManageChild (form_0);
	    /*-------------------------------------------------------------
	    **      Create Frame to hold Mode Label in Main Window
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    frame_00 = XmCreateFrame (form_0, "frame_00", Args, Nargs);
    XtManageChild (frame_00);
	    /*    
	    **      Create Label in this Frame
	    */
    if (Cntr_state_mode == VMECNT__PRESET_COUNT) {
      Old_Cntr_state.mon_preset = 0x7fffffff;
      units = Old_Cntr_state.mon_preset;
      thou  = units/1000; units = units - (1000 * thou);
      mill  = thou/1000;  thou  = thou  - (1000 * mill);
      sprintf (text, "Preset Count Mode: %d'%03d'%03d", mill, thou, units);
      Cntr_state_mode_in_window = VMECNT__PRESET_COUNT;
      Cntr_state_mon_preset_in_window = Old_Cntr_state.mon_preset;
    }else {
      strcpy (Old_Cntr_state.timer_preset, "2000000.0");
      strcpy (Cntr_state_timer_preset, "10000.0");
      TimeString (text, "Preset Time Mode: ", Cntr_state_timer_preset);
      Cntr_state_mode_in_window = VMECNT__PRESET_TIME;
      strcpy (Cntr_state_timer_preset_in_window, Old_Cntr_state.timer_preset);
    }
    tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
    XtSetArg (Args[Nargs], XmNalignment, XmALIGNMENT_BEGINNING); Nargs++;
    XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++;
    Lbl_counter_mode = XmCreateLabel (frame_00, "Counter_Mode", Args, Nargs);
    XtManageChild (Lbl_counter_mode);
    XmStringFree (tmp_cmpStr);
	    /*-------------------------------------------------------------
	    **      Create Frame to hold RowColumn Widget in Main Window
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    frame_01 = XmCreateFrame (form_0, "frame_01", Args, Nargs);
    XtManageChild (frame_01);
	    /*    
	    **      Create RowColumn Window for register display
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNnumColumns, 3);  Nargs++;
    XtSetArg (Args[Nargs], XmNpacking, XmPACK_COLUMN);  Nargs++;
    XtSetArg (Args[Nargs], XmNorientation, XmVERTICAL);  Nargs++;
    XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_END); Nargs++;

    rc_window_1 = XmCreateRowColumn (frame_01, "rc_window_1", Args, Nargs);
    XtManageChild (rc_window_1);
	    /*
	    **    create labels for Col 1 (Identifiers)
	    */
    MakeLabel (rc_window_1, " ",	    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "Timer:",	    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "Monitor:",	    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "Detector:",    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "C3:",	    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "C4:",	    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "C5:",	    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "C6:",	    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "C7:",	    XmALIGNMENT_END);
    MakeLabel (rc_window_1, "C8:",	    XmALIGNMENT_END);
	    /*
	    **    create labels for Col 2 (Values)
	    */
    MakeLabel (rc_window_1, "Value  ", XmALIGNMENT_END);

    f_tmp = 99 * 3600 + 59 * 60 + 59;		/* Set up 99h:59m:59s */
    sprintf (Old_Cntr_state.timer, "%f", f_tmp);
    sscanf (Cntr_state.timer, "%f", &f_tmp);
    ss = (int) f_tmp;
    mm = ss/60; ss = ss - (mm * 60);
    hh = mm/60; mm = mm - (hh * 60);
    sprintf (text, "%d:%02d:%02d", hh, mm, ss);
    Lbl_timer = MakeLabel (rc_window_1, text, XmALIGNMENT_END);

    Old_Cntr_state.cntrs[0] = 0x7fffffff;
    sprintf (text, "%d", Old_Cntr_state.cntrs[0]);
    Lbl_mon = MakeLabel (rc_window_1, text, XmALIGNMENT_END);

    for (i = 1; i < 8; i++) Old_Cntr_state.cntrs[i] = 0;
    Lbl_det = MakeLabel (rc_window_1, "0", XmALIGNMENT_END);
    Lbl_c3  = MakeLabel (rc_window_1, "0", XmALIGNMENT_END);
    Lbl_c4  = MakeLabel (rc_window_1, "0", XmALIGNMENT_END);
    Lbl_c5  = MakeLabel (rc_window_1, "0", XmALIGNMENT_END);
    Lbl_c6  = MakeLabel (rc_window_1, "0", XmALIGNMENT_END);
    Lbl_c7  = MakeLabel (rc_window_1, "0", XmALIGNMENT_END);
    Lbl_c8  = MakeLabel (rc_window_1, "0", XmALIGNMENT_END);
	    /*
	    **    create labels for Col 3 (Rates)
	    */
    MakeLabel (rc_window_1, "  Rate  ", XmALIGNMENT_END);
    MakeLabel (rc_window_1, " ", XmALIGNMENT_END);

    strcpy (Old_Cntr_state.rates[0], "4000000.0");
    sscanf (Old_Cntr_state.rates[0], "%f", &f_tmp);
    sprintf (text, "%.1f kHz", f_tmp/1000.0);
    Lbl_mon_rate = MakeLabel (rc_window_1, text, XmALIGNMENT_END);

    for (i = 1; i < 8; i++) strcpy (Old_Cntr_state.rates[i], "0.0");
    Lbl_det_rate = MakeLabel (rc_window_1, "0.0", XmALIGNMENT_END);
    Lbl_c3_rate  = MakeLabel (rc_window_1, "0.0", XmALIGNMENT_END);
    Lbl_c4_rate  = MakeLabel (rc_window_1, "0.0", XmALIGNMENT_END);
    Lbl_c5_rate  = MakeLabel (rc_window_1, "0.0", XmALIGNMENT_END);
    Lbl_c6_rate  = MakeLabel (rc_window_1, "0.0", XmALIGNMENT_END);
    Lbl_c7_rate  = MakeLabel (rc_window_1, "0.0", XmALIGNMENT_END);
    Lbl_c8_rate  = MakeLabel (rc_window_1, "0.0", XmALIGNMENT_END);
	    /*-------------------------------------------------------------
	    **	    The rate of counter which goes to analogue display is
	    **	    displayed in reverse video. Make this C1 to start off with.
	    */
    Nargs = 0;	    /* Get default foreground and background first. */
    XtSetArg (Args[Nargs], XmNforeground, &Dflt_foreground); Nargs++;
    XtSetArg (Args[Nargs], XmNbackground, &Dflt_background); Nargs++;
    XtGetValues (Lbl_mon_rate, Args, Nargs);

    Old_Cntr_state.analog_indx = 0;	/* Make C1 reverse video for starters */

    Nargs = 0;		    /* Prepare arguments to make a reverse-video */
    XtSetArg (Args[Nargs], XmNforeground, Dflt_background); Nargs++;
    XtSetArg (Args[Nargs], XmNbackground, Dflt_foreground); Nargs++;
    XtSetValues (Lbl_mon_rate, Args, Nargs);	/* And do it */
	    /*-------------------------------------------------------------
	    **      Create Frame to hold Counter Status Label in Main Window
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    frame_02 = XmCreateFrame (form_0, "frame_02", Args, Nargs);
    XtManageChild (frame_02);
	    /*    
	    **      Create Label in this Frame
	    */
    tmp_cmpStr = XmStringCreateLtoR ("This_is_a_Place_Holder", 
						XmSTRING_DEFAULT_CHARSET);
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
    XtSetArg (Args[Nargs], XmNalignment, XmALIGNMENT_CENTER); Nargs++;
    XtSetArg (Args[Nargs], XmNrecomputeSize, False); Nargs++;
    Lbl_counter_state = XmCreateLabel (frame_02, "Counter_Status", Args, Nargs);
    XtManageChild (Lbl_counter_state);
    XmStringFree (tmp_cmpStr);
	    /*    
	    **      Create RowColumn Window for command buttons
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNnumColumns, 1);  Nargs++;
    XtSetArg (Args[Nargs], XmNpacking, XmPACK_COLUMN);  Nargs++;
    XtSetArg (Args[Nargs], XmNorientation, XmHORIZONTAL);  Nargs++;
    XtSetArg (Args[Nargs], XmNtraversalOn, True); Nargs++;

    rc_window_04 = XmCreateRowColumn (form_0, "rc_window_04", Args, Nargs);
    XtManageChild (rc_window_04);

    Go_button    = AddMenuItem (rc_window_04, "Go",
				    '\0', PULL_DOWN, NULL, RunCB);
    Stop_button  = AddMenuItem (rc_window_04, "Stop",
				    '\0', PULL_DOWN, NULL, RunCB);
    Pause_button = AddMenuItem (rc_window_04, "Pause",
				    '\0', PULL_DOWN, NULL, RunCB);
    Cont_button  = AddMenuItem (rc_window_04, "Cont",
				    '\0', PULL_DOWN, NULL, RunCB);
    Updt_button  = AddMenuItem (rc_window_04, "Update",
				    '\0', PULL_DOWN, NULL, RunCB);
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    XtSetValues (Go_button, Args, Nargs);
    XtSetValues (Stop_button, Args, Nargs);
    XtSetValues (Pause_button, Args, Nargs);
    XtSetValues (Cont_button, Args, Nargs);
	    /*    
	    **      Create scale to show run progress
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNorientation, XmHORIZONTAL); Nargs++;
    XtSetArg (Args[Nargs], XmNmaximum, SCALE_RUN_MAX); Nargs++;
    XtSetArg (Args[Nargs], XmNsensitive, False); Nargs++;
    Scale_run_progress = XmCreateScale (form_0, "Run_Scale", Args, Nargs);
    XtManageChild (Scale_run_progress);
	    /*-------------------------------------------------------------
	    **      Create Form to hold the Threshold/Rate Indicators
	    */
    Nargs = 0;
    form_03 = XmCreateForm (form_0, "form_03", Args, Nargs);
    XtManageChild (form_03);
	    /*    
	    **      Pick out values for this Form
	    */
    indx = 1;	    /* Ensure the first display has the longest content so that,
		    ** if they get changed, there will be room for the
		    ** new selection.
		    */
    Old_Cntr_state.thresh_indx = indx;
    title = "\"Detector\" Threshold/Rate";
    strcpy (Old_Cntr_state.threshes[indx], "4000000.0");
    strcpy (Old_Cntr_state.rates[indx], "3000000.0");
    sscanf (Old_Cntr_state.threshes[indx], "%f", &Thresh_cntr_thresh);
    sscanf (Old_Cntr_state.rates[indx],    "%f", &Thresh_cntr_rate);
    f_max = (Thresh_cntr_rate > Thresh_cntr_thresh) ?
					Thresh_cntr_rate : Thresh_cntr_thresh;
    f_tmp = 1.0e2;
    if (f_max > f_tmp) f_tmp = 1.0e3;
    if (f_max > f_tmp) f_tmp = 1.0e4;
    if (f_max > f_tmp) f_tmp = 1.0e5;
    if (f_max > f_tmp) f_tmp = 1.0e6;
    if (f_max > f_tmp) f_tmp = 1.0e7;
    f_max = f_tmp;
    Scale_is_khz = TRUE;
    dec_points = 1;	    /* Play tricks to get 1 dec place in display */
    f_max = f_max/100.0;
    Thresh_cntr_thresh = Thresh_cntr_thresh/100.0;
    Thresh_cntr_rate   = Thresh_cntr_rate/100.0;
    Scale_max = (int) f_max;
	    /*    
	    **      Create Label for Threshold/Rate Form
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    Lbl_thresh_scales = XmCreateLabel (form_03, title, Args, Nargs);
    XtManageChild (Lbl_thresh_scales);
	    /*    
	    **      Create Scale for Threshold
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNdecimalPoints, dec_points); Nargs++;
    XtSetArg (Args[Nargs], XmNorientation, XmVERTICAL); Nargs++;
    XtSetArg (Args[Nargs], XmNminimum, 0); Nargs++;
    XtSetArg (Args[Nargs], XmNmaximum, (int) Scale_max); Nargs++;
    XtSetArg (Args[Nargs], XmNshowValue, True); Nargs++;
    XtSetArg (Args[Nargs], XmNvalue, (int) Thresh_cntr_thresh); Nargs++;
    XtSetArg (Args[Nargs], XmNsensitive, True); Nargs++;
    Scale_thresh = XmCreateScale (form_03, "Thr_Scale", Args, Nargs);
    XtManageChild (Scale_thresh);
    XtAddCallback (Scale_thresh, XmNvalueChangedCallback, ThreshThreshCB, NULL);
	    /*    
	    **      Create Scale for Rate
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNdecimalPoints, dec_points); Nargs++;
    XtSetArg (Args[Nargs], XmNorientation, XmVERTICAL); Nargs++;
    XtSetArg (Args[Nargs], XmNminimum, 0); Nargs++;
    XtSetArg (Args[Nargs], XmNmaximum, (int) f_max); Nargs++;
    XtSetArg (Args[Nargs], XmNvalue, (int) Thresh_cntr_rate); Nargs++;
    XtSetArg (Args[Nargs], XmNsensitive, False); Nargs++;
    Scale_rate = XmCreateScale (form_03, "Rate_Scale", Args, Nargs);
    XtManageChild (Scale_rate);
	    /*    
	    **      Create Label giving scale maximum
	    */
    sprintf (text, "<-- %d kHz", ((int) f_max)/10);
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    Lbl_rate_scale_max = XmCreateLabel (form_03, text, Args, Nargs);
    XtManageChild (Lbl_rate_scale_max);
	    /*    
	    **      Create Labels giving present rate and thresh values
	    */
    sprintf (text, "Thresh = %.1f kHz", Thresh_cntr_thresh/10.0);
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    Lbl_thr_scale_val = XmCreateLabel (form_03, text, Args, Nargs);
    XtManageChild (Lbl_thr_scale_val);

    sprintf (text, "Rate   = %.1f kHz", Thresh_cntr_rate/10.0);
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    Lbl_rate_scale_val = XmCreateLabel (form_03, text, Args, Nargs);
    XtManageChild (Lbl_rate_scale_val);
	    /*    
	    **      Create arrow buttons for changing scale
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNarrowDirection, XmARROW_UP); Nargs++;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    if (Scale_is_khz && (Scale_max >= 100000)) {
      XtSetArg (Args[Nargs], XmNsensitive, False); Nargs++;
    }
    Btn_scale_up = XmCreateArrowButton (form_03, "Scale_up", Args, Nargs);
    XtManageChild (Btn_scale_up);
    XtAddCallback (Btn_scale_up, XmNactivateCallback, ScaleCB, NULL);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNarrowDirection, XmARROW_DOWN); Nargs++;
    XtSetArg (Args[Nargs], XmNtraversalOn, False);  Nargs++;
    if (!Scale_is_khz && (Scale_max <= 100)) {
      XtSetArg (Args[Nargs], XmNsensitive, False); Nargs++;
    }
    Btn_scale_down = XmCreateArrowButton (form_03, "Scale_down", Args, Nargs);
    XtManageChild (Btn_scale_down);
    XtAddCallback (Btn_scale_down, XmNactivateCallback, ScaleCB, NULL);
	    /*-------------------------------------------------------------
	    **      Organise the components of the Threshold/Rate Form
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (Lbl_thresh_scales, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, Lbl_thresh_scales); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_FORM); Nargs++;
    XtSetArg (Args[Nargs], XmNbottomAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (Scale_thresh, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, Lbl_thresh_scales); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNleftWidget, Scale_thresh); Nargs++;
    XtSetArg (Args[Nargs], XmNbottomAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (Scale_rate, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, Lbl_thresh_scales); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNleftWidget, Scale_rate); Nargs++;
    XtSetValues (Lbl_rate_scale_max, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNleftWidget, Scale_rate); Nargs++;
    XtSetArg (Args[Nargs], XmNbottomAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (Lbl_thr_scale_val, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNleftWidget, Scale_rate); Nargs++;
    XtSetArg (Args[Nargs], XmNbottomAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNbottomWidget, Lbl_thr_scale_val); Nargs++;
    XtSetValues (Lbl_rate_scale_val, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, Lbl_thresh_scales); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNleftWidget, Lbl_rate_scale_max); Nargs++;
    XtSetValues (Btn_scale_up, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, Btn_scale_up); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNleftWidget, Lbl_rate_scale_max); Nargs++;
    XtSetValues (Btn_scale_down, Args, Nargs);
	    /*-------------------------------------------------------------
	    **      Organise the components of the Main Form
	    */
    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_FORM); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (frame_00, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, frame_00); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (frame_01, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, frame_01); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (frame_02, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_FORM); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNleftWidget, frame_01); Nargs++;
    XtSetArg (Args[Nargs], XmNbottomAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNbottomWidget, frame_02); Nargs++;
    XtSetValues (form_03, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, frame_01); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNleftWidget, frame_02); Nargs++;
    XtSetArg (Args[Nargs], XmNrightAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (rc_window_04, Args, Nargs);

    Nargs = 0;
    XtSetArg (Args[Nargs], XmNtopAttachment, XmATTACH_WIDGET); Nargs++;
    XtSetArg (Args[Nargs], XmNtopWidget, rc_window_04); Nargs++;
    XtSetArg (Args[Nargs], XmNleftAttachment, XmATTACH_FORM); Nargs++;
    XtSetArg (Args[Nargs], XmNrightAttachment, XmATTACH_FORM); Nargs++;
    XtSetValues (Scale_run_progress, Args, Nargs);

    SetStateInWindows ();

    return (main_window);
  }
/*
**==========================================================================
**			Main line program
**			------------------
*/
  int	main (int argc, char **argv) {
/*      ============================
*/
    Widget		main_window;	/* MainWindow		*/
    int			status, i, errcode, my_errno, vaxc_errno;
    char		my_buff[32] = "Empty";
    char		secs_text[32], *pntr, buff[80];
    struct RS__RplyStruct   *rply_ptr;
	/*
	**	Initialize toolkit and open the display.
	*/
    Top_level = XtAppInitialize (&App_context, "SinQ_rc",
			    OpTable, XtNumber(OpTable),
			    &argc, argv, NULL, NULL, 0);

    XtGetApplicationResources (Top_level, (XtPointer) &AppData,
                              Resources, XtNumber(Resources), NULL, 0);

    printf ("%s\n", setupTime (buff, sizeof (buff)));
    printf ("\n VME Neutron Counter, EL737, Client, Version %s\n\n", ident);
    printf ("   RS-232-C Server  = \"%s\"\n",
			AppData.rs232c_srv_host);
    printf ("   TCP/IP Port      = %d\n", AppData.rs232c_srv_inet_port);
    printf ("   RS-232-C Channel = %d\n", AppData.v24_chan);
    printf ("   Polling delay    = %d msec.\n", AppData.msec_poll);
    printf ("   Time-out         = %d msec.\n", AppData.msec_tmo);
    if (AppData.persist)
      printf ("   Persistent Mode  = on.\n");
    printf ("\n");

    printf (" Opening connection to RS-232-C Server .. "); fflush (NULL);
    status = EL737_Open (&Hndl,
		AppData.rs232c_srv_host,
		AppData.rs232c_srv_inet_port,
		AppData.v24_chan);
    if (status) {
      printf ("connection established.\n");
      InfoHndl = (struct EL737info *) Hndl;
    }else {
      printf ("\n\007   .. connection failed. I can't go on!\n");
      EL737_ErrInfo (&pntr, &errcode, &my_errno, &vaxc_errno);
      if (pntr != NULL) printf ("%s\n", pntr);
      #ifdef  __VMS
        exit (errcode);
      #else
        exit (EXIT_FAILURE);
      #endif
    }

    if (!PutOnLine ()) {
      printf ("\n\007   PutOnLine failed. I can't go on!\n");
      EL737_ErrInfo (&pntr, &errcode, &my_errno, &vaxc_errno);
      if (pntr != NULL) printf ("%s\n", pntr);
      #ifdef  __VMS
        exit (errcode);
      #else
        exit (EXIT_FAILURE);
      #endif
    }
	/*
	**	Initialize Cntr_state to something harmless
	*/
    strcpy (Cntr_state.timer, "0.0");
    for (i = 0; i < 8; i++) Cntr_state.cntrs[i] = 0;
    for (i = 0; i < 8; i++) strcpy (Cntr_state.rates[i], "0.0");
    Cntr_state.state = OFFLINE;
    for (i = 0; i < 8; i++) strcpy (Cntr_state.thresh_integ_time[i], "0.1");
    strcpy (Cntr_state.rate_integ_time,	"0.1");
    Cntr_state.analog_indx = 0;
    Cntr_state.thresh_indx = 0;
    for (i = 0; i < 8; i++) strcpy (Cntr_state.threshes[i], "0.0");
    Cntr_state.mon_preset = 1;
    strcpy (Cntr_state.timer_preset, "10.0");

    memcpy (&Old_Cntr_state, &Cntr_state, sizeof (Old_Cntr_state));
    Old_Cntr_state.analog_indx++;
    Old_Cntr_state.thresh_indx++;

    printf (" Getting full status of counter ...\n");
    status = GetCounterStatus (VMECNT__FULL);
    if (!status) {
      printf (" Bad counter status -- aborting!\n");
      EL737_ErrInfo (&pntr, &errcode, &my_errno, &vaxc_errno);
      if (pntr != NULL) printf ("%s\n", pntr);
      #ifdef  __VMS
        exit (errcode);
      #else
        exit (EXIT_FAILURE);
      #endif
    }
		/*
		** Try to make an intelligent guess as to which mode (preset-
		** time or preset-count) the user wants at first. The following
		** is the list of precedence:
		**  a) If counter status is other than MS, the value selects
		**	the mode. 
		**  b) The values of the MP and TP registers are checked. If
		**	they are both set to power-up values (100 and 10.00)
		**	or neither is set to its power-up value, go to (c).
		**	Otherwise, select the mode corresponding to the non-
		**	power-up value.
		**  c) Select the mode according to the -mode option (or
		**	*vmeCntrMode resource) if it is present and valid.
		**  d) Everything failed so set preset-tcount mode.
		**
		** In case (a) or (b), use the value of the MP register as the
		** initial preset value. In (c) or (d), the initial preset
		** value is that given by flag -count or -time (or resources
		** *vmeCntrPresetCount or *vmeCntrPresetTime), if present and
		** valid.
		**
		** For the other mode, the initial preset value is the value
		** of the register if it is not the power-up value. Otherwise,
		** it is that given by flag -count or -time (or resources
		** *vmeCntrPresetCount or *vmeCntrPresetTime), if present and
		** valid.
		*/
    if ((Cntr_state.state & PTS) != 0) {
      Cntr_state_mode = VMECNT__PRESET_TIME;
      strcpy (Cntr_state_timer_preset, Cntr_state.timer_preset);
      printf (" Counter is active and in \"Preset-time\" mode.\n");
    }else if ((Cntr_state.state & PCS) != 0) {
      Cntr_state_mode = VMECNT__PRESET_COUNT;
      Cntr_state_mon_preset = Cntr_state.mon_preset;
      printf (" Counter is active and in \"Preset-count\" mode.\n");
    }else if ((Cntr_state.mon_preset == 100) &&
	      (strcmp (Cntr_state.timer_preset, "10.00") != 0)) {
      Cntr_state_mode = VMECNT__PRESET_TIME;
      strcpy (Cntr_state_timer_preset, Cntr_state.timer_preset);
      printf (" Counter assumed to be in \"Preset-time\" mode.\n");
    }else if ((Cntr_state.mon_preset != 100) &&
	      (strcmp (Cntr_state.timer_preset, "10.00") == 0)) {
      Cntr_state_mode = VMECNT__PRESET_COUNT;
      Cntr_state_mon_preset = Cntr_state.mon_preset;
      printf (" Counter assumed to be in \"Preset-count\" mode.\n");
    }else {	/*
		** The status of the counter was no help. See if "-mode" set.
		*/
      strncpy (my_buff, AppData.mode, (sizeof (my_buff) - 1));
      for (i = 0; my_buff[i] != 0; i++) my_buff[i] = tolower (my_buff[i]);
      if (strcmp (my_buff, "count") == 0) {
	Cntr_state_mode = VMECNT__PRESET_COUNT;
	printf (" Initial mode of counter specified as \"Preset-count\".\n");
	if (AppData.preset_count > 0) {
	  Cntr_state.mon_preset = AppData.preset_count;
	  Cntr_state_mon_preset = AppData.preset_count;
	}else {
	  Cntr_state_mon_preset = Cntr_state.mon_preset;
	}
      }else if (strcmp (my_buff, "time") == 0) {
	Cntr_state_mode = VMECNT__PRESET_TIME;
	printf (" Initial mode of counter specified as \"Preset-time\".\n");
	if (strcmp (AppData.preset_time, "0") != 0) {
	  pntr = CheckTimeSyntax (AppData.preset_time, secs_text);
	  if (pntr != NULL) {
	    strcpy (Cntr_state.timer_preset, secs_text);
	    strcpy (Cntr_state_timer_preset, secs_text);
	  }else {
	    strcpy (Cntr_state_timer_preset, Cntr_state.timer_preset);
	  }
	}else {
	  strcpy (Cntr_state_timer_preset, Cntr_state.timer_preset);
	}
      }else {
	printf (" Initial mode of counter is undefined. "
		  "\"Preset-count\" selected by default.\n");
	Cntr_state_mode = VMECNT__PRESET_COUNT;
	Cntr_state_mon_preset = Cntr_state.mon_preset;
	if (AppData.preset_count > 0)
	  Cntr_state.mon_preset = AppData.preset_count;
      }
    }

    if (Cntr_state_mode == VMECNT__PRESET_TIME) {
      if (Cntr_state.mon_preset != 100) {
	Cntr_state_mon_preset = Cntr_state.mon_preset;
      }else {
	if (AppData.preset_count > 0) {
	  Cntr_state.mon_preset = AppData.preset_count;
	  Cntr_state_mon_preset = AppData.preset_count;
	}
      }
    }else {
      if (strcmp (Cntr_state.timer_preset, "10.00") != 0) {
	strcpy (Cntr_state_timer_preset, Cntr_state.timer_preset);
      }else {
	if (strcmp (AppData.preset_time, "0") != 0) {
	  pntr = CheckTimeSyntax (AppData.preset_time, secs_text);
	  if (pntr != NULL) {
	    strcpy (Cntr_state.timer_preset, secs_text);
	    strcpy (Cntr_state_timer_preset, secs_text);
	  }
	}
      }
    }

    main_window = CreateApplication (Top_level);
	/*
	**	Realize Widgets
	*/
    XtRealizeWidget (Top_level);
	/*
	**	Make a timer so that the display gets updated regularly.
	*/
    if ((AppData.msec_poll > 0) && (Cntr_state.state != OFFLINE)) {
      Timer_id = XtAppAddTimeOut (App_context, AppData.msec_poll,
					TimerCB, NULL);
    } else if (AppData.msec_poll == 0) {
      printf (" msecPoll = 0. Continuous status update disabled.\n");
    } else {
      printf (" EL737 is off-line. Continuous status update disabled.\n");
    }
	/*
	**	process events
	*/
    XtAppMainLoop (App_context);
  }
/*------------------------------------------------------ End of EL737.C */
