home *** CD-ROM | disk | FTP | other *** search
- /* code to manage the stuff on the (permanent) main menu.
- * this is also where the single static Now struct is maintained.
- * the calendar is managed in calmenu.c.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #if defined(__STDC__)
- #include <stdlib.h>
- #endif
- #include <X11/Xlib.h>
- #include <X11/keysym.h>
- #include <Xm/Xm.h>
- #include <Xm/Form.h>
- #include <Xm/Frame.h>
- #include <Xm/Label.h>
- #include <Xm/PushB.h>
- #include <Xm/RowColumn.h>
- #include <Xm/Separator.h>
- #include <Xm/SelectioB.h>
- #include "astro.h"
- #include "circum.h"
- #include "preferences.h"
-
- typedef struct {
- int id; /* see below -- used just as a cross-check */
- char *prompt; /* used when asking for new value or NULL if can't */
- char *label; /* used for the menu label or NULL */
- char *name; /* used when selecting for plotting or NULL if can't */
- char *altp[3]; /* alternate prompts based on preferences */
- Widget pb_w; /* pushbutton for display and changing/selecting */
- } Field;
-
- #if defined(__STDC__) || defined(__cplusplus)
- #define P_(s) s
- #else
- #define P_(s) ()
- #endif
-
- extern double mjd_day P_((double jd));
- extern double mjd_hr P_((double jd));
- extern int f_ison P_((void));
- extern int listing_ison P_((void));
- extern int plot_cartesian P_((FILE *pfp, Widget widget, unsigned int nx, unsigned int ny, int flipx, int flipy, int grid));
- extern int plot_ison P_((void));
- extern int srch_eval P_((double Mjd, double *tmincp));
- extern void all_update P_((Now *np, int how_much));
- extern void cal_mjd P_((int mn, double dy, int yr, double *Mjd));
- extern void calm_set P_((Now *np));
- extern void db_invalidate P_((void));
- extern void f_date P_((Widget w, double jd));
- extern void f_dec_sexsign P_((double x, int *h, int *m, int *s));
- extern void f_double P_((Widget w, char *fmt, double f));
- extern void f_gangle P_((Widget w, double a));
- extern void f_mtime P_((Widget w, double t));
- extern void f_off P_((void));
- extern void f_on P_((void));
- extern void f_signtime P_((Widget w, double t));
- extern void f_sscandate P_((char *bp, int pref, int *m, double *d, int *y));
- extern void f_sscansex P_((char *bp, int *d, int *m, int *s));
- extern void f_string P_((Widget w, char *s));
- extern void f_time P_((Widget w, double t));
- extern void get_xmstring P_((Widget w, char *resource, char **txtp));
- extern void gst_utc P_((double Mjd, double gst, double *utc));
- extern void inc_mjd P_((Now *np, double inc));
- extern void listing P_((void));
- extern void mjd_cal P_((double Mjd, int *mn, double *dy, int *yr));
- extern void mjd_year P_((double Mjd, double *yr));
- extern void now_lst P_((Now *np, double *lst));
- extern void plot P_((void));
- extern void plot_manage P_((void));
- extern void prompt_map_cb P_((Widget w, XtPointer client, XtPointer call));
- extern void range P_((double *v, double r));
- extern void register_selection P_((char *name));
- extern void set_t0 P_((Now *np));
- extern void set_xmstring P_((Widget w, char *resource, char *txt));
- extern void sex_dec P_((int hd, int m, int s, double *d));
- extern void time_fromsys P_((Now *np));
- extern void twilight_cir P_((Now *np, double dis, double *dawn, double *dusk, int *status));
- extern void watch_cursor P_((int want));
- extern void xe_msg P_((char *msg, int app_modal));
- extern void year_mjd P_((double y, double *Mjd));
-
- void mm_manage P_((Widget main_window));
- void mm_reset P_((void));
- void mm_newcaldate P_((double newmjd));
- void mm_selection_mode P_((int whether));
- Now *mm_get_now P_((void));
- void redraw_screen P_((int how_much));
- static void create_main_form P_((Widget main_window));
- static void read_default_resources P_((void));
- static Widget fw P_((int fid));
- static void mm_set_buttons P_((int whether));
- static void mm_activate_cb P_((Widget w, XtPointer client, XtPointer call));
- static void mm_set_pref_prompts P_((Field *fp));
- static void mm_timer_cb P_((XtPointer client, XtIntervalId *id));
- static void mm_go_cb P_((Widget w, XtPointer client, XtPointer call));
- static void mm_go P_((void));
- static void print_tminc P_((int force));
- static void print_updating P_((void));
- static void print_idle P_((void));
- static void print_running P_((void));
- static void print_status P_((char *s));
- static void print_nstep P_((int force));
- static void print_spause P_((int force));
- static crack_fieldset P_((char *buf));
- static chg_fld P_((char *bp, Field *fp));
- static void prompt_ok_cb P_((Widget w, XtPointer client, XtPointer call));
- static void prompt P_((Field *fp));
- static void mm_now P_((int all));
- static void mm_twilight P_((int force));
- static void mm_newcir P_((int y));
-
- #undef P_
-
- extern Widget toplevel_w;
- extern char *myclass;
- extern XtAppContext xe_app;
- #define XtD XtDisplay(toplevel_w)
- extern char *sys_errlist[];
- extern errno;
- extern Widget calm_create();
-
- /* shorthands for fields of a Now structure, now.
- * first undo the ones for a Now pointer from circum.h.
- */
- #undef mjd
- #undef lat
- #undef lng
- #undef tz
- #undef temp
- #undef pressure
- #undef elev
- #undef dip
- #undef epoch
- #undef tznm
-
- #define mjd now.n_mjd
- #define lat now.n_lat
- #define lng now.n_lng
- #define tz now.n_tz
- #define temp now.n_temp
- #define pressure now.n_pressure
- #define elev now.n_elev
- #define dip now.n_dip
- #define epoch now.n_epoch
- #define tznm now.n_tznm
-
- static Now now; /* where when and how, right now */
- static double tminc; /* hrs to inc time by each loop; RTC means use clock */
- static int nstep; /* steps to go before stopping */
- static int spause; /* secs to pause between steps */
- static int newcir = 1; /* set when circumstances change - means don't tminc */
-
- static XtIntervalId mm_interval_id; /* set while waiting in a pause loop */
- static int mm_selecting; /* set while our fields are being selected */
-
- /* field ids
- * N.B. must be in same order as they appear in mm_field_map[].
- */
- enum {
- UD_FID, UT_FID, JD_FID, LST_FID,TZN_FID, TZONE_FID, LD_FID, LT_FID,
- DIP_FID, DAWN_FID, DUSK_FID, LON_FID, GAP, NSTEP_FID, STPSZ_FID, PAUSE_FID,
- LAT_FID, LONG_FID, ELEV_FID, TEMP_FID, PRES_FID, EPOCH_FID
- };
-
- /* array of label/button pairs.
- * N.B. these must be in the same order as the _FID enums so the XX_FID may
- * be used as indices into the array.
- * N.B. some of the prompts get set based on preferences but we need to put
- * *something* in the prompt field of selectable fields to trigger making a
- * button. These alternate prompts must be set to match the PREF_ enums.
- */
- static Field mm_field_map[] = {
- {UD_FID, "dummy", "UTC Date:","UD",
- { "UTC date (m/d/y or year.d): ",
- "UTC date (y/m/d or year.d): ",
- "UTC date (d/m/y or year.d): "
- }
- },
- {UT_FID, "UTC time (h:m:s): ", "UTC Time:", "UT"},
- {JD_FID, "Julian Date: ", "Julian:", "JD"},
- {LST_FID, "Local sidereal time (h:m:s): ", "Sidereal:", "LST"},
- {TZN_FID, "Timezone abbreviation (3 char max): ", "TZ Name:", NULL},
- {TZONE_FID, "Hours behind UTC: ", "TZ Offset:", "TZ"},
- {LD_FID, "dummy", "Local Date:", "LD",
- { "Local date (m/d/y or year.d): ",
- "Local date (y/m/d or year.d): ",
- "Local date (d/m/y or year.d): "
- }
- },
- {LT_FID, "Local time (h:m:s): ", "Local Time:", "LT"},
- {DIP_FID, "Sun's twilight dip, degrees below", "Twilight Dip:", NULL},
- {DAWN_FID, NULL, "Dawn:", "Dawn"},
- {DUSK_FID, NULL, "Dusk:", "Dusk"},
- {LON_FID, NULL, "Night Length:", "NiteLen"},
- {GAP},
- {NSTEP_FID, "Number of steps to run: ", "N Steps:", NULL},
- {STPSZ_FID, "\
- Step size increment:\n\
- h:m:s, or\n\
- <x>d for x days, or\n\
- <x>s for x sidereal days, or\n\
- r for RTC", "Step Size:", NULL},
- {PAUSE_FID, "Seconds to pause between steps: ", "Pause:", NULL},
- {LAT_FID, "Latitude (+ north) (d:m:s): ", "Latitude:", "Lat"},
- {LONG_FID, "Longitude (+ west) (d:m:s): ", "Longitude:", "Long"},
- {ELEV_FID, "dummy", "Elevation:", "Elev",
- { "Elevation above sea level (ft): ",
- "Elevation above sea level (m): "
- }
- },
- {TEMP_FID, "dummy", "Temperature:", "Temp",
- { "Temperature (degrees F): ",
- "Temperature (degrees C): "
- }
- },
- {PRES_FID, "dummy", "Atm Pressure:","AtmPr",
- { "Atmospheric pressure (inches of Mercury):",
- "Atmospheric pressure (mBar):"
- }
- },
- {EPOCH_FID, "Epoch (decimal year): ", "Epoch:", NULL},
- };
-
- #define NFM XtNumber(mm_field_map)
- #define LFM (&mm_field_map[NFM])
-
- static Widget newcir_w;
- static Widget status_w;
- static Widget go_w;
-
- /* this is the list of keywords that allow some initial values to be set.
- * these are resources to the XEphem class as "XEphem.<keyword>: <value>".
- */
- /* N.B. index of item is its switch/case value in crack_fieldset ()
- */
- static char *keywords[] = {
- /* 0 */ "Epoch",
- /* 1 */ "Elevation",
- /* 2 */ "JD",
- /* 3 */ "Lat",
- /* 4 */ "Long",
- /* 5 */ "NSteps",
- /* 6 */ "Pause",
- /* 7 */ "Pressure",
- /* 8 */ "StepSize",
- /* 9 */ "Temp",
- /* 10 */ "TZName",
- /* 11 */ "TZone",
- /* 12 */ "UD",
- /* 13 */ "UT",
- /* 14 */ "TwilightDip",
- /* 15 */ "LD",
- /* 16 */ "LT",
- /* 17 */ "LST",
- };
-
- /* called exactly once when the main form is made.
- * create and manage all the widgets as children of the form_w.
- */
- void
- mm_manage (main_window)
- Widget main_window;
- {
- create_main_form(main_window);
- mm_reset();
- }
-
- /* reset things to their initial resource settings */
- void
- mm_reset()
- {
- read_default_resources ();
- redraw_screen (1);
- mm_newcir(0);
- mm_set_buttons (mm_selecting);
- print_idle();
- }
-
- /* called by the calendar subsystem to set a new UT date.
- * newmjd is the new UT date/time as a modifed Julian date.
- */
- void
- mm_newcaldate (newmjd)
- double newmjd;
- {
- mjd = newmjd;
- set_t0 (&now);
- mm_now (1);
- mm_newcir(1);
- newcir = 1;
- }
-
- /* called by other menus as they want to hear from our buttons or not.
- * the "on"s and "off"s stack - only really redo the buttons if it's the
- * first on or the last off.
- */
- void
- mm_selection_mode (whether)
- int whether; /* whether setting up for plotting or for not plotting */
- {
- mm_selecting += whether ? 1 : -1;
-
- if (whether && mm_selecting == 1 /* first one to want on */
- || !whether && mm_selecting == 0 /* last one to want off */)
- mm_set_buttons (whether);
- }
-
- /* a way for anyone to know what now is */
- Now *
- mm_get_now()
- {
- return (&now);
- }
-
- /* draw all the stuff on the managed menus.
- * if how_much == 0 then just update fields that need it;
- * if how_much == 1 then redraw all fields;
- */
- void
- redraw_screen (how_much)
- int how_much;
- {
- watch_cursor(1);
-
- /* invalidate any cached values in the database */
- db_invalidate();
-
- /* print the single-step message if this is the last loop */
- if (nstep < 1)
- print_updating();
-
- /* if just updating changed fields while plotting or listing
- * unattended then suppress most screen updates except
- * always show nstep to show plot loops to go and
- * always show tminc to show search convergence progress.
- */
- print_nstep(how_much);
- print_tminc(how_much);
- print_spause(how_much);
- if (how_much == 0 && nstep > 0 && spause == 0)
- f_off();
-
- /* print all the time-related fields */
- mm_now (how_much);
-
- mm_twilight (how_much);
-
- /* print stuff on other menus */
- all_update(&now, how_much);
-
- f_on();
-
- watch_cursor(0);
- }
-
- static void
- create_main_form(main_window)
- Widget main_window;
- {
- static int fmi[4] = {0, 8, 16, NFM};
- XmString str;
- Widget mrc_w, hrc_w, rc_w;
- Widget sep_w;
- Widget w;
- Arg args[20];
- int i, n;
-
- /* create the main vertical r/c */
- n = 0;
- XtSetArg (args[n], XmNisAligned, False); n++;
- mrc_w = XmCreateRowColumn (main_window, "MainRC", args, n);
-
- /* make the status label */
- n = 0;
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- XtSetArg (args[n], XmNrecomputeSize, False); n++;
- status_w = XmCreateLabel (mrc_w, "Status", args, n);
- XtManageChild (status_w);
-
- /* make a separator widget */
- n = 0;
- sep_w = XmCreateSeparator (mrc_w, "HSep2", args, n);
- XtManageChild (sep_w);
-
- /* make the "NEW CIRCUMSTANCES" label */
- n = 0;
- XtSetArg (args[n], XmNrecomputeSize, False); n++;
- newcir_w = XmCreateLabel (mrc_w, "NewCir", args, n);
- XtManageChild(newcir_w);
-
- /* make a separator widget */
- n = 0;
- sep_w = XmCreateSeparator (mrc_w, "HSep3", args, n);
- XtManageChild (sep_w);
-
- /* make a horizontal r/c across the bottom.
- * fill it in with three vertical r/cs and the calendar, with
- * separators.
- */
-
- n = 0;
- XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
- hrc_w = XmCreateRowColumn (mrc_w, "BottomRC", args, n);
- XtManageChild (hrc_w);
-
- for (i = 0; i < 3; i++) {
- int f;
-
- n = 0;
- rc_w = XmCreateRowColumn (hrc_w, "MainRC", args, n);
- XtManageChild (rc_w);
-
- for (f = fmi[i]; f < fmi[i+1]; f++) {
- Field *fp = &mm_field_map[f];
- Widget f_w;
-
- switch (fp->id) {
- case GAP: /* make a gap label */
- n = 0;
- w = XmCreateSeparator (rc_w, "GapSep", args, n);
- XtManageChild (w);
- n = 0;
- fp->pb_w = XmCreatePushButton (rc_w, "Gap", args, n);
- XtManageChild (fp->pb_w);
- set_xmstring (fp->pb_w, XmNlabelString, " ");
- continue;
- }
-
- /* make a form */
- n = 0;
- f_w = XmCreateForm (rc_w, "MainF", args, n);
- XtManageChild (f_w);
-
- /* make the pushbutton in the right half. */
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++;
- if (fp->name)
- XtSetArg (args[n], XmNuserData, fp->name); n++;
- fp->pb_w = XmCreatePushButton (f_w, "MainPB", args, n);
- if (fp->prompt || fp->name)
- XtAddCallback (fp->pb_w, XmNactivateCallback,
- mm_activate_cb, fp);
- XtManageChild(fp->pb_w);
-
- /* make the label in the left half */
- n = 0;
- str = XmStringCreateLtoR(fp->label, XmSTRING_DEFAULT_CHARSET);
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNrightWidget, fp->pb_w); n++;
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- XtSetArg (args[n], XmNlabelString, str); n++;
- w = XmCreateLabel (f_w, "MainLabel", args, n);
- XtManageChild(w);
- XmStringFree (str);
- }
-
- /* make a separator widget */
- n = 0;
- XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
- sep_w = XmCreateSeparator (hrc_w, "VSep", args, n);
- XtManageChild (sep_w);
- }
-
- /* make the calendar */
-
- w = calm_create (hrc_w);
- XtManageChild (w);
-
- /* make a separator widget */
- n = 0;
- sep_w = XmCreateSeparator (mrc_w, "HSep4", args, n);
- XtManageChild (sep_w);
-
- /* put a wide and thick "go" button below all */
- n = 0;
- XtSetArg (args[n], XmNshowAsDefault, True); n++;
- XtSetArg (args[n], XmNrecomputeSize, False); n++;
- XtSetArg (args[n], XmNmarginTop, 3); n++;
- XtSetArg (args[n], XmNmarginBottom, 3); n++;
- go_w = XmCreatePushButton (mrc_w, "Update", args, n);
- XtAddCallback (go_w, XmNactivateCallback, mm_go_cb, 0);
- XtManageChild (go_w);
-
- XtManageChild (mrc_w);
- }
-
- /* set the initial stuff in the Now struct and looping params from the XEphem
- * resources.
- */
- static void
- read_default_resources()
- {
- int i;
-
- for (i = 0; i < XtNumber(keywords); i++) {
- char *dp = XGetDefault (XtD, myclass, keywords[i]);
- if (dp) {
- char buf[128];
- (void) sprintf (buf, "%s=%s", keywords[i], dp);
- if (crack_fieldset (buf) < 0) {
- printf ("Bad resource spec: %s", buf);
- exit (1);
- }
- }
- }
- }
-
- /* get the widget associated with this _FID.
- * We do some error checking.
- */
- static Widget
- fw(fid)
- int fid;
- {
- Field *fp;
-
- if (fid < 0 || fid >= NFM || (fp = &mm_field_map[fid])->id != fid) {
- printf ("mainmenu:fw(): bad field id: %d\n", fid);
- exit(1);
- }
- return (fp->pb_w);
- }
-
- /* go through all the buttons just pickable for plotting and set whether they
- * should appear to look like buttons or just flat labels.
- */
- static void
- mm_set_buttons (whether)
- int whether;
- {
- static Arg look_like_button[] = {
- {XmNtopShadowColor, (XtArgVal) 0},
- {XmNbottomShadowColor, (XtArgVal) 0},
- {XmNfillOnArm, (XtArgVal) True},
- };
- static Arg look_like_label[] = {
- {XmNtopShadowColor, (XtArgVal) 0},
- {XmNbottomShadowColor, (XtArgVal) 0},
- {XmNfillOnArm, (XtArgVal) False},
- };
- static int called;
- Field *fp;
-
- if (!called) {
- /* get baseline label and shadow appearances.
- * arbitrarily get these from the go_w button.
- */
- Pixel topshad, botshad, bgcol;
- Arg args[20];
- int n;
-
- n = 0;
- XtSetArg (args[n], XmNtopShadowColor, &topshad); n++;
- XtSetArg (args[n], XmNbottomShadowColor, &botshad); n++;
- XtSetArg (args[n], XmNbackground, &bgcol); n++;
- XtGetValues (go_w, args, n);
-
- look_like_button[0].value = topshad;
- look_like_button[1].value = botshad;
- look_like_label[0].value = bgcol;
- look_like_label[1].value = bgcol;
-
- called = 1;
- }
-
- for (fp = mm_field_map; fp < LFM; fp++)
- if (whether) {
- if (fp->name)
- XtSetValues(fp->pb_w, look_like_button,
- XtNumber(look_like_button));
- else
- XtSetValues(fp->pb_w, look_like_label,
- XtNumber(look_like_label));
- } else {
- if (fp->prompt)
- XtSetValues(fp->pb_w, look_like_button,
- XtNumber(look_like_button));
- else
- XtSetValues(fp->pb_w, look_like_label,
- XtNumber(look_like_label));
- }
- }
-
- /* callback from any of the main menu buttons being activated.
- * if we are currently selecting fields to plot and the field has a name
- * then inform all the potentially interested parties;
- * else if the field has a prompt then ask the user for a new value.
- */
- /* ARGSUSED */
- static void
- mm_activate_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- Field *fp = (Field *)client;
-
- if (mm_selecting) {
- if (fp->name)
- register_selection (fp->name);
- } else {
- if (fp->prompt) {
- mm_set_pref_prompts (fp);
- prompt (fp);
- }
- }
- }
-
- /* set up those prompts that depend in preferences.
- */
- static void
- mm_set_pref_prompts(fp)
- Field *fp;
- {
- switch (fp->id) {
- case UD_FID:
- case LD_FID:
- fp->prompt = fp->altp[pref_get(PREF_DATE_FORMAT)];
- break;
- case ELEV_FID:
- case TEMP_FID:
- case PRES_FID:
- fp->prompt = fp->altp[pref_get(PREF_UNITS)];
- break;
- }
- }
-
- /* function called from the interval timer used to implement the
- * auto repeat feature.
- */
- /* ARGSUSED */
- static void
- mm_timer_cb (client, id)
- XtPointer client;
- XtIntervalId *id;
- {
- int waited_so_far = (int)client + 1;
-
- mm_interval_id = 0;
-
- if (waited_so_far < spause)
- mm_interval_id = XtAppAddTimeOut (xe_app, 1000, mm_timer_cb,
- (XtPointer)waited_so_far);
- else
- mm_go();
- }
-
- /* callback from the main "go" button being armed.
- * if we are looping (as evidenced by an active timer) then stop, else go.
- */
- /* ARGSUSED */
- static void
- mm_go_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- if (mm_interval_id != 0) {
- XtRemoveTimeOut (mm_interval_id);
- mm_interval_id = 0;
- redraw_screen (1);
- print_idle();
- } else {
- if (nstep > 1)
- print_running();
- mm_go();
- }
- }
-
- /* increment, update all fields, and go again if more steps.
- */
- static void
- mm_go()
- {
- int srchdone;
-
- /* increment time only if op didn't change cirumstances */
- if (!newcir)
- inc_mjd (&now, tminc);
-
- nstep -= 1;
-
- /* recalculate everything and update all the fields */
- redraw_screen(newcir);
- mm_newcir(0);
-
- /* let searching functions change tminc and check for done */
- srchdone = srch_eval (mjd, &tminc) < 0;
- print_tminc(0); /* to show possibly new search increment */
-
- /* update plot and listing files, now that all fields are up
- * to date and search function has been evaluated.
- */
- plot();
- listing();
-
- /* stop loop to allow op to change parameters:
- * if a search evaluation converges (or errors out),
- * or if steps are done,
- * or if op hits any key.
- */
- newcir = 0;
- if (srchdone || nstep <= 0) {
-
- /* update screen with the current stuff if stopped during
- * searching, unattended plotting or listing since last
- * redraw_screen() didn't.
- */
- if ((srchdone || plot_ison() || listing_ison()) && nstep > 0)
- redraw_screen (1);
-
- /* return nstep to default of 1 */
- if (nstep <= 0) {
- nstep = 1;
- print_nstep (0);
- }
- print_idle();
- } else {
- mm_interval_id =
- XtAppAddTimeOut (xe_app, spause>0 ? 1000 : 120, mm_timer_cb, 0);
- }
- }
-
- static void
- print_tminc(force)
- int force;
- {
- static double last = -123.456; /* anything unlikely */
-
- if (force || tminc != last) {
- if (tminc == RTC)
- f_string (fw(STPSZ_FID), " RT CLOCK");
- else if (fabs(tminc) >= 24.0)
- f_double (fw(STPSZ_FID), "%6.4g dy", tminc/24.0);
- else
- f_signtime (fw(STPSZ_FID), tminc);
- last = tminc;
- }
- }
-
- static void
- print_updating()
- {
- print_status ("Updating...");
- }
-
- static void
- print_idle()
- {
- print_status ("Make changes as desired or select Update to run.");
- f_string (go_w, "Update");
- }
-
- static void
- print_running()
- {
- print_status ("Running... select Stop to stop.");
- f_string (go_w, "Stop");
- }
-
- static void
- print_status (s)
- char *s;
- {
- static char *last_s;
-
- if (s != last_s) {
- f_string (status_w, s);
- XFlush (XtD);
- last_s = s;
- }
- }
-
- static void
- print_nstep(force)
- int force;
- {
- static int last;
-
- if (force || nstep != last) {
- char buf[16];
- (void) sprintf (buf, "%8d", nstep);
- f_string (fw(NSTEP_FID), buf);
- last = nstep;
- }
- }
-
- static void
- print_spause(force)
- int force;
- {
- static int last;
-
- if (force || spause != last) {
- char buf[16];
- (void) sprintf (buf, "%8d", spause);
- f_string (fw(PAUSE_FID), buf);
- last = spause;
- }
- }
-
- /* process a field spec in buf, either from config file or argv.
- * return 0 if recognized ok, else -1.
- */
- static
- crack_fieldset (buf)
- char *buf;
- {
- int i;
-
- for (i = 0; i < XtNumber(keywords); i++) {
- int l = strlen(keywords[i]);
- if (strncmp (buf, keywords[i], l) == 0) {
- buf += l+1; /* skip keyword and its subsequent delimiter */
- break;
- }
- }
-
- /* N.B. the switch entries must match the order in keywords[] */
- switch (i) {
- case 0: (void) chg_fld (buf, &mm_field_map[EPOCH_FID]); break;
- case 1: (void) chg_fld (buf, &mm_field_map[ELEV_FID]); break;
- case 2: (void) chg_fld (buf, &mm_field_map[JD_FID]); break;
- case 3: (void) chg_fld (buf, &mm_field_map[LAT_FID]); break;
- case 4: (void) chg_fld (buf, &mm_field_map[LONG_FID]); break;
- case 5: (void) chg_fld (buf, &mm_field_map[NSTEP_FID]); break;
- case 6: (void) chg_fld (buf, &mm_field_map[PAUSE_FID]); break;
- case 7: (void) chg_fld (buf, &mm_field_map[PRES_FID]); break;
- case 8: (void) chg_fld (buf, &mm_field_map[STPSZ_FID]); break;
- case 9: (void) chg_fld (buf, &mm_field_map[TEMP_FID]); break;
- case 10: (void) chg_fld (buf, &mm_field_map[TZN_FID]); break;
- case 11: (void) chg_fld (buf, &mm_field_map[TZONE_FID]); break;
- case 12: (void) chg_fld (buf, &mm_field_map[UD_FID]); break;
- case 13: (void) chg_fld (buf, &mm_field_map[UT_FID]); break;
- case 14: (void) chg_fld (buf, &mm_field_map[DIP_FID]); break;
- case 15: (void) chg_fld (buf, &mm_field_map[LD_FID]); break;
- case 16: (void) chg_fld (buf, &mm_field_map[LT_FID]); break;
- case 17: (void) chg_fld (buf, &mm_field_map[LST_FID]); break;
- default: return (-1);
- }
- return (0);
- }
-
- /* react to the field at *fp according to the string input at bp.
- * crack the buffer and update the corresponding (global) variable(s)
- * or do whatever a pick at that field should do.
- * return 1 if we change a field that invalidates any of the times or
- * to update all related fields.
- */
- static
- chg_fld (bp, fp)
- char *bp;
- Field *fp;
- {
- int deghrs = 0, mins = 0, secs = 0;
- int new = 0;
- double tmp;
-
- switch (fp->id) {
- case JD_FID:
- if (bp[0] == 'n' || bp[0] == 'N')
- time_fromsys (&now);
- else
- mjd = atof(bp) - MJD0;
- set_t0 (&now);
- new = 1;
- break;
- case UD_FID:
- if (bp[0] == 'n' || bp[0] == 'N')
- time_fromsys (&now);
- else {
- double day, newmjd0;
- int month, year;
-
- mjd_cal (mjd, &month, &day, &year); /* init with now */
- f_sscandate (bp, pref_get(PREF_DATE_FORMAT),
- &month, &day, &year);
- cal_mjd (month, day, year, &newmjd0);
-
- /* if don't give a fractional part to days
- * then retain current hours.
- */
- if ((long)day == day)
- mjd = newmjd0 + mjd_hr(mjd)/24.0;
- else
- mjd = newmjd0;
- }
- set_t0 (&now);
- new = 1;
- break;
- case UT_FID:
- if (bp[0] == 'n' || bp[0] == 'N')
- time_fromsys (&now);
- else {
- double newutc = (mjd-mjd_day(mjd)) * 24.0;
- f_dec_sexsign (newutc, °hrs, &mins, &secs);
- f_sscansex (bp, °hrs, &mins, &secs);
- sex_dec (deghrs, mins, secs, &newutc);
- mjd = mjd_day(mjd) + newutc/24.0;
- }
- set_t0 (&now);
- new = 1;
- break;
- case LD_FID:
- if (bp[0] == 'n' || bp[0] == 'N')
- time_fromsys (&now);
- else {
- double day, newlmjd0;
- int month, year;
-
- mjd_cal (mjd-tz/24.0, &month, &day, &year); /* now */
- f_sscandate (bp, pref_get(PREF_DATE_FORMAT),
- &month, &day, &year);
- cal_mjd (month, day, year, &newlmjd0);
-
- /* if don't give a fractional part to days
- * then retain current hours.
- */
- if ((long)day == day)
- mjd = newlmjd0 + mjd_hr(mjd-tz/24.0)/24.0;
- else
- mjd = newlmjd0;
- mjd += tz/24.0;
- }
- set_t0 (&now);
- new = 1;
- break;
- case LT_FID:
- if (bp[0] == 'n' || bp[0] == 'N')
- time_fromsys (&now);
- else {
- double newlt = (mjd-mjd_day(mjd)) * 24.0 - tz;
- range (&newlt, 24.0);
- f_dec_sexsign (newlt, °hrs, &mins, &secs);
- f_sscansex (bp, °hrs, &mins, &secs);
- sex_dec (deghrs, mins, secs, &newlt);
- mjd = mjd_day(mjd-tz/24.0) + (newlt + tz)/24.0;
- }
- set_t0 (&now);
- new = 1;
- break;
- case LST_FID:
- if (bp[0] == 'n' || bp[0] == 'N')
- time_fromsys (&now);
- else {
- double lst, utc;
- now_lst (&now, &lst);
- f_dec_sexsign (lst, °hrs, &mins, &secs);
- f_sscansex (bp, °hrs, &mins, &secs);
- sex_dec (deghrs, mins, secs, &lst);
- lst -= radhr(lng); /* convert to gst */
- range (&lst, 24.0);
- gst_utc (mjd_day(mjd), lst, &utc);
- mjd = mjd_day(mjd) + utc/24.0;
- }
- set_t0 (&now);
- new = 1;
- break;
- case TZN_FID:
- (void) strncpy (tznm, bp, sizeof(tznm)-1);
- new = 1;
- break;
- case TZONE_FID:
- f_dec_sexsign (tz, °hrs, &mins, &secs);
- f_sscansex (bp, °hrs, &mins, &secs);
- sex_dec (deghrs, mins, secs, &tz);
- new = 1;
- break;
- case LONG_FID:
- f_dec_sexsign (-raddeg(lng), °hrs, &mins, &secs);
- f_sscansex (bp, °hrs, &mins, &secs);
- sex_dec (deghrs, mins, secs, &lng);
- lng = degrad (-lng); /* want - radians west */
- new = 1;
- break;
- case LAT_FID:
- f_dec_sexsign (raddeg(lat), °hrs, &mins, &secs);
- f_sscansex (bp, °hrs, &mins, &secs);
- sex_dec (deghrs, mins, secs, &lat);
- lat = degrad (lat);
- new = 1;
- break;
- case ELEV_FID:
- if (sscanf (bp, "%lf", &elev) == 1) {
- if (pref_get(PREF_UNITS) == PREF_ENGLISH)
- elev /= (ERAD*FTPM); /* ft to earth radii */
- else
- elev /= ERAD; /* m to earth radii */
- new = 1;
- }
- break;
- case DIP_FID:
- if (sscanf (bp, "%lf", &tmp) == 1) {
- if (tmp < 0)
- xe_msg ("Twilight dip must be at least 0", 1);
- else {
- dip = degrad(tmp);
- mm_twilight (1);
- }
- }
- break;
- case NSTEP_FID:
- (void) sscanf (bp, "%d", &nstep);
- print_nstep (0);
- break;
- case PAUSE_FID:
- (void) sscanf (bp, "%d", &spause);
- print_spause (0);
- break;
- case TEMP_FID:
- if (sscanf (bp, "%lf", &temp) == 1) {
- if (pref_get(PREF_UNITS) == PREF_ENGLISH)
- temp = 5./9.*(temp - 32.0); /* want degs C */
- new = 1;
- }
- break;
- case PRES_FID:
- if (sscanf (bp, "%lf", &pressure) == 1) {
- if (pref_get(PREF_UNITS) == PREF_ENGLISH)
- pressure *= 33.86; /* want mBar */
- new = 1;
- }
- break;
- case EPOCH_FID:
- if (bp[0] == 'e' || bp[0] == 'E')
- epoch = EOD;
- else {
- double e;
- e = atof(bp);
- year_mjd (e, &epoch);
- }
- new = 1;
- break;
- case STPSZ_FID:
- if (bp[0] == 'r' || bp[0] == 'R')
- tminc = RTC;
- else {
- char lastc = bp[strlen(bp)-1];
- if (lastc == 'd' || lastc == 'D') {
- /* ends in d so treat as a number of days */
- double x;
- if (sscanf (bp, "%lf", &x) == 1)
- tminc = x * 24.0;
- } else if (lastc == 's' || lastc == 'S') {
- /* ends in s so treat as a number of sidereal days */
- double x;
- if (sscanf (bp, "%lf", &x) == 1)
- tminc = x * 24.0 * SIDRATE;
- } else {
- if (tminc == RTC)
- deghrs = mins = secs = 0;
- else
- f_dec_sexsign (tminc, °hrs, &mins, &secs);
- f_sscansex (bp, °hrs, &mins, &secs);
- sex_dec (deghrs, mins, secs, &tminc);
- }
- }
- print_tminc(0);
- set_t0 (&now);
- break;
- default:
- printf ("chg_fld: unknown id: 0x%x\n", fp->id);
- exit (1);
- }
-
- return (new);
- }
-
- /* user typed OK to a prompt for fp. get his new value and use it */
- static void
- prompt_ok_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XmSelectionBoxCallbackStruct *s = (XmSelectionBoxCallbackStruct *)call;
- Field *fp = (Field *)client;
- char *text, *tmptext;
-
- switch (s->reason) {
- case XmCR_OK:
- get_xmstring(w, XmNtextString, &text);
- break;
- case XmCR_APPLY: /* used for several special short cuts */
- switch (fp->id) {
- case STPSZ_FID:
- tmptext = "r"; /* command to mean "RTC" */
- break;
- case EPOCH_FID:
- tmptext = "e"; /* command to mean "EOD" */
- break;
- case NSTEP_FID:
- tmptext = "99999999"; /* command to mean "Many steps" */
- break;
- case PAUSE_FID:
- tmptext = "0"; /* command to mean "no pause" */
- break;
- case PRES_FID:
- tmptext = "0"; /* command to mean "no refraction" */
- break;
- case UD_FID:
- case JD_FID:
- case LST_FID:
- case LD_FID:
- case LT_FID:
- tmptext = "n"; /* command to mean "Now" */
- break;
- case UT_FID:
- tmptext = "0:00:00"; /* command to mean midnight */
- break;
- default:
- printf ("mainmenu:prompt_ok_cb: bad fid=%d\n", fp->id);
- exit (1);
- break;
- }
- (void) strcpy (text = XtMalloc(strlen(tmptext)+1), tmptext);
- break;
- default:
- return;
- }
-
- if (chg_fld (text, fp)) {
- mm_now (1);
- mm_newcir(1);
- newcir = 1;
- }
- XtDestroyWidget (w);
- XtFree (text);
- }
-
- /* put up a prompt dialog near the cursor to ask about fp.
- * use the Apply button for special shortcuts.
- */
- static void
- prompt (fp)
- Field *fp;
- {
- Widget w, sw, hw, aw;
- XmString str, title;
- Arg args[20];
- int n;
-
- str = XmStringCreateLtoR (fp->prompt, XmSTRING_DEFAULT_CHARSET);
- title = XmStringCreateLtoR ("xephem Prompt", XmSTRING_DEFAULT_CHARSET);
- n = 0;
- XtSetArg(args[n], XmNselectionLabelString, str); n++;
- XtSetArg(args[n], XmNdefaultPosition, False); n++;
- XtSetArg(args[n], XmNdialogTitle, title); n++;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
- sw = XmCreatePromptDialog(toplevel_w, "MainPrompt", args, n);
- XtAddCallback (sw, XmNmapCallback, prompt_map_cb, NULL);
- XtAddCallback (sw, XmNokCallback, prompt_ok_cb, fp);
- XmStringFree (str);
- XmStringFree (title);
-
- /* we don't use the Help button at all. */
- hw = XmSelectionBoxGetChild (sw, XmDIALOG_HELP_BUTTON);
- XtUnmanageChild (hw);
-
- /* we don't use the Apply button except for the special shortcuts */
- aw = XmSelectionBoxGetChild (sw, XmDIALOG_APPLY_BUTTON);
- XtUnmanageChild (aw);
-
- /* use the Apply button for several special shortcuts */
- switch (fp->id) {
- case JD_FID: case UD_FID:
- case LD_FID: case LT_FID: case LST_FID:
- XtAddCallback (sw, XmNapplyCallback, prompt_ok_cb, fp);
- XtManageChild (aw);
- set_xmstring (sw, XmNapplyLabelString, "Now");
- break;
- case UT_FID:
- XtAddCallback (sw, XmNapplyCallback, prompt_ok_cb, fp);
- XtManageChild (aw);
- set_xmstring (sw, XmNapplyLabelString, "0:00:00");
- break;
- case STPSZ_FID:
- XtAddCallback (sw, XmNapplyCallback, prompt_ok_cb, fp);
- XtManageChild (aw);
- set_xmstring (sw, XmNapplyLabelString, "RTC");
- break;
- case EPOCH_FID:
- XtAddCallback (sw, XmNapplyCallback, prompt_ok_cb, fp);
- XtManageChild (aw);
- set_xmstring (sw, XmNapplyLabelString, "Of Date");
- break;
- case NSTEP_FID:
- XtAddCallback (sw, XmNapplyCallback, prompt_ok_cb, fp);
- XtManageChild (aw);
- set_xmstring (sw, XmNapplyLabelString, "Many");
- break;
- case PAUSE_FID:
- XtAddCallback (sw, XmNapplyCallback, prompt_ok_cb, fp);
- XtManageChild (aw);
- set_xmstring (sw, XmNapplyLabelString, "No Pause");
- break;
- case PRES_FID:
- XtAddCallback (sw, XmNapplyCallback, prompt_ok_cb, fp);
- XtManageChild (aw);
- set_xmstring (sw, XmNapplyLabelString, "No Refraction");
- break;
- }
-
- XtManageChild (sw);
-
- #if XmVersion >= 1001
- w = XmSelectionBoxGetChild (sw, XmDIALOG_TEXT);
- XmProcessTraversal (w, XmTRAVERSE_CURRENT);
- XmProcessTraversal (w, XmTRAVERSE_CURRENT); /* yes, twice!! */
- #endif
- }
-
- /* print all the time/date/where related stuff: the Now structure.
- * print in a nice order, based on the field locations, as much as possible.
- */
- static void
- mm_now (all)
- int all;
- {
- char buf[32];
- double lmjd = mjd - tz/24.0;
- double jd = mjd + MJD0;
- double tmp;
-
- (void) sprintf (buf, "%-3.3s", tznm);
- f_string (fw(TZN_FID), buf);
- f_time (fw(LT_FID), mjd_hr(lmjd));
- f_date (fw(LD_FID), lmjd);
-
- f_time (fw(UT_FID), mjd_hr(mjd));
- f_date (fw(UD_FID), mjd);
-
- f_double (fw(JD_FID), "%14.5f", jd);
-
- now_lst (&now, &tmp);
- f_time (fw(LST_FID), tmp);
-
- if (all) {
- f_gangle (fw(LAT_FID), lat);
- f_gangle (fw(LONG_FID), -lng); /* + west */
-
- if (pref_get(PREF_UNITS) == PREF_ENGLISH) {
- tmp = elev * (ERAD*FTPM); /* want ft, not earth radii*/
- f_double (fw(ELEV_FID), "%8.1f ft", tmp);
- } else {
- tmp = elev * ERAD; /* want m, not earth radii */
- f_double (fw(ELEV_FID), "%8.1f m", tmp);
- }
-
- tmp = temp;
- if (pref_get(PREF_UNITS) == PREF_ENGLISH) {
- tmp = 9.*temp/5. + 32.0; /* want to see degrees F, not C */
- #ifdef XK_degree
- (void) sprintf (buf, "%%5.1f %cF", XK_degree);
- } else
- (void) sprintf (buf, "%%5.1f %cC", XK_degree);
- #else
- (void) sprintf (buf, "%%5.1f F");
- } else
- (void) sprintf (buf, "%%5.1f C");
- #endif
- f_double (fw(TEMP_FID), buf, tmp);
-
- tmp = pressure;
- if (pref_get(PREF_UNITS) == PREF_ENGLISH) {
- tmp /= 33.86; /* want to see in. Hg, not mBar */
- f_double (fw(PRES_FID), "%5.2f in", tmp);
- } else {
- f_double (fw(PRES_FID), "%5.0f mB", tmp);
- }
-
- f_signtime (fw(TZONE_FID), tz);
-
- if (epoch == EOD)
- f_string (fw(EPOCH_FID), "Of Date");
- else {
- mjd_year (epoch, &tmp);
- f_double (fw(EPOCH_FID), "%8.1f", tmp);
- }
- }
-
- if (f_ison())
- calm_set (&now);
- }
-
- /* display dawn/dusk/length-of-night times.
- */
- /* ARGSUSED */
- static void
- mm_twilight (force)
- int force;
- {
- double dusk, dawn;
- int status;
- char buf[64];
-
- twilight_cir (&now, dip, &dawn, &dusk, &status);
- if (status & (RS_NORISE|RS_RISERR|RS_NOSET|RS_CIRCUMPOLAR|RS_NEVERUP)) {
- static char nope[] = "-----";
- f_string (fw(DAWN_FID), nope);
- f_string (fw(DUSK_FID), nope);
- f_string (fw(LON_FID), nope);
- } else {
- double tmp;
- f_mtime (fw(DAWN_FID), dawn);
- f_mtime (fw(DUSK_FID), dusk);
- tmp = dawn - dusk; range (&tmp, 24.0);
- f_mtime (fw(LON_FID), tmp);
- }
- #ifdef XK_degree
- (void) sprintf (buf, "%%g%c", XK_degree);
- #else
- (void) sprintf (buf, "%%g degs");
- #endif
- f_double (fw(DIP_FID), buf, raddeg(dip));
- }
-
- static void
- mm_newcir (y)
- int y;
- {
- static char ncmsg[] = "NEW CIRCUMSTANCES";
- static char nomsg[] = " ";
- static int last_y = -1;
-
- if (y != last_y) {
- f_string (newcir_w, y ? ncmsg : nomsg);
- last_y = y;
- }
- }
-