#define ident "1A07" #define Active_Server 1 #define Blink_On 0 #ifdef __DECC #pragma module EL734 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 **!$! **!$! To build on LNSA09 ... **!$! $ build_cc_select :== decc **!$! $ import tasmad **!$! $ def/job deltat_c_tlb sinq_c_tlb **!$! $ bui ud0:[maden.motor]el734 debug **!$! **!$! To build on PSICL0 ... **!$! $ build_cc_select :== decc **!$! $ set default usr_scroot:[maden] **!$! $ copy lnsa09::ud0:[maden.motor]el734.c [] **!$! $ copy lnsa09::tasmad_disk:[mad.lib]sinq_dbg.olb [] **!$! $ copy lnsa09::tasmad_disk:[mad.lib]sinq_c.tlb [] **!$! $ def/job sinq_olb usr_scroot:[maden]sinq_dbg.olb **!$! $ def/job sinq_c_tlb usr_scroot:[maden]sinq_c.tlb **!$! $ def/job deltat_c_tlb sinq_c_tlb **!$! $ bui el734 debug **!$! **!$ if p1 .eqs. "DEBUG" then dbg1 := /debug **!$ if p1 .eqs. "DEBUG" then dbg2 := _dbg **!$ link 'dbg1'/exe=cpt:[exe]el734'dbg2'.exe sys$input/options **! el734 **! sinq_olb/lib **! sys$share:decw$xmlibshr12.exe/share **! sys$share:decw$xtlibshrr5.exe/share **!$ purge/nolog cpt:[exe]el734'dbg2'.exe **!$ exit **!$! ** Link_options_end ** ** Building on Alpha Digital Unix: ** ** setenv TAS_BASE ~maden/tasmad ** source $TAS_BASE/tasmad.setup ** rcp -p "lnsa09:tas_src:[utils]el734.c" \ ** $TAS_SRC/utils/el734.c ** cc -std -g -o $TAS_BIN/el734 \ ** -I$TAS_INC \ ** $TAS_SRC/utils/el734.c \ ** -L$TAS_LIB -lsinq -lXm -lXt -lX11 **+ ** Resource File: decw$user_defaults:SinQ_rc.dat ** ------------- or $HOME/SinQ_rc ** ** *el734Host: Undefined <-- the name of the server ** *el734Port: 4000 <-- the port of the server ** *el734Chan: 0 <-- the RS232C channel of EL734 ** *el734Motor: 1 <-- the motor number (1..12) ** plus ** EL734.msecPoll: 1000 <-- 1.0 sec updates ** EL734.scaleWidth: 800 <-- scale width **--------------------------------------------------------------------------- ** Module Name . . . . . . . . : [...MOTOR]EL734.C ** ** Author . . . . . . . . . . : D. Maden ** Date of creation . . . . . . : Nov 1994 ** ** Purpose ** ======= ** EL734 is a test program for using with the SINQ VME/RS-232-C ** Motor Controller, EL734. ** ** Use: ** === ** 1) Ensure that EL734_SRV is running on the appropriate computer. ** ** 2) Define a foreign command and the workstation where the display ** is to appear via the commands: ** ** $ motor :== $cpt:[exe]el734 ** $ 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 flags - 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: $ motor [-options] ** ** Options are: Equivalent Resource Name Default ** ------- ------------------------ ------- ** -host *el734Host None ** -port *el734Port 4000 ** -chan *el734Chan None ** -poll EL734.msecPoll 1000 ** -m EL734.el734Motor None ** -scale EL734.scaleWidth: 800 ** where ** must be in the range 1 to 12. It is the motor which ** will be controlled. ** specifies the width of the displayed scale in pixels. ** ** If specified, a flag takes precedence over the resource file. ** ** Updates: ** 1A01 20-Dec-1994 DM. Initial version. **- **==================================================================== */ #include #include #include #include #include #ifdef __VMS #include #include #else #include #endif #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 #include #define TMO 50 /* Units are 0.1 secs */ #define MAX_ARGS 20 enum Menu_Type {CASCADE, PULL_DOWN, SEPARATOR}; enum CmndFmts {ONE_INT, ONE_HEX, ONE_STRING, TWO_INT, TWO_STRING, NO_MORE}; typedef struct { int msec_timer; /* Poll rate in msec */ char* vme_motor_host; /* Name of Motor Server */ int vme_motor_port; /* Port Number of Motor Server */ int vme_motor_number; /* Motor Number of Interest */ int v24_chan; /* Motor Number of Interest */ int scale_width; /* Scale width */ } ApplicationData; /* **------------------------------------------------------------- ** Global Variables */ ApplicationData AppData; XtAppContext App_context; /* application context; */ static XtResource Resources[] = { {"el734Host", "El734Host", XmRString, sizeof(String), XtOffsetOf (ApplicationData, vme_motor_host), XmRString, "Undefined"}, {"el734Port", "El734Port", XmRInt, sizeof(int), XtOffsetOf (ApplicationData, vme_motor_port), XmRImmediate, (XtPointer) 0}, {"el734Chan", "El734Chan", XmRInt, sizeof(int), XtOffsetOf (ApplicationData, v24_chan), XmRImmediate, (XtPointer) 0xffff}, {"el734Motor", "El734Motor", XmRInt, sizeof(int), XtOffsetOf (ApplicationData, vme_motor_number), XmRImmediate, (XtPointer) 0}, {"scaleWidth", "ScaleWidth", XmRInt, sizeof(int), XtOffsetOf (ApplicationData, scale_width), XmRImmediate, (XtPointer) 800}, {"msecPoll", "MsecPoll", XmRInt, sizeof(int), XtOffsetOf (ApplicationData, msec_timer), XmRImmediate, (XtPointer) 1000}, }; static XrmOptionDescRec OpTable[] = { {"-host", ".el734Host", XrmoptionSepArg, (XPointer) NULL}, {"-port", ".el734Port", XrmoptionSepArg, (XPointer) NULL}, {"-chan", ".el734Chan", XrmoptionSepArg, (XPointer) NULL}, {"-m", ".el734Motor", XrmoptionSepArg, (XPointer) NULL}, {"-motor", ".el734Motor", XrmoptionSepArg, (XPointer) NULL}, {"-poll", ".msecPoll", XrmoptionSepArg, (XPointer) NULL}, {"-scale", ".scaleWidth", XrmoptionSepArg, (XPointer) NULL}, }; static int Motor; static int Scale_width; static int Msg_seq = 1234; struct Motor_State Old_Mot_state; struct Motor_State Mot_state; struct RS__RespStruct Respon_buff; int Mot_factor; float Mot_pos_ist; float Mot_pos_soll; float Mot_inertia_tol; float Mot_ref_param; float Mot_null_pt; float Mot_lo_lim; float Mot_hi_lim; float Mot_scale_middle; int Mot_is_on_left; int Cnct_skt = 0; char Err_text[80]; Widget Wtop_level; /* Top window */ Widget Wquit_cascade; /* Quit CascadeButton */ Widget Wslct_cascade; /* Select CascadeButton */ Widget Whelp_cascade; /* Help CascadeButton */ Widget Wupdt_button; /* Update Push Button */ Widget Wgo_button; /* Go Push Button */ Widget Wstop_button; /* Stop Push Button */ Widget Wmot_cascade; /* Motor Selection CascadeButton */ Widget Wlbl_state; /* Status Label */ Widget Label_name; Widget Label_lo_lim; Widget Label_hi_lim; Widget Label_ist; Widget Label_soll; Widget Scale_soll; Widget Scale_ist; Widget Label_msr; Widget Label_ss; Widget Label_stats; Widget Label_fd; Widget Label_fm; Widget Label_d; Widget Label_e; Widget Label_f; Widget Label_g; Widget Label_j; Widget Label_k; Widget Label_l; Widget Label_m; Widget Label_q; Widget Label_t; Widget Label_w; Widget Label_v; Widget Label_out; Widget Label_in; Widget Label_z; Widget DrawnBut, DrawnButFrame; int Scale_is_khz; int Scale_max; float Thresh_cntr_thresh; float Thresh_cntr_rate; int Nargs; /* Argument list variables - these must .. */ Arg Args[MAX_ARGS]; /* .. only be used as temporary variables. */ enum CmndFmts Cmnd_fmt[] = { ONE_STRING, ONE_INT, TWO_INT, TWO_INT, ONE_STRING, ONE_INT, ONE_INT, ONE_INT, TWO_STRING, ONE_INT, ONE_INT, ONE_INT, ONE_INT, ONE_STRING, ONE_INT, ONE_STRING, ONE_INT, ONE_INT, ONE_STRING, ONE_INT, ONE_INT, ONE_INT, NO_MORE}; size_t Offsets[] = { OffsetOf (struct Motor_State, name[0]), OffsetOf (struct Motor_State, dec_pt), OffsetOf (struct Motor_State, enc_factor[0]), OffsetOf (struct Motor_State, enc_factor[1]), OffsetOf (struct Motor_State, mot_factor[0]), OffsetOf (struct Motor_State, mot_factor[1]), OffsetOf (struct Motor_State, inertia_tol[0]), OffsetOf (struct Motor_State, ramp), OffsetOf (struct Motor_State, loop_mode), OffsetOf (struct Motor_State, slow_hz), OffsetOf (struct Motor_State, lims[0][0]), OffsetOf (struct Motor_State, lims[1][0]), OffsetOf (struct Motor_State, fast_hz), OffsetOf (struct Motor_State, ref_mode), OffsetOf (struct Motor_State, backlash), OffsetOf (struct Motor_State, pos_tol), OffsetOf (struct Motor_State, ref_param[0]), OffsetOf (struct Motor_State, is_sided), OffsetOf (struct Motor_State, null_pt[0]), OffsetOf (struct Motor_State, ac_par), OffsetOf (struct Motor_State, enc_circ), OffsetOf (struct Motor_State, set_real[0]), OffsetOf (struct Motor_State, ac_state), OffsetOf (struct Motor_State, out), OffsetOf (struct Motor_State, in) }; /* **--------------------------------------------------------------------------- ** DecodeFloats - decode the fl. pt. strings. */ int DecodeFloats () { /* ============= */ int status, i; static int do_warn_dec_pt = True; static int do_warn_pos_real = True; static int do_warn_pos_set = True; status = True; /* Assume all will be OK */ if (sscanf (Mot_state.pos_real, "%f", &Mot_pos_ist) != 1) status = False; if (sscanf (Mot_state.inertia_tol, "%f", &Mot_inertia_tol) != 1) status = False; if (sscanf (Mot_state.lims[0], "%f", &Mot_lo_lim) != 1) status = False; if (sscanf (Mot_state.lims[1], "%f", &Mot_hi_lim) != 1) status = False; if (sscanf (Mot_state.ref_param, "%f", &Mot_ref_param) != 1) status = False; if (sscanf (Mot_state.null_pt, "%f", &Mot_null_pt) != 1) status = False; if (sscanf (Mot_state.set_real, "%f", &Mot_pos_soll) != 1) status = False; if (Mot_lo_lim > Mot_hi_lim) { sscanf (Mot_state.lims[1], "%f", &Mot_lo_lim); sscanf (Mot_state.lims[0], "%f", &Mot_hi_lim); } if ((Mot_pos_ist < Mot_lo_lim) || (Mot_hi_lim < Mot_pos_ist)) { if (do_warn_pos_real) { printf ("\007Warning -- actual position is outside low/high limits\n"); printf (" Low/actual/high are %f, %f, %f.\n", Mot_lo_lim, Mot_pos_ist, Mot_hi_lim); Mot_pos_ist = (Mot_lo_lim + Mot_hi_lim)/2.0; printf (" Actual position will be displayed as %f.\n", Mot_pos_ist); do_warn_pos_real = False; } }else { do_warn_pos_real = True; } if ((Mot_pos_soll < Mot_lo_lim) || (Mot_hi_lim < Mot_pos_soll)) { if (do_warn_pos_set) { printf ("\007Warning -- set position is outside low/high limits\n"); printf (" Low/set/high are %f, %f, %f.\n", Mot_lo_lim, Mot_pos_soll, Mot_hi_lim); Mot_pos_soll = (Mot_lo_lim + Mot_hi_lim)/2.0; printf (" Set position will be displayed as %f.\n", Mot_pos_soll); do_warn_pos_set = False; } }else { do_warn_pos_set = True; } if ((Mot_state.dec_pt < 0) || (6 < Mot_state.dec_pt)) { if (do_warn_dec_pt) { printf ("\007Warning -- number of decimal digits is invalid.\n"); printf (" Low/value/high are %d, %d, %d.\n", 0, Mot_state.dec_pt, 6); Mot_state.dec_pt = 2; printf (" A value of %d will be assumed.\n", Mot_state.dec_pt); do_warn_dec_pt = False; } }else { do_warn_dec_pt = True; } Mot_factor = 1; for (i = 0; i < Mot_state.dec_pt; i++) Mot_factor = Mot_factor * 10; return status; } /* **--------------------------------------------------------------------------- ** EncodeSS - encode the SS flags into text. */ void EncodeSS (char *text, int ss) { /* ======== */ int len; if (ss == 0) { sprintf (text, "Flags, SS = 0"); }else if ((ss & ~(0x3f)) != 0) { sprintf (text, "Flags, SS = ??"); }else { sprintf (text, "Flags, SS = %#x ", ss); if ((ss & 0x20) != 0) strcat (text, "LSX/"); if ((ss & 0x10) != 0) strcat (text, "LS2/"); if ((ss & 0x08) != 0) strcat (text, "LS1/"); if ((ss & 0x04) != 0) strcat (text, "STP/"); if ((ss & 0x02) != 0) strcat (text, "CCW/"); if ((ss & 0x01) != 0) strcat (text, "HLT/"); len = strlen (text); text[len-1] = '\0'; } return; } /* **--------------------------------------------------------------------------- ** EncodeMSR - encode the MSR flags into text. */ void EncodeMSR (char *text, int text_len, /* ========= */ int msr, int ored_msr, int fp_cntr, int fr_cntr) { int len; char my_text[132]; char my_text_0[32]; if (msr == 0) { ored_msr = ored_msr & ~(MSR__BUSY); /* Zero "Busy" bit */ if (ored_msr == MSR__OK) { StrJoin (text, text_len, "Status, MSR = Idle. Positioned OK.", ""); }else { if ((ored_msr & MSR__OK) != 0) { StrJoin (text, text_len, "Status, MSR = Idle. Positioned OK. ", ""); }else { StrJoin (text, text_len, "Status, MSR = Idle. ", ""); } if ((ored_msr & MSR__REF_OK) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Ref. Pos'n OK. "); } if ((ored_msr & MSR__LIM_ERR) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Limit Switch Problem. "); } if ((ored_msr & MSR__AC_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Air-Cushion Error. "); } if ((ored_msr & MSR__REF_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Ref. Pos'n Fail. "); } if ((ored_msr & MSR__POS_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Pos'n Fail. "); } if ((ored_msr & MSR__POS_FAULT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); if (fp_cntr == 1) { StrJoin (text, text_len, my_text, "1 Pos'n Fault. "); }else { sprintf (my_text_0, "%d Pos'n Faults. ", fp_cntr); StrJoin (text, text_len, my_text, my_text_0); } } if ((ored_msr & MSR__RUN_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Run Fail. "); } if ((ored_msr & MSR__RUN_FAULT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); if (fr_cntr == 1) { StrJoin (text, text_len, my_text, "1 Run Fault. "); }else { sprintf (my_text_0, "%d Run Faults. ", fr_cntr); StrJoin (text, text_len, my_text, my_text_0); } } if ((ored_msr & MSR__HALT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Halt. "); } if ((ored_msr & MSR__HI_LIM) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Hit HiLim. "); } if ((ored_msr & MSR__LO_LIM) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Hit LoLim. "); } if ((ored_msr & MSR__STOPPED) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Stopped. "); } } }else if ((msr & ~(0x2fff)) != 0) { StrJoin (text, text_len, "Status, MSR = ??", ""); }else { sprintf (my_text, "%#x ", msr); StrJoin (text, text_len, "Status, MSR = ", my_text); if ((msr & MSR__LIM_ERR) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Limit Switch Problem/"); } if ((msr & MSR__AC_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Air-Cushion Error/"); } if ((msr & MSR__REF_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Ref. Pos'n Fail/"); } if ((msr & MSR__POS_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Pos'n Fail/"); } if ((msr & MSR__POS_FAULT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Pos'n Fault/"); } if ((msr & MSR__RUN_FAIL) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Run Fail/"); } if ((msr & MSR__RUN_FAULT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Run Fault/"); } if ((msr & MSR__HALT) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Halt/"); } if ((msr & MSR__HI_LIM) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Hit HiLim/"); } if ((msr & MSR__LO_LIM) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Hit LoLim/"); } if ((msr & MSR__STOPPED) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Stopped/"); } if ((msr & MSR__REF_OK) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Ref. Pos'n OK/"); } if ((msr & MSR__OK) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "OK/"); } if ((msr & MSR__BUSY) != 0) { StrJoin (my_text, sizeof (my_text), text, ""); StrJoin (text, text_len, my_text, "Busy/"); } len = strlen (text); text[len-1] = '\0'; } return; } /* **--------------------------------------------------------------------------- ** ConnectToSrvr - make connection to Motor Server */ int ConnectToSrvr (char *host, int port) { /* ============= */ int status; int my_cnct_skt; /* Socket for connecting to Motor Srv */ struct sockaddr_in lcl_sockname; struct sockaddr_in rmt_sockname; int rmt_inet_addr; struct in_addr *rmt_inet_addr_pntr; int rmt_port; int rmt_sockname_len; int i; struct hostent *rmt_hostent; #if Active_Server rmt_hostent = gethostbyname (host); if (rmt_hostent == NULL) FailInet ("Gethostbyname error.\n"); rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0]; rmt_port = port; /* ** Create a TCP/IP socket for connecting to root and bind it. */ my_cnct_skt = socket (AF_INET, SOCK_STREAM, 0); if (my_cnct_skt == -1) FailInet ("Socket error.\n"); lcl_sockname.sin_family = AF_INET; lcl_sockname.sin_port = htons (0); lcl_sockname.sin_addr.s_addr = 0; status = bind (my_cnct_skt, (struct sockaddr *) &lcl_sockname, sizeof (lcl_sockname)); if (status == -1) FailInet ("Bind error.\n"); /* ** Connect to Motor Server. */ rmt_sockname_len = sizeof (rmt_sockname); rmt_sockname.sin_family = AF_INET; rmt_sockname.sin_port = htons (rmt_port); rmt_sockname.sin_addr.s_addr = rmt_inet_addr_pntr->s_addr; status = connect (my_cnct_skt, (struct sockaddr *) &rmt_sockname, sizeof (rmt_sockname)); if (status == -1) { FailInet ("Connect error.\n"); } return my_cnct_skt; #else /* Active_Server */ return 0; /* "No server" mode - don't connect to server */ #endif /* Active_Server */ } /* **--------------------------------------------------------------------------- ** ModifyLabel - modify text of a simple label */ void ModifyLabel ( /* =========== */ Widget labl, /* widget id of label */ char *text) { /* The text for the label */ XmString my_compString; my_compString = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); XtVaSetValues (labl, XmNlabelString, my_compString, NULL); XmStringFree (my_compString); return; } /* **--------------------------------------------------------------------------- ** SetStateInWindows - update State fields in Windows to ** match state_ptr->msr, etc. */ void SetStateInWindows ( /* ================= */ struct Motor_State *old_state_ptr, /* Motor status of display */ struct Motor_State *state_ptr) { /* current motor status */ XmString tmp_cmpStr; int i_left, i_right, i_ist, i_soll; float flt; char text[80]; static int state_len; /* ** First time in, ensure that state_len is set to the length of ** the Motor_State structure which must be checked for changes. */ if (state_len == 0) state_len = sizeof (struct Motor_State); if (memcmp (old_state_ptr, state_ptr, state_len) == 0) return; if (strcmp (state_ptr->pos_real, old_state_ptr->pos_real) != 0) { sscanf (state_ptr->pos_real, "%f", &flt); i_left = (int) (Mot_lo_lim * Mot_factor); i_right = (int) (Mot_hi_lim * Mot_factor); i_ist = (int) (flt * Mot_factor); /* ** Update "Ist" scale slider */ if (i_ist < i_left) i_ist = i_left; if (i_ist > i_right) i_ist = i_right; XmScaleSetValue (Scale_ist, i_ist); /* ** Update "Ist" label */ sprintf (text, "%.*f", state_ptr->dec_pt, Mot_pos_ist); ModifyLabel (Label_ist, text); if (Mot_is_on_left) { XtVaSetValues (Label_ist, XmNleftPosition, (i_ist - i_left), NULL); }else { XtVaSetValues (Label_ist, XmNrightPosition, (i_ist - i_left), NULL); } } if (strcmp (state_ptr->set_real, old_state_ptr->set_real) != 0) { sscanf (state_ptr->set_real, "%f", &flt); i_left = (int) (Mot_lo_lim * Mot_factor); i_right = (int) (Mot_hi_lim * Mot_factor); i_soll = (int) (flt * Mot_factor); /* ** Update "Soll" scale slider */ if (i_soll < i_left) i_soll = i_left; if (i_soll > i_right) i_soll = i_right; XmScaleSetValue (Scale_soll, i_soll); /* ** Update "Soll" label */ sprintf (text, "%.*f", state_ptr->dec_pt, Mot_pos_soll); ModifyLabel (Label_soll, text); if (Mot_is_on_left) { XtVaSetValues (Label_soll, XmNleftPosition, (i_soll - i_left), NULL); }else { XtVaSetValues (Label_soll, XmNrightPosition, (i_soll - i_left), NULL); } } /* ** Update MSR label if necessary */ if (state_ptr->msr != old_state_ptr->msr) { EncodeMSR (text, sizeof (text), state_ptr->msr, state_ptr->ored_msr, state_ptr->fp_cntr, state_ptr->fr_cntr); ModifyLabel (Label_msr, text); } /* ** Update SS label if necessary */ if (state_ptr->ss != old_state_ptr->ss) { EncodeSS (text, state_ptr->ss); ModifyLabel (Label_ss, text); } /* ** Update Statistics label if necessary */ if ((state_ptr->stat_pos != old_state_ptr->stat_pos) || (state_ptr->stat_pos_flt != old_state_ptr->stat_pos_flt) || (state_ptr->stat_pos_fail != old_state_ptr->stat_pos_fail) || (state_ptr->stat_cush_fail != old_state_ptr->stat_cush_fail)) { sprintf (text, "Statistics: Total/Faults/Fails/Cush-fails = %d/%d/%d/%d", state_ptr->stat_pos, state_ptr->stat_pos_flt, state_ptr->stat_pos_fail, state_ptr->stat_cush_fail); ModifyLabel (Label_stats, text); } /* ** Update FD label if necessary */ if ((state_ptr->enc_factor[0] != old_state_ptr->enc_factor[0]) || (state_ptr->enc_factor[1] != old_state_ptr->enc_factor[1])) { sprintf (text, "Encoder Ratio, FD = %d:%d", state_ptr->enc_factor[0], state_ptr->enc_factor[1]); ModifyLabel (Label_fd, text); } /* ** Update FM label if necessary */ if ((state_ptr->mot_factor[0] != old_state_ptr->mot_factor[0]) || (state_ptr->mot_factor[1] != old_state_ptr->mot_factor[1])) { sprintf (text, "Motor Ratio, FM = %d:%d", state_ptr->mot_factor[0], state_ptr->mot_factor[1]); ModifyLabel (Label_fm, text); } /* ** Update D label if necessary */ if (strcmp (state_ptr->inertia_tol, old_state_ptr->inertia_tol) != 0) { sprintf (text, "Inertia tol'nce, D = %s", state_ptr->inertia_tol); ModifyLabel (Label_d, text); } /* ** Update E label if necessary */ if (state_ptr->ramp != old_state_ptr->ramp) { sprintf (text, "Start/stop ramp, E = %d", state_ptr->ramp); ModifyLabel (Label_e, text); } /* ** Update F label if necessary */ if (state_ptr->loop_mode != old_state_ptr->loop_mode) { switch (state_ptr->loop_mode) { case 0: sprintf (text, "Open loop mode, F = 0"); break; case 1: sprintf (text, "Closed loop mode, F = 1"); break; default: sprintf (text, "Bad loop mode, F = %d", state_ptr->loop_mode); } ModifyLabel (Label_f, text); } /* ** Update G label if necessary */ if (state_ptr->slow_hz != old_state_ptr->slow_hz) { sprintf (text, "Start/stop Hz, G = %d", state_ptr->slow_hz); ModifyLabel (Label_g, text); } /* ** Update J label if necessary */ if (state_ptr->fast_hz != old_state_ptr->fast_hz) { sprintf (text, "Positioning Hz, J = %d", state_ptr->fast_hz); ModifyLabel (Label_j, text); } /* ** Update K label if necessary */ if (state_ptr->ref_mode != old_state_ptr->ref_mode) { switch (state_ptr->ref_mode) { case 0: sprintf (text, "Absolute encoder, K = 0"); break; case 1: sprintf (text, "HiLimit is RefPt, K = 1"); break; case -1: sprintf (text, "LoLimit is RefPt, K = -1"); break; case 2: sprintf (text, "Sep RefPt, K = 2"); break; case 11: sprintf (text, "HiLimit is RefPt + Indx, K = 11"); break; case -11: sprintf (text, "LoLimit is RefPt + Indx, K = -11"); break; case 12: sprintf (text, "Sep RefPt + Indx, K = 12"); break; default: sprintf (text, "RefMode unknown, K = %d", state_ptr->ref_mode); } ModifyLabel (Label_k, text); } /* ** Update L label if necessary */ if (state_ptr->backlash != old_state_ptr->backlash) { sprintf (text, "Backlash, L = %d", state_ptr->backlash); ModifyLabel (Label_l, text); } /* ** Update M label if necessary */ if (state_ptr->pos_tol != old_state_ptr->pos_tol) { sprintf (text, "Position Tol'nce, M = %d", state_ptr->pos_tol); ModifyLabel (Label_m, text); } /* ** Update Q label if necessary */ if (strcmp (state_ptr->ref_param, old_state_ptr->ref_param) != 0) { sprintf (text, "RefPt Width, Q = %s", state_ptr->ref_param); ModifyLabel (Label_q, text); } /* ** Update T label if necessary */ if (state_ptr->is_sided != old_state_ptr->is_sided) { if (state_ptr->is_sided == 0) { sprintf (text, "No dir'n dependency, T = 0"); }else if (state_ptr->is_sided > 0) { sprintf (text, "Position from above, T = %d", state_ptr->is_sided); }else { sprintf (text, "Position from below, T = %d", state_ptr->is_sided); } ModifyLabel (Label_t, text); } /* ** Update V label if necessary */ if (strcmp (state_ptr->null_pt, old_state_ptr->null_pt) != 0) { sprintf (text, "NullPt, V = %s", state_ptr->null_pt); ModifyLabel (Label_v, text); } /* ** Update W label if necessary */ if ((state_ptr->ac_par != old_state_ptr->ac_par) || (state_ptr->ac_state != old_state_ptr->ac_state)) { if (state_ptr->ac_par == 0) { sprintf (text, "No air-cushion present, W = 0"); }else if (state_ptr->ac_par == Motor) { if (state_ptr->ac_state == 0) { sprintf (text, "Air-cushion down"); }else { sprintf (text, "Air-cushion up"); } }else { if (state_ptr->ac_state == 0) { sprintf (text, "Air-cushion up (chained to %d)", state_ptr->ac_par); }else { sprintf (text, "Air-cushion down (chained to %d)", state_ptr->ac_par); } } ModifyLabel (Label_w, text); } /* ** Update Output label if necessary */ if (state_ptr->out != old_state_ptr->out) { if (state_ptr->out == 0) { sprintf (text, "Output signal not active", state_ptr->null_pt); }else { sprintf (text, "Output signal active", state_ptr->null_pt); } ModifyLabel (Label_out, text); } /* ** Update Input label if necessary */ if (state_ptr->in != old_state_ptr->in) { if (state_ptr->in == 0) { sprintf (text, "Input signal not present"); }else { sprintf (text, "Input signal present"); } ModifyLabel (Label_in, text); } /* ** Update Z label if necessary */ if (state_ptr->enc_circ != old_state_ptr->enc_circ) { sprintf (text, "Enc Circum, Z = %d", state_ptr->enc_circ); ModifyLabel (Label_z, text); } /* */ memcpy (old_state_ptr, state_ptr, state_len); } /* **--------------------------------------------------------------------------- ** SendCmndToServer - send command to RS232C server */ int SendCmndToServer ( /* ================= */ int v24_chan, /* RS232C port number */ int tmo, /* Time-out (0.1 secs) */ struct RS__RespStruct *respon_ptr, /* Buffer for response */ int respon_size, /* Size of resp'se buff */ ...) { /* Now we have parameter pairs - ** char *fmt = pntr to format strng ** char *param = pntr to param ** Terminate list with *fmt = NULL. */ struct RS__MsgStruct msg_buff; int status, c_len, size, max_size, ncmnds; char text[20]; va_list ap; /* Pointer to variable args */ char *fmt_ptr; char *param_ptr; char *cmnd_lst_ptr; if (Cnct_skt == 0) return True; /* Do nothing if no connection - this ** allows testing in "client-only" mode. */ Msg_seq++; /* Set up an incrementing message id */ if (Msg_seq > 9999) Msg_seq = 1; sprintf (msg_buff.msg_id, "%04.4d", Msg_seq); memcpy (msg_buff.c_pcol_lvl, RS__PROTOCOL_ID, sizeof (msg_buff.c_pcol_lvl)); sprintf (msg_buff.serial_port, "%04.4d", v24_chan); sprintf (msg_buff.tmo, "%04.4d", tmo); memcpy (msg_buff.terms, "1\r\0\0", sizeof (msg_buff.terms)); memcpy (msg_buff.n_cmnds, "0000", sizeof (msg_buff.n_cmnds)); va_start (ap, respon_size); /* Set up var arg machinery */ fmt_ptr = va_arg (ap, char *); /* Get pntr to next format string */ ncmnds = 0; cmnd_lst_ptr = &msg_buff.cmnds[0]; while (fmt_ptr != NULL) { param_ptr = va_arg (ap, char *); /* Get pntr to next param */ c_len = sprintf (cmnd_lst_ptr+2, fmt_ptr, param_ptr); sprintf (text, "%02.2d", c_len); memcpy (cmnd_lst_ptr, text, 2); cmnd_lst_ptr = cmnd_lst_ptr + c_len + 2; ncmnds++; fmt_ptr = va_arg (ap, char *); } sprintf (text, "%04.4d", ncmnds); memcpy (msg_buff.n_cmnds, text, sizeof (msg_buff.n_cmnds)); size = cmnd_lst_ptr - msg_buff.msg_id; size = (size + 3) & (~3); /* Round up to multiple of 4 */ sprintf (text, "%04.4d", size); memcpy (msg_buff.msg_size, text, 4); status = send (Cnct_skt, (char *) &msg_buff, size+4, 0); if (status != (size+4)) { sprintf (Err_text, "send: did not send all of buffer: %d %d.\n", size+4, status); FailInet (Err_text); } size = sizeof (respon_ptr->msg_size); status = recv (Cnct_skt, respon_ptr->msg_size, size, 0); if (status != size) { sprintf (Err_text, "recv: did not get full byte count: %d %d.\n", size, status); FailInet (Err_text); } if (sscanf (respon_ptr->msg_size, "%4d", &size) != 1) { sprintf (Err_text, "recv: byte count is not ASCII decimal: %4s\n", respon_ptr->msg_size); FailInet (Err_text); } max_size = respon_size - sizeof (respon_ptr->msg_size); if (size > max_size) { sprintf (Err_text, "recv: message length is too big: %d, %d.\n", max_size, size); FailInet (Err_text); } status = recv (Cnct_skt, (char *) respon_ptr->msg_id, size, 0); if (status != size) { sprintf (Err_text, "recv: did not get all of expected data: %d %d.\n", size, status); FailInet (Err_text); } return status; } /* **--------------------------------------------------------------------------- ** GetReply - get next reply from a reply buffer */ struct RS__RplyStruct *GetReply ( /* ======== */ struct RS__RespStruct *respon_ptr, /* Structure to pull apart */ struct RS__RplyStruct *last_rply) { /* Starting point */ int rply_len; struct RS__RplyStruct *ptr; static int n_replies, max_replies; ptr = NULL; if (last_rply == NULL) { /* Start with first reply? */ if (sscanf (respon_ptr->n_rply, "%4d", &max_replies) != 1) max_replies = 0; if (max_replies > 0) ptr = (struct RS__RplyStruct *) respon_ptr->u.rplys; n_replies = 1; }else { n_replies++; if (n_replies <= max_replies) { if (sscanf (last_rply->rply_len, "%2d", &rply_len) == 1) { ptr = (struct RS__RplyStruct *) ((char *) last_rply + rply_len + 2); } } } return ptr; } /* **--------------------------------------------------------------------------- ** GetMotorStatus - get Motor status from srvr */ int GetMotorStatus ( /* ================ */ int type, /* FULL__STATUS or SHORT__STATUS */ struct Motor_State *state) { /* Structure to hold status */ struct RS__MsgStruct msg_buff; int status, size, max_size; int i, indx; int j0, j1; char txt0[16], txt1[16], mot_txt[10]; struct RS__RplyStruct *rply_ptr; /* ** Start by getting "short" status of motor. */ #if Active_Server sprintf (mot_txt, "%d", state->motor); status = SendCmndToServer (AppData.v24_chan, TMO, &Respon_buff, sizeof (Respon_buff), "msr %s\r", mot_txt, "ss %s\r", mot_txt, "u %s\r", mot_txt, "p %s\r", mot_txt, "sp %s\r", mot_txt, "st %s\r", mot_txt, "sr %s\r", mot_txt, "sa %s\r", mot_txt, NULL); rply_ptr = GetReply (&Respon_buff, NULL); if (rply_ptr != NULL) { if (sscanf (rply_ptr->rply, "%x", &state->msr) == 1) { state->exists = True; state->ored_msr = state->ored_msr | state->msr; if ((state->msr & MSR__POS_FAULT) != 0) state->fp_cntr++; if ((state->msr & MSR__RUN_FAULT) != 0) state->fr_cntr++; rply_ptr = GetReply (&Respon_buff, rply_ptr); if (rply_ptr != NULL) { if (sscanf (rply_ptr->rply, "%x", &state->ss) != 1) state->ss = -1; rply_ptr = GetReply (&Respon_buff, rply_ptr); if (rply_ptr != NULL) { strncpy (state->pos_real, rply_ptr->rply, sizeof (state->pos_real) - 1); sscanf (state->pos_real, "%f", &Mot_pos_ist); rply_ptr = GetReply (&Respon_buff, rply_ptr); if (rply_ptr != NULL) { strncpy (state->set_real, rply_ptr->rply, sizeof (state->set_real) - 1); sscanf (state->set_real, "%f", &Mot_pos_soll); rply_ptr = GetReply (&Respon_buff, rply_ptr); if (rply_ptr != NULL) { sscanf (rply_ptr->rply, "%d", &state->stat_pos); rply_ptr = GetReply (&Respon_buff, rply_ptr); if (rply_ptr != NULL) { sscanf (rply_ptr->rply, "%d", &state->stat_pos_flt); rply_ptr = GetReply (&Respon_buff, rply_ptr); if (rply_ptr != NULL) { sscanf (rply_ptr->rply, "%d", &state->stat_pos_fail); rply_ptr = GetReply (&Respon_buff, rply_ptr); if (rply_ptr != NULL) { sscanf (rply_ptr->rply, "%d", &state->stat_cush_fail); rply_ptr = GetReply (&Respon_buff, rply_ptr); } } } } } } } }else { state->exists = False; } } if ((type == FULL__STATUS) && state->exists) { status = SendCmndToServer (AppData.v24_chan, TMO, &Respon_buff, sizeof (Respon_buff), "mn %s\r", mot_txt, "a %s\r", mot_txt, "fd %s\r", mot_txt, "fm %s\r", mot_txt, "d %s\r", mot_txt, "e %s\r", mot_txt, "f %s\r", mot_txt, "g %s\r", mot_txt, "h %s\r", mot_txt, "j %s\r", mot_txt, "k %s\r", mot_txt, "l %s\r", mot_txt, "m %s\r", mot_txt, "q %s\r", mot_txt, "t %s\r", mot_txt, "v %s\r", mot_txt, "w %s\r", mot_txt, "z %s\r", mot_txt, "p %s\r", mot_txt, "ac %s\r", mot_txt, "so %s\r", mot_txt, "ri %s\r", mot_txt, NULL); rply_ptr = GetReply (&Respon_buff, NULL); indx = 0; for (i = 0; Cmnd_fmt[i] != NO_MORE; i++) { if (rply_ptr != NULL) { switch (Cmnd_fmt[i]) { case ONE_INT: sscanf (rply_ptr->rply, "%d", (int *)(((char *) state) + Offsets[indx])); indx++; break; case TWO_INT: sscanf (rply_ptr->rply, "%d %d", (int *)(((char *) state) + Offsets[indx]), (int *)(((char *) state) + Offsets[indx+1])); indx++; indx++; break; case ONE_STRING: sscanf (rply_ptr->rply, "%15s", ((char *) state) + Offsets[indx]); indx++; break; case TWO_STRING: sscanf (rply_ptr->rply, "%15s %15s", ((char *) state) + Offsets[indx], ((char *) state) + Offsets[indx+1]); indx++; indx++; break; } rply_ptr = GetReply (&Respon_buff, rply_ptr); } } DecodeFloats (); /* Convert all strings in state to binary */ } #else state->exists = True; state->msr = 1; state->ss = 2; strcpy (state->pos_real, "12.2"); state->pos_hex = 0x1234; strcpy (state->name, "DELTA"); state->dec_pt = 3; state->enc_factor[0] = 400; state->enc_factor[1] = 2; state->mot_factor[0] = -300; state->mot_factor[1] = 3; strcpy (state->inertia_tol, "0.1"); state->ramp = 20; state->loop_mode = 1; state->slow_hz = 300; strcpy (&state->lims[0][0], "-50.0"); strcpy (&state->lims[1][0], "200.0"); state->fast_hz = 1000; state->ref_mode = 2; state->backlash = 0; state->pos_tol = 1; strcpy (state->ref_param, "10.0"); state->is_sided = 0; strcpy (state->null_pt, "-15.0"); state->ac_par = state->motor; state->enc_circ = 0; state->stat_pos = 1234; state->stat_pos_flt = 2345; state->stat_pos_fail = 3456; state->stat_cush_fail = 4567; strcpy (state->set_real, "70.5"); state->set_hex = 0x4321; state->ac_state = 0; state->out = 0; state->in = 0; #endif /* Active_Server */ return True; } /* **--------------------------------------------------------------------------- ** ActivateCB - callback for button */ void ActivateCB ( /* ========== */ Widget w, /* widget id */ XtPointer client_data, /* data from application */ XtPointer call_data) { /* data from widget class */ Widget w_tmp; char *button_name, *parent_name; /* ** print message to prove we got activated */ w_tmp = XtParent (w); button_name = XtName (w); parent_name = XtName (w_tmp); printf ("Push button \"%s\" of Parent \"%s\" selected.\n", button_name, parent_name); } /* **--------------------------------------------------------------------------- ** MotorSelectCB - callback for Select .../Motor .../Number */ void MotorSelectCB ( /* ============= */ Widget w, /* widget id */ XtPointer client_data, /* data from application */ XtPointer call_data) { /* data from widget class */ int motor = 0, i_left, i_right, i_soll, i_ist; char *button_name, text[80]; XmString tmp_cmpStr; /* ** print message to prove we got activated */ button_name = XtName (w); printf ("Push button \"%s\" selected.\n", button_name); if ((sscanf (button_name, "%i", &motor) != 1) || (motor <= 0) || (motor > 12)) { printf ("Invalid push button label or motor number!\n"); return; } if (motor != Motor) { Motor = motor; Mot_state.motor = Motor; printf ("Getting full status of Motor %d ...\n", Motor); GetMotorStatus (FULL__STATUS, &Mot_state); sprintf (text, "%.*f", Mot_state.dec_pt, Mot_lo_lim); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); XtVaSetValues (Label_lo_lim, XmNlabelString, tmp_cmpStr, NULL); XmStringFree (tmp_cmpStr); sprintf (text, "Motor %d \"%s\"", Motor, Mot_state.name); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); XtVaSetValues (Label_name, XmNlabelString, tmp_cmpStr, NULL); XmStringFree (tmp_cmpStr); sprintf (text, "%.*f", Mot_state.dec_pt, Mot_hi_lim); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); XtVaSetValues (Label_hi_lim, XmNlabelString, tmp_cmpStr, NULL); XmStringFree (tmp_cmpStr); i_left = (int) (Mot_lo_lim * Mot_factor); i_right = (int) (Mot_hi_lim * Mot_factor); i_soll = (int) (Mot_pos_soll * Mot_factor); i_ist = (int) (Mot_pos_ist * Mot_factor); if (i_ist < i_left) i_ist = i_left; if (i_ist > i_right) i_ist = i_right; if (i_soll < i_left) i_soll = i_left; if (i_soll > i_right) i_soll = i_right; XtVaSetValues (Scale_ist, XmNminimum, i_left, XmNmaximum, i_right, XmNvalue, i_ist, NULL); XtVaSetValues (Scale_soll, XmNminimum, i_left, XmNmaximum, i_right, XmNvalue, i_soll, NULL); SetStateInWindows (&Old_Mot_state, &Mot_state); /* Update window display. */ } } /* **--------------------------------------------------------------------------- ** 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 */ char buff[4]; if (Cnct_skt != 0) { send (Cnct_skt, "-001", 4, 0); /* Tell our TCP/IP server that .. ** .. we are about to quit. */ recv (Cnct_skt, buff, sizeof (buff), 0); /* And wait for his ack */ close (Cnct_skt); } exit (True); /* Terminate the application. */ } /* **--------------------------------------------------------------------------- ** SollCB - callback for Soll-position Scale */ void SollCB ( /* ====== */ Widget w, /* widget id */ XtPointer client_data, /* data from application */ XmScaleCallbackStruct *call_data) { /* data from widget class */ int status; int i_tmp; float f_tmp; char fmt[80]; char text[80]; XmString tmp_cmpStr; f_tmp = ((float) call_data->value)/((float) Mot_factor); sprintf (text, "%.*f", Mot_state.dec_pt, f_tmp); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); XtVaSetValues (Label_soll, XmNlabelString, tmp_cmpStr, NULL); XmStringFree (tmp_cmpStr); if (call_data->reason != XmCR_VALUE_CHANGED) { XmUpdateDisplay (Wtop_level); return; } /* ** Adjust position of label to be near pointer. There is a ** complication if the position goes over the mid-point. */ i_tmp = call_data->value - (int) (Mot_lo_lim * Mot_factor); if (((f_tmp < Mot_scale_middle) && Mot_is_on_left) || ((f_tmp > Mot_scale_middle) && !Mot_is_on_left)) { /* ** Get here if side has not changed. */ if (Mot_is_on_left) { XtVaSetValues (Label_soll, XmNleftPosition, i_tmp, NULL); XtVaSetValues (Label_ist, XmNleftPosition, i_tmp, NULL); }else { XtVaSetValues (Label_soll, XmNrightPosition, i_tmp, NULL); XtVaSetValues (Label_ist, XmNrightPosition, i_tmp, NULL); } }else if (Mot_is_on_left) { /* ** Get here if side has changed from left to right. */ Mot_is_on_left = False; XtVaSetValues (Label_soll, XmNleftAttachment, XmATTACH_NONE, XmNleftPosition, 0, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, i_tmp, NULL); XtVaSetValues (Label_ist, XmNleftAttachment, XmATTACH_NONE, XmNleftPosition, 0, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, i_tmp, NULL); }else { /* ** Get here if side has changed from right to left. */ Mot_is_on_left = True; XtVaSetValues (Label_soll, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, i_tmp, XmNrightAttachment, XmATTACH_NONE, XmNrightPosition, 0, NULL); XtVaSetValues (Label_ist, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, i_tmp, XmNrightAttachment, XmATTACH_NONE, XmNrightPosition, 0, NULL); } XmUpdateDisplay (Wtop_level); Mot_state.ored_msr = 0; Mot_state.fp_cntr = 0; Mot_state.fr_cntr = 0; sprintf (fmt, "p %d %%s\r", Motor); status = SendCmndToServer (AppData.v24_chan, TMO, &Respon_buff, sizeof (Respon_buff), fmt, text, NULL); } /* **--------------------------------------------------------------------------- ** TimerCB - callback for timer */ void TimerCB ( /* ======= */ XtPointer client_data, /* data from application */ XtIntervalId *id) { /* data from widget class */ static int first = True; static int blink = True; static Display *disp; static Window wind; static GC gc; GetMotorStatus (SHORT__STATUS, &Mot_state); SetStateInWindows (&Old_Mot_state, &Mot_state); /* Update window display. */ if (AppData.msec_timer > 0) { XtAppAddTimeOut (App_context, AppData.msec_timer, TimerCB, NULL); }else { printf ("\007EL734 -- status polling disabled.\n"); } #if Blink_On /* This is just an exercise to do a bit of graphics!! */ if (first) { first = False; disp = XtDisplay (DrawnBut); wind = XtWindow (DrawnBut); gc = DefaultGCOfScreen (XtScreen (DrawnBut)); } if (blink) { XFillArc (disp, wind, gc, 10, 10, 50, 50, 0, 360*64); }else { XClearArea (disp, wind, 10, 10, 50, 50, False); } blink = !blink; #endif /* Blink_On */ } /* **--------------------------------------------------------------------------- ** CreateMenuBar - Create menu bar for main window. */ Widget CreateMenuBar (Widget window) { /* ============= */ Widget my_menu_bar; /* MenuBar */ Widget quit_menu_pane; /* Quit MenuPane */ Widget slct_menu_pane; /* Select MenuPane */ Widget help_menu_pane; /* Help MenuPane */ Widget mot_menu_pane; /* Motor 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; quit_menu_pane = XmCreatePulldownMenu (my_menu_bar, "Quit_Menu", Args, Nargs); slct_menu_pane = XmCreatePulldownMenu (my_menu_bar, "Select_Menu", Args, Nargs); help_menu_pane = XmCreatePulldownMenu (my_menu_bar, "Help_Menu", Args, Nargs); mot_menu_pane = XmCreatePulldownMenu (slct_menu_pane, "Motor_Menu", Args, Nargs); /*------------------------------------------------------------- ** Create buttons on menu bar and specify afterwards ** which one is the Help item. */ Wquit_cascade = AddMenuItem (my_menu_bar, "File", 'F', CASCADE, quit_menu_pane, NULL); Wslct_cascade = AddMenuItem (my_menu_bar, "Select", 'S', CASCADE, slct_menu_pane, NULL); Whelp_cascade = AddMenuItem (my_menu_bar, "Help", 'H', CASCADE, help_menu_pane, NULL); XtSetArg (Args[0], XmNmenuHelpWidget, Whelp_cascade); XtSetValues (my_menu_bar, Args, 1); /*--------------------------------------------------------- ** Put items into the menu bar menu panes. Start with Exit. */ AddMenuItem (quit_menu_pane, "Quit/Finish", 'F', PULL_DOWN, NULL, QuitCB); /*--------------------------------------------------------- ** Now do Select. */ Wmot_cascade = AddMenuItem (slct_menu_pane, "Motor", 'M', CASCADE, mot_menu_pane, NULL); /*--------------------------------------------------------- ** Now do Help. */ AddMenuItem (help_menu_pane, "Context-sensitive Help", 'C', PULL_DOWN, NULL, ActivateCB); AddMenuItem (help_menu_pane, NULL, '\0', SEPARATOR, NULL, NULL); AddMenuItem (help_menu_pane, "Overview", 'O', PULL_DOWN, NULL, ActivateCB); /*--------------------------------------------------------- ** Now do Motor. */ AddMenuItem (mot_menu_pane, "1", '1', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "2", '2', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "3", '3', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "4", '4', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "5", '5', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "6", '6', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "7", '7', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "8", '8', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "9", '9', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "10 (0x0a)", 'a', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "11 (0x0b)", 'b', PULL_DOWN, NULL, MotorSelectCB); AddMenuItem (mot_menu_pane, "12 (0x0c)", 'c', PULL_DOWN, NULL, MotorSelectCB); return my_menu_bar; } /* **--------------------------------------------------------------------------- ** CreateApplication - set up main window. Return value ** is main window widget. */ Widget CreateApplication (Widget parent) { /* ================= */ Widget main_window; /* MainWindow */ Widget form_0; /* Form Widget */ Widget rc_00; /* RowColumn Widget */ Widget rc_01; /* RowColumn Widget */ XmString tmp_cmpStr; char text[80]; int i_left, i_right, i_soll, i_ist; /*-------------------------------------------------------------*/ i_left = (int) (Mot_lo_lim * Mot_factor); i_right = (int) (Mot_hi_lim * Mot_factor); i_soll = (int) (Mot_pos_soll * Mot_factor); i_ist = (int) (Mot_pos_ist * Mot_factor); Mot_scale_middle = (Mot_lo_lim + Mot_hi_lim)/2.0; if (Mot_pos_soll < Mot_scale_middle) { Mot_is_on_left = True; }else { Mot_is_on_left = False; } /*------------------------------------------------------------- ** 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); XtVaSetValues (form_0, XmNfractionBase, (i_right - i_left), NULL); XtManageChild (form_0); /* ** Create label to show lower limit */ sprintf (text, "%.*f", Mot_state.dec_pt, Mot_lo_lim); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); Nargs = 0; XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_BEGINNING); Nargs++; XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++; XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++; Label_lo_lim = XmCreateLabel (form_0, "Lo_Lim_Label", Args, Nargs); XtManageChild (Label_lo_lim); XmStringFree (tmp_cmpStr); /* ** Create label to show motor number and name */ sprintf (text, "Motor %d \"%s\"", Motor, Mot_state.name); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); Nargs = 0; XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_CENTER); Nargs++; XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++; XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++; Label_name = XmCreateLabel (form_0, "Name_Label", Args, Nargs); XtManageChild (Label_name); XmStringFree (tmp_cmpStr); /* ** Create label to show upper limit */ sprintf (text, "%.*f", Mot_state.dec_pt, Mot_hi_lim); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); Nargs = 0; XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_END); Nargs++; XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++; XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++; Label_hi_lim = XmCreateLabel (form_0, "Hi_Lim_Label", Args, Nargs); XtManageChild (Label_hi_lim); XmStringFree (tmp_cmpStr); /* ** Create scales -- use resource value as dimension. */ /* ** Create label to show "Soll" position */ sprintf (text, "%.*f", Mot_state.dec_pt, Mot_pos_soll); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); Nargs = 0; XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++; Label_soll = XmCreateLabel (form_0, "Soll_Label", Args, Nargs); XtManageChild (Label_soll); XmStringFree (tmp_cmpStr); /* ** Create scales to show "Soll" and "Ist" positions */ Nargs = 0; XtSetArg (Args[Nargs], XmNdecimalPoints, Mot_state.dec_pt); Nargs++; XtSetArg (Args[Nargs], XmNminimum, i_left); Nargs++; XtSetArg (Args[Nargs], XmNmaximum, i_right); Nargs++; XtSetArg (Args[Nargs], XmNorientation, XmHORIZONTAL); Nargs++; XtSetArg (Args[Nargs], XmNscaleWidth, Scale_width); Nargs++; Scale_soll = XmCreateScale (form_0, "Soll_Scale", Args, Nargs); XtManageChild (Scale_soll); Scale_ist = XmCreateScale (form_0, "Ist_Scale", Args, Nargs); XtManageChild (Scale_ist); XtVaSetValues (Scale_soll, XmNvalue, i_soll, XmNsensitive, True, NULL); XtVaSetValues (Scale_ist, XmNvalue, i_ist, XmNsensitive, False, NULL); XtAddCallback (Scale_soll, XmNdragCallback, (XtCallbackProc) SollCB, NULL); XtAddCallback (Scale_soll, XmNvalueChangedCallback, (XtCallbackProc) SollCB, NULL); /* ** Create label to show "Ist" position */ sprintf (text, "%.*f", Mot_state.dec_pt, Mot_pos_ist); tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET); Nargs = 0; XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++; Label_ist = XmCreateLabel (form_0, "Ist_Label", Args, Nargs); XtManageChild (Label_ist); XmStringFree (tmp_cmpStr); /* ** Create RowColumn widgets for status displays */ Nargs = 0; XtSetArg (Args[Nargs], XmNnumColumns, 1); Nargs++; XtSetArg (Args[Nargs], XmNpacking, XmPACK_COLUMN); Nargs++; XtSetArg (Args[Nargs], XmNorientation, XmVERTICAL); Nargs++; XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_BEGINNING); Nargs++; rc_00 = XmCreateRowColumn (form_0, "RowCol_00", Args, Nargs); XtManageChild (rc_00); 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_BEGINNING); Nargs++; rc_01 = XmCreateRowColumn (form_0, "RowCol_01", Args, Nargs); XtManageChild (rc_01); /* ** create labels for RowColumn widgets */ EncodeMSR (text, sizeof (text), Mot_state.msr, Mot_state.ored_msr, Mot_state.fp_cntr, Mot_state.fr_cntr); Label_msr = MakeLabel (rc_00, text, XmALIGNMENT_BEGINNING); EncodeSS (text, Mot_state.ss); Label_ss = MakeLabel (rc_00, text, XmALIGNMENT_BEGINNING); sprintf (text, "Statistics: Total/Faults/Fails/Cush-fails = %d/%d/%d/%d", Mot_state.stat_pos, Mot_state.stat_pos_flt, Mot_state.stat_pos_fail, Mot_state.stat_cush_fail); Label_stats = MakeLabel (rc_00, text, XmALIGNMENT_BEGINNING); sprintf (text, "Encoder Ratio, FD = %d:%d", Mot_state.enc_factor[0], Mot_state.enc_factor[1]); Label_fd = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "Motor Ratio, FM = %d:%d", Mot_state.mot_factor[0], Mot_state.mot_factor[1]); Label_fm = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "Inertia tol'nce, D = %s", Mot_state.inertia_tol); Label_d = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "Start/stop ramp, E = %d", Mot_state.ramp); Label_e = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); switch (Mot_state.loop_mode) { case 0: sprintf (text, "Open loop mode, F = 0"); break; case 1: sprintf (text, "Closed loop mode, F = 1"); break; default: sprintf (text, "Bad loop mode, F = %d", Mot_state.loop_mode); } Label_f = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "Start/stop Hz, G = %d", Mot_state.slow_hz); Label_g = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "Positioning Hz, J = %d", Mot_state.fast_hz); Label_j = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); switch (Mot_state.ref_mode) { case 0: sprintf (text, "Absolute encoder, K = 0"); break; case 1: sprintf (text, "HiLimit is RefPt, K = 1"); break; case -1: sprintf (text, "LoLimit is RefPt, K = -1"); break; case 2: sprintf (text, "Sep RefPt, K = 2"); break; case 11: sprintf (text, "HiLimit is RefPt + Indx, K = 11"); break; case -11: sprintf (text, "LoLimit is RefPt + Indx, K = -11"); break; case 12: sprintf (text, "Sep RefPt + Indx, K = 12"); break; default: sprintf (text, "RefMode unknown, K = %d", Mot_state.ref_mode); } Label_k = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "Backlash, L = %d", Mot_state.backlash); Label_l = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "Position Tol'nce, M = %d", Mot_state.pos_tol); Label_m = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "RefPt Width, Q = %s", Mot_state.ref_param); Label_q = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); if (Mot_state.is_sided == 0) { sprintf (text, "No dir'n dependency, T = 0"); }else if (Mot_state.is_sided > 0) { sprintf (text, "Position from above, T = %d", Mot_state.is_sided); }else { sprintf (text, "Position from below, T = %d", Mot_state.is_sided); } Label_t = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "NullPt, V = %s", Mot_state.null_pt); Label_v = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); if (Mot_state.ac_par == 0) { sprintf (text, "No air-cushion present, W = 0"); }else if (Mot_state.ac_par == Motor) { if (Mot_state.ac_state == 0) { sprintf (text, "Air-cushion down"); }else { sprintf (text, "Air-cushion up"); } }else { if (Mot_state.ac_state == 0) { sprintf (text, "Air-cushion up (chained to %d)", Mot_state.ac_par); }else { sprintf (text, "Air-cushion down (chained to %d)", Mot_state.ac_par); } } Label_w = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); if (Mot_state.out == 0) { sprintf (text, "Output signal not active", Mot_state.null_pt); }else { sprintf (text, "Output signal active", Mot_state.null_pt); } Label_out = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); if (Mot_state.in == 0) { sprintf (text, "Input signal not present"); }else { sprintf (text, "Input signal present"); } Label_in = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); sprintf (text, "Enc Circum, Z = %d", Mot_state.enc_circ); Label_z = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING); /* ** Create DrawnButton in Frame for a bit of research */ #if Blink_On Nargs = 0; DrawnButFrame = XmCreateFrame (form_0, "Button_Frame", Args, Nargs); XtManageChild (DrawnButFrame); Nargs = 0; XtSetArg (Args[Nargs], XmNminimum, i_left); Nargs++; XtSetArg (Args[Nargs], XmNmaximum, i_right); Nargs++; XtSetArg (Args[Nargs], XmNwidth, Scale_width/2); Nargs++; XtSetArg (Args[Nargs], XmNheight, 100); Nargs++; DrawnBut = XmCreateDrawnButton (DrawnButFrame, "Drawn_Button", Args, Nargs); XtManageChild (DrawnBut); #endif /* Blink_On */ /*------------------------------------------------------------- ** Organise the components of the Main Form */ XtVaSetValues (Label_lo_lim, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, NULL); XtVaSetValues (Label_name, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, Label_lo_lim, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, Label_hi_lim, NULL); XtVaSetValues (Label_hi_lim, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); XtVaSetValues (Label_soll, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, Label_name, NULL); if (Mot_is_on_left) { XtVaSetValues (Label_soll, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, (i_soll - i_left), NULL); }else { XtVaSetValues (Label_soll, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, (i_soll - i_left), NULL); } XtVaSetValues (Scale_soll, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, Label_soll, NULL); XtVaSetValues (Scale_ist, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, Scale_soll, NULL); XtVaSetValues (Label_ist, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, Scale_ist, NULL); if (Mot_is_on_left) { XtVaSetValues (Label_ist, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, (i_ist - i_left), NULL); }else { XtVaSetValues (Label_ist, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, (i_ist - i_left), NULL); } XtVaSetValues (rc_00, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, Label_ist, NULL); XtVaSetValues (rc_01, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, rc_00, NULL); #if Blink_On XtVaSetValues (DrawnButFrame, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, Label_stats, NULL); #endif /* Blink_On */ return main_window; } /* **========================================================================== ** Main line program ** ------------------ */ int main (int argc, char **argv) { /* ============================ */ Widget main_window; /* MainWindow */ int status, i; /*------------------------------------------------- ** Initialize Mot_state to rubbish. */ memset (&Mot_state, '%', sizeof (Mot_state)); Mot_state.motor = Motor; Mot_state.exists = False; Mot_state.ored_msr = 0; Mot_state.fp_cntr = 0; Mot_state.fr_cntr = 0; Mot_state.pos_real[15] = '\0'; Mot_state.name[15] = '\0'; Mot_state.inertia_tol[15] = '\0'; Mot_state.lims[0][15] = '\0'; Mot_state.lims[1][15] = '\0'; Mot_state.ref_param[15] = '\0'; Mot_state.null_pt[15] = '\0'; Mot_state.set_real[15] = '\0'; memcpy (&Old_Mot_state, &Mot_state, sizeof (Mot_state)); /* ** Initialize toolkit and open the display. */ Wtop_level = XtAppInitialize (&App_context, "SinQ_rc", OpTable, XtNumber(OpTable), &argc, argv, NULL, NULL, 0); XtGetApplicationResources (Wtop_level, (XtPointer) &AppData, Resources, XtNumber(Resources), NULL, 0); printf ("Motor Client, Version %s\n\n", ident); if (strcmp (AppData.vme_motor_host, "Undefined") == 0) { printf (" \"-host\" not specified!\n\n"); return EXIT_FAILURE; } if (AppData.v24_chan == 0xffff) { printf (" \"-chan\" not specified!\n\n"); return EXIT_FAILURE; }else if ((AppData.v24_chan < 0) || (AppData.v24_chan > 15)) { printf (" \"-chan\" is illegal!\n\n"); return EXIT_FAILURE; } if ((AppData.vme_motor_number <= 0) || (AppData.vme_motor_number > 12)) { printf (" \"-motor\" not specified or illegal!\n\n"); return EXIT_FAILURE; } printf ("Motor Server = \"%s\"\n", AppData.vme_motor_host); if (AppData.vme_motor_port == 0) { AppData.vme_motor_port = 4000; printf ("Default TCP/IP Port = %d\n", AppData.vme_motor_port); }else { printf ("TCP/IP Port = %d\n", AppData.vme_motor_port); } printf ("RS-232-C channel = %d\n", AppData.v24_chan); printf ("Polling delay = %d msec.\n", AppData.msec_timer); Scale_width = AppData.scale_width; printf ("Scale width = %d pixels.\n\n", Scale_width); Motor = AppData.vme_motor_number; printf ("Motor number = %d.\n\n", Motor); printf ("Opening connection to Motor Server ...\n"); Cnct_skt = ConnectToSrvr (AppData.vme_motor_host, AppData.vme_motor_port); Mot_state.motor = Motor; printf ("Ensuring EL734 is in \"rmt 1\" mode ...\n"); status = SendCmndToServer (AppData.v24_chan, TMO, &Respon_buff, sizeof (Respon_buff), "rmt 1\r", NULL, "rmt 1\r", NULL, NULL); printf ("Ensuring EL734 is in \"echo 0\" mode ...\n"); status = SendCmndToServer (AppData.v24_chan, TMO, &Respon_buff, sizeof (Respon_buff), "echo 0\r", NULL, NULL); printf ("Getting full status of Motor ...\n"); GetMotorStatus (FULL__STATUS, &Mot_state); if (!Mot_state.exists) { printf ("\007Selected motor is off-line.\n"); exit (False); } memcpy (&Old_Mot_state, &Mot_state, sizeof (Mot_state)); main_window = CreateApplication (Wtop_level); /* ** Realize Widgets */ XtRealizeWidget (Wtop_level); /* ** Make a timer so that the display gets updated regularly. */ if (AppData.msec_timer > 0) { XtAppAddTimeOut (App_context, AppData.msec_timer, TimerCB, NULL); } else { printf ("msecTimer = 0. Continuous status update disabled.\n"); } /* ** process events */ XtAppMainLoop (App_context); } /*------------------------------------------------------ End of EL734.C */