#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 *rs232cSrvHost Undefined ** -port *rs232cSrvInetPort 4000 ** -chan *rs232cSrvEL737Chan 0 ** -mode *vmeCntrMode ??? ** -count *vmeCntrPresetCount 0 ** -time *vmeCntrPresetTime 0 ** -poll *vmeCntrMsecPoll 1000 ** -tmo *vmeCntrTmo 5000 ** -persist *vmeCntrPersist False ** where ** 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. ** may be "Count" or "Time". ** must be an integer. ** 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 #include #include #include #include #include #ifdef __VMS #include #include #else #include #ifdef FORTIFY #include #endif #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* **-------------------------------------------------------------------------- ** Define global structures and constants. */ #include #include #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 */