home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xephem / part11 / datamenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-15  |  46.6 KB  |  1,724 lines

  1. /* code to manage the stuff on the "data" menu.
  2.  * functions for the main data table are prefixed with dm.
  3.  * functions for the setup menu are prefixed with ds.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <math.h>
  9. #if defined(__STDC__)
  10. #include <stdlib.h>
  11. #endif
  12. #include <Xm/Xm.h>
  13. #include <Xm/Form.h>
  14. #include <Xm/Frame.h>
  15. #include <Xm/Label.h>
  16. #include <Xm/PushB.h>
  17. #include <Xm/ToggleB.h>
  18. #include <Xm/RowColumn.h>
  19. #include <Xm/Separator.h>
  20. #include "astro.h"
  21. #include "circum.h"
  22. #include "preferences.h"
  23.  
  24. extern Widget    toplevel_w;
  25.  
  26. #if defined(__STDC__) || defined(__cplusplus)
  27. #define P_(s) s
  28. #else
  29. #define P_(s) ()
  30. #endif
  31.  
  32. extern Now *mm_get_now P_((void));
  33. extern Obj *db_basic P_((int id));
  34. extern int any_ison P_((void));
  35. extern void confnd P_((double r, double d, double e, char **name));
  36. extern void db_update P_((Obj *op));
  37. extern void f_angle P_((Widget w, double a));
  38. extern void f_double P_((Widget w, char *fmt, double f));
  39. extern void f_mtime P_((Widget w, double t));
  40. extern void f_ra P_((Widget w, double ra));
  41. extern void f_showit P_((Widget w, char *s));
  42. extern void f_string P_((Widget w, char *s));
  43. extern void get_something P_((Widget w, char *resource, char *value));
  44. extern void get_xmstring P_((Widget w, char *resource, char **txtp));
  45. extern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
  46. extern void prompt_map_cb P_((Widget w, XtPointer client, XtPointer call));
  47. extern void register_selection P_((char *name));
  48. extern void riset_cir P_((Now *np, Obj *op, double dis, RiseSet *rp));
  49. extern void set_something P_((Widget w, char *resource, char *value));
  50. extern void timestamp P_((Now *np, Widget w));
  51. extern void unrefract P_((double pr, double tr, double aa, double *ta));
  52. extern void watch_cursor P_((int want));
  53. extern void xe_msg P_((char *msg, int app_modal));
  54.  
  55. void dm_manage P_((void));
  56. void dm_newobj P_((int dbidx));
  57. void dm_update P_((Now *np, int how_much));
  58. void dm_selection_mode P_((int whether));
  59. void dm_cursor P_((Cursor c));
  60. static void dm_create_form P_((void));
  61. static void dm_set_buttons P_((int whether));
  62. static void dm_create_table P_((Widget parent));
  63. static void dm_activate_cb P_((Widget w, XtPointer client, XtPointer call));
  64. static void dm_close_cb P_((Widget w, XtPointer client, XtPointer call));
  65. static void dm_setup_cb P_((Widget w, XtPointer client, XtPointer call));
  66. static void dm_help_cb P_((Widget w, XtPointer client, XtPointer call));
  67. static void dm_compute P_((int r, int force, Now *np));
  68. static void dm_format P_((Now *np, Obj *op, RiseSet *rp, int c, Widget w));
  69. static void dm_rs_addplus P_((Widget w, int addplus));
  70. static void dm_rs_hrsup P_((Widget w, RiseSet *rp));
  71. static void show_constellation P_((Now *np, Obj *op, Widget w));
  72. static void dm_separation P_((Obj *p, Obj *q, int how, Widget w));
  73. static void ds_create_selection P_((Widget parent));
  74. static void ds_setup_row_selections P_((void));
  75. static void ds_setup_col_selections P_((int what));
  76. static void ds_apply_selections P_((void));
  77. static void ds_ctl_cb P_((Widget w, XtPointer client, XtPointer call));
  78. static void ds_help P_((void));
  79. static void ds_row_toggle_cb P_((Widget w, XtPointer client, XtPointer call));
  80. static void ds_col_toggle_cb P_((Widget w, XtPointer client, XtPointer call));
  81. static void ds_row_all_cb P_((Widget w, XtPointer client, XtPointer call));
  82. static void ds_col_all_cb P_((Widget w, XtPointer client, XtPointer call));
  83. static void ds_row_reset_cb P_((Widget w, XtPointer client, XtPointer call));
  84. static void ds_col_reset_cb P_((Widget w, XtPointer client, XtPointer call));
  85.  
  86. #undef P_
  87.  
  88. typedef struct {
  89.     int dbidx;        /* db index of object on this row */
  90.     int on;        /* whether this row is currently to be on */
  91.     Widget lw;        /* label widget for this row's header */
  92.     Widget sw;        /* pushbutton widget for this row in selection menu */
  93. } RowHdr;
  94.  
  95. static RowHdr row[NOBJ] = {
  96.     {SUN},
  97.     {MOON},
  98.     {MERCURY},
  99.     {VENUS},
  100.     {MARS},
  101.     {JUPITER},
  102.     {SATURN},
  103.     {URANUS},
  104.     {NEPTUNE},
  105.     {PLUTO},
  106.     {OBJX},
  107.     {OBJY},
  108. };
  109.  
  110. typedef struct {
  111.     int type;        /* one of XXX_COL, below */
  112.     char *name;        /* name of column, unless SEP_COL then use db_name */
  113.     int dbidx;        /* if type == SEP_COL, db index of cross object */
  114.     int on;        /* whether this column is currently to be on */
  115.     Widget rcw;        /* RowColumn widget for this column */
  116.     Widget lw;        /* label widget for this column's header */
  117.     Widget sw;        /* pushbutton widget for this col in selection menu */
  118. } ColHdr;
  119.  
  120. /* possible values for ColHdr.type. */
  121. enum {
  122.     MISC_COL, RISET_COL, SEP_COL
  123. };
  124.  
  125. /* identifiers for each entry in col[]. these must match the order therein.
  126.  */
  127. enum {
  128.     CONSTEL_ID, RA_ID, DEC_ID, AZ_ID, ALT_ID, HLONG_ID, HLAT_ID,
  129.     EDST_ID, SDST_ID, ELONG_ID, SIZE_ID, VMAG_ID, PHS_ID, RSTIME_ID,
  130.     RSAZ_ID, TRTIME_ID, TRALT_ID, SETTIME_ID, SETAZ_ID, HRSUP_ID
  131. };
  132.  
  133. /* tags for the various Data Selection control panel buttons */
  134. enum {OK, APPLY, CANCEL, HELP};
  135.  
  136. static ColHdr col[] = {
  137.     {MISC_COL,    "Cns"},
  138.     {MISC_COL,    "R_A"},
  139.     {MISC_COL,    "Dec"},
  140.     {MISC_COL,    "Az"},
  141.     {MISC_COL,    "Alt"},
  142.     {MISC_COL,    "HeLong"},
  143.     {MISC_COL,    "HeLat"},
  144.     {MISC_COL,    "EaDst"},
  145.     {MISC_COL,    "SnDst"},
  146.     {MISC_COL,    "Elong"},
  147.     {MISC_COL,    "Size"},
  148.     {MISC_COL,    "VMag"},
  149.     {MISC_COL,    "Phase"},
  150.     {RISET_COL,    "RiseTm"},
  151.     {RISET_COL,    "RiseAz"},
  152.     {RISET_COL,    "TrnTm"},
  153.     {RISET_COL,    "TrnAlt"},
  154.     {RISET_COL,    "SetTm"},
  155.     {RISET_COL,    "SetAz"},
  156.     {RISET_COL,    "HrsUp"},
  157.     {SEP_COL, (char *)0, SUN},
  158.     {SEP_COL, (char *)0, MOON},
  159.     {SEP_COL, (char *)0, MERCURY},
  160.     {SEP_COL, (char *)0, VENUS},
  161.     {SEP_COL, (char *)0, MARS},
  162.     {SEP_COL, (char *)0, JUPITER},
  163.     {SEP_COL, (char *)0, SATURN},
  164.     {SEP_COL, (char *)0, URANUS},
  165.     {SEP_COL, (char *)0, NEPTUNE},
  166.     {SEP_COL, (char *)0, PLUTO},
  167.     {SEP_COL, (char *)0, OBJX},
  168.     {SEP_COL, (char *)0, OBJY},
  169. };
  170.  
  171. #define    NR    XtNumber(row)
  172. #define    NC    XtNumber(col)
  173.  
  174. static Widget t_w[NR][NC];    /* pushbuttons within table */
  175. static Widget dataform_w;    /* the overall table form */
  176. static Widget table_w;        /* the overall RowColumn table */
  177. static Widget corner_w;        /* upper left corner of table */
  178. static Widget hdrcol_w;        /* RowColumn for first column */
  179. static Widget sel_w;        /* setup menu */
  180. static Widget dt_w;        /* date/time stamp label widget */
  181.  
  182. /* separation perspective */
  183. enum {GEO_CEN, TOPO_CEN};
  184.  
  185. enum {STDREFR, ADPREFR};
  186. enum {LIMB, CENTER};
  187.  
  188. static Widget stdrefr_w;    /* the StdRefr toggle button */
  189. static Widget limb_w;        /* the Center/Limb toggle button */
  190. static Widget refr_w;        /* the horizon label on the data table */
  191. static Widget limbl_w;        /* the Limb label on the data table */
  192. static int horizon;        /* one of STDREFR or ADPREFR */
  193. static int limb;        /* one of CENTER or LIMB */
  194. static Widget geocen_w;        /* the Geocentric toggle button */
  195. static Widget centric_w;    /* the centric label on the data table */
  196. static int centric;        /* one of GEO_CEN or TOPO_CEN */
  197.  
  198. static int dm_selecting;    /* set while our fields are being selected */
  199.  
  200. /* called when the data menu is activated via the main menu pulldown.
  201.  * if never called before, create all the widgets form;
  202.  * otherwise, just toggle whether the form is managed.
  203.  */
  204. void
  205. dm_manage ()
  206. {
  207.     if (!dataform_w)
  208.         dm_create_form();
  209.     
  210.     if (XtIsManaged(dataform_w)) {
  211.         XtUnmanageChild (dataform_w);
  212.         if (XtIsManaged(sel_w))
  213.         XtUnmanageChild(sel_w);
  214.     } else {
  215.         XtManageChild (dataform_w);
  216.         dm_update (mm_get_now(), 1);
  217.         dm_set_buttons (dm_selecting);
  218.     }
  219. }
  220.  
  221. /* user-defined object dbidx has changed.
  222.  * might have a new name, or might be defined or undefined now.
  223.  * must check both the data table and the selection menu.
  224.  * N.B. no need to recompute math -- dm_update() will be called for us.
  225.  */
  226. void
  227. dm_newobj(dbidx)
  228. int dbidx;
  229. {
  230.     static char me[] = "dm_newobj()";
  231.     int i, c;
  232.  
  233.     /* might get called before we have been managed the first time */
  234.     if (!dataform_w)
  235.         return;
  236.  
  237.     for (i = 0; i < NR; i++)
  238.         if (row[i].dbidx == dbidx) {
  239.         Obj *op = db_basic (dbidx);
  240.         if (op->type == UNDEFOBJ) {
  241.             /* it's now undefined so turn off */
  242.             row[i].on = False;
  243.             for (c = 0; c < NC; c++)
  244.             XtUnmanageChild (t_w[i][c]);
  245.             XtUnmanageChild (row[i].lw);
  246.             XtUnmanageChild (row[i].sw);
  247.             XmToggleButtonSetState (row[i].sw, False, False);
  248.         } else {
  249.             f_string (row[i].lw, op->o_name);
  250.             XtManageChild (row[i].sw);
  251.             f_string (row[i].sw, op->o_name);
  252.         }
  253.         break;
  254.         }
  255.     if (i == NR) {
  256.         printf ("Bug: %s: dbidx not in row[]: 0x%x\n", me, dbidx);
  257.         exit (1);
  258.     }
  259.  
  260.     for (i = 0; i < NC; i++)
  261.         if (col[i].type == SEP_COL && col[i].dbidx == dbidx) {
  262.         Obj *op = db_basic (dbidx);
  263.         if (op->type == UNDEFOBJ) {
  264.             /* it's now undefined so turn off */
  265.             col[i].on = False;
  266.             XtUnmanageChild (col[i].rcw);
  267.             XtUnmanageChild (col[i].sw);
  268.             XmToggleButtonSetState (col[i].sw, False, False);
  269.         } else {
  270.             f_string (col[i].lw, op->o_name);
  271.             XtManageChild (col[i].sw);
  272.             f_string (col[i].sw, op->o_name);
  273.         }
  274.         break;
  275.         }
  276.     if (i == NC) {
  277.         printf ("Bug: %s: dbidx not in col[]: 0x%x\n", me, dbidx);
  278.         exit (1);
  279.     }
  280. }
  281.  
  282. /* called to recompute and fill in values for the data menu.
  283.  * don't bother if it doesn't exist or is unmanaged now or no one is logging.
  284.  */
  285. void
  286. dm_update (np, how_much)
  287. Now *np;
  288. int how_much;
  289. {
  290.     int i;
  291.  
  292.     if (!dataform_w)
  293.         return;
  294.     if (!XtIsManaged(dataform_w) && !any_ison() && !how_much)
  295.         return;
  296.  
  297.     /* update each row that is on */
  298.     for (i = 0; i < NR; i++)
  299.         if (row[i].on)
  300.         dm_compute (i, how_much, np);
  301.  
  302.     /* update the datestamp */
  303.     timestamp (np, dt_w);
  304. }
  305.  
  306. /* called by other menus as they want to hear from our buttons or not.
  307.  * the "on"s and "off"s stack - only really redo the buttons if it's the
  308.  * first on or the last off.
  309.  */
  310. void
  311. dm_selection_mode (whether)
  312. int whether;    /* whether setting up for plotting or for not plotting */
  313. {
  314.     dm_selecting += whether ? 1 : -1;
  315.  
  316.     if (dataform_w && XtIsManaged(dataform_w))
  317.         if (whether && dm_selecting == 1     /* first one to want on */
  318.         || !whether && dm_selecting == 0 /* last one to want off */)
  319.         dm_set_buttons (whether);
  320. }
  321.  
  322. /* called to put up or remove the watch cursor.  */
  323. void
  324. dm_cursor (c)
  325. Cursor c;
  326. {
  327.     Window win;
  328.  
  329.     if (dataform_w && (win = XtWindow(dataform_w))) {
  330.         Display *dsp = XtDisplay(dataform_w);
  331.         if (c)
  332.         XDefineCursor (dsp, win, c);
  333.         else
  334.         XUndefineCursor (dsp, win);
  335.     }
  336.  
  337.     if (sel_w && (win = XtWindow(sel_w))) {
  338.         Display *dsp = XtDisplay(sel_w);
  339.         if (c)
  340.         XDefineCursor (dsp, win, c);
  341.         else
  342.         XUndefineCursor (dsp, win);
  343.     }
  344. }
  345.  
  346. static void
  347. dm_create_form()
  348. {
  349.     Widget ctlrc_w, w;
  350.     Arg args[20];
  351.     int n;
  352.  
  353.     /* create the form */
  354.     n = 0;
  355.     XtSetArg (args[n], XmNallowShellResize, True); n++;
  356.     XtSetArg (args[n], XmNautoUnmanage, False); n++;
  357.     XtSetArg (args[n], XmNdefaultPosition, False); n++;
  358.     XtSetArg (args[n], XmNallowOverlap, False); n++;
  359.     dataform_w = XmCreateFormDialog (toplevel_w, "Data", args, n);
  360.  
  361.     /* set some stuff in the parent DialogShell.
  362.      * setting XmNdialogTitle in the Form didn't work..
  363.      */
  364.     n = 0;
  365.     XtSetArg (args[n], XmNtitle, "xephem General Data Table"); n++;
  366.     XtSetValues (XtParent(dataform_w), args, n);
  367.  
  368.     /* make a rowcolumn for the bottom control panel */
  369.  
  370.     n = 0;
  371.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  372.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  373.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  374.     XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
  375.     XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
  376.     XtSetArg (args[n], XmNentryAlignment, XmALIGNMENT_CENTER); n++;
  377.     ctlrc_w = XmCreateRowColumn (dataform_w, "DataTblRC", args, n);
  378.     XtManageChild (ctlrc_w);
  379.  
  380.         /* make the Setup button */
  381.  
  382.         n = 0;
  383.         w = XmCreatePushButton (ctlrc_w, "Setup", args, n);
  384.         XtAddCallback (w, XmNactivateCallback, dm_setup_cb, 0);
  385.         XtManageChild (w);
  386.  
  387.         /* make the close button */
  388.  
  389.         n = 0;
  390.         w = XmCreatePushButton (ctlrc_w, "Close", args, n);
  391.         XtAddCallback (w, XmNactivateCallback, dm_close_cb, 0);
  392.         XtManageChild (w);
  393.  
  394.         /* make the help pushbutton */
  395.  
  396.         n = 0;
  397.         w = XmCreatePushButton (ctlrc_w, "Help", args, n);
  398.         XtAddCallback (w, XmNactivateCallback, dm_help_cb, 0);
  399.         XtManageChild (w);
  400.  
  401.         /* make the horizon, limb and centric indicators in frames.
  402.          * turn them on and off by managing the frames -- but not yet!
  403.          */
  404.  
  405.         n = 0;
  406.         w = XmCreateFrame (ctlrc_w, "DRefrF", args, n);
  407.         n = 0;
  408.         refr_w = XmCreateLabel (w, "DRefrL", args, n);
  409.         XtManageChild (refr_w);
  410.         n = 0;
  411.         w = XmCreateFrame (ctlrc_w, "DLimblF", args, n);
  412.         n = 0;
  413.         limbl_w = XmCreateLabel (w, "DLimblL", args, n);
  414.         XtManageChild (limbl_w);
  415.         n = 0;
  416.         w = XmCreateFrame (ctlrc_w, "DCentricF", args, n);
  417.         n = 0;
  418.         centric_w = XmCreateLabel (w, "DCentricL", args, n);
  419.         XtManageChild (centric_w);
  420.  
  421.         /* make a label for the date/time stamp */
  422.  
  423.         n = 0;
  424.         dt_w = XmCreateLabel (ctlrc_w, "DateStamp", args, n);
  425.         timestamp (mm_get_now(), dt_w);    /* sets initial size correctly*/
  426.         XtManageChild (dt_w);
  427.  
  428.     /* create the table */
  429.  
  430.     n = 0;
  431.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  432.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  433.     XtSetArg (args[n], XmNbottomWidget, ctlrc_w); n++;
  434.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  435.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  436.     XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
  437.     XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
  438.     table_w = XmCreateRowColumn (dataform_w, "DataTable", args, n);
  439.     XtManageChild (table_w);
  440.  
  441.     dm_create_table (table_w);
  442.  
  443.     /* create the selection dialog.
  444.      * don't manage it yet but its state info is used right off.
  445.      */
  446.     ds_create_selection(toplevel_w);
  447.     ds_apply_selections();
  448. }
  449.  
  450. /* go through all the buttons and set whether they
  451.  * should appear to look like buttons or just flat labels.
  452.  */
  453. static void
  454. dm_set_buttons (whether)
  455. int whether;    /* whether setting up for plotting or for not plotting */
  456. {
  457.     static Arg look_like_button[] = {
  458.         {XmNtopShadowColor, (XtArgVal) 0},
  459.         {XmNbottomShadowColor, (XtArgVal) 0},
  460.         {XmNfillOnArm, (XtArgVal) True},
  461.     };
  462.     static Arg look_like_label[] = {
  463.         {XmNtopShadowColor, (XtArgVal) 0},
  464.         {XmNbottomShadowColor, (XtArgVal) 0},
  465.         {XmNfillOnArm, (XtArgVal) False},
  466.     };
  467.     static int called;
  468.     int r, c;
  469.     Arg *ap;
  470.     int na;
  471.  
  472.     if (!called) {
  473.         /* get baseline label and shadow appearances.
  474.          * also make the corner and headers look like labels forever.
  475.          */
  476.         Pixel topshad, botshad, bgcol;
  477.         Arg args[20];
  478.         int n;
  479.         int i;
  480.  
  481.         n = 0;
  482.         XtSetArg (args[n], XmNtopShadowColor, &topshad); n++;
  483.         XtSetArg (args[n], XmNbottomShadowColor, &botshad); n++;
  484.         XtSetArg (args[n], XmNbackground, &bgcol); n++;
  485.         XtGetValues (corner_w, args, n);
  486.  
  487.         look_like_button[0].value = topshad;
  488.         look_like_button[1].value = botshad;
  489.         look_like_label[0].value = bgcol;
  490.         look_like_label[1].value = bgcol;
  491.  
  492.         ap = look_like_label;
  493.         na = XtNumber(look_like_label);
  494.         XtSetValues (corner_w, ap, na);
  495.         for (i = 0; i < NR; i++)
  496.         XtSetValues (row[i].lw, ap, na);
  497.         for (i = 0; i < NC; i++)
  498.         XtSetValues (col[i].lw, ap, na);
  499.  
  500.         called = 1;
  501.     }
  502.  
  503.     if (whether) {
  504.         ap = look_like_button;
  505.         na = XtNumber(look_like_button);
  506.     } else {
  507.         ap = look_like_label;
  508.         na = XtNumber(look_like_label);
  509.     }
  510.     for (r = 0; r < NR; r++)
  511.         for (c = 0; c < NC; c++)
  512.         if (t_w[r][c])
  513.             XtSetValues (t_w[r][c], ap, na);
  514. }
  515.  
  516. /* create the main data table - everything but the first column is unmanaged.
  517.  */
  518. static void
  519. dm_create_table(parent)
  520. Widget parent;    /* overall RowColumn */
  521. {
  522.     Arg args[20];
  523.     XmString str;
  524.     Widget w;
  525.     int r, c;
  526.     int n;
  527.  
  528.     /* first column is the row headers.
  529.      * it's always managed so init what rows we can too.
  530.      */
  531.     n = 0;
  532.     hdrcol_w = XmCreateRowColumn (parent, "DataHdrC", args, n);
  533.     XtManageChild (hdrcol_w);
  534.  
  535.         /* first row is a dummy */
  536.         n = 0;
  537.         str = XmStringCreateLtoR (" ", XmSTRING_DEFAULT_CHARSET);
  538.         n = 0;
  539.         XtSetArg (args[n], XmNlabelString, str); n++;
  540.         corner_w = XmCreatePushButton (hdrcol_w, "DataCorner", args, n);
  541.         XmStringFree (str);
  542.         XtManageChild (corner_w);
  543.  
  544.         /* remaining rows are per object */
  545.         for (r = 0; r < NR; r++) {
  546.         Obj *op = db_basic (row[r].dbidx);
  547.         n = 0;
  548.         if (op->type != UNDEFOBJ)
  549.             w = XmCreatePushButton (hdrcol_w, op->o_name, args, n);
  550.         else
  551.             w = XmCreatePushButton (hdrcol_w, "DRow", args, n);
  552.         row[r].lw = w;
  553.  
  554.         }
  555.  
  556.     /* remaining columns.
  557.      * don't manage any but set names of what we can now too.
  558.      */
  559.     for (c = 0; c < NC; c++) {
  560.         Widget rcw;
  561.  
  562.         n = 0;
  563.         XtSetArg (args[n], XmNadjustMargin, False); n++;
  564.         XtSetArg (args[n], XmNisAligned, False); n++;
  565.         rcw = col[c].rcw = XmCreateRowColumn (parent, "DataCol", args, n);
  566.  
  567.         /* first row is column header */
  568.         n = 0;
  569.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  570.         if (col[c].type != SEP_COL)
  571.         w = XmCreatePushButton (rcw, col[c].name, args, n);
  572.         else {
  573.         Obj *op = db_basic (col[c].dbidx);
  574.         if (op->type != UNDEFOBJ)
  575.             w = XmCreatePushButton (rcw, op->o_name, args, n);
  576.         else
  577.             w = XmCreatePushButton (rcw, "DCHdr", args, n);
  578.         }
  579.         col[c].lw = w;
  580.         XtManageChild (w);
  581.  
  582.         /* remaining rows are per object */
  583.         for (r = 0; r < NR; r++) {
  584.         n = 0;
  585.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  586.         w = t_w[r][c] = XmCreatePushButton (rcw, "DataPB", args, n);
  587.         XtAddCallback(w, XmNactivateCallback, dm_activate_cb,
  588.                     (XtPointer)((c<<8)|r));
  589.         }
  590.     }
  591. }
  592.  
  593. /* callback from any of the data menu buttons being activated.
  594.  * do nothing unless we are being used to set up a selection collection.
  595.  * if the latter, make a name for our field, put it in UserData and inform
  596.  * all interested parties.
  597.  * to form the name, client data is (col<<8)|row
  598.  * N.B. we assume we can't be called if our row and column are not on.
  599.  */
  600. static void
  601. /* ARGSUSED */
  602. dm_activate_cb (w, client, call)
  603. Widget w;
  604. XtPointer client;
  605. XtPointer call;
  606. {
  607.     static char me[] = "dm_activate_cb()";
  608.  
  609.     if (dm_selecting) {
  610.         int r = (unsigned)client & 0xff;
  611.         int c = (unsigned)client >> 8;
  612.         char *name, *rname, *cname;
  613.         Obj *op;
  614.         char *userD;   /* Heller, pg 852, say's this is type Pointer?? */
  615.         int len;
  616.  
  617.         /* figure out our row name */
  618.         if (!row[r].on) {
  619.         printf ("Bug: %s: row[%d] not on\n", me, r);
  620.         exit (1);
  621.         }
  622.         op = db_basic (row[r].dbidx);
  623.         rname = op->o_name;
  624.         len = strlen (rname);
  625.  
  626.         /* figure out our col name */
  627.         if (!col[c].on) {
  628.         printf ("Bug: %s: col[%d] not on\n", me, c);
  629.         exit (1);
  630.         }
  631.         if (col[c].type == SEP_COL) {
  632.         op = db_basic (col[c].dbidx);
  633.         cname = op->o_name;
  634.         } else
  635.         cname = col[c].name;
  636.         len += strlen(cname);
  637.  
  638.         name = XtMalloc (len + 2);    /* '.' plus '\0' */
  639.         (void) sprintf (name, "%s.%s", rname, cname);
  640.  
  641.         /* set XmNuserData to be the name we want to go by */
  642.         get_something (w, XmNuserData, (char *)&userD);
  643.         if (userD)
  644.         XtFree (userD);
  645.         userD = name;
  646.         set_something (w, XmNuserData, userD);
  647.  
  648.         /* tell the world our name */
  649.         register_selection (name);
  650.     }
  651. }
  652.  
  653. /* callback from the Data table Close button
  654.  */
  655. static void
  656. /* ARGSUSED */
  657. dm_close_cb (w, client, call)
  658. Widget w;
  659. XtPointer client;
  660. XtPointer call;
  661. {
  662.     XtUnmanageChild (dataform_w);
  663.     if (XtIsManaged (sel_w))
  664.         XtUnmanageChild (sel_w);
  665. }
  666.  
  667. /* callback from the Data table Setup button.
  668.  */
  669. static void
  670. /* ARGSUSED */
  671. dm_setup_cb (w, client, call)
  672. Widget w;
  673. XtPointer client;
  674. XtPointer call;
  675. {
  676.     if (XtIsManaged(sel_w))
  677.         XtUnmanageChild (sel_w);
  678.     else {
  679.         ds_setup_row_selections();
  680.         ds_setup_col_selections(MISC_COL);
  681.         ds_setup_col_selections(RISET_COL);
  682.         ds_setup_col_selections(SEP_COL);
  683.         XtManageChild (sel_w);
  684.     }
  685. }
  686.  
  687. /* callback from the Data table Help button
  688.  */
  689. static void
  690. /* ARGSUSED */
  691. dm_help_cb (w, client, call)
  692. Widget w;
  693. XtPointer client;
  694. XtPointer call;
  695. {
  696.     static char *msg[] = {
  697. "This table displays various information about the planets and objects.",
  698. "To reduce computation and save screen space, each row and column may be",
  699. "individually turned off or on using the Select button."
  700. };
  701.  
  702.     hlp_dialog ("Data Table", msg, XtNumber(msg));
  703. }
  704.  
  705. /* compute and print body info in data menu format */
  706. /* ARGSUSED */
  707. static void
  708. dm_compute (r, force, np)
  709. int r;        /* which row */
  710. int force;    /* whether to print for sure or only if things have changed */
  711. Now *np;
  712. {
  713.     RiseSet rs;
  714.     Obj *op;
  715.     int c;
  716.     int did_rs = 0;
  717.  
  718.     op = db_basic (row[r].dbidx);
  719.     db_update (op);
  720.  
  721.     for (c = 0; c < NC; c++)
  722.         if (col[c].on) {
  723.         if (col[c].type == RISET_COL && !did_rs) {
  724.             double dis = 0;    /* rads apparent horizon is from true */
  725.             int close = is_planet(op,MOON) || is_planet(op,SUN); 
  726.  
  727.             /* refraction correction */
  728.             if (horizon == STDREFR) {
  729.             /* `nominal' atmospheric refraction. */
  730.             dis += STDREF;
  731.             } else {
  732.             /* `Adaptive:' actual refraction conditions  */
  733.             double ref;
  734.             unrefract (pressure, temp, 0.0, &ref);
  735.             dis -= ref;    /* downwards */
  736.             }
  737.  
  738.             /* add object's semi-diameter if want upper limb.
  739.              * only worth it for SUN and MOON.
  740.              */
  741.             if (limb == LIMB && close)
  742.             dis += degrad((double)op->s_size/3600./2.0);
  743.  
  744.             /* add effect of being above surface
  745.              * TODO: this works but refraction model breaks down.
  746.             dis += asin (sqrt(surfalt*surfalt + 2.0*ERAD*surfalt)
  747.                   /(ERAD + surfalt));
  748.              */
  749.             
  750.             riset_cir (np, op, dis, &rs);
  751.             did_rs = 1;
  752.         }
  753.         dm_format(np, op, &rs, c, t_w[r][c]);
  754.         }
  755. }
  756.  
  757. static void
  758. dm_format (np, op, rp, c, w)
  759. Now *np;
  760. Obj *op;
  761. RiseSet *rp;
  762. int c;
  763. Widget w;
  764. {
  765.     static char me[] = "dm_format()";
  766.  
  767.     switch (c) {
  768.     case CONSTEL_ID:
  769.         show_constellation (np, op, w);
  770.         break;
  771.     case RA_ID:
  772.         f_ra (w, op->s_ra);
  773.         break;
  774.     case DEC_ID:
  775.         f_angle (w, op->s_dec);
  776.         break;
  777.     case AZ_ID:
  778.         f_angle (w, op->s_az);
  779.         break;
  780.     case ALT_ID:
  781.         f_angle (w, op->s_alt);
  782.         break;
  783.     case HLONG_ID:
  784.         if (is_ssobj(op))
  785.         f_angle (w, op->s_hlong);
  786.         else
  787.         f_string (w, " ");
  788.         break;
  789.     case HLAT_ID:
  790.         if (is_ssobj(op))
  791.         f_angle (w, op->s_hlat);
  792.         else
  793.         f_string (w, " ");
  794.         break;
  795.     case EDST_ID:
  796.         if (is_planet(op, MOON)) {
  797.         double tmp = op->s_edist;
  798.         if (pref_get(PREF_UNITS) == PREF_ENGLISH) {
  799.             /* s_edist is stored in km, show in miles */
  800.             tmp /= 1.609344;
  801.         }
  802.         f_double (w, "%6.0f", tmp);
  803.         } else if (is_ssobj(op)) {
  804.         /* show distance in au */
  805.         f_double (w, op->s_edist >= 9.99995 ? "%6.3f" : "%6.4f",
  806.                                 op->s_edist);
  807.         } else
  808.         f_string (w, " ");
  809.         break;
  810.     case SDST_ID:
  811.         if (is_ssobj(op) && !is_planet(op, SUN))
  812.         f_double (w, op->s_sdist >= 9.99995 ? "%6.3f" : "%6.4f",
  813.                                 op->s_sdist);
  814.         else
  815.         f_string (w, "      ");
  816.         break;
  817.     case ELONG_ID:
  818.         if (is_ssobj(op) && !is_planet(op, SUN))
  819.         f_double (w, "%6.1f", op->s_elong);
  820.         else
  821.         f_string (w, " ");
  822.         break;
  823.     case SIZE_ID:
  824.         f_double (w, "%4.0f", (double)(op->s_size));
  825.         break;
  826.     case VMAG_ID: {
  827.         double m = (double) (op->s_mag / MAGSCALE);
  828.         f_double (w, m <= -9.95 ? "%4.0f" : "%4.1f", m);
  829.     }
  830.         break;
  831.     case PHS_ID:
  832.         if (is_ssobj(op) && !is_planet(op, SUN))
  833.         f_double (w, "%3.0f", op->s_phase);
  834.         else
  835.         f_string (w, "   ");
  836.         break;
  837.  
  838.     case RSTIME_ID:
  839.         if (rp->rs_flags & RS_ERROR)
  840.         f_string (w, "Error ");
  841.         else if (rp->rs_flags & RS_CIRCUMPOLAR)
  842.         f_string (w, "CirPol");
  843.         else if (rp->rs_flags & RS_NEVERUP)
  844.         f_string (w, "NvrUp ");
  845.         else if (rp->rs_flags & RS_NORISE)
  846.         f_string (w, "NoRise");
  847.         else {
  848.         f_mtime (w, rp->rs_risetm);    /* 5 chars wide */
  849.         dm_rs_addplus (w, rp->rs_flags & RS_2RISES);    /* adds 1 */
  850.         }
  851.         break;
  852.  
  853.     case RSAZ_ID:
  854.         if (rp->rs_flags & RS_ERROR)
  855.         f_string (w, "Error ");
  856.         else if (rp->rs_flags & RS_CIRCUMPOLAR)
  857.         f_string (w, "CirPol");
  858.         else if (rp->rs_flags & RS_NEVERUP)
  859.         f_string (w, "NvrUp ");
  860.         else if (rp->rs_flags & RS_NORISE)
  861.         f_string (w, "NoRise");
  862.         else
  863.         f_angle (w, rp->rs_riseaz);    /* 6 chars wide */
  864.         break;
  865.  
  866.     case SETTIME_ID:
  867.         if (rp->rs_flags & RS_ERROR)
  868.         f_string (w, "Error ");
  869.         else if (rp->rs_flags & RS_CIRCUMPOLAR)
  870.         f_string (w, "CirPol");
  871.         else if (rp->rs_flags & RS_NEVERUP)
  872.         f_string (w, "NvrUp ");
  873.         else if (rp->rs_flags & RS_NOSET)
  874.         f_string (w, "NoSet ");
  875.         else {
  876.         f_mtime (w, rp->rs_settm);    /* 5 chars wide */
  877.         dm_rs_addplus (w, rp->rs_flags & RS_2SETS);    /* adds 1 */
  878.         }
  879.         break;
  880.  
  881.     case SETAZ_ID:
  882.         if (rp->rs_flags & RS_ERROR)
  883.         f_string (w, "Error ");
  884.         else if (rp->rs_flags & RS_CIRCUMPOLAR)
  885.         f_string (w, "CirPol");
  886.         else if (rp->rs_flags & RS_NEVERUP)
  887.         f_string (w, "NvrUp ");
  888.         else if (rp->rs_flags & RS_NOSET)
  889.         f_string (w, "NoSet ");
  890.         else
  891.         f_angle (w, rp->rs_setaz);    /* 6 chars wide */
  892.         break;
  893.  
  894.     case TRTIME_ID:
  895.         if (rp->rs_flags & RS_ERROR)
  896.         f_string (w, "Error ");
  897.         else if (rp->rs_flags & RS_NEVERUP)
  898.         f_string (w, "NvrUp ");
  899.         else if (rp->rs_flags & RS_NOTRANS)
  900.         f_string (w, "NoTran");
  901.         else {
  902.         f_mtime (w, rp->rs_trantm);    /* 5 chars wide */
  903.         dm_rs_addplus (w, rp->rs_flags & RS_2TRANS);    /* adds 1 */
  904.         }
  905.         break;
  906.  
  907.     case TRALT_ID:
  908.         if (rp->rs_flags & RS_ERROR)
  909.         f_string (w, "Error ");
  910.         else if (rp->rs_flags & RS_NEVERUP)
  911.         f_string (w, "NvrUp ");
  912.         else if (rp->rs_flags & RS_NOTRANS)
  913.         f_string (w, "NoTran");
  914.         else {
  915.         f_angle (w, rp->rs_tranalt);    /* 6 chars wide */
  916.         }
  917.         break;
  918.  
  919.     case HRSUP_ID:
  920.         dm_rs_hrsup (w, rp);
  921.         break;
  922.  
  923.     default:
  924.         /* these are effectively all the separation columns */
  925.         if (c < 0 || c >= NC) {
  926.         printf ("Bug: %s: c = %d but max = %d\n", me, c, NC-1);
  927.         exit (1);
  928.         }
  929.         if (col[c].type != SEP_COL) {
  930.         printf ("Bug: %s: col[%d].type = 0x%x\n", me, c, col[c].type);
  931.         exit (1);
  932.         }
  933.         if (op != db_basic(col[c].dbidx)) {
  934.         db_update(db_basic(col[c].dbidx));
  935.         dm_separation (op, db_basic(col[c].dbidx), centric, w);
  936.         } else
  937.         f_string (w, " ");
  938.         break;
  939.     }
  940. }
  941.  
  942. static void
  943. dm_rs_addplus (w, addplus)
  944. Widget w;
  945. int addplus;
  946. {
  947.     char *orig, *new;
  948.  
  949.     get_xmstring (w, XmNlabelString, &orig);
  950.     new = XtMalloc(strlen(orig)+2); /* '+' plus the '\0' */
  951.     (void) sprintf (new, addplus ? "%s+" : "%s ", orig);
  952.     f_string (w, new);
  953.     XtFree (orig);
  954.     XtFree (new);
  955. }
  956.  
  957. /* display the total hours this object has been up.
  958.  * N.B. insure string length is always 6 chars wide.
  959.  */
  960. static void
  961. dm_rs_hrsup (w, rp)
  962. Widget w;
  963. RiseSet *rp;
  964. {
  965.     double r, s, hrs;
  966.  
  967.     if (rp->rs_flags & (RS_ERROR|RS_RISERR)) {
  968.         f_string (w, "Error ");
  969.         return;
  970.     }
  971.     if (rp->rs_flags & RS_CIRCUMPOLAR) {
  972.         f_double (w, "%3.0f:00", 24.0); /* f_mtime() changes to 00:00 */
  973.         return;
  974.     }
  975.     if (rp->rs_flags & RS_NEVERUP) {
  976.         f_mtime (w, 0.0);        /* 5 chars wide */
  977.         dm_rs_addplus(w, 0);    /* adds 1 */
  978.         return;
  979.     }
  980.  
  981.     r = (rp->rs_flags & RS_NORISE) ?  0.0 : rp->rs_risetm;
  982.     s = (rp->rs_flags & RS_NOSET)  ? 24.0 : rp->rs_settm;
  983.     hrs = s - r;
  984.     if (hrs < 0)
  985.         hrs += 24.0;
  986.     f_mtime (w, hrs);    /* 5 chars wide */
  987.     dm_rs_addplus(w, rp->rs_flags&(RS_NORISE|RS_NOSET|RS_2RISES|RS_2SETS));
  988. }
  989.  
  990. static void
  991. show_constellation (np, op, w)
  992. Now *np;
  993. Obj *op;
  994. Widget w;
  995. {
  996.     char nm[10], *name;
  997.  
  998.         confnd (op->s_ra, op->s_dec, epoch == EOD ? mjd : epoch, &name);
  999.     (void) sprintf (nm, "%.3s", name);
  1000.     f_string(w, nm);
  1001. }
  1002.  
  1003. /* compute and display the separation between the two sky locations */
  1004. static void
  1005. dm_separation (p, q, how, w)
  1006. Obj *p, *q;
  1007. int how;    /* GEO_CEN or TOPO_CEN */
  1008. Widget w;
  1009. {
  1010.     double spy, cpy, px, qx, sqy, cqy;
  1011.     double sep;
  1012.  
  1013.     if (how == GEO_CEN) {
  1014.         /* use ra for "x", dec for "y". */
  1015.         spy = sin (p->s_dec);
  1016.         cpy = cos (p->s_dec);
  1017.         px = p->s_ra;
  1018.         qx = q->s_ra;
  1019.         sqy = sin (q->s_dec);
  1020.         cqy = cos (q->s_dec);
  1021.     } else {
  1022.         /* use azimuth for "x", altitude for "y". */
  1023.         spy = sin (p->s_alt);
  1024.         cpy = cos (p->s_alt);
  1025.         px = p->s_az;
  1026.         qx = q->s_az;
  1027.         sqy = sin (q->s_alt);
  1028.         cqy = cos (q->s_alt);
  1029.     }
  1030.  
  1031.     sep = acos(spy*sqy + cpy*cqy*cos(px-qx));
  1032.     f_angle (w, sep);
  1033. }
  1034.  
  1035. /* create the selections dialog */
  1036. static void
  1037. ds_create_selection(parent)
  1038. Widget parent;
  1039. {
  1040.     static char me[] = "ds_create_selection()";
  1041.     static struct { /* info to streamline creation of control buttons */
  1042.         int id;
  1043.         int lpos, rpos;
  1044.         char *name;
  1045.     } ctlbtns[] = {
  1046.         {OK, 1, 3, "Ok"},
  1047.         {APPLY, 4, 6, "Apply"},
  1048.         {CANCEL, 7, 9, "Close"},
  1049.         {HELP, 10, 12, "Help"}
  1050.     };
  1051.     Arg args[20];
  1052.     XmString str;
  1053.     Widget rl_w, cl_w;
  1054.     Widget rf_w, mf_w, rsf_w, sf_w, ctlf_w, rowrc_w, mrc_w, rsrc_w, src_w;
  1055.     Widget sep_w, w, tb1, tb2;
  1056.     Widget rb_w;
  1057.     int n;
  1058.     int i;
  1059.  
  1060.     /* create form */
  1061.     n = 0;
  1062.     XtSetArg (args[n], XmNallowShellResize, True); n++;
  1063.     XtSetArg (args[n], XmNautoUnmanage, False); n++;
  1064.     XtSetArg (args[n], XmNdefaultPosition, False); n++;
  1065.     XtSetArg (args[n], XmNallowOverlap, False); n++;
  1066.     sel_w = XmCreateFormDialog (parent, "DataSelection", args, n);
  1067.     XtAddCallback (sel_w, XmNmapCallback, prompt_map_cb, NULL);
  1068.  
  1069.     /* set some stuff in the parent DialogShell.
  1070.      * setting XmNdialogTitle in the Form didn't work..
  1071.      */
  1072.     n = 0;
  1073.     XtSetArg (args[n], XmNtitle, "xephem Data Table setup"); n++;
  1074.     XtSetValues (XtParent(sel_w), args, n);
  1075.  
  1076.     /* make a form for bottom control panel */
  1077.     n = 0;
  1078.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1079.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1080.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1081.     XtSetArg (args[n], XmNfractionBase, 13); n++;
  1082.     XtSetArg (args[n], XmNverticalSpacing, 5); n++;
  1083.     ctlf_w = XmCreateForm (sel_w, "DataSelF", args, n);
  1084.     XtManageChild (ctlf_w);
  1085.  
  1086.         /* make the control buttons */
  1087.  
  1088.         for (i = 0; i < XtNumber(ctlbtns); i++) {
  1089.         n = 0;
  1090.         XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1091.         XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1092.         XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  1093.         XtSetArg (args[n], XmNleftPosition, ctlbtns[i].lpos); n++;
  1094.         XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  1095.         XtSetArg (args[n], XmNrightPosition, ctlbtns[i].rpos); n++;
  1096.         w = XmCreatePushButton (ctlf_w, ctlbtns[i].name, args, n);
  1097.         XtAddCallback (w, XmNactivateCallback, ds_ctl_cb,
  1098.                             (XtPointer)ctlbtns[i].id);
  1099.         XtManageChild (w);
  1100.         }
  1101.  
  1102.     /* make a top separator */
  1103.     n = 0;
  1104.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1105.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1106.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1107.     sep_w = XmCreateSeparator (sel_w, "DSSep", args, n);
  1108.     XtManageChild (sep_w);
  1109.  
  1110.     /* make the Rows heading */
  1111.  
  1112.     n = 0;
  1113.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1114.     XtSetArg (args[n], XmNtopWidget, sep_w); n++;
  1115.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1116.     XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  1117.     rl_w = XmCreateLabel (sel_w, "Rows:", args, n);
  1118.     XtManageChild (rl_w);
  1119.  
  1120.     /* make the row selection rc in a frame */
  1121.  
  1122.     n = 0;
  1123.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1124.     XtSetArg (args[n], XmNtopWidget, rl_w); n++;
  1125.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1126.     XtSetArg (args[n], XmNbottomWidget, ctlf_w); n++;
  1127.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1128.     rf_w = XmCreateFrame (sel_w, "DSRFrame", args, n);
  1129.     XtManageChild (rf_w);
  1130.  
  1131.     n = 0;
  1132.     XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
  1133.     XtSetArg (args[n], XmNadjustMargin, False); n++;
  1134.     XtSetArg (args[n], XmNisAligned, False); n++;
  1135.     XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
  1136.     rowrc_w = XmCreateRowColumn (rf_w, "DataSelRows", args, n);
  1137.     XtManageChild (rowrc_w);
  1138.  
  1139.         /* fill up with buttons for each possible row.
  1140.          * fill in name if it's a planet since that won't change.
  1141.          */
  1142.  
  1143.         /* make the "Toggle" push button */
  1144.  
  1145.         str = XmStringCreate("Toggle", XmSTRING_DEFAULT_CHARSET);
  1146.         n = 0;
  1147.         XtSetArg (args[n], XmNlabelString, str); n++;
  1148.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1149.         w = XmCreatePushButton (rowrc_w, "DSRToggle", args, n);
  1150.         XtAddCallback (w, XmNactivateCallback, ds_row_toggle_cb, 0);
  1151.         XtManageChild (w);
  1152.         XmStringFree (str);
  1153.  
  1154.         /* make the "All" push button */
  1155.  
  1156.         str = XmStringCreate("All", XmSTRING_DEFAULT_CHARSET);
  1157.         n = 0;
  1158.         XtSetArg (args[n], XmNlabelString, str); n++;
  1159.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1160.         w = XmCreatePushButton (rowrc_w, "DSRAll", args, n);
  1161.         XtAddCallback (w, XmNactivateCallback, ds_row_all_cb, 0);
  1162.         XtManageChild (w);
  1163.         XmStringFree (str);
  1164.  
  1165.         /* make the "Reset" push button */
  1166.  
  1167.         str = XmStringCreate("Reset", XmSTRING_DEFAULT_CHARSET);
  1168.         n = 0;
  1169.         XtSetArg (args[n], XmNlabelString, str); n++;
  1170.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1171.         w = XmCreatePushButton (rowrc_w, "DSRReset", args, n);
  1172.         XtAddCallback (w, XmNactivateCallback, ds_row_reset_cb, 0);
  1173.         XtManageChild (w);
  1174.         XmStringFree (str);
  1175.  
  1176.         for (i = 0; i < NR; i++) {
  1177.         Obj *op = db_basic(row[i].dbidx);
  1178.         n = 0;
  1179.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  1180.         if (op->type != UNDEFOBJ) {
  1181.             w = row[i].sw = XmCreateToggleButton(rowrc_w, op->o_name,
  1182.                                     args, n);
  1183.             XtManageChild (w);
  1184.         } else
  1185.             row[i].sw = XmCreateToggleButton(rowrc_w, "RowSelObj",
  1186.                                     args, n);
  1187.         }
  1188.  
  1189.     /* make the Columns heading */
  1190.  
  1191.     n = 0;
  1192.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1193.     XtSetArg (args[n], XmNtopWidget, sep_w); n++;
  1194.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  1195.     XtSetArg (args[n], XmNleftWidget, rf_w); n++;
  1196.     XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  1197.     cl_w = XmCreateLabel (sel_w, "Columns:", args, n);
  1198.     XtManageChild (cl_w);
  1199.  
  1200.     /* make the misc col selection rc in a frame */
  1201.  
  1202.     n = 0;
  1203.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1204.     XtSetArg (args[n], XmNtopWidget, cl_w); n++;
  1205.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1206.     XtSetArg (args[n], XmNbottomWidget, ctlf_w); n++;
  1207.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  1208.     XtSetArg (args[n], XmNleftWidget, rf_w); n++;
  1209.     mf_w = XmCreateFrame (sel_w, "DSMCFrame", args, n);
  1210.     XtManageChild (mf_w);
  1211.  
  1212.     n = 0;
  1213.     XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
  1214.     XtSetArg (args[n], XmNadjustMargin, False); n++;
  1215.     XtSetArg (args[n], XmNisAligned, False); n++;
  1216.     XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
  1217.     mrc_w = XmCreateRowColumn (mf_w, "DataSelMiscCols", args, n);
  1218.     XtManageChild (mrc_w);
  1219.  
  1220.         /* fill up with buttons for each possible col in misc range.
  1221.          * set those columns names that are stable.
  1222.          */
  1223.  
  1224.         /* make the "Toggle" push button */
  1225.  
  1226.         n = 0;
  1227.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1228.         w = XmCreatePushButton (mrc_w, "Toggle", args, n);
  1229.         XtAddCallback (w, XmNactivateCallback, ds_col_toggle_cb,
  1230.                             (XtPointer)MISC_COL);
  1231.         XtManageChild (w);
  1232.  
  1233.         /* make the "All" push button */
  1234.  
  1235.         n = 0;
  1236.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1237.         w = XmCreatePushButton (mrc_w, "All", args, n);
  1238.         XtAddCallback (w, XmNactivateCallback, ds_col_all_cb,
  1239.                             (XtPointer)MISC_COL);
  1240.         XtManageChild (w);
  1241.  
  1242.         /* make the "Reset" push button */
  1243.  
  1244.         n = 0;
  1245.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1246.         w = XmCreatePushButton (mrc_w, "Reset", args, n);
  1247.         XtAddCallback (w, XmNactivateCallback, ds_col_reset_cb,
  1248.                             (XtPointer)MISC_COL);
  1249.         XtManageChild (w);
  1250.  
  1251.     /* make the rise/set col selection rc in a frame */
  1252.  
  1253.     n = 0;
  1254.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1255.     XtSetArg (args[n], XmNtopWidget, cl_w); n++;
  1256.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1257.     XtSetArg (args[n], XmNbottomWidget, ctlf_w); n++;
  1258.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  1259.     XtSetArg (args[n], XmNleftWidget, mf_w); n++;
  1260.     rsf_w = XmCreateFrame (sel_w, "DSRCFrame", args, n);
  1261.     XtManageChild (rsf_w);
  1262.  
  1263.     n = 0;
  1264.     XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
  1265.     XtSetArg (args[n], XmNadjustMargin, False); n++;
  1266.     XtSetArg (args[n], XmNisAligned, False); n++;
  1267.     XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
  1268.     rsrc_w = XmCreateRowColumn (rsf_w, "DataSelRisetCols", args, n);
  1269.     XtManageChild (rsrc_w);
  1270.  
  1271.         /* fill up with buttons for each possible col in rise/set range.
  1272.          * set those columns names that are stable.
  1273.          */
  1274.  
  1275.         /* make the "Toggle" push button */
  1276.  
  1277.         n = 0;
  1278.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1279.         w = XmCreatePushButton (rsrc_w, "Toggle", args, n);
  1280.         XtAddCallback (w, XmNactivateCallback, ds_col_toggle_cb,
  1281.                             (XtPointer)RISET_COL);
  1282.         XtManageChild (w);
  1283.  
  1284.         /* make the "All" push button */
  1285.  
  1286.         n = 0;
  1287.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1288.         w = XmCreatePushButton (rsrc_w, "All", args, n);
  1289.         XtAddCallback (w, XmNactivateCallback, ds_col_all_cb,
  1290.                             (XtPointer)RISET_COL);
  1291.         XtManageChild (w);
  1292.  
  1293.         /* make the "Reset" push button */
  1294.  
  1295.         n = 0;
  1296.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1297.         w = XmCreatePushButton (rsrc_w, "Reset", args, n);
  1298.         XtAddCallback (w, XmNactivateCallback, ds_col_reset_cb,
  1299.                             (XtPointer)RISET_COL);
  1300.         XtManageChild (w);
  1301.  
  1302.         /* make the STDREFR/ADPREFR radio box */
  1303.  
  1304.         n = 0;
  1305.         w = XmCreateFrame (rsrc_w, "DSRefrF", args, n);
  1306.         XtManageChild (w);
  1307.         n = 0;
  1308.         rb_w = XmCreateRadioBox (w, "DSRefrRB", args, n);
  1309.         XtManageChild (rb_w);
  1310.  
  1311.         n = 0;
  1312.         stdrefr_w = tb1 = XmCreateToggleButton (rb_w, "StdRefr",args,n);
  1313.         XtManageChild (tb1);
  1314.         n = 0;
  1315.         tb2 = XmCreateToggleButton (rb_w, "AdpRefr", args, n);
  1316.         XtManageChild (tb2);
  1317.         /* if neither or both is set up in defaults, set for StdRefr */
  1318.         if (XmToggleButtonGetState(tb1) == XmToggleButtonGetState(tb2)){
  1319.             xe_msg (
  1320.              "Conflicting Refraction resources -- defaulting to StdRefr\n",
  1321.                                         0);
  1322.             XmToggleButtonSetState (tb1, True, True);
  1323.         }
  1324.  
  1325.         /* make the CENTER/LIMB radio box */
  1326.  
  1327.         n = 0;
  1328.         w = XmCreateFrame (rsrc_w, "DSLimbF", args, n);
  1329.         XtManageChild (w);
  1330.         n = 0;
  1331.         rb_w = XmCreateRadioBox (w, "DSLimbRB", args, n);
  1332.         XtManageChild (rb_w);
  1333.  
  1334.         n = 0;
  1335.         limb_w = tb1 = XmCreateToggleButton (rb_w, "Limb", args, n);
  1336.         XtManageChild (tb1);
  1337.         n = 0;
  1338.         tb2 = XmCreateToggleButton (rb_w, "Center", args, n);
  1339.         XtManageChild (tb2);
  1340.         /* if neither or both is set up in defaults, set for Limb */
  1341.         if (XmToggleButtonGetState(tb1) == XmToggleButtonGetState(tb2)){
  1342.             xe_msg (
  1343.               "Conflicting Limb resources -- defaulting to Limb\n",
  1344.                                         0);
  1345.             XmToggleButtonSetState (tb1, True, True);
  1346.         }
  1347.  
  1348.     /* make the separations col selection rc in a frame */
  1349.  
  1350.     n = 0;
  1351.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1352.     XtSetArg (args[n], XmNtopWidget, cl_w); n++;
  1353.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1354.     XtSetArg (args[n], XmNbottomWidget, ctlf_w); n++;
  1355.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  1356.     XtSetArg (args[n], XmNleftWidget, rsf_w); n++;
  1357.     sf_w = XmCreateFrame (sel_w, "DSRCFrame", args, n);
  1358.     XtManageChild (sf_w);
  1359.  
  1360.     n = 0;
  1361.     XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
  1362.     XtSetArg (args[n], XmNadjustMargin, False); n++;
  1363.     XtSetArg (args[n], XmNisAligned, False); n++;
  1364.     XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
  1365.     src_w = XmCreateRowColumn (sf_w, "DataSelSepCols", args, n);
  1366.     XtManageChild (src_w);
  1367.  
  1368.         /* fill up with buttons for each possible col in sep range.
  1369.          * set those columns names that are stable.
  1370.          */
  1371.  
  1372.         /* make the "Toggle" push button */
  1373.  
  1374.         n = 0;
  1375.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1376.         w = XmCreatePushButton (src_w, "Toggle", args, n);
  1377.         XtAddCallback (w, XmNactivateCallback, ds_col_toggle_cb,
  1378.                             (XtPointer)SEP_COL);
  1379.         XtManageChild (w);
  1380.  
  1381.         /* make the "All" push button */
  1382.  
  1383.         n = 0;
  1384.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1385.         w = XmCreatePushButton (src_w, "All", args, n);
  1386.         XtAddCallback (w, XmNactivateCallback, ds_col_all_cb,
  1387.                             (XtPointer)SEP_COL);
  1388.         XtManageChild (w);
  1389.  
  1390.         /* make the "Reset" push button */
  1391.  
  1392.         n = 0;
  1393.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1394.         w = XmCreatePushButton (src_w, "Reset", args, n);
  1395.         XtAddCallback (w, XmNactivateCallback, ds_col_reset_cb,
  1396.                             (XtPointer)SEP_COL);
  1397.         XtManageChild (w);
  1398.  
  1399.         /* make the GEOCENTRIC/TOPOCENTRIC radio box */
  1400.  
  1401.         n = 0;
  1402.         w = XmCreateFrame (src_w, "DSCentricF", args, n);
  1403.         XtManageChild (w);
  1404.         n = 0;
  1405.         rb_w = XmCreateRadioBox (w, "DSCentricRB", args, n);
  1406.         XtManageChild (rb_w);
  1407.  
  1408.         n = 0;
  1409.         geocen_w = tb1 = XmCreateToggleButton (rb_w, "Geocentric",
  1410.                                     args, n);
  1411.         XtManageChild (tb1);
  1412.         n = 0;
  1413.         tb2 = XmCreateToggleButton (rb_w, "Topocentric", args, n);
  1414.         XtManageChild (tb2);
  1415.         /* if neither or both is set up in defaults, set for geocntrc */
  1416.         if (XmToggleButtonGetState(tb1) == XmToggleButtonGetState(tb2)){
  1417.             xe_msg ("conflicting Centric resources -- defaulting to Geocentric\n", 0);
  1418.             XmToggleButtonSetState (tb1, True, True);
  1419.         }
  1420.  
  1421.     /* now fill in the column entries */
  1422.     for (i = 0; i < NC; i++) {
  1423.         n = 0;
  1424.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  1425.         switch (col[i].type) {
  1426.         case MISC_COL:
  1427.         /* one of the misc columns */
  1428.         w = col[i].sw = XmCreateToggleButton(mrc_w, col[i].name,args,n);
  1429.         XtManageChild (w);
  1430.         break;
  1431.         case RISET_COL:
  1432.         /* one of the rise/set columns */
  1433.         w = col[i].sw = XmCreateToggleButton(rsrc_w,col[i].name,args,n);
  1434.         XtManageChild (w);
  1435.         break;
  1436.         case SEP_COL: {
  1437.         /* one of the separation columns */
  1438.         Obj *op = db_basic (col[i].dbidx);
  1439.         if (op->type != UNDEFOBJ) {
  1440.             w = col[i].sw = XmCreateToggleButton(src_w,op->o_name,args,n);
  1441.             XtManageChild (w);
  1442.         } else
  1443.             col[i].sw = XmCreateToggleButton(src_w, "ColSelObj",args,n);
  1444.         break;
  1445.         }
  1446.         default:
  1447.         printf ("Bug: %s: col[%d].type = 0x%x\n", me, i, col[i].type);
  1448.         exit (1);
  1449.         break;
  1450.         }
  1451.     }
  1452. }
  1453.  
  1454. /* set up the Data selection row menu based on what is currently on and defined.
  1455.  */
  1456. static void
  1457. ds_setup_row_selections()
  1458. {
  1459.     int i;
  1460.  
  1461.     for (i = 0; i < NR; i++) {
  1462.         Widget sw = row[i].sw;
  1463.         Obj *op = db_basic (row[i].dbidx);
  1464.         if (op->type == UNDEFOBJ)
  1465.         XtUnmanageChild (sw);
  1466.         else 
  1467.         XtManageChild (sw);
  1468.         XmToggleButtonSetState (sw, row[i].on, False);
  1469.     }
  1470. }
  1471.  
  1472. /* set up a Data selection col menu based on what is currently on and defined.
  1473.  */
  1474. static void
  1475. ds_setup_col_selections(what)
  1476. int what;
  1477. {
  1478.     int i;
  1479.  
  1480.     for (i = 0; i < NC; i++) {
  1481.         if (col[i].type == what) {
  1482.         Widget sw = col[i].sw;
  1483.         if (col[i].type == SEP_COL) {
  1484.             Obj *op = db_basic (col[i].dbidx);
  1485.             if (op->type == UNDEFOBJ)
  1486.             XtUnmanageChild (sw);
  1487.             else 
  1488.             XtManageChild (sw);
  1489.         }
  1490.         XmToggleButtonSetState (sw, col[i].on, False);
  1491.         }
  1492.     }
  1493.  
  1494.     switch (what) {
  1495.     case RISET_COL:
  1496.         XmToggleButtonSetState (stdrefr_w, horizon == STDREFR, True);
  1497.         XmToggleButtonSetState (limb_w, limb == LIMB, True);
  1498.         break;
  1499.     case SEP_COL:
  1500.         XmToggleButtonSetState (geocen_w, centric == GEO_CEN, True);
  1501.         break;
  1502.     }
  1503. }
  1504.  
  1505.  
  1506. /* change the Data table according to what is now defined and set up in the
  1507.  * Selection menu.
  1508.  * N.B. can be called before we are managed.
  1509.  */
  1510. static void
  1511. ds_apply_selections()
  1512. {
  1513.     int i, c;
  1514.     int n_riset, n_sep;
  1515.     int wasman;
  1516.  
  1517.     watch_cursor(1);
  1518.  
  1519.     if (wasman = XtIsManaged(dataform_w))
  1520.         XtUnmanageChild (dataform_w);
  1521.  
  1522.     for (i = 0; i < NR; i++) {
  1523.         int wantset = XmToggleButtonGetState(row[i].sw);
  1524.         if (wantset != row[i].on) {
  1525.         if (wantset) {
  1526.             for (c = 0; c < NC; c++)
  1527.             XtManageChild (t_w[i][c]);
  1528.             XtManageChild (row[i].lw);
  1529.         } else {
  1530.             for (c = 0; c < NC; c++)
  1531.             XtUnmanageChild (t_w[i][c]);
  1532.             XtUnmanageChild (row[i].lw);
  1533.         }
  1534.         row[i].on = wantset;
  1535.         }
  1536.     }
  1537.  
  1538.     n_riset = n_sep = 0;
  1539.     for (i = 0; i < NC; i++) {
  1540.         int wantset = XmToggleButtonGetState(col[i].sw);
  1541.         if (wantset != col[i].on) {
  1542.         if (wantset)
  1543.             XtManageChild (col[i].rcw);
  1544.         else
  1545.             XtUnmanageChild (col[i].rcw);
  1546.         col[i].on = wantset;
  1547.         }
  1548.         if (col[i].type == RISET_COL && col[i].on)
  1549.         n_riset++;
  1550.         if (col[i].type == SEP_COL && col[i].on)
  1551.         n_sep++;
  1552.     }
  1553.  
  1554.     horizon = XmToggleButtonGetState (stdrefr_w) ? STDREFR : ADPREFR;
  1555.     limb = XmToggleButtonGetState (limb_w) ? LIMB : CENTER;
  1556.     if (n_riset) {
  1557.         f_showit (refr_w, horizon==STDREFR ? "StdRefr" : "AdpRefr");
  1558.         XtManageChild (XtParent(refr_w));
  1559.         f_showit (limbl_w, limb==LIMB ? "UpLimb" : "Center");
  1560.         XtManageChild (XtParent(limbl_w));
  1561.     } else {
  1562.         XtUnmanageChild (XtParent(refr_w));
  1563.         XtUnmanageChild (XtParent(limbl_w));
  1564.     }
  1565.  
  1566.     centric = XmToggleButtonGetState (geocen_w) ? GEO_CEN : TOPO_CEN;
  1567.     if (n_sep) {
  1568.         f_string (centric_w,
  1569.             centric==GEO_CEN ? "GeoSeps" : "TopoSeps");
  1570.         XtManageChild (XtParent(centric_w));
  1571.     } else
  1572.         XtUnmanageChild (XtParent(centric_w));
  1573.  
  1574.     if (wasman)
  1575.         XtManageChild (dataform_w);
  1576.  
  1577.     watch_cursor(0);
  1578. }
  1579.  
  1580. /* callback from any of the Data selection control panel buttons.
  1581.  * which is in client.
  1582.  */
  1583. static void
  1584. /* ARGSUSED */
  1585. ds_ctl_cb (w, client, call)
  1586. Widget w;
  1587. XtPointer client;
  1588. XtPointer call;
  1589. {
  1590.     int id = (int) client;
  1591.  
  1592.     switch (id) {
  1593.     case OK:
  1594.         ds_apply_selections();
  1595.         dm_update (mm_get_now(), 1);
  1596.         XtUnmanageChild (sel_w);
  1597.         break;
  1598.     case APPLY:
  1599.         ds_apply_selections();
  1600.         dm_update (mm_get_now(), 1);
  1601.         break;
  1602.     case CANCEL:
  1603.         XtUnmanageChild (sel_w);
  1604.         break;
  1605.     case HELP:
  1606.         ds_help();
  1607.         break;
  1608.     }
  1609. }
  1610.  
  1611. /* called from the Data selection table Help button
  1612.  */
  1613. static void
  1614. ds_help ()
  1615. {
  1616.     static char *msg[] = {
  1617. "This table lets you configure the rows and columns of the data table."
  1618. };
  1619.  
  1620.     hlp_dialog ("DataSelection Table", msg, XtNumber(msg));
  1621. }
  1622.  
  1623. /* callback from the Data selection row toggle button.
  1624.  */
  1625. static void
  1626. /* ARGSUSED */
  1627. ds_row_toggle_cb (w, client, call)
  1628. Widget w;
  1629. XtPointer client;
  1630. XtPointer call;
  1631. {
  1632.     int i;
  1633.  
  1634.     for (i = 0; i < NR; i++) {
  1635.         Widget sw = row[i].sw;
  1636.         if (XtIsManaged(sw))
  1637.         XmToggleButtonSetState (sw,
  1638.             !XmToggleButtonGetState(sw), False);
  1639.     }
  1640. }
  1641.  
  1642. /* callback from any of the Data selection col toggle button.
  1643.  */
  1644. static void
  1645. /* ARGSUSED */
  1646. ds_col_toggle_cb (w, client, call)
  1647. Widget w;
  1648. XtPointer client;
  1649. XtPointer call;
  1650. {
  1651.     int what = (int)client;
  1652.     int i;
  1653.  
  1654.     for (i = 0; i < NC; i++)
  1655.         if (col[i].type == what) {
  1656.         Widget sw = col[i].sw;
  1657.         if (XtIsManaged(sw))
  1658.             XmToggleButtonSetState (sw,
  1659.             !XmToggleButtonGetState(sw), False);
  1660.         }
  1661. }
  1662.  
  1663. /* callback from the Data selection row all toggle button.
  1664.  */
  1665. static void
  1666. /* ARGSUSED */
  1667. ds_row_all_cb (w, client, call)
  1668. Widget w;
  1669. XtPointer client;
  1670. XtPointer call;
  1671. {
  1672.     int i;
  1673.  
  1674.     for (i = 0; i < NR; i++) {
  1675.         Widget sw = row[i].sw;
  1676.         if (XtIsManaged(sw) && !XmToggleButtonGetState (sw))
  1677.         XmToggleButtonSetState(sw, True, False);
  1678.     }
  1679. }
  1680.  
  1681. /* callback from any of the Data selection col all toggle buttons.
  1682.  */
  1683. static void
  1684. /* ARGSUSED */
  1685. ds_col_all_cb (w, client, call)
  1686. Widget w;
  1687. XtPointer client;
  1688. XtPointer call;
  1689. {
  1690.     int what = (int)client;
  1691.     int i;
  1692.  
  1693.     for (i = 0; i < NC; i++)
  1694.         if (col[i].type == what) {
  1695.             Widget sw = col[i].sw;
  1696.         if (XtIsManaged(sw) && !XmToggleButtonGetState (sw))
  1697.             XmToggleButtonSetState(sw, True, False);
  1698.         }
  1699. }
  1700.  
  1701. /* callback from the Data selection row reset button.
  1702.  */
  1703. static void
  1704. /* ARGSUSED */
  1705. ds_row_reset_cb (w, client, call)
  1706. Widget w;
  1707. XtPointer client;
  1708. XtPointer call;
  1709. {
  1710.     ds_setup_row_selections();
  1711. }
  1712.  
  1713. /* callback from any of the Data selection col reset buttons.
  1714.  */
  1715. /* ARGSUSED */
  1716. static void
  1717. ds_col_reset_cb (w, client, call)
  1718. Widget w;
  1719. XtPointer client;
  1720. XtPointer call;
  1721. {
  1722.     ds_setup_col_selections((int)client);
  1723. }
  1724.