home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xephem / part15 < prev    next >
Encoding:
Text File  |  1993-05-15  |  76.7 KB  |  2,484 lines

  1. Newsgroups: comp.sources.x
  2. From: ecdowney@pobox.cca.cr.rockwell.com (Elwood Downey)
  3. Subject: v19i103:  xephem - astronomical ephemeris program, Part15/21
  4. Message-ID: <1993May10.221205.9291@sparky.imd.sterling.com>
  5. X-Md4-Signature: f810dcf9e2ead43098fc57f606a7f115
  6. Date: Mon, 10 May 1993 22:12:05 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ecdowney@pobox.cca.cr.rockwell.com (Elwood Downey)
  10. Posting-number: Volume 19, Issue 103
  11. Archive-name: xephem/part15
  12. Environment: X11r4, OSF/Motif
  13. Supersedes: xephem: Volume 16, Issue 112-134
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  parallax.c plotmenu.c riset_cir.c skyviewmenu.c.1
  22. # Wrapped by chris@nova on Mon May 10 16:41:51 1993
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 15 (of 21)."'
  26. if test -f 'parallax.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'parallax.c'\"
  28. else
  29.   echo shar: Extracting \"'parallax.c'\" \(2603 characters\)
  30.   sed "s/^X//" >'parallax.c' <<'END_OF_FILE'
  31. X#include <stdio.h>
  32. X#include <math.h>
  33. X#include "astro.h"
  34. X
  35. X#if defined(__STDC__) || defined(__cplusplus)
  36. X#define P_(s) s
  37. X#else
  38. X#define P_(s) ()
  39. X#endif
  40. X
  41. Xextern void range P_((double *v, double r));
  42. X
  43. X/* parallax.c */
  44. Xvoid ta_par P_((double tha, double tdec, double phi, double ht, double ehp, double *aha, double *adec));
  45. X
  46. X#undef P_
  47. X
  48. X/* given true ha and dec, tha and tdec, the geographical latitude, phi, the
  49. X * height above sea-level (as a fraction of the earths radius, 6378.16km),
  50. X * ht, and the equatorial horizontal parallax, ehp, find the apparent
  51. X * ha and dec, aha and adec allowing for parallax.
  52. X * all angles in radians. ehp is the angle subtended at the body by the
  53. X * earth's equator.
  54. X */
  55. Xvoid
  56. Xta_par (tha, tdec, phi, ht, ehp, aha, adec)
  57. Xdouble tha, tdec, phi, ht, ehp;
  58. Xdouble *aha, *adec;
  59. X{
  60. X    static double last_phi = 1000.0, last_ht = -1000.0, rsp, rcp;
  61. X    double rp;    /* distance to object in Earth radii */
  62. X    double ctha;
  63. X    double stdec, ctdec;
  64. X    double tdtha, dtha;
  65. X    double caha;
  66. X
  67. X    /* avoid calcs involving the same phi and ht */
  68. X    if (phi != last_phi || ht != last_ht) {
  69. X        double cphi, sphi, u;
  70. X        cphi = cos(phi);
  71. X        sphi = sin(phi);
  72. X        u = atan(9.96647e-1*sphi/cphi);
  73. X        rsp = (9.96647e-1*sin(u))+(ht*sphi);
  74. X        rcp = cos(u)+(ht*cphi);
  75. X        last_phi  =  phi;
  76. X        last_ht  =  ht;
  77. X    }
  78. X
  79. X        rp = 1/sin(ehp);
  80. X
  81. X        ctha = cos(tha);
  82. X    stdec = sin(tdec);
  83. X    ctdec = cos(tdec);
  84. X        tdtha = (rcp*sin(tha))/((rp*ctdec)-(rcp*ctha));
  85. X        dtha = atan(tdtha);
  86. X    *aha = tha+dtha;
  87. X    caha = cos(*aha);
  88. X    range (aha, 2*PI);
  89. X        *adec = atan(caha*(rp*stdec-rsp)/(rp*ctdec*ctha-rcp));
  90. X}
  91. X
  92. X#ifdef NEEDIT
  93. X/* given the apparent ha and dec, aha and adec, the geographical latitude, phi,
  94. X * the height above sea-level (as a fraction of the earths radius, 6378.16km),
  95. X * ht, and the equatorial horizontal parallax, ehp, find the true ha and dec,
  96. X * tha and tdec allowing for parallax.
  97. X * all angles in radians. ehp is the angle subtended at the body by the
  98. X * earth's equator.
  99. X * uses ta_par() iteratively: find a set of true ha/dec that converts back
  100. X  *  to the given apparent ha/dec.
  101. X */
  102. Xvoid
  103. Xat_par (aha, adec, phi, ht, ehp, tha, tdec)
  104. Xdouble aha, adec, phi, ht, ehp;
  105. Xdouble *tha, *tdec;
  106. X{
  107. X    double nha, ndec;    /* ha/dec corres. to current true guesses */
  108. X    double eha, edec;    /* error in ha/dec */
  109. X
  110. X    /* first guess for true is just the apparent */
  111. X    *tha = aha;
  112. X    *tdec = adec;
  113. X
  114. X    while (1) {
  115. X        ta_par (*tha, *tdec, phi, ht, ehp, &nha, &ndec);
  116. X        eha = aha - nha;
  117. X        edec = adec - ndec;
  118. X        if (fabs(eha)<1e-6 && fabs(edec)<1e-6)
  119. X        break;
  120. X        *tha += eha;
  121. X        *tdec += edec;
  122. X    }
  123. X}
  124. X#endif
  125. END_OF_FILE
  126.   if test 2603 -ne `wc -c <'parallax.c'`; then
  127.     echo shar: \"'parallax.c'\" unpacked with wrong size!
  128.   fi
  129.   # end of 'parallax.c'
  130. fi
  131. if test -f 'plotmenu.c' -a "${1}" != "-c" ; then 
  132.   echo shar: Will not clobber existing file \"'plotmenu.c'\"
  133. else
  134.   echo shar: Extracting \"'plotmenu.c'\" \(30247 characters\)
  135.   sed "s/^X//" >'plotmenu.c' <<'END_OF_FILE'
  136. X/* code to manage the stuff on the "plot" menu.
  137. X */
  138. X
  139. X#include <stdio.h>
  140. X#include <ctype.h>
  141. X#include <math.h>
  142. X#if defined(__STDC__)
  143. X#include <stdlib.h>
  144. X#endif
  145. X#include <X11/Xlib.h>
  146. X#include <Xm/Xm.h>
  147. X#include <Xm/Form.h>
  148. X#include <Xm/Frame.h>
  149. X#include <Xm/DrawingA.h>
  150. X#include <Xm/Label.h>
  151. X#include <Xm/PushB.h>
  152. X#include <Xm/ToggleB.h>
  153. X#include <Xm/RowColumn.h>
  154. X#include <Xm/Separator.h>
  155. X#include <Xm/Text.h>
  156. X
  157. X#if defined(__STDC__) || defined(__cplusplus)
  158. X#define P_(s) s
  159. X#else
  160. X#define P_(s) ()
  161. X#endif
  162. X
  163. Xextern int plot_cartesian P_((FILE *pfp, Widget widget, unsigned int nx, unsigned int ny, int flipx, int flipy, int grid));
  164. Xextern void all_selection_mode P_((int whether));
  165. Xextern void f_string P_((Widget w, char *s));
  166. Xextern void get_something P_((Widget w, char *resource, char *value));
  167. Xextern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
  168. Xextern void query P_((Widget tw, char *msg, char *label1, char *label2, char *label3, void (*func1)(), void (*func2)(), void (*func3)()));
  169. Xextern void set_something P_((Widget w, char *resource, char *value));
  170. Xextern void set_xmstring P_((Widget w, char *resource, char *txt));
  171. Xextern void xe_msg P_((char *msg, int app_modal));
  172. X
  173. Xvoid plot_manage P_((void));
  174. Xvoid plt_selection P_((char *name));
  175. Xvoid plt_log P_((char *name, double value));
  176. Xvoid plot P_((void));
  177. Xint plot_ison P_((void));
  178. Xvoid plt_cursor P_((Cursor c));
  179. Xstatic void plt_select P_((int whether));
  180. Xstatic void plot_create_form P_((void));
  181. Xstatic void plt_activate_cb P_((Widget w, XtPointer client, XtPointer call));
  182. Xstatic void plt_close_cb P_((Widget w, XtPointer client, XtPointer call));
  183. Xstatic void plt_help_cb P_((Widget w, XtPointer client, XtPointer call));
  184. Xstatic void plt_reset P_((void));
  185. Xstatic void plt_stop_selecting P_((void));
  186. Xstatic void plt_turn_off P_((void));
  187. Xstatic void init_next_tag P_((void));
  188. Xstatic void plt_try_append P_((void));
  189. Xstatic void plt_try_overwrite P_((void));
  190. Xstatic void plt_try_cancel P_((void));
  191. Xstatic void plt_try_turn_on P_((void));
  192. Xstatic void plt_turn_on P_((char *how));
  193. Xstatic void plt_da_manage P_((void));
  194. Xstatic void plt_da_destroy P_((Widget daform_w));
  195. Xstatic void plt_daform_map_cb P_((Widget w, XtPointer client, XtPointer call));
  196. Xstatic void plt_da_close_cb P_((Widget w, XtPointer client, XtPointer call));
  197. Xstatic void plt_da_flipx_cb P_((Widget w, XtPointer client, XtPointer call));
  198. Xstatic void plt_da_flipy_cb P_((Widget w, XtPointer client, XtPointer call));
  199. Xstatic void plt_da_grid_cb P_((Widget w, XtPointer client, XtPointer call));
  200. Xstatic void plt_da_exp_cb P_((Widget da_w, XtPointer client, XtPointer call));
  201. X
  202. X#undef P_
  203. X
  204. Xextern int access();
  205. Xextern Widget toplevel_w;
  206. X#define    XtD    XtDisplay(toplevel_w)
  207. X
  208. X#ifdef VMS
  209. X#include <perror.h>
  210. X#include <errno.h>
  211. X#else
  212. Xextern char *sys_errlist[];
  213. Xextern errno;
  214. X#endif
  215. X
  216. X#define    errsys    (sys_errlist[errno])
  217. X
  218. X/* max number of things we can keep track of at once to plot */
  219. X#define    MAXPLTLINES    10
  220. X#define    MAXFLDNAM    32    /* longest allowed field name */
  221. X
  222. Xstatic Widget plotform_w;
  223. Xstatic Widget select_w, active_w, prompt_w;
  224. Xstatic Widget title_w, filename_w;
  225. Xstatic Widget table_w[MAXPLTLINES][3];    /* column indeces follow.. */
  226. Xstatic int selecting_xy;        /* also one of ... */
  227. X#define    T    0
  228. X#define    X    1
  229. X#define    Y    2
  230. X
  231. X#define    DEF_PLTFN    "ephem.plt"    /* default plot file name */
  232. Xstatic FILE *plt_fp;            /* the plot file; == 0 means don't plot */
  233. X
  234. X
  235. X/* plt_activate_cb client values. */
  236. Xenum { SELECT, ACTIVE, SHOW};
  237. X
  238. X/* store the name of each x and y line to track and their values.
  239. X * we get the label straight from the Text widget in the table as needed.
  240. X */
  241. Xtypedef struct {
  242. X    char pl_xn[MAXFLDNAM];    /* name of x field, or 0 if none */
  243. X    double pl_xv;        /* last known value of x field */
  244. X    char pl_yn[MAXFLDNAM];    /* name of y field, or 0 if none */
  245. X    double pl_yv;        /* last known value of x field */
  246. X} PltLine;
  247. Xstatic PltLine pltlines[MAXPLTLINES];
  248. Xstatic int npltlines;        /* number of pltlines[] in actual use */
  249. X
  250. X/* one of these gets malloced and passed to the drawing area expose callback via
  251. X * its client parameter. be sure to free it when the parent FormDialog goes
  252. X * away too.
  253. X * by doing this, we can have lots of different plots up at once and yet we
  254. X * don't have to keep track of them - they track themselves.
  255. X */
  256. Xtypedef struct {
  257. X    char *filename;    /* name of file being plotted (also malloced) */
  258. X    FILE *fp;        /* FILE pointer for the file */
  259. X    int flipx, flipy;    /* flip state for this instance */
  260. X    int grid;        /* whether to include a grid */
  261. X} DrawInfo;
  262. X
  263. X/* called when the plot menu is activated via the main menu pulldown.
  264. X * if never called before, create and manage all the widgets as a child of a
  265. X * form. otherwise, just toggle whether the form is managed.
  266. X */
  267. Xvoid
  268. Xplot_manage ()
  269. X{
  270. X    if (!plotform_w)
  271. X        plot_create_form();
  272. X    
  273. X    if (XtIsManaged(plotform_w))
  274. X        XtUnmanageChild (plotform_w);
  275. X    else
  276. X        XtManageChild (plotform_w);
  277. X}
  278. X
  279. X/* called by the other menus (data, etc) as their buttons are
  280. X * selected to inform us that that button is to be included in a plot.
  281. X */
  282. Xvoid
  283. Xplt_selection (name)
  284. Xchar *name;
  285. X{
  286. X    Widget tw;
  287. X
  288. X    if (!plotform_w
  289. X        || !XtIsManaged(plotform_w)
  290. X        || !XmToggleButtonGetState(select_w))
  291. X        return;
  292. X
  293. X    tw = table_w[npltlines][selecting_xy];
  294. X    set_xmstring (tw, XmNlabelString, name);
  295. X    XtManageChild (tw);
  296. X
  297. X    if (selecting_xy == X) {
  298. X        (void) strncpy (pltlines[npltlines].pl_xn, name, MAXFLDNAM-1);
  299. X        selecting_xy = Y;
  300. X        XtManageChild (prompt_w);
  301. X        f_string (prompt_w, "Select quantity for Y..");
  302. X    } else {
  303. X        (void) strncpy (pltlines[npltlines].pl_yn, name, MAXFLDNAM-1);
  304. X        if (++npltlines == MAXPLTLINES)
  305. X        plt_stop_selecting();
  306. X        else {
  307. X        selecting_xy = X;
  308. X        init_next_tag();
  309. X        }
  310. X    }
  311. X}
  312. X
  313. X/* called as each different field is written -- just save in pltlines[]
  314. X * if we are interested in it.
  315. X * might have the same field listed more than once so can't stop if find one.
  316. X */
  317. Xvoid
  318. Xplt_log (name, value)
  319. Xchar *name;
  320. Xdouble value;
  321. X{
  322. X    if (plt_fp) {
  323. X        PltLine *plp;
  324. X        for (plp = pltlines; plp < &pltlines[npltlines]; plp++) {
  325. X        if (strcmp (name, plp->pl_xn) == 0)
  326. X            plp->pl_xv = value;
  327. X        if (strcmp (name, plp->pl_yn) == 0)
  328. X            plp->pl_yv = value;
  329. X        }
  330. X    }
  331. X}
  332. X
  333. X/* called when all fields have been updated and it's time to
  334. X * write the active plotfields to the current plot file, if one is open.
  335. X */
  336. Xvoid
  337. Xplot()
  338. X{
  339. X    if (plt_fp) {
  340. X        /* plot in order of original selection */
  341. X        PltLine *plp;
  342. X        for (plp = pltlines; plp < &pltlines[npltlines]; plp++) {
  343. X        char *lbl = XmTextGetString (table_w[plp-pltlines][T]);
  344. X        (void) fprintf (plt_fp, "%c,%.12g,%.12g\n", lbl[0],
  345. X                            plp->pl_xv, plp->pl_yv);
  346. X        XtFree (lbl);
  347. X        }
  348. X    }
  349. X}
  350. X
  351. Xplot_ison()
  352. X{
  353. X    return (plt_fp != 0);
  354. X}
  355. X
  356. X/* called to put up or remove the watch cursor.  */
  357. Xvoid
  358. Xplt_cursor (c)
  359. XCursor c;
  360. X{
  361. X    Window win;
  362. X
  363. X    if (plotform_w && (win = XtWindow(plotform_w))) {
  364. X        Display *dsp = XtDisplay(plotform_w);
  365. X        if (c)
  366. X        XDefineCursor (dsp, win, c);
  367. X        else
  368. X        XUndefineCursor (dsp, win);
  369. X    }
  370. X}
  371. X
  372. X/* inform the other menues whether we are setting up for them to tell us
  373. X * what fields to plot.
  374. X */
  375. Xstatic void
  376. Xplt_select(whether)
  377. Xint whether;
  378. X{
  379. X    all_selection_mode(whether);
  380. X}
  381. X
  382. Xstatic void
  383. Xplot_create_form()
  384. X{
  385. X    static struct {
  386. X        char *title;
  387. X        int cb_data;
  388. X        Widget *wp;
  389. X    } tbs[] = {
  390. X        {"Select fields", SELECT, &select_w},
  391. X        {"Plot to file", ACTIVE, &active_w},
  392. X        {"Show plot file", SHOW, NULL},
  393. X    };
  394. X    XmString str;
  395. X    Widget f_w, rc_w;
  396. X    Widget w;
  397. X    char *deffn;
  398. X    Arg args[20];
  399. X    int i, n;
  400. X
  401. X    /* create the main dialog */
  402. X
  403. X    n = 0;
  404. X    XtSetArg (args[n], XmNautoUnmanage, False); n++;
  405. X    XtSetArg (args[n], XmNdefaultPosition, False); n++;
  406. X    plotform_w = XmCreateFormDialog (toplevel_w, "Plot", args, n);
  407. X
  408. X    n = 0;
  409. X    XtSetArg (args[n], XmNtitle, "xephem Plot Control"); n++;
  410. X    XtSetValues (XtParent(plotform_w), args, n);
  411. X
  412. X    /* make a RowColumn to hold everything */
  413. X
  414. X    n = 0;
  415. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  416. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  417. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  418. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  419. X    XtSetArg (args[n], XmNisAligned, False); n++;
  420. X    XtSetArg (args[n], XmNadjustMargin, False); n++;
  421. X    rc_w = XmCreateRowColumn(plotform_w, "PlotRC", args, n);
  422. X    XtManageChild (rc_w);
  423. X
  424. X    /* make the control toggle buttons */
  425. X
  426. X    for (i = 0; i < XtNumber(tbs); i++) {
  427. X        str = XmStringCreate(tbs[i].title, XmSTRING_DEFAULT_CHARSET);
  428. X        n = 0;
  429. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  430. X        XtSetArg (args[n], XmNlabelString, str); n++;
  431. X        w = XmCreateToggleButton(rc_w, "PlotTB", args, n);
  432. X        XmStringFree (str);
  433. X        XtManageChild (w);
  434. X        XtAddCallback(w, XmNvalueChangedCallback, plt_activate_cb,
  435. X                            (XtPointer)tbs[i].cb_data);
  436. X        if (tbs[i].wp)
  437. X        *tbs[i].wp = w;
  438. X    }
  439. X
  440. X    /* create filename text area and its label */
  441. X
  442. X    n = 0;
  443. X    str = XmStringCreate("File name:", XmSTRING_DEFAULT_CHARSET);
  444. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  445. X    XtSetArg (args[n], XmNlabelString, str); n++;
  446. X    w = XmCreateLabel (rc_w, "PlotFnL", args, n);
  447. X    XmStringFree (str);
  448. X    XtManageChild (w);
  449. X
  450. X    n = 0;
  451. X    filename_w = XmCreateText (rc_w, "Filename", args, n);
  452. X    deffn = XmTextGetString (filename_w);
  453. X    if (strlen(deffn) == 0)
  454. X        XmTextSetString (filename_w, DEF_PLTFN);
  455. X    XtFree (deffn);
  456. X    XtManageChild (filename_w);
  457. X
  458. X    /* create title text area and its label */
  459. X
  460. X    n = 0;
  461. X    str = XmStringCreate("Title:", XmSTRING_DEFAULT_CHARSET);
  462. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  463. X    XtSetArg (args[n], XmNlabelString, str); n++;
  464. X    w = XmCreateLabel (rc_w, "PlotTL", args, n);
  465. X    XtManageChild (w);
  466. X    XmStringFree (str);
  467. X
  468. X    n = 0;
  469. X    title_w = XmCreateText (rc_w, "PlotTitle", args, n);
  470. X    XtManageChild (title_w);
  471. X
  472. X    /* create prompt line -- it will be managed as necessary */
  473. X
  474. X    n = 0;
  475. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  476. X    prompt_w = XmCreateLabel (rc_w, "PlotPrompt", args, n);
  477. X
  478. X    /* create the table.
  479. X     * each row is in a form to control its shape.
  480. X     * loop index of -1 is used to make the column headings.
  481. X     * the table entries are not managed at this time.
  482. X     */
  483. X
  484. X    for (i = -1; i < MAXPLTLINES; i++) {
  485. X        n = 0;
  486. X        XtSetArg (args[n], XmNfractionBase, 9); n++;
  487. X        f_w = XmCreateForm (rc_w, "PlotTF", args, n);
  488. X        XtManageChild (f_w);
  489. X
  490. X        n = 0;
  491. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  492. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  493. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  494. X        XtSetArg (args[n], XmNleftPosition, 0); n++;
  495. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  496. X        XtSetArg (args[n], XmNrightPosition, 1); n++;
  497. X        if (i == -1) {
  498. X        w = XmCreateLabel (f_w, "Tag", args, n);
  499. X        XtManageChild (w);
  500. X        } else {
  501. X        XtSetArg (args[n], XmNmaxLength, 1); n++;
  502. X        XtSetArg (args[n], XmNcolumns, 1); n++;
  503. X        table_w[i][T] = XmCreateText (f_w, "PlotTag", args, n);
  504. X        }
  505. X
  506. X        n = 0;
  507. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  508. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  509. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  510. X        XtSetArg (args[n], XmNleftPosition, 2); n++;
  511. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  512. X        XtSetArg (args[n], XmNrightPosition, 5); n++;
  513. X        if (i == -1) {
  514. X        w = XmCreateLabel (f_w, "X", args, n);
  515. X        XtManageChild (w);
  516. X        } else {
  517. X        table_w[i][X] = XmCreateLabel (f_w, "PlotX", args, n);
  518. X        }
  519. X
  520. X        n = 0;
  521. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  522. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  523. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  524. X        XtSetArg (args[n], XmNleftPosition, 6); n++;
  525. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  526. X        XtSetArg (args[n], XmNrightPosition, 9); n++;
  527. X        if (i == -1) {
  528. X        w = XmCreateLabel (f_w, "Y", args, n);
  529. X        XtManageChild (w);
  530. X        } else {
  531. X        table_w[i][Y] = XmCreateLabel (f_w, "PlotY", args, n);
  532. X        }
  533. X    }
  534. X
  535. X    /* create a separator */
  536. X
  537. X    n = 0;
  538. X    w = XmCreateSeparator (rc_w, "Sep", args, n);
  539. X    XtManageChild (w);
  540. X
  541. X    /* make a form to hold the close and help buttons evenly */
  542. X
  543. X    n = 0;
  544. X    XtSetArg (args[n], XmNfractionBase, 7); n++;
  545. X    f_w = XmCreateForm (rc_w, "PlotCF", args, n);
  546. X    XtManageChild(f_w);
  547. X
  548. X        n = 0;
  549. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  550. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  551. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  552. X        XtSetArg (args[n], XmNleftPosition, 1); n++;
  553. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  554. X        XtSetArg (args[n], XmNrightPosition, 3); n++;
  555. X        w = XmCreatePushButton (f_w, "Close", args, n);
  556. X        XtAddCallback (w, XmNactivateCallback, plt_close_cb, 0);
  557. X        XtManageChild (w);
  558. X
  559. X        n = 0;
  560. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  561. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  562. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  563. X        XtSetArg (args[n], XmNleftPosition, 4); n++;
  564. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  565. X        XtSetArg (args[n], XmNrightPosition, 6); n++;
  566. X        w = XmCreatePushButton (f_w, "Help", args, n);
  567. X        XtAddCallback (w, XmNactivateCallback, plt_help_cb, 0);
  568. X        XtManageChild (w);
  569. X}
  570. X
  571. X/* callback from any of the plot menu toggle buttons being activated.
  572. X */
  573. X/* ARGSUSED */
  574. Xstatic void
  575. Xplt_activate_cb (w, client, call)
  576. XWidget w;
  577. XXtPointer client;
  578. XXtPointer call;
  579. X{
  580. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  581. X    int what = (int) client;
  582. X
  583. X    switch (what) {
  584. X    case SELECT:
  585. X        if (t->set) {
  586. X        /* first turn off plotting, if on, while we change things */
  587. X        if (XmToggleButtonGetState(active_w))
  588. X            XmToggleButtonSetState(active_w, False, True);
  589. X        plt_reset();    /* reset pltlines array and unmanage the table*/
  590. X        plt_select(1);    /* inform other menus to inform us of fields */
  591. X        init_next_tag();/* set first tag to something and show it */
  592. X        selecting_xy = X;
  593. X        } else
  594. X        plt_stop_selecting();
  595. X        break;
  596. X    case ACTIVE:
  597. X        if (t->set) {
  598. X        /* first turn off selecting, if on */
  599. X        if (XmToggleButtonGetState(select_w))
  600. X            XmToggleButtonSetState(select_w, False, True);
  601. X        plt_try_turn_on();
  602. X        } else
  603. X        plt_turn_off();
  604. X        break;
  605. X    case SHOW:
  606. X        /* turn off plotting, if on, to make sure file is complete. */
  607. X        if (XmToggleButtonGetState(active_w))
  608. X        XmToggleButtonSetState(active_w, False, True);
  609. X        plt_da_manage();
  610. X        /* we want this to work like it was a pushbutton, really */
  611. X        XmToggleButtonSetState(w, False, False);
  612. X        break;
  613. X    }
  614. X}
  615. X
  616. X/* callback from the Close button.
  617. X */
  618. X/* ARGSUSED */
  619. Xstatic void
  620. Xplt_close_cb (w, client, call)
  621. XWidget w;
  622. XXtPointer client;
  623. XXtPointer call;
  624. X{
  625. X    XtUnmanageChild (plotform_w);
  626. X}
  627. X
  628. X/* callback from the Help button.
  629. X */
  630. X/* ARGSUSED */
  631. Xstatic void
  632. Xplt_help_cb (w, client, call)
  633. XWidget w;
  634. XXtPointer client;
  635. XXtPointer call;
  636. X{
  637. Xstatic char *help_msg[] = {
  638. X"This menu controls the plot generation and display functionality of xephem.",
  639. X"Select fields to form x/y pairs, enable plotting to write them to a file on",
  640. X"each xephem iteration step, then view. Each file may be titled, as desired."
  641. X};
  642. X    hlp_dialog ("Plot", help_msg, sizeof(help_msg)/sizeof(help_msg[0]));
  643. X}
  644. X
  645. X/* forget our list, and unmanage the table.
  646. X */
  647. Xstatic void
  648. Xplt_reset()
  649. X{
  650. X    int i;
  651. X
  652. X    for (i = 0; i < npltlines; i++) {
  653. X        XtUnmanageChild (table_w[i][T]);
  654. X        XtUnmanageChild (table_w[i][X]);
  655. X        XtUnmanageChild (table_w[i][Y]);
  656. X    }
  657. X
  658. X    npltlines = 0;
  659. X}
  660. X
  661. X/* stop selecting: unmanage a partitially filled in line specs; tell
  662. X * everybody else to drop their buttons, make sure toggle is off.
  663. X */
  664. Xstatic void
  665. Xplt_stop_selecting()
  666. X{
  667. X    /* harmless to unmanage something already unmanaged so do them all */
  668. X    if (npltlines < MAXPLTLINES) {
  669. X        XtUnmanageChild (table_w[npltlines][T]);
  670. X        XtUnmanageChild (table_w[npltlines][X]);
  671. X        XtUnmanageChild (table_w[npltlines][Y]);
  672. X    }
  673. X
  674. X    XmToggleButtonSetState (select_w, False, False);
  675. X    plt_select(0);
  676. X    XtUnmanageChild (prompt_w);
  677. X}
  678. X
  679. Xstatic void
  680. Xplt_turn_off ()
  681. X{
  682. X    if (plt_fp) {
  683. X        (void) fclose (plt_fp);
  684. X        plt_fp = 0;
  685. X    }
  686. X}
  687. X
  688. Xstatic void
  689. Xinit_next_tag()
  690. X{
  691. X    char buf[100];
  692. X    Widget w = table_w[npltlines][T];
  693. X
  694. X    XtManageChild (prompt_w);
  695. X    f_string (prompt_w, "Select quantity for X..");
  696. X    (void) sprintf (buf, "%c", 'A' + npltlines);
  697. X    XmTextSetString (w, buf);
  698. X    XtManageChild (w);
  699. X}
  700. X
  701. X/* called from the query routine when want to append to an existing plot file.*/
  702. Xstatic void
  703. Xplt_try_append()
  704. X{
  705. X    plt_turn_on("a");
  706. X}
  707. X
  708. X/* called from the query routine when want to overwrite to an existing plot
  709. X * file.
  710. X */
  711. Xstatic void
  712. Xplt_try_overwrite()
  713. X{
  714. X    plt_turn_on("w");
  715. X}
  716. X
  717. X/* called from the query routine when want decided not to make a plot file.  */
  718. Xstatic void
  719. Xplt_try_cancel()
  720. X{
  721. X    XmToggleButtonSetState (active_w, False, False);
  722. X}
  723. X
  724. X/* attempt to open file for use as a plot file.
  725. X * if it doesn't exist, then go ahead and make it.
  726. X * but if it does, first ask wheher to append or overwrite.
  727. X */
  728. Xstatic void
  729. Xplt_try_turn_on()
  730. X{
  731. X    char *txt = XmTextGetString (filename_w);
  732. X    if (access (txt, 0) == 0) {
  733. X        char *buf;
  734. X        buf = XtMalloc (strlen(txt)+100);
  735. X        (void) sprintf (buf, "%s exists: Append or Overwrite?", txt);
  736. X        query (toplevel_w, buf, "Append", "Overwrite", "Cancel",
  737. X                plt_try_append, plt_try_overwrite, plt_try_cancel);
  738. X        XtFree (buf);
  739. X    } else
  740. X        plt_turn_on("w");
  741. X    XtFree (txt);
  742. X}
  743. X
  744. X/* turn on plotting.
  745. X * establish a file to use (and thereby set plt_fp, the plotting_is_on flag).
  746. X */
  747. Xstatic void
  748. Xplt_turn_on (how)
  749. Xchar *how;    /* fopen how argument */
  750. X{
  751. X    char *txt;
  752. X
  753. X    /* plotting is on if file opens ok */
  754. X    txt = XmTextGetString (filename_w);
  755. X    plt_fp = fopen (txt, how);
  756. X    if (!plt_fp) {
  757. X        char *buf;
  758. X        XmToggleButtonSetState (active_w, False, False);
  759. X        buf = XtMalloc (strlen(txt)+100);
  760. X        (void) sprintf (buf, "Can not open %s: %s", txt, errsys);
  761. X        xe_msg (buf, 1);
  762. X        XtFree (buf);
  763. X    }
  764. X    XtFree (txt);
  765. X    
  766. X    if (plt_fp) {
  767. X        /* add a title if it's not null */
  768. X        txt = XmTextGetString (title_w);
  769. X        if (txt[0] != '\0')
  770. X        (void) fprintf (plt_fp, "* %s\n", txt);
  771. X        XtFree (txt);
  772. X    }
  773. X}
  774. X
  775. X/* make a new drawing area widget and manage it. it's unmanaged and destroyed
  776. X *   from the Close button or if something goes wrong during plotting.
  777. X * open the plot file and save it, the current state of the flipx/flipy/grid
  778. X *   buttons and the filename in a DrawInfo struct in the userData resource
  779. X *   for the FormDialog where the drawingarea callback can get at it each time.
  780. X * this way, we can have lots of different plots up at once yet we don't
  781. X *   have to keep track of them.
  782. X * by leaving the file open, we gain some protection against it being removed
  783. X *   or renamed.
  784. X */
  785. Xstatic void
  786. Xplt_da_manage()
  787. X{
  788. X    Widget daform_w;
  789. X    Widget da_w, w;
  790. X    Widget ctl_w;
  791. X    Widget fr_w;
  792. X    XmString str;
  793. X    Arg args[20];
  794. X    char titlebuf[64];
  795. X    int n;
  796. X    DrawInfo *di;
  797. X    FILE *fp;
  798. X    char *fn;
  799. X
  800. X    /* first make sure we can open the plot file */
  801. X    fn = XmTextGetString (filename_w);
  802. X    fp = fopen (fn, "r");
  803. X    if (!fp) {
  804. X        char *buf;
  805. X        buf = XtMalloc (strlen(fn)+100);
  806. X        (void) sprintf (buf, "Can not open %s: %s", fn, errsys);
  807. X        xe_msg (buf, 1);
  808. X        XtFree (buf);
  809. X        XtFree (fn);
  810. X        return;
  811. X    }
  812. X
  813. X    /* create the form dialog parent.
  814. X     * arrange for it to be square when it first comes up.
  815. X     */
  816. X    n = 0;
  817. X    daform_w = XmCreateFormDialog (toplevel_w, "PlotD", args, n);
  818. X    XtAddCallback (daform_w, XmNmapCallback, plt_daform_map_cb, NULL);
  819. X
  820. X    /* set some stuff in the parent DialogShell.
  821. X     * setting XmNdialogTitle in the Form didn't work..
  822. X     */
  823. X    (void) sprintf (titlebuf, "xephem Plot of `%.*s'", sizeof(titlebuf)-20,
  824. X                                        fn);
  825. X    n = 0;
  826. X    XtSetArg (args[n], XmNtitle, titlebuf); n++;
  827. X    XtSetValues (XtParent(daform_w), args, n);
  828. X
  829. X    /* make the DrawInfo structure and save it in the userData of the Form.
  830. X     * the memory gets freed when the the dialog is closed/unmanaged.
  831. X     */
  832. X    di = (DrawInfo *) XtMalloc (sizeof(DrawInfo));
  833. X    di->filename = fn;
  834. X    di->fp = fp;
  835. X    di->flipx = 0;
  836. X    di->flipy = 0;
  837. X    di->grid = 0;
  838. X    set_something (daform_w, XmNuserData, (char *)di);
  839. X
  840. X    /* make a form for the bottom controls */
  841. X
  842. X    n = 0;
  843. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  844. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  845. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  846. X    XtSetArg (args[n], XmNverticalSpacing, 5); n++;
  847. X    XtSetArg (args[n], XmNfractionBase, 17); n++;
  848. X    ctl_w = XmCreateForm (daform_w, "CtlF", args, n);
  849. X    XtManageChild (ctl_w);
  850. X
  851. X    /* create the drawing area and connect plt_da_exp_cb().
  852. X     * N.B. be sure this guys parent is the FormDialog so exp_cb can find
  853. X     *   the DrawInfo by looking there at its userData.
  854. X     * make this as high as it is wide when it is first mapped.
  855. X     * N.B. if ever want this is a frame beware that other functions
  856. X     *   assume that the daform_w is the parent of the DrawingArea.
  857. X     */
  858. X    n = 0;
  859. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  860. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  861. X    XtSetArg (args[n], XmNbottomWidget, ctl_w); n++;
  862. X    XtSetArg (args[n], XmNbottomOffset, 2); n++;
  863. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  864. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  865. X    XtSetArg (args[n], XmNmarginWidth, 0); n++;
  866. X    XtSetArg (args[n], XmNmarginHeight, 0); n++;
  867. X    da_w = XmCreateDrawingArea (daform_w, "PlotDA", args, n);
  868. X    XtAddCallback (da_w, XmNexposeCallback, plt_da_exp_cb, NULL);
  869. X    XtManageChild (da_w);
  870. X
  871. X        /* make the flipx/y and grid toggle buttons (within frames) and the
  872. X         * close button in the control form
  873. X         */
  874. X
  875. X        n = 0;
  876. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  877. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  878. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  879. X        XtSetArg (args[n], XmNleftPosition, 1); n++;
  880. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  881. X        XtSetArg (args[n], XmNrightPosition, 4); n++;
  882. X        fr_w = XmCreateFrame (ctl_w, "FlipXF", args, n);
  883. X        XtManageChild (fr_w);
  884. X        str = XmStringCreate("Flip X", XmSTRING_DEFAULT_CHARSET);
  885. X        n = 0;
  886. X        XtSetArg (args[n], XmNlabelString, str); n++;
  887. X        XtSetArg (args[n], XmNset, di->flipx); n++;
  888. X        w = XmCreateToggleButton(fr_w, "FlipX", args, n);
  889. X        XmStringFree (str);
  890. X        XtAddCallback (w, XmNvalueChangedCallback, plt_da_flipx_cb, da_w);
  891. X        XtManageChild (w);
  892. X
  893. X        n = 0;
  894. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  895. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  896. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  897. X        XtSetArg (args[n], XmNleftPosition, 5); n++;
  898. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  899. X        XtSetArg (args[n], XmNrightPosition, 8); n++;
  900. X        fr_w = XmCreateFrame (ctl_w, "FlipYF", args, n);
  901. X        XtManageChild (fr_w);
  902. X        str = XmStringCreate("Flip Y", XmSTRING_DEFAULT_CHARSET);
  903. X        n = 0;
  904. X        XtSetArg (args[n], XmNlabelString, str); n++;
  905. X        XtSetArg (args[n], XmNset, di->flipy); n++;
  906. X        w = XmCreateToggleButton(fr_w, "FlipY", args, n);
  907. X        XmStringFree (str);
  908. X        XtAddCallback (w, XmNvalueChangedCallback, plt_da_flipy_cb, da_w);
  909. X        XtManageChild (w);
  910. X
  911. X        n = 0;
  912. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  913. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  914. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  915. X        XtSetArg (args[n], XmNleftPosition, 9); n++;
  916. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  917. X        XtSetArg (args[n], XmNrightPosition, 12); n++;
  918. X        fr_w = XmCreateFrame (ctl_w, "GridF", args, n);
  919. X        XtManageChild (fr_w);
  920. X        n = 0;
  921. X        XtSetArg (args[n], XmNset, di->grid); n++;
  922. X        w = XmCreateToggleButton(fr_w, "Grid", args, n);
  923. X        XtAddCallback (w, XmNvalueChangedCallback, plt_da_grid_cb, da_w);
  924. X        XtManageChild (w);
  925. X
  926. X        /* create a "Close" button.
  927. X         * it destroys the dialog and frees the DrawInfo struct.
  928. X         */
  929. X        n = 0;
  930. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  931. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  932. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  933. X        XtSetArg (args[n], XmNleftPosition, 13); n++;
  934. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  935. X        XtSetArg (args[n], XmNrightPosition, 16); n++;
  936. X        w = XmCreatePushButton (ctl_w, "Close", args, n);
  937. X        XtAddCallback (w, XmNactivateCallback, plt_da_close_cb, daform_w);
  938. X        XtManageChild (w);
  939. X    
  940. X    /* go. the expose will do the actual plotting */
  941. X    XtManageChild (daform_w);
  942. X}
  943. X
  944. X/* called when finished with a plot with its FormDialog widget.
  945. X * reclaim all memory in the userData DrawInfo and destroy it.
  946. X * N.B. caller's daform_w is useless when this returns.
  947. X */
  948. Xstatic void
  949. Xplt_da_destroy (daform_w)
  950. XWidget daform_w;
  951. X{
  952. X    DrawInfo *di;
  953. X
  954. X    get_something (daform_w, XmNuserData, (char *)&di);
  955. X    (void) fclose (di->fp);
  956. X    XtFree(di->filename);
  957. X    XtFree((char *)di);
  958. X    XtDestroyWidget(daform_w);
  959. X}
  960. X
  961. X/* called when a plot dialog is mapped.
  962. X * set the height equal to the width.
  963. X */
  964. X/* ARGSUSED */
  965. Xstatic void
  966. Xplt_daform_map_cb (w, client, call)
  967. XWidget w;
  968. XXtPointer client;
  969. XXtPointer call;
  970. X{
  971. X    Widget shell_w = XtParent(w);
  972. X    Dimension width;
  973. X    int iwidth;
  974. X
  975. X    get_something (shell_w, XmNwidth, (char *)&width);
  976. X    iwidth = width;
  977. X    set_something (shell_w, XmNheight, (char *)iwidth);
  978. X}
  979. X
  980. X
  981. X/* called when the Close button is pushed on a plot.
  982. X * free the DrawInfo and destroy the dialog (passed as client).
  983. X */
  984. X/* ARGSUSED */
  985. Xstatic void
  986. Xplt_da_close_cb (w, client, call)
  987. XWidget w;
  988. XXtPointer client;
  989. XXtPointer call;
  990. X{
  991. X    plt_da_destroy ((Widget)client);
  992. X}
  993. X
  994. X/* callback from the Flip X toggle button within the drawing FormDiag itself.
  995. X * toggle the x bit in the parent's DrawInfo structure and fake an expose.
  996. X * client is the DrawingArea widget.
  997. X */
  998. X/* ARGSUSED */
  999. Xstatic void
  1000. Xplt_da_flipx_cb (w, client, call)
  1001. XWidget w;
  1002. XXtPointer client;
  1003. XXtPointer call;
  1004. X{
  1005. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  1006. X    Widget da_w = (Widget) client;
  1007. X    Widget daform_w = XtParent(da_w);
  1008. X    Display *dsp = XtDisplay(da_w);
  1009. X    Window win = XtWindow(da_w);
  1010. X    DrawInfo *di;
  1011. X    XExposeEvent ev;
  1012. X    Window root;
  1013. X    int x, y;
  1014. X    unsigned int nx, ny, bw, d;
  1015. X
  1016. X    get_something (daform_w, XmNuserData, (char *)&di);
  1017. X    di->flipx = t->set;
  1018. X
  1019. X    XGetGeometry(dsp, win, &root, &x, &y, &nx, &ny, &bw, &d);
  1020. X
  1021. X    ev.type = Expose;
  1022. X    ev.send_event = 1;    /* gets set anyways */
  1023. X    ev.display = dsp;
  1024. X    ev.window = win;
  1025. X    ev.x = ev.y = 0;
  1026. X    ev.width = nx;
  1027. X    ev.height = ny;
  1028. X    ev.count = 0;
  1029. X
  1030. X    XSendEvent (dsp, win, /*propagate*/False, ExposureMask, (XEvent *)&ev);
  1031. X}
  1032. X
  1033. X/* callback from the Flip Y toggle button within the drawing FormDiag itself.
  1034. X * toggle the y bit in the parent's DrawInfo structure and fake an expose.
  1035. X * client is the DrawingArea widget.
  1036. X */
  1037. X/* ARGSUSED */
  1038. Xstatic void
  1039. Xplt_da_flipy_cb (w, client, call)
  1040. XWidget w;
  1041. XXtPointer client;
  1042. XXtPointer call;
  1043. X{
  1044. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  1045. X    Widget da_w = (Widget) client;
  1046. X    Widget daform_w = XtParent(da_w);
  1047. X    Display *dsp = XtDisplay(da_w);
  1048. X    Window win = XtWindow(da_w);
  1049. X    DrawInfo *di;
  1050. X    XExposeEvent ev;
  1051. X    Window root;
  1052. X    int x, y;
  1053. X    unsigned int nx, ny, bw, d;
  1054. X
  1055. X    get_something (daform_w, XmNuserData, (char *)&di);
  1056. X    di->flipy = t->set;
  1057. X
  1058. X    XGetGeometry(dsp, win, &root, &x, &y, &nx, &ny, &bw, &d);
  1059. X
  1060. X    ev.type = Expose;
  1061. X    ev.send_event = 1;    /* gets set anyways */
  1062. X    ev.display = dsp;
  1063. X    ev.window = win;
  1064. X    ev.x = ev.y = 0;
  1065. X    ev.width = nx;
  1066. X    ev.height = ny;
  1067. X    ev.count = 0;
  1068. X
  1069. X    XSendEvent (dsp, win, /*propagate*/False, ExposureMask, (XEvent *)&ev);
  1070. X}
  1071. X
  1072. X/* callback from the grid toggle button within the drawing FormDiag itself.
  1073. X * toggle the grid flag in the parent's DrawInfo structure and fake an expose.
  1074. X * client is the DrawingArea widget.
  1075. X */
  1076. X/* ARGSUSED */
  1077. Xstatic void
  1078. Xplt_da_grid_cb (w, client, call)
  1079. XWidget w;
  1080. XXtPointer client;
  1081. XXtPointer call;
  1082. X{
  1083. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  1084. X    Widget da_w = (Widget) client;
  1085. X    Widget daform_w = XtParent(da_w);
  1086. X    Display *dsp = XtDisplay(da_w);
  1087. X    Window win = XtWindow(da_w);
  1088. X    DrawInfo *di;
  1089. X    XExposeEvent ev;
  1090. X    Window root;
  1091. X    int x, y;
  1092. X    unsigned int nx, ny, bw, d;
  1093. X
  1094. X    get_something (daform_w, XmNuserData, (char *)&di);
  1095. X    di->grid = t->set;
  1096. X
  1097. X    XGetGeometry(dsp, win, &root, &x, &y, &nx, &ny, &bw, &d);
  1098. X
  1099. X    ev.type = Expose;
  1100. X    ev.send_event = 1;    /* gets set anyways */
  1101. X    ev.display = dsp;
  1102. X    ev.window = win;
  1103. X    ev.x = ev.y = 0;
  1104. X    ev.width = nx;
  1105. X    ev.height = ny;
  1106. X    ev.count = 0;
  1107. X
  1108. X    XSendEvent (dsp, win, /*propagate*/False, ExposureMask, (XEvent *)&ev);
  1109. X}
  1110. X
  1111. X/* plot drawing area's expose callback.
  1112. X * redraw the graph to the (new?) size.
  1113. X * get a DrawInfo from our parent's userData.
  1114. X */
  1115. X/* ARGSUSED */
  1116. Xstatic void
  1117. Xplt_da_exp_cb (da_w, client, call)
  1118. XWidget da_w;
  1119. XXtPointer client;
  1120. XXtPointer call;
  1121. X{
  1122. X    XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
  1123. X    DrawInfo *di;
  1124. X    Widget daform_w;
  1125. X    XWindowAttributes xwa;
  1126. X
  1127. X    switch (c->reason) {
  1128. X    case XmCR_EXPOSE: {
  1129. X        /* turn off gravity so we get expose events for either shrink or
  1130. X         * expand if we have never seen this window before.
  1131. X         */
  1132. X        XExposeEvent *e = &c->event->xexpose;
  1133. X
  1134. X        /* wait for the last in the series */
  1135. X        if (e->count != 0)
  1136. X        return;
  1137. X
  1138. X        XGetWindowAttributes (e->display, e->window, &xwa);
  1139. X        if (xwa.bit_gravity != ForgetGravity) {
  1140. X        /* first expose for this window -- set no gravity */
  1141. X        XSetWindowAttributes swa;
  1142. X        swa.bit_gravity = ForgetGravity;
  1143. X        XChangeWindowAttributes (e->display, e->window,
  1144. X                                CWBitGravity, &swa);
  1145. X        }
  1146. X        break;
  1147. X        }
  1148. X    default:
  1149. X        printf ("Unexpected da_w event. type=%d\n", c->reason);
  1150. X        exit(1);
  1151. X    }
  1152. X
  1153. X    /* use xwa for the drawing area window size.
  1154. X     * get di from the FormDiaglog parent and plot fresh.
  1155. X     */
  1156. X
  1157. X    daform_w = XtParent(da_w);
  1158. X    get_something (daform_w, XmNuserData, (char *)&di);
  1159. X    XClearWindow (XtDisplay(da_w), XtWindow(da_w));
  1160. X    rewind (di->fp);
  1161. X    if (plot_cartesian (di->fp, da_w, xwa.width, xwa.height,
  1162. X                    di->flipx, di->flipy, di->grid) < 0) {
  1163. X        /* had trouble, so done with this FormDialog.
  1164. X         */
  1165. X        char buf[128];
  1166. X        (void) sprintf (buf, "Error plotting `%.*s'\n", sizeof(buf)-20,
  1167. X                                di->filename);
  1168. X        xe_msg (buf, 0);
  1169. X        plt_da_destroy (daform_w);
  1170. X    }
  1171. X}
  1172. END_OF_FILE
  1173.   if test 30247 -ne `wc -c <'plotmenu.c'`; then
  1174.     echo shar: \"'plotmenu.c'\" unpacked with wrong size!
  1175.   fi
  1176.   # end of 'plotmenu.c'
  1177. fi
  1178. if test -f 'riset_cir.c' -a "${1}" != "-c" ; then 
  1179.   echo shar: Will not clobber existing file \"'riset_cir.c'\"
  1180. else
  1181.   echo shar: Extracting \"'riset_cir.c'\" \(7897 characters\)
  1182.   sed "s/^X//" >'riset_cir.c' <<'END_OF_FILE'
  1183. X/* find rise and set circumstances, ie, riset_cir() and related functions. */
  1184. X
  1185. X#include <stdio.h>
  1186. X#include <math.h>
  1187. X#if defined(__STDC__)
  1188. X#include <stdlib.h>
  1189. X#endif
  1190. X#include "astro.h"
  1191. X#include "circum.h"
  1192. X
  1193. X#if defined(__STDC__) || defined(__cplusplus)
  1194. X#define P_(s) s
  1195. X#else
  1196. X#define P_(s) ()
  1197. X#endif
  1198. X
  1199. Xextern double mjd_day P_((double jd));
  1200. Xextern int obj_cir P_((Now *np, Obj *op));
  1201. Xextern void now_lst P_((Now *np, double *lst));
  1202. Xextern void range P_((double *v, double r));
  1203. Xextern void refract P_((double pr, double tr, double ta, double *aa));
  1204. Xextern void riset P_((double ra, double dec, double lati, double dis, double *lstr, double *lsts, double *azr, double *azs, int *status));
  1205. Xextern void riset_cir P_((Now *np, Obj *op, double dis, RiseSet *rp));
  1206. Xextern void ta_par P_((double tha, double tdec, double phi, double ht, double ehp, double *aha, double *adec));
  1207. Xextern void unrefract P_((double pr, double tr, double aa, double *ta));
  1208. X
  1209. Xvoid riset_cir P_((Now *np, Obj *op, double dis, RiseSet *rp));
  1210. Xvoid twilight_cir P_((Now *np, double dis, double *dawn, double *dusk, int *status));
  1211. Xstatic void stationary_riset P_((Obj *op, Now *np, double dis, double *lstr, double *lsts, double *lstt, double *azr, double *azs, double *altt, int *status));
  1212. Xstatic void transit P_((double r, double d, Now *np, double *lstt, double *altt));
  1213. X
  1214. X#undef P_
  1215. X
  1216. X
  1217. X#define    TMACC    (15./3600.)    /* convergence accuracy, hours */
  1218. X
  1219. X/* find where and when an object, op, will rise and set and
  1220. X *   it's transit circumstances. all times are local, angles rads e of n.
  1221. X * dis is the angle down from an ideal horizon, in rads (see riset()).
  1222. X */
  1223. Xvoid
  1224. Xriset_cir (np, op, dis, rp)
  1225. XNow *np;
  1226. XObj *op;
  1227. Xdouble dis;
  1228. XRiseSet *rp;
  1229. X{
  1230. X#define    MAXPASSES    6
  1231. X    double lstr, lsts, lstt; /* local sidereal times of rising/setting */
  1232. X    double lnoon;        /* mjd of local noon */
  1233. X    double x;        /* discarded tmp value */
  1234. X    Now n;            /* copy to move time around */
  1235. X    Obj o;            /* copy to get circumstances at n */
  1236. X    double lst;        /* lst at local noon */
  1237. X    double diff, lastdiff;    /* iterative improvement to mjd0 */
  1238. X    int pass;
  1239. X    int rss;
  1240. X
  1241. X    /* find mjd of local noon -- all iterations start then */
  1242. X    lnoon = mjd_day(mjd - tz/24.0) + (12.0 + tz)/24.0;
  1243. X
  1244. X    /* work with local copies so we can move the time around */
  1245. X    n = *np;
  1246. X    o = *op;
  1247. X
  1248. X    /* assume no problems initially */
  1249. X    rp->rs_flags = 0;
  1250. X
  1251. X    /* first approximation is to find rise/set times of a fixed object
  1252. X     * at the current epoch in its position at local noon.
  1253. X     */
  1254. X    n.n_mjd = lnoon;
  1255. X    n.n_epoch = EOD;
  1256. X    now_lst (&n, &lst);    /* lst at local noon */
  1257. X    stationary_riset (&o, &n, dis, &lstr, &lsts, &lstt, &x, &x, &x, &rss);
  1258. X
  1259. X    chkrss:    /* come here to check rss status and control next step */
  1260. X    switch (rss) {
  1261. X    case  0:  break;
  1262. X    case  1: rp->rs_flags = RS_NEVERUP; return;
  1263. X    case -1: rp->rs_flags = RS_CIRCUMPOLAR; goto dotransit;
  1264. X    default: rp->rs_flags = RS_ERROR; return;
  1265. X    }
  1266. X
  1267. X    /* find a better approximation to the rising circumstances based on
  1268. X     * more passes, each using a "fixed" object at the location at
  1269. X     * previous approximation of the rise time.
  1270. X     */
  1271. X    lastdiff = 1000.0;
  1272. X    for (pass = 1; pass < MAXPASSES; pass++) {
  1273. X        diff = (lstr - lst)*SIDRATE; /* next guess at rise time wrt noon */
  1274. X        if (diff > 12.0)
  1275. X        diff -= 24.0*SIDRATE;    /* not tomorrow, today */
  1276. X        else if (diff < -12.0)
  1277. X        diff += 24.0*SIDRATE;    /* not yesterday, today */
  1278. X        n.n_mjd = lnoon + diff/24.0;    /* next guess at mjd of rise */
  1279. X        stationary_riset (&o, &n, dis, &lstr, &x, &x, &rp->rs_riseaz,
  1280. X                                &x, &x, &rss);
  1281. X        if (rss != 0) goto chkrss;
  1282. X        if (fabs (diff - lastdiff) < TMACC)
  1283. X        break;
  1284. X        lastdiff = diff;
  1285. X    }
  1286. X    if (pass == MAXPASSES)
  1287. X        rp->rs_flags |= RS_NORISE;    /* didn't converge - no rise today */
  1288. X    else {
  1289. X        rp->rs_risetm = 12.0 + diff;
  1290. X        if (!is_planet(op, MOON) &&
  1291. X            (rp->rs_risetm <= 24.0*(1.0-SIDRATE)
  1292. X            || rp->rs_risetm >= 24.0*SIDRATE))
  1293. X        rp->rs_flags |= RS_2RISES;
  1294. X    }
  1295. X
  1296. X    /* find a better approximation to the setting circumstances based on
  1297. X     * more passes, each using a "fixed" object at the location at
  1298. X     * previous approximation of the set time.
  1299. X     */
  1300. X    lastdiff = 1000.0;
  1301. X    for (pass = 1; pass < MAXPASSES; pass++) {
  1302. X        diff = (lsts - lst)*SIDRATE; /* next guess at set time wrt noon */
  1303. X        if (diff > 12.0)
  1304. X        diff -= 24.0*SIDRATE;    /* not tomorrow, today */
  1305. X        else if (diff < -12.0)
  1306. X        diff += 24.0*SIDRATE;    /* not yesterday, today */
  1307. X        n.n_mjd = lnoon + diff/24.0;    /* next guess at mjd of set */
  1308. X        stationary_riset (&o, &n, dis, &x, &lsts, &x, &x,
  1309. X                            &rp->rs_setaz, &x, &rss);
  1310. X        if (rss != 0) goto chkrss;
  1311. X        if (fabs (diff - lastdiff) < TMACC)
  1312. X        break;
  1313. X        lastdiff = diff;
  1314. X    }
  1315. X    if (pass == MAXPASSES)
  1316. X        rp->rs_flags |= RS_NOSET;    /* didn't converge - no set today */
  1317. X    else {
  1318. X        rp->rs_settm = 12.0 + diff;
  1319. X        if (!is_planet(op, MOON) &&
  1320. X            (rp->rs_settm <= 24.0*(1.0-SIDRATE)
  1321. X            || rp->rs_settm >= 24.0*SIDRATE))
  1322. X        rp->rs_flags |= RS_2SETS;
  1323. X    }
  1324. X
  1325. X    dotransit:
  1326. X    /* find a better approximation to the transit circumstances based on
  1327. X     * more passes, each using a "fixed" object at the location at
  1328. X     * previous approximation of the transit time.
  1329. X     */
  1330. X    lastdiff = 1000.0;
  1331. X    for (pass = 1; pass < MAXPASSES; pass++) {
  1332. X        diff = (lstt - lst)*SIDRATE; /*next guess at transit time wrt noon*/
  1333. X        if (diff > 12.0)
  1334. X        diff -= 24.0*SIDRATE;    /* not tomorrow, today */
  1335. X        else if (diff < -12.0)
  1336. X        diff += 24.0*SIDRATE;    /* not yesterday, today */
  1337. X        n.n_mjd = lnoon + diff/24.0; /* next guess at mjd of transit */
  1338. X        stationary_riset (&o, &n, dis, &x, &x, &lstt, &x, &x,
  1339. X                            &rp->rs_tranalt, &rss);
  1340. X        if (fabs (diff - lastdiff) < TMACC)
  1341. X        break;
  1342. X        lastdiff = diff;
  1343. X    }
  1344. X    if (pass == MAXPASSES)
  1345. X        rp->rs_flags |= RS_NOTRANS;    /* didn't converge - no transit today */
  1346. X    else {
  1347. X        rp->rs_trantm = 12.0 + diff;
  1348. X        if (!is_planet(op, MOON) &&
  1349. X            (rp->rs_trantm <= 24.0*(1.0-SIDRATE)
  1350. X            || rp->rs_trantm >= 24.0*SIDRATE))
  1351. X        rp->rs_flags |= RS_2TRANS;
  1352. X    }
  1353. X}
  1354. X
  1355. X/* find local times when sun is dis rads below horizon.
  1356. X */
  1357. Xvoid
  1358. Xtwilight_cir (np, dis, dawn, dusk, status)
  1359. XNow *np;
  1360. Xdouble dis;
  1361. Xdouble *dawn, *dusk;
  1362. Xint *status;
  1363. X{
  1364. X    RiseSet rs;
  1365. X    Obj o;
  1366. X
  1367. X    o.type = PLANET;
  1368. X    o.pl.code = SUN;
  1369. X    riset_cir (np, &o, dis, &rs);
  1370. X    *dawn = rs.rs_risetm;
  1371. X    *dusk = rs.rs_settm;
  1372. X    *status = rs.rs_flags;
  1373. X}
  1374. X
  1375. X/* find the local rise/set/transit circumstances of a fixed object, *op.
  1376. X * use lp to decide the day and the location circumstances.
  1377. X * fill *status is have any problems.
  1378. X */
  1379. Xstatic void
  1380. Xstationary_riset (op, np, dis, lstr, lsts, lstt, azr, azs, altt, status)
  1381. XObj *op;
  1382. XNow *np;
  1383. Xdouble dis;
  1384. Xdouble *lstr, *lsts, *lstt;
  1385. Xdouble *azr, *azs, *altt;
  1386. Xint *status;
  1387. X{
  1388. X    /* find object op's topocentric ra/dec at np..
  1389. X     * (this must include parallax if it's in the solar system).
  1390. X     */
  1391. X    if (obj_cir (np, op) < 0) {
  1392. X        printf ("stationary_riset: can't get object loc\n");
  1393. X        exit (1);
  1394. X    }
  1395. X    
  1396. X    if (is_ssobj(op)) {
  1397. X        /* obj_cir() gives geocentric ra/dec; we need to account for
  1398. X         * parallax in solar system objects to get topocentric ra/dec.
  1399. X         */
  1400. X        double tra, tdec;
  1401. X        double ehp, lst, ha;
  1402. X        if (is_planet(op, MOON))
  1403. X        ehp = asin (6378.14/op->s_edist);
  1404. X        else
  1405. X        ehp = (2.*6378./146e6)/op->s_edist;
  1406. X        now_lst (np, &lst);
  1407. X        ha = hrrad(lst) - op->s_ra;
  1408. X        ta_par (ha, op->s_dec, lat, elev, ehp, &ha, &tdec);
  1409. X        tra = hrrad(lst) - ha;
  1410. X        range (&tra, 2*PI);
  1411. X        op->s_ra = tra;
  1412. X        op->s_dec = tdec;
  1413. X    }
  1414. X
  1415. X    riset (op->s_ra, op->s_dec, lat, dis, lstr, lsts, azr, azs, status);
  1416. X    transit (op->s_ra, op->s_dec, np, lstt, altt);
  1417. X}
  1418. X
  1419. X
  1420. X/* find when and how hi object at (r,d) is when it transits. */
  1421. Xstatic void
  1422. Xtransit (r, d, np, lstt, altt)
  1423. Xdouble r, d;    /* ra and dec, rads */
  1424. XNow *np;    /* for refraction info */
  1425. Xdouble *lstt;    /* local sidereal time of transit */
  1426. Xdouble *altt;    /* local, refracted, altitude at time of transit */
  1427. X{
  1428. X    *lstt = radhr(r);
  1429. X    *altt = PI/2 - lat + d;
  1430. X    if (*altt > PI/2)
  1431. X        *altt = PI - *altt;
  1432. X    refract (pressure, temp, *altt, altt);
  1433. X}
  1434. END_OF_FILE
  1435.   if test 7897 -ne `wc -c <'riset_cir.c'`; then
  1436.     echo shar: \"'riset_cir.c'\" unpacked with wrong size!
  1437.   fi
  1438.   # end of 'riset_cir.c'
  1439. fi
  1440. if test -f 'skyviewmenu.c.1' -a "${1}" != "-c" ; then 
  1441.   echo shar: Will not clobber existing file \"'skyviewmenu.c.1'\"
  1442. else
  1443.   echo shar: Extracting \"'skyviewmenu.c.1'\" \(31658 characters\)
  1444.   sed "s/^X//" >'skyviewmenu.c.1' <<'END_OF_FILE'
  1445. X/* code to manage the stuff on the sky view display.
  1446. X * the filter menu is in filtermenu.c.
  1447. X */
  1448. X
  1449. X#include <stdio.h>
  1450. X#include <ctype.h>
  1451. X#include <math.h>
  1452. X#if defined(__STDC__)
  1453. X#include <stdlib.h>
  1454. X#endif
  1455. X#include <X11/Xlib.h>
  1456. X#include <Xm/Xm.h>
  1457. X#include <Xm/Form.h>
  1458. X#include <Xm/Frame.h>
  1459. X#include <Xm/DrawingA.h>
  1460. X#include <Xm/Label.h>
  1461. X#include <Xm/PushB.h>
  1462. X#include <Xm/CascadeB.h>
  1463. X#include <Xm/RowColumn.h>
  1464. X#include <Xm/ToggleB.h>
  1465. X#include <Xm/Text.h>
  1466. X#include <Xm/Scale.h>
  1467. X#include <Xm/Separator.h>
  1468. X#include "astro.h"
  1469. X#include "circum.h"
  1470. X
  1471. X/* we keep a linked-list of Objects we want trails for. these in turn "contain"
  1472. X * a variable-length array of TSkys for each location in the trail. The TSkys
  1473. X * are kept in increasing-time order as they are inserted for later plotting.
  1474. X * an item is added when the popup says so; it is removed if we are told the
  1475. X * object has been changed via sv_newobj(); all are removed if the whole db
  1476. X * changes.
  1477. X * also, we add to sky[] in multiples of TRAILCHUNKS for memory efficiency.
  1478. X */
  1479. Xtypedef struct {
  1480. X    unsigned flags;    /* OBJF_ things for this particular point */
  1481. X    double ts_mjd;    /* mjd when this Obj was valid */
  1482. X    Obj o;        /* copy of the object at ts_mjd */
  1483. X} TSky;
  1484. Xstruct trailObj {
  1485. X    struct trailObj *ntop;    /* pointer to next, or NULL */
  1486. X    int on;        /* use to mark on/off; actually remved on next update */
  1487. X    Obj *op;        /* object being trailed */
  1488. X    int nsky;        /* number of items in use within sky[] */
  1489. X    int nskymem;    /* total space of sky[] */
  1490. X    TSky sky[1];    /* basicaly a variable-length array of Objs */
  1491. X};
  1492. Xtypedef struct trailObj TrailObj;
  1493. X
  1494. X#if defined(__STDC__) || defined(__cplusplus)
  1495. X#define P_(s) s
  1496. X#else
  1497. X#define P_(s) ()
  1498. X#endif
  1499. X
  1500. Xextern Now *mm_get_now P_((void));
  1501. Xextern Obj *db_basic P_((int id));
  1502. Xextern Obj *db_next P_((Obj *op, HowNext how));
  1503. Xextern char *obj_description P_((Obj *op));
  1504. Xextern double mjd_hr P_((double jd));
  1505. Xextern int f_ison P_((void));
  1506. Xextern int lc P_((int cx, int cy, int cw, int x1, int y1, int x2, int y2, int *sx1, int *sy1, int *sx2, int *sy2));
  1507. Xextern int svf_filter_ok P_((Obj *op));
  1508. Xextern int tickmarks P_((double min, double max, int numdiv, double ticks[]));
  1509. Xextern void aa_hadec P_((double lati, double alt, double az, double *ha, double *dec));
  1510. Xextern void db_update P_((Obj *op));
  1511. Xextern void ecl_eq P_((double Mjd, double Lat, double Lng, double *ra, double *dec));
  1512. Xextern void eq_ecl P_((double Mjd, double ra, double dec, double *Lat, double *Lng));
  1513. Xextern void f_showit P_((Widget w, char *s));
  1514. Xextern void fs_angle P_((char out[], double a));
  1515. Xextern void fs_date P_((char out[], double jd));
  1516. Xextern void fs_ra P_((char out[], double ra));
  1517. Xextern void fs_time P_((char out[], double t));
  1518. Xextern void get_something P_((Widget w, char *resource, char *value));
  1519. Xextern void gk_mag P_((double g, double k, double rp, double rho, double *mp));
  1520. Xextern void hadec_aa P_((double lati, double ha, double dec, double *alt, double *az));
  1521. Xextern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
  1522. Xextern void now_lst P_((Now *np, double *lst));
  1523. Xextern void obj_pickgc P_((Obj *op, Widget w, GC *gcp));
  1524. Xextern void obj_set P_((Obj *op));
  1525. Xextern void precess P_((double mjd1, double mjd2, double *ra, double *dec));
  1526. Xextern void range P_((double *v, double r));
  1527. Xextern void refract P_((double pr, double tr, double ta, double *aa));
  1528. Xextern void set_something P_((Widget w, char *resource, char *value));
  1529. Xextern void set_xmstring P_((Widget w, char *resource, char *txt));
  1530. Xextern void svf_create P_((void));
  1531. Xextern void svf_manage P_((void));
  1532. Xextern void svf_manage_toggle P_((void));
  1533. Xextern void svf_unmanage P_((void));
  1534. Xextern void timestamp P_((Now *np, Widget w));
  1535. Xextern void unrefract P_((double pr, double tr, double aa, double *ta));
  1536. Xextern void watch_cursor P_((int want));
  1537. Xextern void xe_msg P_((char *msg, int app_modal));
  1538. X
  1539. Xvoid sv_manage P_((void));
  1540. Xint sv_ison P_((void));
  1541. Xvoid sv_newobj P_((int dbidx));
  1542. Xvoid sv_newdb P_((int appended));
  1543. Xvoid sv_update P_((Now *np, int how_much));
  1544. Xvoid sv_point P_((Obj *op));
  1545. Xint sv_id P_((Obj *op));
  1546. Xvoid sv_cursor P_((Cursor c));
  1547. Xvoid sv_all P_((Now *np, int preclr));
  1548. Xvoid sv_draw_obj P_((Display *dsp, Drawable win, GC gc, Obj *op, int x, int y, int diam, int dotsonly));
  1549. Xstatic void sv_copy_sky P_((void));
  1550. Xstatic void sv_create_svform P_((void));
  1551. Xstatic void sv_create_find P_((Widget parent));
  1552. Xstatic void sv_close_cb P_((Widget w, XtPointer client, XtPointer call));
  1553. Xstatic void sv_help_cb P_((Widget w, XtPointer client, XtPointer call));
  1554. Xstatic void sv_aa_cb P_((Widget w, XtPointer client, XtPointer call));
  1555. Xstatic void sv_all_labels_cb P_((Widget w, XtPointer client, XtPointer call));
  1556. Xstatic void sv_filter_cb P_((Widget w, XtPointer client, XtPointer call));
  1557. Xstatic void sv_grid_cb P_((Widget w, XtPointer client, XtPointer call));
  1558. Xstatic void sv_set_scales P_((void));
  1559. Xstatic void sv_da_exp_cb P_((Widget w, XtPointer client, XtPointer call));
  1560. Xstatic void sv_da_input_cb P_((Widget w, XtPointer client, XtPointer call));
  1561. Xstatic void sv_da_motion_cb P_((Widget w, XtPointer client, XEvent *ev, Boolean *continue_to_dispatch));
  1562. Xstatic void sv_changed_cb P_((Widget w, XtPointer client, XtPointer call));
  1563. Xstatic void sv_ecliptic_cb P_((Widget w, XtPointer client, XtPointer call));
  1564. Xstatic void sv_justdots_cb P_((Widget w, XtPointer client, XtPointer call));
  1565. Xstatic void sv_finding_cb P_((Widget wid, XtPointer client, XtPointer call));
  1566. Xstatic void sv_find_cb P_((Widget w, XtPointer client, XtPointer call));
  1567. Xstatic void sv_magdrag_cb P_((Widget w, XtPointer client, XtPointer call));
  1568. Xstatic void sv_set_view P_((void));
  1569. Xstatic void sv_getcircle P_((unsigned int *wp, unsigned int *hp, unsigned int *rp, unsigned int *xbp, unsigned int *ybp));
  1570. Xstatic void sv_popup P_((XEvent *ev, Obj *op, TSky *tsp));
  1571. Xstatic void sv_create_popup P_((void));
  1572. Xstatic void sv_pu_activate_cb P_((Widget w, XtPointer client, XtPointer call));
  1573. Xstatic void sv_pu_trail_cb P_((Widget wid, XtPointer client, XtPointer call));
  1574. Xstatic void sv_pu_label_cb P_((Widget wid, XtPointer client, XtPointer call));
  1575. Xstatic void tobj_rmoff P_((void));
  1576. Xstatic void tobj_rmobj P_((Obj *op));
  1577. Xstatic TrailObj *tobj_addobj P_((Obj *op));
  1578. Xstatic TrailObj *tobj_growsky P_((TrailObj *top));
  1579. Xstatic void tobj_reset P_((void));
  1580. Xstatic TrailObj *tobj_find P_((Obj *op));
  1581. Xstatic TrailObj *tobj_addsky P_((TrailObj *top, double jd, Obj *op));
  1582. Xstatic void tobj_display_all P_((unsigned r, unsigned xb, unsigned yb));
  1583. Xstatic sv_dbobjloc P_((Obj *op, int r, int *xp, int *yp));
  1584. Xstatic sv_trailobjloc P_((TSky *tsp, int r, int *xp, int *yp));
  1585. Xstatic sv_precheck P_((Obj *op));
  1586. Xstatic sv_bright_ok P_((Obj *op));
  1587. Xstatic sv_infov P_((Obj *op));
  1588. Xstatic sv_loc P_((int rad, double altdec, double azra, int *xp, int *yp));
  1589. Xstatic sv_unloc P_((int rad, int x, int y, double *altdecp, double *azrap));
  1590. Xstatic void draw_ecliptic P_((Display *dsp, Window win, GC gc, unsigned int r, unsigned int xb, unsigned int yb));
  1591. Xstatic void draw_grid P_((Display *dsp, Window win, GC gc, unsigned int r, unsigned int xb, unsigned int yb));
  1592. Xstatic magdiam P_((double m));
  1593. Xstatic void sv_mk_gcs P_((Display *dsp, Window win));
  1594. Xstatic void draw_label P_((Display *dsp, Window win, GC gc, char label[], int x, int y));
  1595. X
  1596. X#undef P_
  1597. X
  1598. Xextern Widget toplevel_w;
  1599. X
  1600. X#define    NGRID    20        /* max grid lines each dimension */
  1601. X#define    NSEGS    5        /* piecewise segments per arc */
  1602. X#define    ECL_TICS    2    /* period of points for ecliptic, pixels */
  1603. X
  1604. X#define    MARKER    20        /* pointer marker half-width, pixels */
  1605. X
  1606. X#define    BMAGLIMIT    (-28)    /* brightest setting for the Mag scales */
  1607. X#define    FMAGLIMIT    20    /* faintest setting for the Mag scales */
  1608. X#define    TRAILCHUNKS    50    /* we malloc these many at a time */
  1609. X
  1610. Xstatic Widget svform_w;            /* main sky view form dialog */
  1611. Xstatic Widget svda_w;            /* sky view drawing area */
  1612. Xstatic Widget fov_w, altdec_w, azra_w;    /* scale widgets */
  1613. Xstatic Widget fmag_w, bmag_w;        /* magnitude scale widgets */
  1614. Xstatic Widget hgrid_w, vgrid_w;        /* h and v grid spacing labels */
  1615. Xstatic Widget aa_w, rad_w;        /* altaz/radec toggle buttons */
  1616. Xstatic Widget dt_w;            /* the date/time stamp label widget */
  1617. Xstatic Widget find_w[2];        /* cascade buttons for "find" objx/y */
  1618. Xstatic Pixmap sv_pm;            /* off-screen pixmap we *really* draw */
  1619. Xstatic Widget talt_w, taz_w;        /* tracking alt/az report widgets */
  1620. Xstatic Widget tra_w, tdec_w;        /* tracking ra/dec report widgets */
  1621. X
  1622. X/* pixels and GCs
  1623. X */
  1624. Xstatic Pixel fg_p, bg_p, sky_p;    /* default fg, background, and sky colors */
  1625. Xstatic GC sv_gc;        /* the default GC */
  1626. X
  1627. Xstatic int aa_mode = -1;    /* 1 for alt/az or 0 for ra/dec */
  1628. Xstatic double sv_altdec;    /* view center alt or dec, rads */
  1629. Xstatic double sv_azra;        /* view center az or ra, rads */
  1630. Xstatic double sv_fov;        /* field of view, rads */
  1631. Xstatic int fmag, bmag;        /* faintest/brightest magnitude to display */
  1632. Xstatic int justdots;        /* set when only want to use dots on the map */
  1633. Xstatic int want_ecliptic;    /* set when want to see the ecliptic */
  1634. Xstatic TrailObj *trailobj;    /* head of a malloced linked-list -- 0 when
  1635. X                 * empty
  1636. X                 */
  1637. Xstatic int want_grid;        /* set when we want to draw the coord grid */
  1638. Xstatic all_labels;        /* !0 when want to display all labels */
  1639. Xstatic int sv_ournewobj;    /* used to inhibit useless redrawing */
  1640. X
  1641. Xstatic char null_grid_str[] = "             ";
  1642. X
  1643. X/* info about the popup widget.
  1644. X * we make one once and keep reusing it -- seems to be a bit faster that way.
  1645. X */
  1646. Xtypedef struct {
  1647. X    Widget pu_w;
  1648. X    Widget name_w;
  1649. X    Widget desc_w;
  1650. X    Widget spect_w;
  1651. X    Widget ud_w;
  1652. X    Widget ut_w;
  1653. X    Widget ra_w;
  1654. X    Widget dec_w;
  1655. X    Widget alt_w;
  1656. X    Widget az_w;
  1657. X    Widget mag_w;
  1658. X    Widget trail_w;
  1659. X    Widget label_w;
  1660. X    Obj *op;
  1661. X    TSky *tsp;    /* this is used if we are displaying a trailed object */
  1662. X} Popup;
  1663. Xstatic Popup pu;
  1664. X
  1665. Xenum {AIM, MK_OBJX};        /* popup button activate codes */
  1666. X
  1667. X/* Obj.flags or TSky flags values */
  1668. X#define    OBJF_ONSCREEN    0x1    /* bit set if obj is on screen */
  1669. X#define    OBJF_LABEL    0x2    /* set if label is to be on */
  1670. X
  1671. X/* called when the sky view is activated via the main menu pulldown.
  1672. X * if never called before, create and manage all the widgets as a child of a
  1673. X * form. otherwise, just toggle whether the form is managed.
  1674. X * also manage the corresponding filter dialog along with.
  1675. X * freeing the pixmap will force a fresh update on the next expose.
  1676. X */
  1677. Xvoid
  1678. Xsv_manage ()
  1679. X{
  1680. X    if (!svform_w)
  1681. X        sv_create_svform(); /* also creates the filter */
  1682. X    
  1683. X    if (XtIsManaged(svform_w)) {
  1684. X        XtUnmanageChild (svform_w);
  1685. X        svf_unmanage();
  1686. X        if (sv_pm) {
  1687. X        XFreePixmap (XtDisplay(svda_w), sv_pm);
  1688. X        sv_pm = (Pixmap) NULL;
  1689. X        }
  1690. X    } else {
  1691. X        XtManageChild (svform_w);
  1692. X        /* rely on expose to a fresh update */
  1693. X    }
  1694. X}
  1695. X
  1696. Xsv_ison()
  1697. X{
  1698. X    return (svform_w && XtIsManaged(svform_w));
  1699. X}
  1700. X
  1701. X/* called when a user-defined object has changed.
  1702. X * take it off the trailobj list, if it's there (it's ok if it's not).
  1703. X * then since we rely on knowing our update will be called we need do nothing
  1704. X *   more to redisplay without the object.
  1705. X */
  1706. Xvoid
  1707. Xsv_newobj(dbidx)
  1708. Xint dbidx;        /* OBJX or OBJY */
  1709. X{
  1710. X    Obj *op = db_basic(dbidx);
  1711. X
  1712. X    tobj_rmobj (op);
  1713. X
  1714. X}
  1715. X
  1716. X/* called when the db (beyond NOBJ) has changed.
  1717. X * if it was appended to we can just redraw; if it was changed we need to
  1718. X * discard any trails we are keeping first.
  1719. X */
  1720. Xvoid
  1721. Xsv_newdb(appended)
  1722. Xint appended;
  1723. X{
  1724. X    if (!appended)
  1725. X        tobj_reset();
  1726. X    sv_update (mm_get_now(), 1);
  1727. X}
  1728. X
  1729. X/* called when we are to update our view.
  1730. X * don't bother if we are unmanaged unless there are trails to be saved.
  1731. X * add any objects in the trails list then redraw the screen if we are up.
  1732. X * also don't bother if we are the reason for an all_newobj() or if fields are
  1733. X *   off.
  1734. X * we also remove any trails that have been turned off.
  1735. X */
  1736. X/* ARGSUSED */
  1737. Xvoid
  1738. Xsv_update (np, how_much)
  1739. XNow *np;
  1740. Xint how_much;
  1741. X{
  1742. X    TrailObj *top;
  1743. X    int up;
  1744. X
  1745. X    if (sv_ournewobj)
  1746. X        return;
  1747. X
  1748. X    up = svform_w && XtIsManaged(svform_w);
  1749. X    if (!up && !trailobj)
  1750. X        return;
  1751. X
  1752. X    /* remove trails no longer wanted. */
  1753. X    tobj_rmoff();
  1754. X
  1755. X    /* add an entry to each trailed object for this time. */
  1756. X    for (top = trailobj; top; top = top->ntop) {
  1757. X        db_update (top->op);
  1758. X        top = tobj_addsky (top, mjd, top->op);
  1759. X    }
  1760. X
  1761. X    if (up && f_ison())
  1762. X        sv_all(np, 1);
  1763. X}
  1764. X
  1765. X/* point at the given object and mark it.
  1766. X * N.B. we do *not* update the s_ fields of op.
  1767. X */
  1768. Xvoid
  1769. Xsv_point (op)
  1770. XObj *op;
  1771. X{
  1772. X    double d;
  1773. X
  1774. X    if (!svform_w || !op || op->type == UNDEFOBJ)
  1775. X        return;
  1776. X
  1777. X    if (aa_mode && op->s_alt < 0.0) {
  1778. X        xe_msg ("Object is below the horizon", 1);
  1779. X        return;
  1780. X    }
  1781. X
  1782. X    d = raddeg(aa_mode ? op->s_alt : op->s_dec);
  1783. X    XmScaleSetValue (altdec_w, (int)floor(d + 0.5));
  1784. X    d = aa_mode ? raddeg(op->s_az) : 10.0*radhr(op->s_ra);
  1785. X    XmScaleSetValue (azra_w, (int)floor(d + 0.5));
  1786. X    sv_set_view();
  1787. X    sv_all(mm_get_now(), 1);
  1788. X
  1789. X    switch (sv_id(op)) {
  1790. X    case -1: xe_msg ("sv_point: object is below horizon", 0); break;
  1791. X    case -2: xe_msg ("sv_point: object is outside FOV", 0); break;
  1792. X    }
  1793. X}
  1794. X
  1795. X/* show a marker at the location of the given object.
  1796. X * return 0 if object was in fact in the field of view;
  1797. X *       -1 if in alt/az mode and op is below the horizon now;
  1798. X *       -2 if object is otherwise outside the field of view now.
  1799. X * N.B. we do *not* update the s_ fields of op.
  1800. X */
  1801. Xsv_id (op)
  1802. XObj *op;
  1803. X{
  1804. X    Display *dsp = XtDisplay (svda_w);
  1805. X    Window win = XtWindow (svda_w);
  1806. X    unsigned int wide, h, r, xb, yb;
  1807. X    double altdec, azra;
  1808. X    int x, y;
  1809. X
  1810. X    if (!svform_w || !XtIsManaged(svform_w) || !op || op->type == UNDEFOBJ)
  1811. X        return (-2);
  1812. X
  1813. X    sv_getcircle (&wide, &h, &r, &xb, &yb);
  1814. X
  1815. X    altdec = aa_mode ? op->s_alt : op->s_dec;
  1816. X    azra   = aa_mode ? op->s_az  : op->s_ra;
  1817. X    if (!sv_loc (r, altdec, azra, &x, &y))
  1818. X        return (aa_mode && op->s_alt < 0.0 ? -1 : -2);
  1819. X
  1820. X    x += xb;
  1821. X    y += yb;
  1822. X
  1823. X    XSetForeground (dsp, sv_gc, fg_p);
  1824. X    XDrawLine (dsp, win, sv_gc, x-MARKER, y-MARKER, x+MARKER, y+MARKER);
  1825. X    XDrawLine (dsp, win, sv_gc, x+MARKER, y-MARKER, x-MARKER, y+MARKER);
  1826. X
  1827. X    return (0);
  1828. X}
  1829. X
  1830. X/* called to put up or remove the watch cursor.  */
  1831. Xvoid
  1832. Xsv_cursor (c)
  1833. XCursor c;
  1834. X{
  1835. X    Window win;
  1836. X
  1837. X    if (svform_w && (win = XtWindow(svform_w))) {
  1838. X        Display *dsp = XtDisplay(svform_w);
  1839. X        if (c)
  1840. X        XDefineCursor (dsp, win, c);
  1841. X        else
  1842. X        XUndefineCursor (dsp, win);
  1843. X    }
  1844. X}
  1845. X
  1846. X/* draw everything subject to any filtering.
  1847. X */
  1848. X/* ARGSUSED */
  1849. Xvoid
  1850. Xsv_all(np, preclr)
  1851. XNow *np;
  1852. Xint preclr;
  1853. X{
  1854. X    Display *dsp = XtDisplay(svda_w);
  1855. X    Window win = sv_pm;
  1856. X    unsigned int w, h, r, xb, yb;
  1857. X    Obj *op;
  1858. X
  1859. X    watch_cursor(1);
  1860. X
  1861. X    /* put up the timestamp */
  1862. X    timestamp (np, dt_w);
  1863. X
  1864. X    sv_getcircle (&w, &h, &r, &xb, &yb);
  1865. X
  1866. X    /* rebuild the clean circle */
  1867. X    XSetForeground (dsp, sv_gc, bg_p);
  1868. X    XFillRectangle (dsp, win, sv_gc, 0, 0, w, h);
  1869. X    XSetForeground (dsp, sv_gc, sky_p);
  1870. X    XFillArc (dsp, win, sv_gc, xb+1, yb+1, 2*r-2, 2*r-2, 0, 360*64);
  1871. X    XSetForeground (dsp, sv_gc, fg_p);
  1872. X    XDrawArc (dsp, win, sv_gc, xb, yb, 2*r-1, 2*r-1, 0, 360*64);
  1873. X
  1874. X    /* go through the database and display what we want */
  1875. X    for (op = db_next(NULL, OBJS_ALL); op; op = db_next(op, OBJS_ALL)) {
  1876. X        GC gc;
  1877. X        int x, y;
  1878. X        obj_pickgc(op, svda_w, &gc);
  1879. X        if (!sv_dbobjloc(op, r, &x, &y))
  1880. X        op->o_flags &= ~OBJF_ONSCREEN;
  1881. X        else {
  1882. X        /* yup, it's really supposed to be on the screen */
  1883. X        db_update (op);
  1884. X        x += xb;
  1885. X        y += yb;
  1886. X        sv_draw_obj (dsp, win, gc, op, x, y,
  1887. X                    magdiam(op->s_mag/MAGSCALE), justdots);
  1888. X        op->o_flags |= OBJF_ONSCREEN;
  1889. X        if (all_labels || (op->o_flags & OBJF_LABEL))
  1890. X            draw_label (dsp, win, gc, op->o_name, x, y);
  1891. X        }
  1892. X    }
  1893. X
  1894. X    sv_draw_obj (dsp, win, (GC)0, NULL, 0, 0, 0, 0);    /* flush */
  1895. X
  1896. X    /* go through the trailobj list and display that stuff too. */
  1897. X    tobj_display_all(r, xb, yb);
  1898. X
  1899. X    /* draw a grid on top if desired */
  1900. X    if (want_grid) {
  1901. X        XSetForeground (dsp, sv_gc, fg_p);
  1902. X        draw_grid(dsp, win, sv_gc, r, xb, yb);
  1903. X    }
  1904. X
  1905. X    /* and finally draw the ecliptic on top if desired */
  1906. X    if (want_ecliptic) {
  1907. X        XSetForeground (dsp, sv_gc, fg_p);
  1908. X        draw_ecliptic (dsp, win, sv_gc, r, xb, yb);
  1909. X    }
  1910. X
  1911. X    /* and we're done */
  1912. X    sv_copy_sky();
  1913. X
  1914. X    watch_cursor(0);
  1915. X}
  1916. X
  1917. X/* draw the given object so it has a nominal diameter of diam pixels.
  1918. X * we maintain a static cache of common X drawing objects for efficiency.
  1919. X * (mallocing seemed to keep the memory arena too fragmented).
  1920. X * to force a flush, call with op == NULL.
  1921. X */
  1922. Xvoid
  1923. Xsv_draw_obj (dsp, win, gc, op, x, y, diam, dotsonly)
  1924. XDisplay *dsp;
  1925. XDrawable win;
  1926. XGC gc;
  1927. XObj *op;
  1928. Xint x, y;
  1929. Xint diam;
  1930. Xint dotsonly;
  1931. X{
  1932. X#define    CACHE_SZ    100
  1933. X#define    CACHE_PAD    10    /* most we ever need in one call */
  1934. X#define    CACHE_HWM    (CACHE_SZ - CACHE_PAD)    /* hi water mark */
  1935. X    static XPoint   xpoints[CACHE_SZ],   *xp  = xpoints;
  1936. X    static XArc     xdrawarcs[CACHE_SZ], *xda = xdrawarcs;
  1937. X    static XArc     xfillarcs[CACHE_SZ], *xfa = xfillarcs;
  1938. X    static XSegment xsegments[CACHE_SZ], *xs  = xsegments;
  1939. X    static GC cache_gc;
  1940. X    int force;
  1941. X    int t;
  1942. X
  1943. X    /* for sure if no op or different gc */
  1944. X    force = !op || gc != cache_gc;
  1945. X
  1946. X    if (force || xp >= xpoints + CACHE_HWM) {
  1947. X        int n;
  1948. X        if ((n = xp - xpoints) > 0) {
  1949. X        XDrawPoints (dsp, win, cache_gc, xpoints, n, CoordModeOrigin);
  1950. X        xp = xpoints;
  1951. X#ifdef SVTRACE
  1952. X        printf ("points=%d\n", n);
  1953. X#endif
  1954. X        }
  1955. X    }
  1956. X    if (force || xda >= xdrawarcs + CACHE_HWM) {
  1957. X        int n;
  1958. X        if ((n = xda - xdrawarcs) > 0) {
  1959. X        XDrawArcs (dsp, win, cache_gc, xdrawarcs, n);
  1960. X        xda = xdrawarcs;
  1961. X#ifdef SVTRACE
  1962. X        printf ("drawarcs=%d\n", n);
  1963. X#endif
  1964. X        }
  1965. X    }
  1966. X    if (force || xfa >= xfillarcs + CACHE_HWM) {
  1967. X        int n;
  1968. X        if ((n = xfa - xfillarcs) > 0) {
  1969. X        XFillArcs (dsp, win, cache_gc, xfillarcs, n);
  1970. X        xfa = xfillarcs;
  1971. X#ifdef SVTRACE
  1972. X        printf ("fillarcs=%d\b", n);
  1973. X#endif
  1974. X        }
  1975. X    }
  1976. X    if (force || xs >= xsegments + CACHE_HWM) {
  1977. X        int n;
  1978. X        if ((n = xs - xsegments) > 0) {
  1979. X        XDrawSegments (dsp, win, cache_gc, xsegments, n);
  1980. X        xs = xsegments;
  1981. X#ifdef SVTRACE
  1982. X        printf ("segments=%d\n", n);
  1983. X#endif
  1984. X        }
  1985. X    }
  1986. X
  1987. X    cache_gc = gc;
  1988. X
  1989. X    if (!op)
  1990. X        return;    /* just flushing, thanks */
  1991. X
  1992. X    /* one-pixel wide anything is just a dot */
  1993. X    if (diam <= 1) {
  1994. X        xp->x = x;
  1995. X        xp->y = y;
  1996. X        xp++;
  1997. X        return;
  1998. X    }
  1999. X
  2000. X    /* if dotsonly is on don't use the fancy symbols, just use dots */
  2001. X    if (dotsonly) {
  2002. X        xfa->x = x - diam/2;
  2003. X        xfa->y = y - diam/2;
  2004. X        xfa->width = diam;
  2005. X        xfa->height = diam;
  2006. X        xfa->angle1 = 0;
  2007. X        xfa->angle2 = 360*64;
  2008. X        xfa++;
  2009. X        return;
  2010. X    }
  2011. X
  2012. X    switch (op->type) {
  2013. X    case PLANET:
  2014. X        /* filled circle */
  2015. X        xfa->x = x - diam/2;
  2016. X        xfa->y = y - diam/2;
  2017. X        xfa->width = diam;
  2018. X        xfa->height = diam;
  2019. X        xfa->angle1 = 0;
  2020. X        xfa->angle2 = 360*64;
  2021. X        xfa++;
  2022. X        break;
  2023. X    case FIXED:
  2024. X        switch (op->f_class) {
  2025. X        case 'G': case 'H': case 'A': /* galaxy */
  2026. X        /* filled ellipse */
  2027. X        xfa->x = x - diam/2;
  2028. X        xfa->y = y - diam/4;
  2029. X        xfa->width = diam;
  2030. X        xfa->height = diam/2;
  2031. X        xfa->angle1 = 0;
  2032. X        xfa->angle2 = 360*64;
  2033. X        xfa++;
  2034. X        break;
  2035. X        case 'C': case 'U': /* globular clusters */
  2036. X        /* same as cluster but with a central dot */
  2037. X        xfa->x = x - 1;
  2038. X        xfa->y = y - 1;
  2039. X        xfa->width = 3;
  2040. X        xfa->height = 3;
  2041. X        xfa->angle1 = 0;
  2042. X        xfa->angle2 = 360*64;
  2043. X        xfa++;
  2044. X        /* fall through */
  2045. X        case 'O': /* open cluster */
  2046. X        /* open circle of dots */
  2047. X        xp->x = x;    xp->y = y-3;    xp++;
  2048. X        xp->x = x+3;    xp->y = y-1;    xp++;
  2049. X        xp->x = x+3;    xp->y = y+1;    xp++;
  2050. X        xp->x = x;    xp->y = y+3;    xp++;
  2051. X        xp->x = x-3;    xp->y = y+1;    xp++;
  2052. X        xp->x = x-3;    xp->y = y-1;    xp++;
  2053. X        break;
  2054. X        case 'P': /* planetary nebula */
  2055. X        /* open ellipse */
  2056. X        xda->x = x - diam/2;
  2057. X        xda->y = y - diam/4;
  2058. X        xda->width = diam;
  2059. X        xda->height = diam/2;
  2060. X        xda->angle1 = 0;
  2061. X        xda->angle2 = 360*64;
  2062. X        xda++;
  2063. X        break;
  2064. X        case 'S': /* stars */
  2065. X        /* filled circle */
  2066. X        xfa->x = x - diam/2;
  2067. X        xfa->y = y - diam/2;
  2068. X        xfa->width = diam;
  2069. X        xfa->height = diam;
  2070. X        xfa->angle1 = 0;
  2071. X        xfa->angle2 = 360*64;
  2072. X        xfa++;
  2073. X        break;
  2074. X        case 'B': case 'D': /* binary and double stars */
  2075. X        /* filled circle with one horizontal line through it */
  2076. X        xfa->x = x - diam/2;
  2077. X        xfa->y = y - diam/2;
  2078. X        xfa->width = diam;
  2079. X        xfa->height = diam;
  2080. X        xfa->angle1 = 0;
  2081. X        xfa->angle2 = 360*64;
  2082. X        xfa++;
  2083. X        t = 3*diam/4;
  2084. X        xs->x1 = x - t;
  2085. X        xs->y1 = y;
  2086. X        xs->x2 = x + t;
  2087. X        xs->y2 = y;
  2088. X        xs++;
  2089. X        break;
  2090. X        case 'M': /* multiple stars */
  2091. X        /* filled circle with two horizontal lines through it */
  2092. X        xfa->x = x - diam/2;
  2093. X        xfa->y = y - diam/2;
  2094. X        xfa->width = diam;
  2095. X        xfa->height = diam;
  2096. X        xfa->angle1 = 0;
  2097. X        xfa->angle2 = 360*64;
  2098. X        xfa++;
  2099. X        t = 3*diam/4;
  2100. X        xs->x1 = x - t;
  2101. X        xs->y1 = y - diam/6;
  2102. X        xs->x2 = x + t;
  2103. X        xs->y2 = y - diam/6;
  2104. X        xs++;
  2105. X        xs->x1 = x - t;
  2106. X        xs->y1 = y + diam/6;
  2107. X        xs->x2 = x + t;
  2108. X        xs->y2 = y + diam/6;
  2109. X        xs++;
  2110. X        break;
  2111. X        case 'V': /* variable star */
  2112. X        /* central dot with concentric circle */
  2113. X        xfa->x = x - diam/4;
  2114. X        xfa->y = y - diam/4;
  2115. X        xfa->width = diam/2;
  2116. X        xfa->height = diam/2;
  2117. X        xfa->angle1 = 0;
  2118. X        xfa->angle2 = 360*64;
  2119. X        xfa++;
  2120. X        xda->x = x - diam/2;
  2121. X        xda->y = y - diam/2;
  2122. X        xda->width = diam;
  2123. X        xda->height = diam;
  2124. X        xda->angle1 = 0;
  2125. X        xda->angle2 = 360*64;
  2126. X        xda++;
  2127. X        break;
  2128. X        case 'F': case 'K': /* diffuse and dark nebulea */
  2129. X        /* open diamond */
  2130. X        xs->x1 = x-diam/2;    xs->y1 = y;
  2131. X            xs->x2 = x;            xs->y2 = y-diam/2;    xs++;
  2132. X        xs->x1 = x;        xs->y1 = y-diam/2;
  2133. X            xs->x2 = x+diam/2;        xs->y2 = y;        xs++;
  2134. X        xs->x1 = x+diam/2;    xs->y1 = y;
  2135. X            xs->x2 = x;            xs->y2 = y+diam/2;    xs++;
  2136. X        xs->x1 = x;        xs->y1 = y+diam/2;
  2137. X            xs->x2 = x-diam/2;        xs->y2 = y;        xs++;
  2138. X        break;
  2139. X        case 'N': /* bright nebulea */
  2140. X        /* filled diamond */
  2141. X        {   XPoint p[5];
  2142. X            p[0].x = x-diam/2;    p[0].y = y;
  2143. X            p[1].x = x;        p[1].y = y-diam/2;
  2144. X            p[2].x = x+diam/2;    p[2].y = y;
  2145. X            p[3].x = x;        p[3].y = y+diam/2;
  2146. X            p[4].x = x-diam/2;    p[4].y = y;
  2147. X            XFillPolygon (dsp, win, gc, p, 5, Convex, CoordModeOrigin);
  2148. X        }
  2149. X        break;
  2150. X        case 'Q': /* Quasar */
  2151. X        /* plus sign */
  2152. X        xs->x1 = x-diam/2;    xs->y1 = y;
  2153. X            xs->x2 = x+diam/2;        xs->y2 = y;        xs++;
  2154. X        xs->x1 = x;        xs->y1 = y-diam/2;
  2155. X            xs->x2 = x;            xs->y2 = y+diam/2;    xs++;
  2156. X        break;
  2157. X        case 'T':    /* stellar object */
  2158. X        case '\0':    /* undefined type */
  2159. X        default:    /* unknown type */
  2160. X        /* an X */
  2161. X        xs->x1 = x-diam/3;    xs->y1 = y-diam/3;
  2162. X            xs->x2 = x+diam/3;        xs->y2 = y+diam/3;    xs++;
  2163. X        xs->x1 = x-diam/3;    xs->y1 = y+diam/3;
  2164. X            xs->x2 = x+diam/3;        xs->y2 = y-diam/3;    xs++;
  2165. X        break;
  2166. X        }
  2167. X        break;
  2168. X    case HYPERBOLIC:
  2169. X    case PARABOLIC:
  2170. X        /* usually cometose -- draw a filled circle with tail */
  2171. X        t = 3*diam/4;
  2172. X        xfa->x = x - diam/4;
  2173. X        xfa->y = y - diam/4;
  2174. X        xfa->width = diam/2;
  2175. X        xfa->height = diam/2;
  2176. X        xfa->angle1 = 0;
  2177. X        xfa->angle2 = 360*64;
  2178. X        xfa++;
  2179. X        xfa->x = x - t;
  2180. X        xfa->y = y - t;
  2181. X        xfa->width = 2*t;
  2182. X        xfa->height = 2*t;
  2183. X        xfa->angle1 = 120*64;
  2184. X        xfa->angle2 = 30*64;
  2185. X        xfa++;
  2186. X        break;
  2187. X    case ELLIPTICAL:
  2188. X        /* filled square */
  2189. X        XFillRectangle (dsp, win, gc, x-diam/2, y-diam/2, diam, diam);
  2190. X        break;
  2191. X    }
  2192. X}
  2193. X
  2194. X/* create the main skyview form */
  2195. Xstatic void
  2196. Xsv_create_svform()
  2197. X{
  2198. X    static struct {
  2199. X        char *name;
  2200. X        void (*cb)();
  2201. X    } cbs[] = {
  2202. X        {"Filter", sv_filter_cb},
  2203. X        {"Close", sv_close_cb},
  2204. X        {"Help", sv_help_cb},
  2205. X    };
  2206. X    Widget rc_w;
  2207. X    Widget w;
  2208. X    Widget rb_w;
  2209. X    Widget sep_w;
  2210. X    Widget ctlfr_w, ctl_w;
  2211. X    XmString str;
  2212. X    Arg args[20];
  2213. X    EventMask mask;
  2214. X    int i, n;
  2215. X
  2216. X    /* create form */
  2217. X    n = 0;
  2218. X    XtSetArg (args[n], XmNautoUnmanage, False); n++;
  2219. X    XtSetArg (args[n], XmNdefaultPosition, False); n++;
  2220. X    XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  2221. X    svform_w = XmCreateFormDialog (toplevel_w, "SkyView", args, n);
  2222. X
  2223. X    /* set some stuff in the parent DialogShell.
  2224. X     * setting XmNdialogTitle in the Form didn't work..
  2225. X     */
  2226. X    n = 0;
  2227. X    XtSetArg (args[n], XmNtitle, "xephem Sky view"); n++;
  2228. X    XtSetValues (XtParent(svform_w), args, n);
  2229. X
  2230. X    /* make a form across the bottom in a frame for the control buttons */
  2231. X
  2232. X    n = 0;
  2233. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2234. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2235. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2236. X    ctlfr_w = XmCreateFrame (svform_w, "CtlFr", args, n);
  2237. X    XtManageChild (ctlfr_w);
  2238. X
  2239. X    n = 0;
  2240. X    XtSetArg (args[n], XmNfractionBase, 10); n++;
  2241. X    ctl_w = XmCreateForm (ctlfr_w, "CtlF", args, n);
  2242. X    XtManageChild (ctl_w);
  2243. X
  2244. X        /* make the control buttons */
  2245. X
  2246. X        for (i = 0; i < XtNumber(cbs); i++) {
  2247. X        n = 0;
  2248. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2249. X        XtSetArg (args[n], XmNtopOffset, 10); n++;
  2250. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2251. X        XtSetArg (args[n], XmNbottomOffset, 10); n++;
  2252. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  2253. X        XtSetArg (args[n], XmNleftPosition, 1+i*3); n++;
  2254. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  2255. X        XtSetArg (args[n], XmNrightPosition, 3+i*3); n++;
  2256. X        w = XmCreatePushButton (ctl_w, cbs[i].name, args, n);
  2257. X        XtAddCallback (w, XmNactivateCallback, cbs[i].cb, 0);
  2258. X        XtManageChild (w);
  2259. X        }
  2260. X
  2261. X    /* make a RowColumn down the left side for the misc controls */
  2262. X
  2263. X    n = 0;
  2264. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2265. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  2266. X    XtSetArg (args[n], XmNbottomWidget, ctlfr_w); n++;
  2267. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2268. X    XtSetArg (args[n], XmNisAligned, False); n++;
  2269. X    XtSetArg (args[n], XmNadjustMargin, False); n++;
  2270. X    rc_w = XmCreateRowColumn (svform_w, "SVRC", args, n);
  2271. X    XtManageChild (rc_w);
  2272. X
  2273. X        /* make the radio box for alt/az vs ra/dec */
  2274. X
  2275. X        n = 0;
  2276. X        rb_w = XmCreateRadioBox (rc_w, "SVModeRB", args, n);
  2277. X        XtManageChild (rb_w);
  2278. X
  2279. X        str = XmStringCreate ("Alt-Az", XmSTRING_DEFAULT_CHARSET);
  2280. X        n = 0;
  2281. X        XtSetArg (args[n], XmNlabelString, str); n++;
  2282. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2283. X        aa_w = XmCreateToggleButton (rb_w, "AltAzMode", args, n);
  2284. X        XtAddCallback (aa_w, XmNvalueChangedCallback, sv_aa_cb, NULL);
  2285. X        XtManageChild (aa_w);
  2286. X        XmStringFree (str);
  2287. X
  2288. X        str = XmStringCreate ("RA-Dec", XmSTRING_DEFAULT_CHARSET);
  2289. X        n = 0;
  2290. X        XtSetArg (args[n], XmNlabelString, str); n++;
  2291. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2292. X        rad_w = XmCreateToggleButton(rb_w, "RADecMode", args, n);
  2293. X        XtManageChild (rad_w);
  2294. X        XmStringFree (str);
  2295. X
  2296. X        if(XmToggleButtonGetState(aa_w)==XmToggleButtonGetState(rad_w)){
  2297. X            xe_msg("Sky View display mode conflicts -- using Alt/Az",0);
  2298. X            aa_mode = 1;    /* default to aa if they conflict */
  2299. X            XmToggleButtonSetState (aa_w, aa_mode, False); 
  2300. X            XmToggleButtonSetState (rad_w, !aa_mode, False); 
  2301. X        }
  2302. X        aa_mode = XmToggleButtonGetState(aa_w);
  2303. X
  2304. X        n = 0;
  2305. X        w = XmCreateSeparator (rc_w, "RCSep1", args, n);
  2306. X        XtManageChild (w);
  2307. X
  2308. X        /* make the "grid" toggle button and calibration labels */
  2309. X
  2310. X        n = 0;
  2311. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2312. X        w = XmCreateToggleButton (rc_w, "Grid", args, n);
  2313. X        XtAddCallback (w, XmNvalueChangedCallback, sv_grid_cb, 0);
  2314. X        XtManageChild (w);
  2315. X
  2316. X        n = 0;
  2317. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2318. X        vgrid_w = XmCreateLabel (rc_w, "SVGridV", args, n);
  2319. X        set_xmstring (vgrid_w, XmNlabelString, null_grid_str);
  2320. X        XtManageChild (vgrid_w);
  2321. X
  2322. X        n = 0;
  2323. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2324. X        hgrid_w = XmCreateLabel (rc_w, "SVGridH", args, n);
  2325. X        set_xmstring (hgrid_w, XmNlabelString, null_grid_str);
  2326. X        XtManageChild (hgrid_w);
  2327. X
  2328. X        n = 0;
  2329. X        w = XmCreateSeparator (rc_w, "RCSep2", args, n);
  2330. X        XtManageChild (w);
  2331. X
  2332. X        /* make the faint magnitude slider scale */
  2333. X
  2334. X        str = XmStringCreate ("Faintest Mag", XmSTRING_DEFAULT_CHARSET);
  2335. X        n = 0;
  2336. X        XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
  2337. X        XtSetArg (args[n], XmNminimum, BMAGLIMIT); n++;
  2338. X        XtSetArg (args[n], XmNmaximum, FMAGLIMIT); n++;
  2339. X        XtSetArg (args[n], XmNprocessingDirection, XmMAX_ON_LEFT); n++;
  2340. X        XtSetArg (args[n], XmNscaleMultiple, 1); n++;
  2341. X        XtSetArg (args[n], XmNshowValue, True); n++;
  2342. X        XtSetArg (args[n], XmNtitleString, str); n++;
  2343. X        fmag_w = XmCreateScale (rc_w, "FaintMagScale", args, n);
  2344. X        XtAddCallback(fmag_w, XmNvalueChangedCallback, sv_changed_cb, NULL);
  2345. X        XtAddCallback(fmag_w, XmNdragCallback, sv_magdrag_cb, NULL);
  2346. X        XtManageChild (fmag_w);
  2347. X        XmStringFree (str);
  2348. X
  2349. X        /* make the bright magnitude slider scale */
  2350. X
  2351. X        str = XmStringCreate ("Brightest Mag", XmSTRING_DEFAULT_CHARSET);
  2352. X        n = 0;
  2353. X        XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
  2354. X        XtSetArg (args[n], XmNminimum, BMAGLIMIT); n++;
  2355. X        XtSetArg (args[n], XmNmaximum, FMAGLIMIT); n++;
  2356. X        XtSetArg (args[n], XmNprocessingDirection, XmMAX_ON_LEFT); n++;
  2357. X        XtSetArg (args[n], XmNscaleMultiple, 1); n++;
  2358. X        XtSetArg (args[n], XmNshowValue, True); n++;
  2359. X        XtSetArg (args[n], XmNtitleString, str); n++;
  2360. X        bmag_w = XmCreateScale (rc_w, "BrightMagScale", args, n);
  2361. X        XtAddCallback(bmag_w, XmNvalueChangedCallback, sv_changed_cb, NULL);
  2362. X        XtAddCallback(bmag_w, XmNdragCallback, sv_magdrag_cb, NULL);
  2363. X        XtManageChild (bmag_w);
  2364. X        XmStringFree (str);
  2365. X
  2366. X        n = 0;
  2367. X        w = XmCreateSeparator (rc_w, "RCSep3", args, n);
  2368. X        XtManageChild (w);
  2369. X
  2370. X        /* make the "just dots" toggle button */
  2371. X
  2372. X        str = XmStringCreate ("Just Dots", XmSTRING_DEFAULT_CHARSET);
  2373. X        n = 0;
  2374. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2375. X        XtSetArg (args[n], XmNlabelString, str); n++;
  2376. X        w = XmCreateToggleButton (rc_w, "JustDots", args, n);
  2377. X        XtAddCallback (w, XmNvalueChangedCallback, sv_justdots_cb, NULL);
  2378. X        XtManageChild (w);
  2379. X        justdots = XmToggleButtonGetState (w);
  2380. X        XmStringFree(str);
  2381. X
  2382. X        /* make the "ecliptic" toggle button */
  2383. X
  2384. X        str = XmStringCreate ("Ecliptic", XmSTRING_DEFAULT_CHARSET);
  2385. X        n = 0;
  2386. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2387. X        XtSetArg (args[n], XmNlabelString, str); n++;
  2388. X        w = XmCreateToggleButton (rc_w, "Ecliptic", args, n);
  2389. X        XtAddCallback (w, XmNvalueChangedCallback, sv_ecliptic_cb, NULL);
  2390. X        XtManageChild (w);
  2391. X        want_ecliptic = XmToggleButtonGetState (w);
  2392. X        XmStringFree(str);
  2393. X
  2394. X        /* make the "All labels" toggle button */
  2395. X
  2396. X        str = XmStringCreate ("All labels", XmSTRING_DEFAULT_CHARSET);
  2397. X        n = 0;
  2398. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2399. X        XtSetArg (args[n], XmNlabelString, str); n++;
  2400. X        w = XmCreateToggleButton (rc_w, "AllLabels", args, n);
  2401. X        XtAddCallback (w, XmNvalueChangedCallback, sv_all_labels_cb, NULL);
  2402. X        XtManageChild (w);
  2403. X        all_labels = XmToggleButtonGetState (w);
  2404. X        XmStringFree(str);
  2405. X
  2406. X        n = 0;
  2407. X        w = XmCreateSeparator (rc_w, "RCSep4", args, n);
  2408. X        XtManageChild (w);
  2409. X
  2410. X        /* make the "find" cascade button */
  2411. X        sv_create_find (rc_w);
  2412. X
  2413. X    /* make a vertical sep to the right of the left row/col */
  2414. X
  2415. X    n = 0;
  2416. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2417. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  2418. X    XtSetArg (args[n], XmNbottomWidget, ctlfr_w); n++;
  2419. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  2420. X    XtSetArg (args[n], XmNleftWidget, rc_w); n++;
  2421. X    XtSetArg (args[n], XmNorientation, XmVERTICAL); n++;
  2422. X    sep_w = XmCreateSeparator (svform_w, "Sep1", args, n);
  2423. X    XtManageChild(sep_w);
  2424. X
  2425. X    /* make a timestamp label just above the control panel's frame */
  2426. X
  2427. X    n = 0;
  2428. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  2429. X    XtSetArg (args[n], XmNleftWidget, sep_w); n++;
  2430. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2431. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  2432. X    XtSetArg (args[n], XmNbottomWidget, ctlfr_w); n++;
  2433. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  2434. X    dt_w = XmCreateLabel (svform_w, "TimeStamp", args, n);
  2435. X    XtManageChild(dt_w);
  2436. X
  2437. X    /* make the bottom scale above the time stamp */
  2438. X
  2439. X    n = 0;
  2440. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  2441. X    XtSetArg (args[n], XmNleftWidget, sep_w); n++;
  2442. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2443. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  2444. X    XtSetArg (args[n], XmNbottomWidget, dt_w); n++;
  2445. END_OF_FILE
  2446.   if test 31658 -ne `wc -c <'skyviewmenu.c.1'`; then
  2447.     echo shar: \"'skyviewmenu.c.1'\" unpacked with wrong size!
  2448.   fi
  2449.   # end of 'skyviewmenu.c.1'
  2450. fi
  2451. echo shar: End of archive 15 \(of 21\).
  2452. cp /dev/null ark15isdone
  2453. MISSING=""
  2454. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  2455.     if test ! -f ark${I}isdone ; then
  2456.     MISSING="${MISSING} ${I}"
  2457.     fi
  2458. done
  2459. if test "${MISSING}" = "" ; then
  2460.     echo You have unpacked all 21 archives.
  2461.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2462.     echo Building ephem.db
  2463.     cat > ephem.db.Z.uu ephem.db.Z.uu.?
  2464.     uudecode ephem.db.Z.uu
  2465.     rm ephem.db.Z.uu ephem.db.Z.uu.?
  2466.     uncompress ephem.db.Z
  2467.     echo Building skyviewmenu.c
  2468.     cat > skyviewmenu.c skyviewmenu.c.?
  2469.     rm skyviewmenu.c.?
  2470.     echo Building smallfm.xbm
  2471.     cat > smallfm.xbm smallfm.xbm.?
  2472.     rm smallfm.xbm.?
  2473. else
  2474.     echo You still must unpack the following archives:
  2475.     echo "        " ${MISSING}
  2476. fi
  2477. exit 0
  2478. exit 0 # Just in case...
  2479. -- 
  2480.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  2481. \X/  Amiga - The only way to fly!      |
  2482.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  2483.   casual observer..."                  |
  2484.