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

  1. Newsgroups: comp.sources.x
  2. From: ecdowney@pobox.cca.cr.rockwell.com (Elwood Downey)
  3. Subject: v19i108:  xephem - astronomical ephemeris program, Part20/21
  4. Message-ID: <1993May10.221438.9804@sparky.imd.sterling.com>
  5. X-Md4-Signature: a68ea7bcc2365e4f0aca1a92069c8660
  6. Date: Mon, 10 May 1993 22:14:38 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 108
  11. Archive-name: xephem/part20
  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:  dbmenu.c ephem.plt listmenu.c marsmenu.c moonmenu.c
  22. #   versionmenu.c
  23. # Wrapped by chris@nova on Mon May 10 16:41:54 1993
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 20 (of 21)."'
  27. if test -f 'dbmenu.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'dbmenu.c'\"
  29. else
  30.   echo shar: Extracting \"'dbmenu.c'\" \(7177 characters\)
  31.   sed "s/^X//" >'dbmenu.c' <<'END_OF_FILE'
  32. X/* code to manage the stuff on the "database" menu.
  33. X */
  34. X
  35. X#include <stdio.h>
  36. X#include <ctype.h>
  37. X#include <math.h>
  38. X#include <errno.h>
  39. X#if defined(__STDC__)
  40. X#include <stdlib.h>
  41. X#endif
  42. X#include <Xm/Xm.h>
  43. X#include <Xm/Form.h>
  44. X#include <Xm/Frame.h>
  45. X#include <Xm/Label.h>
  46. X#include <Xm/PushB.h>
  47. X#include <Xm/ToggleB.h>
  48. X#include <Xm/RowColumn.h>
  49. X#include <Xm/SelectioB.h>
  50. X#include "astro.h"
  51. X#include "circum.h"
  52. X
  53. X#if defined(__STDC__) || defined(__cplusplus)
  54. X#define P_(s) s
  55. X#else
  56. X#define P_(s) ()
  57. X#endif
  58. X
  59. Xextern Obj *db_next P_((Obj *op, HowNext how));
  60. Xextern int db_n P_((void));
  61. Xextern int db_read P_((FILE *fp, int append));
  62. Xextern void all_newdb P_((int appended));
  63. Xextern void get_xmstring P_((Widget w, char *resource, char **txtp));
  64. Xextern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
  65. Xextern void prompt_map_cb P_((Widget w, XtPointer client, XtPointer call));
  66. Xextern void set_xmstring P_((Widget w, char *resource, char *txt));
  67. Xextern void watch_cursor P_((int want));
  68. Xextern void xe_msg P_((char *msg, int app_modal));
  69. X
  70. Xvoid db_manage P_((void));
  71. Xvoid db_cursor P_((Cursor c));
  72. Xstatic void db_create_form P_((void));
  73. Xstatic void db_set_title P_((void));
  74. Xstatic FILE *fileopen P_((char *name));
  75. Xstatic void db_cb P_((Widget w, XtPointer client, XtPointer data));
  76. Xstatic void db_help_cb P_((Widget w, XtPointer client, XtPointer data));
  77. X
  78. X#undef P_
  79. X
  80. Xextern char *sys_errlist[];
  81. Xextern Widget    toplevel_w;
  82. Xextern char *myclass;
  83. X#define    XtD    XtDisplay(toplevel_w)
  84. X
  85. Xstatic Widget dbform_w;
  86. X
  87. Xstatic char dbfdef[] = "ephem.db";      /* default database file name */
  88. X
  89. Xvoid
  90. Xdb_manage()
  91. X{
  92. X    if (!dbform_w)
  93. X        db_create_form();
  94. X
  95. X    if (XtIsManaged(dbform_w))
  96. X        XtUnmanageChild (dbform_w);
  97. X    else {
  98. X        db_set_title();
  99. X        XtManageChild (dbform_w);
  100. X    }
  101. X}
  102. X
  103. X/* called to put up or remove the watch cursor.  */
  104. Xvoid
  105. Xdb_cursor (c)
  106. XCursor c;
  107. X{
  108. X    Window win;
  109. X
  110. X    if (dbform_w && (win = XtWindow(dbform_w))) {
  111. X        Display *dsp = XtDisplay(dbform_w);
  112. X        if (c)
  113. X        XDefineCursor (dsp, win, c);
  114. X        else
  115. X        XUndefineCursor (dsp, win);
  116. X    }
  117. X}
  118. X
  119. X/* create a prompt dialog to allow user to enter a db file name. */
  120. Xstatic void
  121. Xdb_create_form ()
  122. X{
  123. X    Widget w;
  124. X    XmString title;
  125. X    Arg args[20];
  126. X    char *deffn;
  127. X    int n;
  128. X    
  129. X    title = XmStringCreateLtoR ("xephem Data Base",
  130. X                            XmSTRING_DEFAULT_CHARSET);
  131. X    n = 0;
  132. X    XtSetArg(args[n], XmNdefaultPosition, False);  n++;
  133. X    XtSetArg(args[n], XmNdialogTitle, title);  n++;
  134. X    XtSetArg(args[n], XmNautoUnmanage, False);  n++;
  135. X    dbform_w = XmCreatePromptDialog(toplevel_w, "DBPromptD", args, n);
  136. X    XtAddCallback (dbform_w, XmNmapCallback, prompt_map_cb, NULL);
  137. X    XmStringFree (title);
  138. X
  139. X    get_xmstring (dbform_w, XmNtextString, &deffn);
  140. X    if (strlen (deffn) == 0)
  141. X        set_xmstring (dbform_w, XmNtextString, dbfdef);
  142. X    XtFree (deffn);
  143. X
  144. X    /* use the Ok button to mean Append */
  145. X    XtAddCallback (dbform_w, XmNokCallback, db_cb, NULL);
  146. X    set_xmstring (dbform_w, XmNokLabelString, "Append");
  147. X
  148. X    /* use the Apply button to mean Replace */
  149. X    XtAddCallback (dbform_w, XmNapplyCallback, db_cb, NULL);
  150. X    XtManageChild (XmSelectionBoxGetChild(dbform_w, XmDIALOG_APPLY_BUTTON));
  151. X    set_xmstring (dbform_w, XmNapplyLabelString, "Replace");
  152. X
  153. X    /* allow cancel to unmanage and call it Close */
  154. X    XtAddCallback (dbform_w, XmNcancelCallback, db_cb, NULL);
  155. X    set_xmstring (dbform_w, XmNcancelLabelString, "Close");
  156. X
  157. X    /* allow for help */
  158. X    /* connecting to XmNhelpCallback doesn't work */
  159. X    XtAddCallback (XmSelectionBoxGetChild(dbform_w, XmDIALOG_HELP_BUTTON),
  160. X                    XmNactivateCallback, db_help_cb, NULL);
  161. X
  162. X#if XmVersion >= 1001
  163. X    w = XmSelectionBoxGetChild (dbform_w, XmDIALOG_TEXT);
  164. X    XmProcessTraversal (w, XmTRAVERSE_CURRENT);
  165. X    XmProcessTraversal (w, XmTRAVERSE_CURRENT); /* yes, twice!! */
  166. X#endif
  167. X}
  168. X
  169. X/* set up the title to the dialog.
  170. X * this is a cheap way to indicate the number of objects in the db.
  171. X */
  172. Xstatic void
  173. Xdb_set_title()
  174. X{
  175. X    char title[1024];
  176. X    Obj *op;
  177. X    int ne=0, np=0, nh=0;
  178. X    int nc=0, ng=0, nn=0, npn=0, nq=0, ns=0, no=0;
  179. X    int npl=0;
  180. X    int t=0;
  181. X
  182. X    for (op= db_next((Obj *)NULL, OBJS_ALL); op; op= db_next(op, OBJS_ALL)){
  183. X        switch (op->type) {
  184. X        case FIXED:
  185. X        switch (op->f_class) {
  186. X        case 'C': case 'U': case 'O': nc++; t++; break;
  187. X        case 'G': case 'H': case 'A': ng++; t++; break;
  188. X        case 'N': case 'F': case 'K': nn++; t++; break;
  189. X        case 'P': npn++; t++; break;
  190. X        case 'Q': nq++; t++; break;
  191. X        case 'T': case 'B': case 'D': case 'M': case 'S': case 'V': 
  192. X            ns++; t++; break;
  193. X        default: no++; t++; break;
  194. X        }
  195. X        break;
  196. X        case ELLIPTICAL: ne++; t++; break;
  197. X        case HYPERBOLIC: nh++; t++; break;
  198. X        case PARABOLIC: np++; t++; break;
  199. X        case PLANET: npl++; t++; break;
  200. X        case UNDEFOBJ: break;
  201. X        default:
  202. X        printf ("Unknown object type: %d\n", op->type);
  203. X        exit (1);
  204. X        }
  205. X    }
  206. X
  207. X    if (db_n() - t > 2) {
  208. X        printf (">2 objects unaccounted for: t=%d n=%d\n", t, db_n());
  209. X        exit(1);
  210. X    }
  211. X
  212. X    (void) sprintf (title,
  213. X"%6d Sol -- elliptical\n\
  214. X%6d Sol -- hyperbolic\n\
  215. X%6d Sol -- parabolic\n\
  216. X%6d Sol -- planets+sun+moon\n\
  217. X%6d Clusters (C,U,O)\n\
  218. X%6d Galaxies (G,H,A)\n\
  219. X%6d Planetary Nebulea (P)\n\
  220. X%6d Nebulea (N,F,K)\n\
  221. X%6d Quasars (Q)\n\
  222. X%6d Stars (S,V,D,B,M,T)\n\
  223. X%6d Undefined\n\
  224. X------\n\
  225. X%6d Total objects in memory\n\
  226. X \n\
  227. XEnter name of database file to read:",
  228. X        ne, nh, np, npl, nc, ng, npn, nn, nq, ns, no, t);
  229. X    set_xmstring (dbform_w, XmNselectionLabelString, title);
  230. X}
  231. X
  232. X/* try to open name for read access.
  233. X * if successful, return FILE *, else print a message and return NULL.
  234. X */
  235. Xstatic FILE *
  236. Xfileopen (name)
  237. Xchar *name;
  238. X{
  239. X    FILE *fp;
  240. X    
  241. X    fp = fopen (name, "r");
  242. X    if (!fp) {
  243. X        char msg[128];
  244. X        (void) sprintf (msg, "Can not open %.75s: %.25s", name,
  245. X                            sys_errlist[errno]);
  246. X        xe_msg (msg, 1);
  247. X    }
  248. X    return (fp);
  249. X}
  250. X
  251. X/* callback from any of the buttons */
  252. X/* ARGSUSED */
  253. Xstatic void
  254. Xdb_cb (w, client, data)
  255. XWidget w;
  256. XXtPointer client;
  257. XXtPointer data;
  258. X{
  259. X    static char me[] = "db_cb()";
  260. X    XmSelectionBoxCallbackStruct *s = (XmSelectionBoxCallbackStruct *)data;
  261. X    char *sp;
  262. X    FILE *fp;
  263. X
  264. X    watch_cursor(1);
  265. X
  266. X    switch (s->reason) {
  267. X    case XmCR_OK: /* append */
  268. X        XmStringGetLtoR (s->value, XmSTRING_DEFAULT_CHARSET, &sp);
  269. X        fp = fileopen (sp);
  270. X        if (fp) {
  271. X        if (db_read (fp, 1) < 0) {
  272. X            char msg[128];
  273. X            (void) sprintf (msg, "Error reading `%.100s'", sp);
  274. X            xe_msg (msg, 1);
  275. X        }
  276. X        all_newdb(1);
  277. X        (void) fclose (fp);
  278. X        }
  279. X        XtFree (sp);
  280. X        db_set_title();
  281. X        break;
  282. X    case XmCR_APPLY:    /* replace */
  283. X        XmStringGetLtoR (s->value, XmSTRING_DEFAULT_CHARSET, &sp);
  284. X        fp = fileopen (sp);
  285. X        if (fp) {
  286. X        if (db_read (fp, 0) < 0) {
  287. X            char msg[128];
  288. X            (void) sprintf (msg, "Error reading `%.100s'", sp);
  289. X            xe_msg (msg, 1);
  290. X        }
  291. X        all_newdb(0);
  292. X        (void) fclose (fp);
  293. X        }
  294. X        XtFree (sp);
  295. X        db_set_title();
  296. X        break;
  297. X    case XmCR_CANCEL:
  298. X        XtUnmanageChild (w);
  299. X        break;
  300. X    default:
  301. X        printf ("%s: Unknown reason = 0x%x\n", me, s->reason);
  302. X        exit(1);
  303. X    }
  304. X
  305. X    watch_cursor(0);
  306. X}
  307. X
  308. X/* ARGSUSED */
  309. Xstatic void
  310. Xdb_help_cb (w, client, data)
  311. XWidget w;
  312. XXtPointer client;
  313. XXtPointer data;
  314. X{
  315. X    static char *msg[] = {
  316. X"This displays a count of the various types of objects currently in memory.",
  317. X"Database files may be read in to replace to add to this list."
  318. X};
  319. X
  320. X    hlp_dialog ("DataBase menu", msg, XtNumber(msg));
  321. X}
  322. END_OF_FILE
  323.   if test 7177 -ne `wc -c <'dbmenu.c'`; then
  324.     echo shar: \"'dbmenu.c'\" unpacked with wrong size!
  325.   fi
  326.   # end of 'dbmenu.c'
  327. fi
  328. if test -f 'ephem.plt' -a "${1}" != "-c" ; then 
  329.   echo shar: Will not clobber existing file \"'ephem.plt'\"
  330. else
  331.   echo shar: Extracting \"'ephem.plt'\" \(5549 characters\)
  332.   sed "s/^X//" >'ephem.plt' <<'END_OF_FILE'
  333. X! Analemma: Sun's az/alt at Noon local time at 40N 90W
  334. X! Jan 1 - Dec 31, 1992, every other day.
  335. XA,179.018370221,27.0345819991
  336. XA,178.775488694,27.2196664652
  337. XA,178.537524904,27.4342027071
  338. XA,178.305134548,27.6778201868
  339. XA,178.078891361,27.9501244611
  340. XA,177.859355421,28.2506869355
  341. XA,177.64700484,28.5790499874
  342. XA,177.442331391,28.93469623
  343. XA,177.24586783,29.3170536348
  344. XA,177.058256194,29.7254852868
  345. XA,176.880152181,30.1593115821
  346. XA,176.712184169,30.6178324264
  347. XA,176.555021516,31.100303329
  348. XA,176.409210638,31.6059558936
  349. XA,176.275202326,32.1339909882
  350. XA,176.153406393,32.6835719144
  351. XA,176.044191668,33.2538448988
  352. XA,175.947749397,33.8439664129
  353. XA,175.864229844,34.4530860982
  354. XA,175.793755952,35.0803570112
  355. XA,175.736314061,35.7249219632
  356. XA,175.691904171,36.3859135201
  357. XA,175.660512622,37.0624198517
  358. XA,175.642221375,37.7535188825
  359. XA,175.637085073,38.4582646312
  360. XA,175.64530862,39.1756803809
  361. XA,175.667096924,39.904772339
  362. XA,175.70235436,40.6445979393
  363. XA,175.751190213,41.3941633894
  364. XA,175.81354984,42.1524885571
  365. XA,175.889282978,42.9186240461
  366. XA,175.97819838,43.6916204601
  367. XA,176.080063822,44.4705523085
  368. XA,176.194442169,45.2545350818
  369. XA,176.320800669,46.0427081762
  370. XA,176.458565585,46.8342075727
  371. XA,176.60714952,47.6281794977
  372. XA,176.76603338,48.4237496869
  373. XA,176.934834676,49.2200097253
  374. XA,177.113157254,50.0160409523
  375. XA,177.300550324,50.8109656886
  376. XA,177.496522112,51.6038857645
  377. XA,177.700567183,52.3939235005
  378. XA,177.912139123,53.1802148777
  379. XA,178.130664195,53.9618958773
  380. XA,178.355541344,54.7381263859
  381. XA,178.585896304,55.5081175167
  382. XA,178.820595264,56.2711350244
  383. XA,179.058477092,57.0264549088
  384. XA,179.298230392,57.7733804908
  385. XA,179.538502787,58.5112185061
  386. XA,179.778133144,59.2392415395
  387. XA,180.015864708,59.9567187609
  388. XA,180.250358763,60.6629330003
  389. XA,180.480358553,61.3571534275
  390. XA,180.704607324,62.0386492124
  391. XA,180.92183466,62.7066963547
  392. XA,181.130852109,63.3605776847
  393. XA,181.330498538,63.9995692023
  394. XA,181.519312288,64.623001549
  395. XA,181.695708753,65.2302053662
  396. XA,181.857939407,65.8205659369
  397. XA,182.004105455,66.3934822045
  398. XA,182.132212483,66.9483804331
  399. XA,182.240361698,67.4846800565
  400. XA,182.326695289,68.0017800182
  401. XA,182.389423747,68.4990929218
  402. XA,182.426866844,68.9759972203
  403. XA,182.438041033,69.4318235549
  404. XA,182.42168956,69.8659913597
  405. XA,182.377129406,70.2778722572
  406. XA,182.304032722,70.6668651908
  407. XA,182.202399507,71.032375934
  408. XA,182.072434667,71.3738170907
  409. XA,181.914643637,71.6906422455
  410. XA,181.72954551,71.9823391344
  411. XA,181.517809646,72.2484706252
  412. XA,181.280405931,72.4886132462
  413. XA,181.018782365,72.7023708465
  414. XA,180.734783099,72.8893745958
  415. XA,180.43077138,73.0492624941
  416. XA,180.109520262,73.1817135224
  417. XA,179.774157974,73.2864817941
  418. XA,179.428236213,73.3633624034
  419. XA,179.075866754,73.4122392371
  420. XA,178.721571181,73.4330371632
  421. XA,178.370062326,73.4257630117
  422. XA,178.025916414,73.3904714242
  423. XA,177.693286202,73.3272990046
  424. XA,177.375832669,73.2364369981
  425. XA,177.076779667,73.1181586122
  426. XA,176.798995873,72.9727643754
  427. XA,176.5450631,72.8006026271
  428. XA,176.317044065,72.602049028
  429. XA,176.116523371,72.3774792382
  430. XA,175.944634831,72.1273030693
  431. XA,175.802143424,71.8519713137
  432. XA,175.68971851,71.5519689148
  433. XA,175.607974806,71.2278422877
  434. XA,175.557349444,70.8801583382
  435. XA,175.537856084,70.509483972
  436. XA,175.549180538,70.1164134154
  437. XA,175.590585145,69.7015204045
  438. XA,175.660908773,69.2653923354
  439. XA,175.758771723,68.8086166045
  440. XA,175.882644034,68.3318079287
  441. XA,176.030667894,67.835505893
  442. XA,176.200848887,67.320270573
  443. XA,176.391096976,66.7866074026
  444. XA,176.599308463,66.2350559667
  445. XA,176.823406969,65.6661558504
  446. XA,177.061616647,65.0804944498
  447. XA,177.312270929,64.478686482
  448. XA,177.573853514,63.8613466641
  449. XA,177.844998364,63.2291238639
  450. XA,178.124407742,62.5826874401
  451. XA,178.410674631,61.9226930908
  452. XA,178.702432991,61.2498033444
  453. XA,178.998275805,60.5646875593
  454. XA,179.296973638,59.8680424149
  455. XA,179.597010188,59.1604894584
  456. XA,179.897101379,58.4426843879
  457. XA,180.195799212,57.7152624111
  458. XA,180.491710327,56.9788450752
  459. XA,180.783605292,56.2340949085
  460. XA,181.070336633,55.4817051752
  461. XA,181.350961785,54.722386215
  462. XA,181.624784069,53.9569098392
  463. XA,181.891229749,53.1860820102
  464. XA,182.149684107,52.4107018602
  465. XA,182.399600728,51.6315890118
  466. XA,182.64048784,50.8495733329
  467. XA,182.871812687,50.0654846917
  468. XA,183.093110816,49.2801632013
  469. XA,183.303958756,48.4944592203
  470. XA,183.503810091,47.7091923714
  471. XA,183.691981802,46.9251583717
  472. XA,183.867872834,46.1431597683
  473. XA,184.030895789,45.3640025237
  474. XA,184.180572555,44.588526751
  475. XA,184.316602602,43.8176169597
  476. XA,184.438835668,43.0521849802
  477. XA,184.547066845,42.2931494728
  478. XA,184.641159531,41.5414359283
  479. XA,184.721100065,40.7979937428
  480. XA,184.786888447,40.0637688976
  481. XA,184.83863396,39.3397210342
  482. XA,184.876445888,38.6268097943
  483. XA,184.90037887,37.9259743288
  484. XA,184.910350947,37.2381196379
  485. XA,184.906293814,36.5641370612
  486. XA,184.88809819,35.9049076931
  487. XA,184.855695773,35.2612853072
  488. XA,184.809154864,34.6341475829
  489. XA,184.748557426,34.0243721994
  490. XA,184.674040062,33.4328402513
  491. XA,184.585821338,32.8604328328
  492. XA,184.484242765,32.3080310384
  493. XA,184.369700493,31.7764852266
  494. XA,184.242740936,31.266645756
  495. XA,184.103828549,30.7793049286
  496. XA,183.953564387,30.3152687065
  497. XA,183.792508527,29.8752918259
  498. XA,183.621152741,29.4601085319
  499. XA,183.439975143,29.0703813529
  500. XA,183.249385544,28.7067318362
  501. XA,183.049821077,28.369743963
  502. XA,182.841759855,28.0599641482
  503. XA,182.62569365,27.7779234393
  504. XA,182.402223521,27.5241289777
  505. XA,182.171977844,27.2990452162
  506. XA,181.935639639,27.103090504
  507. XA,181.693960225,26.9366200109
  508. XA,181.447786547,26.7999376804
  509. XA,181.198074831,26.6933013519
  510. XA,180.945740322,26.6169227616
  511. XA,180.691739247,26.5709675413
  512. XA,180.436904889,26.5555313137
  513. XA,180.18201589,26.5706499375
  514. XA,179.927741608,26.6162892615
  515. XA,179.674751401,26.6923690311
  516. XA,179.423755609,26.7987645954
  517. XA,179.175423591,26.9353137373
  518. END_OF_FILE
  519.   if test 5549 -ne `wc -c <'ephem.plt'`; then
  520.     echo shar: \"'ephem.plt'\" unpacked with wrong size!
  521.   fi
  522.   # end of 'ephem.plt'
  523. fi
  524. if test -f 'listmenu.c' -a "${1}" != "-c" ; then 
  525.   echo shar: Will not clobber existing file \"'listmenu.c'\"
  526. else
  527.   echo shar: Extracting \"'listmenu.c'\" \(13104 characters\)
  528.   sed "s/^X//" >'listmenu.c' <<'END_OF_FILE'
  529. X/* code to manage the stuff on the "listing" menu.
  530. X */
  531. X
  532. X#include <stdio.h>
  533. X#include <ctype.h>
  534. X#include <math.h>
  535. X#if defined(__STDC__)
  536. X#include <stdlib.h>
  537. X#endif
  538. X#include <X11/Xlib.h>
  539. X#include <Xm/Xm.h>
  540. X#include <Xm/Form.h>
  541. X#include <Xm/DrawingA.h>
  542. X#include <Xm/LabelG.h>
  543. X#include <Xm/PushB.h>
  544. X#include <Xm/ToggleB.h>
  545. X#include <Xm/Separator.h>
  546. X#include <Xm/RowColumn.h>
  547. X#include <Xm/Text.h>
  548. X
  549. X
  550. X#if defined(__STDC__) || defined(__cplusplus)
  551. X#define P_(s) s
  552. X#else
  553. X#define P_(s) ()
  554. X#endif
  555. X
  556. Xextern int access();    /* don't know whether to include unistd.h */
  557. X
  558. Xextern void all_selection_mode P_((int whether));
  559. Xextern void f_string P_((Widget w, char *s));
  560. Xextern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
  561. Xextern void query P_((Widget tw, char *msg, char *label1, char *label2, char *label3, void (*func1)(), void (*func2)(), void (*func3)()));
  562. Xextern void set_xmstring P_((Widget w, char *resource, char *txt));
  563. Xextern void xe_msg P_((char *msg, int app_modal));
  564. X
  565. Xvoid lst_manage P_((void));
  566. Xvoid lst_selection P_((char *name));
  567. Xvoid lst_log P_((char *name, char *str));
  568. Xvoid listing P_((void));
  569. Xint listing_ison P_((void));
  570. Xvoid lst_cursor P_((Cursor c));
  571. Xstatic void lst_select P_((int whether));
  572. Xstatic void lst_create_form P_((void));
  573. Xstatic void lst_activate_cb P_((Widget w, XtPointer client, XtPointer call));
  574. Xstatic void lst_close_cb P_((Widget w, XtPointer client, XtPointer call));
  575. Xstatic void lst_help_cb P_((Widget w, XtPointer client, XtPointer call));
  576. Xstatic void lst_reset P_((void));
  577. Xstatic void lst_stop_selecting P_((void));
  578. Xstatic void lst_turn_off P_((void));
  579. Xstatic void lst_try_append P_((void));
  580. Xstatic void lst_try_overwrite P_((void));
  581. Xstatic void lst_try_cancel P_((void));
  582. Xstatic void lst_try_turn_on P_((void));
  583. Xstatic void lst_turn_on P_((char *how));
  584. X
  585. X#undef P_
  586. X
  587. Xextern Widget toplevel_w;
  588. X
  589. X#ifdef VMS
  590. X#include <perror.h>
  591. X#include <errno.h>
  592. X#else
  593. Xextern char *sys_errlist[];
  594. Xextern errno;
  595. X#endif
  596. X
  597. X#define    errsys    (sys_errlist[errno])
  598. X
  599. X/* max number of fields we can keep track of at once to list */
  600. X#define MAXLSTFLDS    10
  601. X#define MAXLSTSTR    32    /* longest string we can list */
  602. X#define MAXFLDNAM    32    /* longest allowed field name */
  603. X
  604. Xstatic Widget lstform_w;
  605. Xstatic Widget select_w, active_w, prompt_w;
  606. Xstatic Widget title_w, filename_w;
  607. Xstatic Widget table_w[MAXLSTFLDS];    /* row indeces follow.. */
  608. X
  609. X#define    DEF_LSTFN    "ephem.lst"    /* default plot file name */
  610. Xstatic FILE *lst_fp;            /* the listing file; == 0 means don't plot */
  611. X
  612. X
  613. X/* lst_activate_cb client values. */
  614. X#define    SELECT    0
  615. X#define    ACTIVE    1
  616. X
  617. X/* store the name and string value of each field to track.
  618. X * we get the label straight from the Text widget in the table as needed.
  619. X */
  620. Xtypedef struct {
  621. X    char l_name[MAXFLDNAM];    /* name of field we are listing */
  622. X    char l_str[MAXLSTSTR];    /* last know string value of field */
  623. X} LstFld;
  624. Xstatic LstFld lstflds[MAXLSTFLDS];
  625. Xstatic int nlstflds;        /* number of lstflds[] in actual use */
  626. X
  627. X/* called when the list menu is activated via the main menu pulldown.
  628. X * if never called before, create and manage all the widgets as a child of a
  629. X * form. otherwise, just toggle whether the form is managed.
  630. X */
  631. Xvoid
  632. Xlst_manage ()
  633. X{
  634. X    if (!lstform_w)
  635. X        lst_create_form();
  636. X    
  637. X    if (XtIsManaged(lstform_w))
  638. X        XtUnmanageChild (lstform_w);
  639. X    else
  640. X        XtManageChild (lstform_w);
  641. X}
  642. X
  643. X/* called by the other menus (data, etc) as their buttons are
  644. X * selected to inform us that that button is to be included in a listing.
  645. X */
  646. Xvoid
  647. Xlst_selection (name)
  648. Xchar *name;
  649. X{
  650. X    Widget tw;
  651. X
  652. X
  653. X    if (!lstform_w
  654. X        || !XtIsManaged(lstform_w)
  655. X        || !XmToggleButtonGetState(select_w))
  656. X            return;
  657. X
  658. X    tw = table_w[nlstflds];
  659. X    set_xmstring (tw, XmNlabelString, name);
  660. X    XtManageChild (tw);
  661. X
  662. X    (void) strncpy (lstflds[nlstflds].l_name, name, MAXFLDNAM);
  663. X    if (++nlstflds == MAXLSTFLDS)
  664. X        lst_stop_selecting();
  665. X}
  666. X
  667. X/* called as each different field is written -- just save in lstflds[]
  668. X * if we are potentially interested.
  669. X */
  670. Xvoid
  671. Xlst_log (name, str)
  672. Xchar *name;
  673. Xchar *str;
  674. X{
  675. X    if (listing_ison()) {
  676. X        LstFld *lp;
  677. X        for (lp = lstflds; lp < &lstflds[nlstflds]; lp++)
  678. X        if (strcmp (name, lp->l_name) == 0) {
  679. X            (void) strncpy (lp->l_str, str, MAXLSTSTR-1);
  680. X            break;
  681. X        }
  682. X    }
  683. X}
  684. X
  685. X/* called when all fields have been updated and it's time to
  686. X * write the active listing to the current listing file, if one is open.
  687. X */
  688. Xvoid
  689. Xlisting()
  690. X{
  691. X    if (lst_fp) {
  692. X        /* list in order of original selection */
  693. X        LstFld *lp;
  694. X        for (lp = lstflds; lp < &lstflds[nlstflds]; lp++)
  695. X        (void) fprintf (lst_fp, "%s  ", lp->l_str);
  696. X        (void) fprintf (lst_fp, "\n");
  697. X    }
  698. X}
  699. X
  700. Xlisting_ison()
  701. X{
  702. X    return (lst_fp != 0);
  703. X}
  704. X
  705. X/* called to put up or remove the watch cursor.  */
  706. Xvoid
  707. Xlst_cursor (c)
  708. XCursor c;
  709. X{
  710. X    Window win;
  711. X
  712. X    if (lstform_w && (win = XtWindow(lstform_w))) {
  713. X        Display *dsp = XtDisplay(lstform_w);
  714. X        if (c)
  715. X        XDefineCursor (dsp, win, c);
  716. X        else
  717. X        XUndefineCursor (dsp, win);
  718. X    }
  719. X}
  720. X
  721. X/* inform the other menues whether we are setting up for them to tell us
  722. X * what fields to list.
  723. X */
  724. Xstatic void
  725. Xlst_select(whether)
  726. Xint whether;
  727. X{
  728. X    all_selection_mode(whether);
  729. X}
  730. X
  731. Xstatic void
  732. Xlst_create_form()
  733. X{
  734. X    static struct {
  735. X        char *title;
  736. X        int cb_data;
  737. X        Widget *wp;
  738. X    } tbs[] = {
  739. X        {"Select fields", SELECT, &select_w},
  740. X        {"List to file", ACTIVE, &active_w}
  741. X    };
  742. X    XmString str;
  743. X    Widget w, rc_w, f_w;
  744. X    Arg args[20];
  745. X    char *deffn;
  746. X    int i, n;
  747. X
  748. X    /* create form dialog */
  749. X    n = 0;
  750. X    XtSetArg (args[n], XmNautoUnmanage, False); n++;
  751. X    XtSetArg (args[n], XmNdefaultPosition, False); n++;
  752. X    lstform_w = XmCreateFormDialog (toplevel_w, "List", args, n);
  753. X
  754. X    n = 0;
  755. X    XtSetArg (args[n], XmNtitle, "xephem Listing Control"); n++;
  756. X    XtSetValues (XtParent(lstform_w), args, n);
  757. X
  758. X    /* make a RowColumn to hold everything */
  759. X
  760. X    n = 0;
  761. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  762. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  763. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  764. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  765. X    XtSetArg (args[n], XmNisAligned, False); n++;
  766. X    XtSetArg (args[n], XmNadjustMargin, False); n++;
  767. X    rc_w = XmCreateRowColumn (lstform_w, "ListRC", args, n);
  768. X    XtManageChild (rc_w);
  769. X
  770. X    /* make the control toggle buttons */
  771. X
  772. X    for (i = 0; i < XtNumber(tbs); i++) {
  773. X        str = XmStringCreate(tbs[i].title, XmSTRING_DEFAULT_CHARSET);
  774. X        n = 0;
  775. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  776. X        XtSetArg (args[n], XmNlabelString, str); n++;
  777. X        w = XmCreateToggleButton(rc_w, "ListTB", args, n);
  778. X        XmStringFree (str);
  779. X        XtManageChild (w);
  780. X        XtAddCallback(w, XmNvalueChangedCallback, lst_activate_cb,
  781. X                            (XtPointer)tbs[i].cb_data);
  782. X        if (tbs[i].wp)
  783. X        *tbs[i].wp = w;
  784. X    }
  785. X
  786. X    /* create filename text area and its label */
  787. X
  788. X    n = 0;
  789. X    str = XmStringCreate("File name:", XmSTRING_DEFAULT_CHARSET);
  790. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  791. X    XtSetArg (args[n], XmNlabelString, str); n++;
  792. X    w = XmCreateLabel (rc_w, "ListFnL", args, n);
  793. X    XmStringFree (str);
  794. X    XtManageChild (w);
  795. X
  796. X    n = 0;
  797. X    filename_w = XmCreateText (rc_w, "Filename", args, n);
  798. X    deffn = XmTextGetString (filename_w);
  799. X    if (strlen(deffn) == 0)
  800. X        XmTextSetString (filename_w, DEF_LSTFN);
  801. X    XtFree (deffn);
  802. X    XtManageChild (filename_w);
  803. X
  804. X    /* create title text area and its label */
  805. X
  806. X    n = 0;
  807. X    str = XmStringCreate("Title:", XmSTRING_DEFAULT_CHARSET);
  808. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  809. X    XtSetArg (args[n], XmNlabelString, str); n++;
  810. X    w = XmCreateLabel (rc_w, "ListTL", args, n);
  811. X    XtManageChild (w);
  812. X    XmStringFree (str);
  813. X
  814. X    n = 0;
  815. X    title_w = XmCreateText (rc_w, "ListTitle", args, n);
  816. X    XtManageChild (title_w);
  817. X
  818. X    /* create prompt line -- it will be managed as necessary */
  819. X
  820. X    n = 0;
  821. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  822. X    prompt_w = XmCreateLabel (rc_w, "ListPrompt", args, n);
  823. X
  824. X    /* make the field name table, but don't manage them now */
  825. X    for (i = 0; i < MAXLSTFLDS; i++) {
  826. X        n = 0;
  827. X        table_w[i] = XmCreateLabel(rc_w, "ListLabel", args, n);
  828. X    }
  829. X
  830. X    /* create a separator */
  831. X
  832. X    n = 0;
  833. X    w = XmCreateSeparator (rc_w, "Sep", args, n);
  834. X    XtManageChild (w);
  835. X
  836. X    /* make a form to hold the close and help buttons evenly */
  837. X
  838. X    n = 0;
  839. X    XtSetArg (args[n], XmNfractionBase, 7); n++;
  840. X    f_w = XmCreateForm (rc_w, "ListCF", args, n);
  841. X    XtManageChild(f_w);
  842. X
  843. X        n = 0;
  844. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  845. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  846. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  847. X        XtSetArg (args[n], XmNleftPosition, 1); n++;
  848. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  849. X        XtSetArg (args[n], XmNrightPosition, 3); n++;
  850. X        w = XmCreatePushButton (f_w, "Close", args, n);
  851. X        XtAddCallback (w, XmNactivateCallback, lst_close_cb, 0);
  852. X        XtManageChild (w);
  853. X
  854. X        n = 0;
  855. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  856. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  857. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  858. X        XtSetArg (args[n], XmNleftPosition, 4); n++;
  859. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  860. X        XtSetArg (args[n], XmNrightPosition, 6); n++;
  861. X        w = XmCreatePushButton (f_w, "Help", args, n);
  862. X        XtAddCallback (w, XmNactivateCallback, lst_help_cb, 0);
  863. X        XtManageChild (w);
  864. X}
  865. X
  866. X/* callback from any of the listing menu toggle buttons being activated.
  867. X */
  868. X/* ARGSUSED */
  869. Xstatic void
  870. Xlst_activate_cb (w, client, call)
  871. XWidget w;
  872. XXtPointer client;
  873. XXtPointer call;
  874. X{
  875. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  876. X    int what = (int) client;
  877. X
  878. X    switch (what) {
  879. X    case SELECT:
  880. X        if (t->set) {
  881. X        /* first turn off listing, if on, while we change things */
  882. X        if (XmToggleButtonGetState(active_w))
  883. X            XmToggleButtonSetState(active_w, False, True);
  884. X        lst_reset();    /* reset lstflds array and unmanage the table*/
  885. X        lst_select(1);    /* inform other menus to inform us of fields */
  886. X        XtManageChild (prompt_w);
  887. X        f_string (prompt_w, "Select quantity for next column...");
  888. X        } else
  889. X        lst_stop_selecting();
  890. X        break;
  891. X    case ACTIVE:
  892. X        if (t->set) {
  893. X        /* first turn off selecting, if on */
  894. X        if (XmToggleButtonGetState(select_w))
  895. X            XmToggleButtonSetState(select_w, False, True);
  896. X        lst_try_turn_on();
  897. X        } else
  898. X        lst_turn_off();
  899. X        break;
  900. X    }
  901. X}
  902. X
  903. X/* callback from the Close button.
  904. X */
  905. X/* ARGSUSED */
  906. Xstatic void
  907. Xlst_close_cb (w, client, call)
  908. XWidget w;
  909. XXtPointer client;
  910. XXtPointer call;
  911. X{
  912. X    XtUnmanageChild (lstform_w);
  913. X}
  914. X
  915. X/* callback from the Help
  916. X */
  917. X/* ARGSUSED */
  918. Xstatic void
  919. Xlst_help_cb (w, client, call)
  920. XWidget w;
  921. XXtPointer client;
  922. XXtPointer call;
  923. X{
  924. X    static char *msg[] = {
  925. X"Select fields to become each column of a listing, then run xephem. Each step",
  926. X"will yield one line in the output file. The filename may be specified in the",
  927. X"text area provided."
  928. X};
  929. X
  930. X    hlp_dialog ("Listing", msg, sizeof(msg)/sizeof(msg[0]));
  931. X}
  932. X
  933. X/* forget our list, and unmanage the table.
  934. X */
  935. Xstatic void
  936. Xlst_reset()
  937. X{
  938. X    int i;
  939. X
  940. X    for (i = 0; i < nlstflds; i++)
  941. X        XtUnmanageChild (table_w[i]);
  942. X
  943. X    nlstflds = 0;
  944. X}
  945. X
  946. X/* stop selecting: tell everybody else to drop their buttons, make sure toggle
  947. X * is off.
  948. X */
  949. Xstatic void
  950. Xlst_stop_selecting()
  951. X{
  952. X    XmToggleButtonSetState (select_w, False, False);
  953. X    lst_select(0);
  954. X    XtUnmanageChild (prompt_w);
  955. X}
  956. X
  957. Xstatic void
  958. Xlst_turn_off ()
  959. X{
  960. X    if (lst_fp) {
  961. X        (void) fclose (lst_fp);
  962. X        lst_fp = 0;
  963. X    }
  964. X}
  965. X
  966. X/* called from the query routine when want to append to an existing list file.*/
  967. Xstatic void
  968. Xlst_try_append()
  969. X{
  970. X    lst_turn_on("a");
  971. X}
  972. X
  973. X/* called from the query routine when want to overwrite to an existing list
  974. X * file.
  975. X */
  976. Xstatic void
  977. Xlst_try_overwrite()
  978. X{
  979. X    lst_turn_on("w");
  980. X}
  981. X
  982. X/* called from the query routine when decided not to make a listing file.  */
  983. Xstatic void
  984. Xlst_try_cancel()
  985. X{
  986. X    XmToggleButtonSetState (active_w, False, False);
  987. X}
  988. X
  989. X/* attempt to open file for use as a listing file.
  990. X * if it doesn't exist, then go ahead and make it.
  991. X * but if it does, first ask wheher to append or overwrite.
  992. X */
  993. Xstatic void
  994. Xlst_try_turn_on()
  995. X{
  996. X    char *txt = XmTextGetString (filename_w);
  997. X    if (access (txt, 0) == 0) {
  998. X        char *buf;
  999. X        buf = XtMalloc (strlen(txt)+100);
  1000. X        (void) sprintf (buf, "%s exists: Append or Overwrite?", txt);
  1001. X        query (toplevel_w, buf, "Append", "Overwrite", "Cancel",
  1002. X                lst_try_append, lst_try_overwrite, lst_try_cancel);
  1003. X        XtFree (buf);
  1004. X    } else
  1005. X        lst_turn_on("w");
  1006. X    XtFree (txt);
  1007. X}
  1008. X
  1009. X/* turn on listing facility.
  1010. X * establish a file to use (and thereby set lst_fp, the "listing-is-on" flag).
  1011. X */
  1012. Xstatic void
  1013. Xlst_turn_on (how)
  1014. Xchar *how;    /* fopen how argument */
  1015. X{
  1016. X    char *txt;
  1017. X
  1018. X    /* listing is on if file opens ok */
  1019. X    txt = XmTextGetString (filename_w);
  1020. X    lst_fp = fopen (txt, how);
  1021. X    if (!lst_fp) {
  1022. X        char *buf;
  1023. X        XmToggleButtonSetState (active_w, False, False);
  1024. X        buf = XtMalloc (strlen(txt)+100);
  1025. X        (void) sprintf (buf, "Can not open %s: %s", txt, errsys);
  1026. X        xe_msg (buf, 1);
  1027. X        XtFree (buf);
  1028. X    }
  1029. X    XtFree (txt);
  1030. X    
  1031. X    if (lst_fp) {
  1032. X        /* add a title if desired */
  1033. X        txt = XmTextGetString (title_w);
  1034. X        if (txt[0] != '\0')
  1035. X        (void) fprintf (lst_fp, "* %s\n", txt);
  1036. X        XtFree (txt);
  1037. X    }
  1038. X}
  1039. END_OF_FILE
  1040.   if test 13104 -ne `wc -c <'listmenu.c'`; then
  1041.     echo shar: \"'listmenu.c'\" unpacked with wrong size!
  1042.   fi
  1043.   # end of 'listmenu.c'
  1044. fi
  1045. if test -f 'marsmenu.c' -a "${1}" != "-c" ; then 
  1046.   echo shar: Will not clobber existing file \"'marsmenu.c'\"
  1047. else
  1048.   echo shar: Extracting \"'marsmenu.c'\" \(15322 characters\)
  1049.   sed "s/^X//" >'marsmenu.c' <<'END_OF_FILE'
  1050. X/* code to manage the stuff on the "mars" menu.
  1051. X */
  1052. X
  1053. X#include <stdio.h>
  1054. X#include <ctype.h>
  1055. X#include <math.h>
  1056. X#if defined(__STDC__)
  1057. X#include <stdlib.h>
  1058. X#endif
  1059. X#include <X11/Xlib.h>
  1060. X#include <Xm/Xm.h>
  1061. X#include <Xm/Form.h>
  1062. X#include <Xm/Frame.h>
  1063. X#include <Xm/Label.h>
  1064. X#include <Xm/PushB.h>
  1065. X#include <Xm/RowColumn.h>
  1066. X#include <Xm/DrawingA.h>
  1067. X#include <Xm/Separator.h>
  1068. X#include <Xm/ToggleB.h>
  1069. X#include "astro.h"
  1070. X#include "circum.h"
  1071. X#include "map.h"
  1072. X
  1073. X
  1074. X#if defined(__STDC__) || defined(__cplusplus)
  1075. X#define P_(s) s
  1076. X#else
  1077. X#define P_(s) ()
  1078. X#endif
  1079. X
  1080. Xextern Now *mm_get_now P_((void));
  1081. Xextern Obj *db_basic P_((int id));
  1082. Xextern int any_ison P_((void));
  1083. Xextern void db_update P_((Obj *op));
  1084. Xextern void f_double P_((Widget w, char *fmt, double f));
  1085. Xextern void get_something P_((Widget w, char *resource, char *value));
  1086. Xextern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
  1087. Xextern void range P_((double *v, double r));
  1088. Xextern void register_selection P_((char *name));
  1089. Xextern void timestamp P_((Now *np, Widget w));
  1090. X
  1091. Xvoid mars_manage P_((void));
  1092. Xvoid mars_update P_((Now *np, int force));
  1093. Xint mars_ison P_((void));
  1094. Xvoid mars_selection_mode P_((int whether));
  1095. Xvoid mars_cursor P_((Cursor c));
  1096. Xstatic void mars_create_form P_((void));
  1097. Xstatic void mars_cml_cb P_((Widget w, XtPointer client, XtPointer call));
  1098. Xstatic void mars_close_cb P_((Widget w, XtPointer client, XtPointer call));
  1099. Xstatic void mars_help_cb P_((Widget w, XtPointer client, XtPointer call));
  1100. Xstatic void mars_exp_cb P_((Widget w, XtPointer client, XtPointer call));
  1101. Xstatic void mars_set_buttons P_((int whether));
  1102. Xstatic double mars_cml P_((Now *np));
  1103. Xstatic void mars_map P_((Now *np, double cml));
  1104. X
  1105. X#undef P_
  1106. X
  1107. Xextern MRegion mreg[];
  1108. Xextern int nmreg;
  1109. X
  1110. Xextern Widget toplevel_w;
  1111. X#define    XtD    XtDisplay(toplevel_w)
  1112. X
  1113. X#define    M_CML0    degrad(325.845)        /* Mars' CML towards Aries at M_MJD0 */
  1114. X#define    M_PER    degrad(350.891962)    /* Mars' rotation period, rads/day */
  1115. X#define    M_MJD0    (2418322.0 - MJD0)    /* mjd date of M_CML0 */
  1116. X
  1117. Xstatic int mars_selecting;    /* set while our fields are being selected */
  1118. X
  1119. Xstatic Widget marsform_w;    /* main form dialog */
  1120. Xstatic Widget mars_cml_w;    /* CML numberic display widget */
  1121. Xstatic Widget mars_da_w;    /* map DrawingArea widget */
  1122. Xstatic Widget mars_dt_w;    /* data/time stamp label widget */
  1123. X
  1124. X#define    DSIN(x)        sin(degrad(x))
  1125. X#define    DCOS(x)        cos(degrad(x))
  1126. X
  1127. X#ifdef __STDC__
  1128. Xstatic double mars_cml(Now *np);
  1129. X#else
  1130. Xstatic double mars_cml();
  1131. X#endif
  1132. X
  1133. Xvoid
  1134. Xmars_manage()
  1135. X{
  1136. X    if (!marsform_w)
  1137. X        mars_create_form();
  1138. X
  1139. X    if (XtIsManaged(marsform_w))
  1140. X        XtUnmanageChild(marsform_w);
  1141. X    else {
  1142. X        XtManageChild(marsform_w);
  1143. X        mars_set_buttons(mars_selecting);
  1144. X    }
  1145. X}
  1146. X
  1147. X/* display the map and CML info for circumstances described by *np..
  1148. X * don't bother with the computation of CML unless we are managed or someone
  1149. X *   cares.
  1150. X * don't bother with the map unless we are managed.
  1151. X */
  1152. Xvoid
  1153. Xmars_update(np, force)
  1154. XNow *np;
  1155. Xint force;
  1156. X{
  1157. X    double cml;
  1158. X
  1159. X    if (!marsform_w)
  1160. X        return;
  1161. X    if (!XtIsManaged(marsform_w) && !any_ison() && !force)
  1162. X        return;
  1163. X
  1164. X    cml = mars_cml (np);
  1165. X    f_double (mars_cml_w, "%5.1f", cml);
  1166. X
  1167. X    if (XtIsManaged(marsform_w))
  1168. X        mars_map (np, cml);
  1169. X}
  1170. X
  1171. Xmars_ison()
  1172. X{
  1173. X    return (marsform_w && XtIsManaged(marsform_w));
  1174. X}
  1175. X
  1176. X/* called by other menus as they want to hear from our buttons or not.
  1177. X * the ons and offs stack.
  1178. X */
  1179. Xvoid
  1180. Xmars_selection_mode (whether)
  1181. Xint whether;
  1182. X{
  1183. X    mars_selecting += whether ? 1 : -1;
  1184. X
  1185. X    if (mars_ison())
  1186. X        if (whether && mars_selecting == 1       /* first one to want on */
  1187. X        || !whether && mars_selecting == 0 /* first one to want off */)
  1188. X        mars_set_buttons (whether);
  1189. X}
  1190. X
  1191. Xvoid
  1192. Xmars_cursor(c)
  1193. XCursor c;
  1194. X{
  1195. X    Window win;
  1196. X
  1197. X    if (marsform_w && (win = XtWindow(marsform_w))) {
  1198. X        Display *dsp = XtDisplay(marsform_w);
  1199. X        if (c)
  1200. X        XDefineCursor(dsp, win, c);
  1201. X        else
  1202. X        XUndefineCursor(dsp, win);
  1203. X    }
  1204. X}
  1205. X
  1206. Xstatic void
  1207. Xmars_create_form()
  1208. X{
  1209. X    static struct {
  1210. X        char *name;
  1211. X        void (*cb)();
  1212. X    } ctls[] = {
  1213. X        {"Close", mars_close_cb},
  1214. X        {"Help", mars_help_cb}
  1215. X    };
  1216. X    Widget w;
  1217. X    Widget fr_w;
  1218. X    Widget f_w;
  1219. X    Widget sep_w;
  1220. X    XmString str;
  1221. X    Arg args[20];
  1222. X    int n;
  1223. X    int i;
  1224. X
  1225. X    /* create form */
  1226. X    n = 0;
  1227. X    XtSetArg (args[n], XmNautoUnmanage, False); n++;
  1228. X    XtSetArg (args[n], XmNdefaultPosition, False); n++;
  1229. X    XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  1230. X    XtSetArg (args[n], XmNhorizontalSpacing, 4); n++;
  1231. X    XtSetArg (args[n], XmNverticalSpacing, 4); n++;
  1232. X    marsform_w = XmCreateFormDialog (toplevel_w, "Mars", args, n);
  1233. X
  1234. X    /* set some stuff in the parent DialogShell.
  1235. X     * setting XmNdialogTitle in the Form didn't work..
  1236. X     */
  1237. X    n = 0;
  1238. X    XtSetArg (args[n], XmNtitle, "xephem Mars view"); n++;
  1239. X    XtSetValues (XtParent(marsform_w), args, n);
  1240. X
  1241. X    /* make the bottom control panel form */
  1242. X
  1243. X    n = 0;
  1244. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1245. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1246. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1247. X    XtSetArg (args[n], XmNfractionBase, 9); n++;
  1248. X    XtSetArg (args[n], XmNverticalSpacing, 5); n++;
  1249. X    f_w = XmCreateForm (marsform_w, "CtlF", args, n);
  1250. X    XtManageChild (f_w);
  1251. X
  1252. X        for (i = 0; i < XtNumber(ctls); i++) {
  1253. X        n = 0;
  1254. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1255. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1256. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  1257. X        XtSetArg (args[n], XmNleftPosition, 1+i*4); n++;
  1258. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  1259. X        XtSetArg (args[n], XmNrightPosition, 4+i*4); n++;
  1260. X        w = XmCreatePushButton (f_w, ctls[i].name, args, n);
  1261. X        XtManageChild (w);
  1262. X        XtAddCallback (w, XmNactivateCallback, ctls[i].cb, NULL);
  1263. X        }
  1264. X
  1265. X    /* make a separator */
  1266. X
  1267. X    n = 0;
  1268. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1269. X    XtSetArg (args[n], XmNbottomWidget, f_w); n++;
  1270. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1271. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1272. X    sep_w = XmCreateSeparator (marsform_w, "Sep", args, n);
  1273. X    XtManageChild(sep_w);
  1274. X
  1275. X    /* make the "cml" label and push button pair */
  1276. X
  1277. X    str = XmStringCreateLtoR("Central Meridian Longitude (degs): ",
  1278. X                        XmSTRING_DEFAULT_CHARSET);
  1279. X    n = 0;
  1280. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1281. X    XtSetArg (args[n], XmNbottomWidget, sep_w); n++;
  1282. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1283. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  1284. X    XtSetArg (args[n], XmNlabelString, str); n++;
  1285. X    w = XmCreateLabel (marsform_w, "CMLLbl", args, n);
  1286. X    XtManageChild (w);
  1287. X    XmStringFree(str);
  1288. X
  1289. X    n = 0;
  1290. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1291. X    XtSetArg (args[n], XmNbottomWidget, sep_w); n++;
  1292. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1293. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  1294. X    XtSetArg (args[n], XmNleftWidget, w); n++;
  1295. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++;
  1296. X    XtSetArg (args[n], XmNuserData, "Mars.CML"); n++;
  1297. X    mars_cml_w = XmCreatePushButton (marsform_w, "CMLVal", args, n);
  1298. X    XtAddCallback (mars_cml_w, XmNactivateCallback, mars_cml_cb, 0);
  1299. X    XtManageChild (mars_cml_w);
  1300. X
  1301. X    /* make the date/time indicator label */
  1302. X
  1303. X    n = 0;
  1304. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1305. X    XtSetArg (args[n], XmNbottomWidget, mars_cml_w); n++;
  1306. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1307. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1308. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1309. X    mars_dt_w = XmCreateLabel (marsform_w, "DTstamp", args, n);
  1310. X    XtManageChild (mars_dt_w);
  1311. X
  1312. X    /* make a drawing area in a frame on top */
  1313. X
  1314. X    n = 0;
  1315. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1316. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1317. X    XtSetArg (args[n], XmNbottomWidget, mars_dt_w); n++;
  1318. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1319. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1320. X    XtSetArg (args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
  1321. X    fr_w = XmCreateFrame (marsform_w, "MarsFrame", args, n);
  1322. X    XtManageChild (fr_w);
  1323. X
  1324. X        n = 0;
  1325. X        mars_da_w = XmCreateDrawingArea (fr_w, "Map", args, n);
  1326. X        XtAddCallback (mars_da_w, XmNexposeCallback, mars_exp_cb, NULL);
  1327. X        XtManageChild (mars_da_w);
  1328. X}
  1329. X
  1330. X/* callback for when the mars CML button is activated. */
  1331. X/* ARGSUSED */
  1332. Xstatic void
  1333. Xmars_cml_cb (w, client, call)
  1334. XWidget w;
  1335. XXtPointer client;
  1336. XXtPointer call;
  1337. X{
  1338. X    if (mars_selecting) {
  1339. X        char *userD;
  1340. X        get_something (w, XmNuserData, (char *)&userD);
  1341. X        register_selection (userD);
  1342. X    }
  1343. X}
  1344. X
  1345. X/* callback for when the Close button is activated. */
  1346. X/* ARGSUSED */
  1347. Xstatic void
  1348. Xmars_close_cb (w, client, call)
  1349. XWidget w;
  1350. XXtPointer client;
  1351. XXtPointer call;
  1352. X{
  1353. X    XtUnmanageChild (marsform_w);
  1354. X}
  1355. X
  1356. X/* callback from the Help button
  1357. X */
  1358. X/* ARGSUSED */
  1359. Xstatic void
  1360. Xmars_help_cb (w, client, call)
  1361. XWidget w;
  1362. XXtPointer client;
  1363. XXtPointer call;
  1364. X{
  1365. X    static char *msg[] = {
  1366. X"This is a simple schematic depiction of the Martian surface at the given time.",
  1367. X"Also included is the current Central Meridian Longitude, in degrees.",
  1368. X"South is up and longitude increases to the right; therefore, the planet",
  1369. X"appears to rotate CW as seen from above."
  1370. X};
  1371. X
  1372. X    hlp_dialog ("Mars", msg, XtNumber(msg));
  1373. X}
  1374. X
  1375. X/* called whenever the mars drawing area gets an expose.
  1376. X */
  1377. X/* ARGSUSED */
  1378. Xstatic void
  1379. Xmars_exp_cb (w, client, call)
  1380. XWidget w;
  1381. XXtPointer client;
  1382. XXtPointer call;
  1383. X{
  1384. X    XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
  1385. X
  1386. X    /* filter out a few oddball cases */
  1387. X    switch (c->reason) {
  1388. X    case XmCR_EXPOSE: {
  1389. X        /* turn off gravity so we get expose events for either shrink or
  1390. X         * expand.
  1391. X         */
  1392. X        static before;
  1393. X        XExposeEvent *e = &c->event->xexpose;
  1394. X
  1395. X        if (!before) {
  1396. X        XSetWindowAttributes swa;
  1397. X        swa.bit_gravity = ForgetGravity;
  1398. X        XChangeWindowAttributes (e->display, e->window, 
  1399. X                                CWBitGravity, &swa);
  1400. X        before = 1;
  1401. X        }
  1402. X        /* wait for the last in the series */
  1403. X        if (e->count != 0)
  1404. X        return;
  1405. X        break;
  1406. X        }
  1407. X    default:
  1408. X        printf ("Unexpected marsform_w event. type=%d\n", c->reason);
  1409. X        exit(1);
  1410. X    }
  1411. X
  1412. X    mars_update (mm_get_now(), 1);
  1413. X}
  1414. X
  1415. X/* go through all the buttons and set whether they
  1416. X * should appear to look like buttons or just flat labels.
  1417. X */
  1418. Xstatic void
  1419. Xmars_set_buttons (whether)
  1420. Xint whether;    /* whether setting up for plotting or for not plotting */
  1421. X{
  1422. X    static Arg look_like_button[] = {
  1423. X        {XmNtopShadowColor, (XtArgVal) 0},
  1424. X        {XmNbottomShadowColor, (XtArgVal) 0},
  1425. X        {XmNfillOnArm, (XtArgVal) True},
  1426. X    };
  1427. X    static Arg look_like_label[] = {
  1428. X        {XmNtopShadowColor, (XtArgVal) 0},
  1429. X        {XmNbottomShadowColor, (XtArgVal) 0},
  1430. X        {XmNfillOnArm, (XtArgVal) False},
  1431. X    };
  1432. X    static int called;
  1433. X    Arg *ap;
  1434. X    int na;
  1435. X
  1436. X    if (!called) {
  1437. X        /* get baseline label and shadow appearances.
  1438. X         */
  1439. X        Pixel topshad, botshad, bgcol;
  1440. X        Arg args[20];
  1441. X        int n;
  1442. X
  1443. X        n = 0;
  1444. X        XtSetArg (args[n], XmNtopShadowColor, &topshad); n++;
  1445. X        XtSetArg (args[n], XmNbottomShadowColor, &botshad); n++;
  1446. X        XtSetArg (args[n], XmNbackground, &bgcol); n++;
  1447. X        XtGetValues (mars_cml_w, args, n);
  1448. X
  1449. X        look_like_button[0].value = topshad;
  1450. X        look_like_button[1].value = botshad;
  1451. X        look_like_label[0].value = bgcol;
  1452. X        look_like_label[1].value = bgcol;
  1453. X
  1454. X        called = 1;
  1455. X    }
  1456. X
  1457. X    if (whether) {
  1458. X        ap = look_like_button;
  1459. X        na = XtNumber(look_like_button);
  1460. X    } else {
  1461. X        ap = look_like_label;
  1462. X        na = XtNumber(look_like_label);
  1463. X    }
  1464. X
  1465. X    XtSetValues (mars_cml_w, ap, na);
  1466. X}
  1467. X
  1468. X/* return the Martian central meridian longitude at np, in degrees. */
  1469. Xstatic double
  1470. Xmars_cml(np)
  1471. XNow *np;
  1472. X{
  1473. X    Obj *sp, *mp;
  1474. X    double a;    /* angle from Sun ccw to Earth seen from Mars, rads */
  1475. X    double Ae;    /* planetocentric longitude of Earth from Mars, rads */
  1476. X    double cml0;    /* Mar's CML towards Aries, rads */
  1477. X    double lc;    /* Mars rotation correction for light travel, rads */
  1478. X    double cml;
  1479. X
  1480. X    sp = db_basic (SUN);
  1481. X    db_update (sp);
  1482. X    mp = db_basic (MARS);
  1483. X    db_update (mp);
  1484. X
  1485. X    a = asin (sp->s_edist/mp->s_edist*sin(mp->s_hlong-sp->s_hlong));
  1486. X    Ae = mp->s_hlong + PI + a;
  1487. X    cml0 = M_CML0 + M_PER*(mjd-M_MJD0) + PI/2;
  1488. X    range(&cml0, 2*PI);
  1489. X    lc = LTAU * mp->s_edist/SPD*M_PER;
  1490. X    cml = cml0 - Ae - lc;
  1491. X    range (&cml, 2*PI);
  1492. X    cml = raddeg(cml);
  1493. X    /*
  1494. X    printf ("a=%g Ae=%g cml0=%g lc=%g cml=%g\n", raddeg(a), raddeg(Ae),
  1495. X                        raddeg(cml0), raddeg(lc), cml);
  1496. X     */
  1497. X    return (cml);
  1498. X}
  1499. X
  1500. Xstatic void
  1501. Xmars_map(np, cml)
  1502. XNow *np;
  1503. Xdouble cml;
  1504. X{
  1505. X    static unsigned long last_w, last_h;
  1506. X    static Pixmap mars_pm;
  1507. X    static GC mars_gc;
  1508. X    static Pixel mars_fg, mars_bg;
  1509. X    Display *dsp = XtDisplay(mars_da_w);
  1510. X    Window win = XtWindow(mars_da_w);
  1511. X    int x, y;
  1512. X    unsigned w, h, b, d;
  1513. X    MRegion *rp;
  1514. X    XPoint p[128];
  1515. X    int npts;
  1516. X    Window root;
  1517. X    int wb, hb, r;
  1518. X    MCoord *cp;
  1519. X    int maxx, minx, maxy, miny;
  1520. X
  1521. X    /* make the GC if this is our first time */
  1522. X    if (!mars_gc) {
  1523. X        XGCValues gcv;
  1524. X        unsigned long gcm;
  1525. X
  1526. X        gcm = 0;
  1527. X        mars_gc = XCreateGC (dsp, win, gcm, &gcv);
  1528. X
  1529. X        get_something (mars_da_w, XmNforeground, (char *)&mars_fg);
  1530. X        get_something (mars_da_w, XmNbackground, (char *)&mars_bg);
  1531. X    }
  1532. X
  1533. X    /* set up width and height borders and the radius so the
  1534. X     * planetary sphere is a circle centered within the window.
  1535. X     */
  1536. X    XGetGeometry (dsp, win, &root, &x, &y, &w, &h, &b, &d);
  1537. X    if (w > h) {
  1538. X        wb = (w - h)/2;
  1539. X        hb = 0;
  1540. X        r = h/2;
  1541. X    } else {
  1542. X        wb = 0;
  1543. X        hb = (h - w)/2;
  1544. X        r = w/2;
  1545. X    }
  1546. X
  1547. X    /* make the pixmap if this is our first time or the size has changed */
  1548. X    if (!mars_pm || w != last_w || h != last_h) {
  1549. X        last_w = w;
  1550. X        last_h = h;
  1551. X        if (mars_pm)
  1552. X        XFreePixmap (dsp, mars_pm);
  1553. X        mars_pm = XCreatePixmap (dsp, win, w, h, d);
  1554. X    }
  1555. X
  1556. X    /* clear the scene, draw filled circle in foreground then fill in
  1557. X     * regions in background. Then make another pass and overlay the names.
  1558. X     * we draw south (negative latitudes) downwards (in X's +y diretion)
  1559. X     * and with increasing longitudes progressing to the right. this
  1560. X     * means the planet appears to rotate CW as seen from above.
  1561. X     */
  1562. X    XSetFunction (dsp, mars_gc, GXcopy);
  1563. X    XSetForeground (dsp, mars_gc, mars_bg);
  1564. X    XFillRectangle (dsp, mars_pm, mars_gc, 0, 0, w, h);
  1565. X    XSetForeground (dsp, mars_gc, mars_fg);
  1566. X    XFillArc (dsp, mars_pm, mars_gc, wb, hb, 2*r, 2*r, 0, 360*64);
  1567. X    XSetForeground (dsp, mars_gc, mars_bg);
  1568. X    for (rp = mreg; rp < mreg+nmreg; rp++) {
  1569. X        npts = 0;
  1570. X        for (cp = rp->mcp; cp < rp->mcp+rp->nmcp; cp++) {
  1571. X        double dlg = cp->lg - cml;
  1572. X        range (&dlg, 360.0);
  1573. X        if (dlg >= 90 && dlg <= 270)
  1574. X            goto skip_region;
  1575. X        p[npts].x = wb + r*(1 + DSIN(dlg)*DCOS(cp->lt));
  1576. X        p[npts].y = hb + r*(1 + DSIN(cp->lt));
  1577. X        npts++;
  1578. X        }
  1579. X        XFillPolygon (dsp, mars_pm, mars_gc, p, npts,Nonconvex,CoordModeOrigin);
  1580. X
  1581. X      skip_region:
  1582. X        continue;
  1583. X    }
  1584. X
  1585. X    XSetFunction (dsp, mars_gc, GXxor);
  1586. X    XSetForeground (dsp, mars_gc, mars_fg^mars_bg);
  1587. X    for (rp = mreg; rp < mreg+nmreg; rp++) {
  1588. X        maxx = 0; minx = w; maxy = 0; miny = h;
  1589. X        for (cp = rp->mcp; cp < rp->mcp+rp->nmcp; cp++) {
  1590. X        double dlg = cp->lg - cml;
  1591. X        range (&dlg, 360.0);
  1592. X        if (dlg >= 90 && dlg <= 270)
  1593. X            goto skip_name;
  1594. X        x = wb + r*(1 + DSIN(dlg)*DCOS(cp->lt));
  1595. X        y = hb + r*(1 + DSIN(cp->lt));
  1596. X        if (x > maxx) maxx = x;
  1597. X        if (x < minx) minx = x;
  1598. X        if (y > maxy) maxy = y;
  1599. X        if (y < miny) miny = y;
  1600. X        }
  1601. X        XDrawString (dsp, mars_pm, mars_gc, (minx+maxx)/2, (miny+maxy)/2,
  1602. X        rp->rname, strlen(rp->rname));
  1603. X
  1604. X      skip_name:
  1605. X        continue;
  1606. X    }
  1607. X
  1608. X    XSetFunction (dsp, mars_gc, GXcopy);
  1609. X    XCopyArea (dsp, mars_pm, win, mars_gc, 0, 0, w, h, 0, 0);
  1610. X
  1611. X    timestamp (np, mars_dt_w);
  1612. X}
  1613. END_OF_FILE
  1614.   if test 15322 -ne `wc -c <'marsmenu.c'`; then
  1615.     echo shar: \"'marsmenu.c'\" unpacked with wrong size!
  1616.   fi
  1617.   # end of 'marsmenu.c'
  1618. fi
  1619. if test -f 'moonmenu.c' -a "${1}" != "-c" ; then 
  1620.   echo shar: Will not clobber existing file \"'moonmenu.c'\"
  1621. else
  1622.   echo shar: Extracting \"'moonmenu.c'\" \(14914 characters\)
  1623.   sed "s/^X//" >'moonmenu.c' <<'END_OF_FILE'
  1624. X/* code to manage the stuff on the moon display.
  1625. X */
  1626. X
  1627. X#include <stdio.h>
  1628. X#include <ctype.h>
  1629. X#include <math.h>
  1630. X#if defined(__STDC__)
  1631. X#include <stdlib.h>
  1632. X#endif
  1633. X#include <X11/Xlib.h>
  1634. X#include <Xm/Xm.h>
  1635. X#include <Xm/Form.h>
  1636. X#include <Xm/Frame.h>
  1637. X#include <Xm/DrawingA.h>
  1638. X#include <Xm/Label.h>
  1639. X#include <Xm/PushB.h>
  1640. X#include <Xm/ToggleB.h>
  1641. X#include <Xm/Text.h>
  1642. X#include "astro.h"
  1643. X#include "circum.h"
  1644. X
  1645. X
  1646. Xextern Widget toplevel_w;
  1647. X
  1648. X#if defined(__STDC__) || defined(__cplusplus)
  1649. X#define P_(s) s
  1650. X#else
  1651. X#define P_(s) ()
  1652. X#endif
  1653. X
  1654. Xextern Now *mm_get_now P_((void));
  1655. Xextern Obj *db_basic P_((int id));
  1656. Xextern void db_update P_((Obj *op));
  1657. Xextern void get_something P_((Widget w, char *resource, char *value));
  1658. Xextern void timestamp P_((Now *np, Widget w));
  1659. X
  1660. Xvoid m_manage P_((void));
  1661. Xint m_ison P_((void));
  1662. Xvoid m_update P_((Now *np, int how_much));
  1663. Xvoid m_cursor P_((Cursor c));
  1664. Xstatic void m_create_form P_((void));
  1665. Xstatic void m_close_cb P_((Widget w, XtPointer client, XtPointer call));
  1666. Xstatic void m_mapvw_cb P_((Widget w, XtPointer client, XtPointer call));
  1667. Xstatic void m_eshine_cb P_((Widget w, XtPointer client, XtPointer call));
  1668. Xstatic void m_da_exp_cb P_((Widget w, XtPointer client, XtPointer call));
  1669. Xstatic void m_draw P_((int force));
  1670. Xstatic void m_draw_mapview P_((double el));
  1671. Xstatic void m_draw_grview P_((double el));
  1672. X
  1673. X#undef P_
  1674. X
  1675. X/* get the small moonbit map and its dimension defines.
  1676. X * moon is roughly centered within the map, with a radius of some 200 pixels.
  1677. X * exact values set by trial and error.
  1678. X */
  1679. X#include "smallfm.xbm"
  1680. X#define    MRAD    191                /* radius of moon image */
  1681. X#define    TOPMAR    (smallfm_height/2 - MRAD + 2)    /* top margin */
  1682. X#define    LEFTMAR    (smallfm_width/2 - MRAD)    /* left margin */
  1683. X
  1684. X#define    NSTARS    300    /* number of fake background stars in graphical view */
  1685. X
  1686. Xstatic Widget mform_w;        /* main moon form dialog */
  1687. Xstatic Widget mda_w;        /* moon drawring area */
  1688. Xstatic Widget eshine_w;        /* whether we want to show earthshine */
  1689. Xstatic Widget mapvw_w;        /* toggle button that selects which view */
  1690. Xstatic Widget dt_w;        /* date/time stamp widget */
  1691. X
  1692. X#define    MAPVW_W    (smallfm_width+20)
  1693. X#define    MAPVW_H    (smallfm_height+40)
  1694. X
  1695. X/* called when the moon view is activated via the main menu pulldown.
  1696. X * if never called before, create and manage all the widgets as a child of a
  1697. X * form. otherwise, just toggle whether the form is managed.
  1698. X */
  1699. Xvoid
  1700. Xm_manage ()
  1701. X{
  1702. X    if (!mform_w)
  1703. X        m_create_form();
  1704. X    
  1705. X    if (XtIsManaged(mform_w))
  1706. X        XtUnmanageChild (mform_w);
  1707. X    else {
  1708. X        XtManageChild (mform_w);
  1709. X        /* let the initial expose do the drawing */
  1710. X    }
  1711. X}
  1712. X
  1713. Xm_ison()
  1714. X{
  1715. X    return (mform_w && XtIsManaged(mform_w));
  1716. X}
  1717. X
  1718. Xvoid
  1719. Xm_update (np, how_much)
  1720. XNow *np;
  1721. Xint how_much;
  1722. X{
  1723. X    if (!mform_w || !XtIsManaged(mform_w))
  1724. X        return;
  1725. X
  1726. X    m_draw (how_much);
  1727. X    timestamp (np, dt_w);
  1728. X}
  1729. X
  1730. X/* called to put up or remove the watch cursor.  */
  1731. Xvoid
  1732. Xm_cursor (c)
  1733. XCursor c;
  1734. X{
  1735. X    Window win;
  1736. X
  1737. X    if (mform_w && (win = XtWindow(mform_w))) {
  1738. X        Display *dsp = XtDisplay(mform_w);
  1739. X        if (c)
  1740. X        XDefineCursor (dsp, win, c);
  1741. X        else
  1742. X        XUndefineCursor (dsp, win);
  1743. X    }
  1744. X}
  1745. X
  1746. Xstatic void
  1747. Xm_create_form()
  1748. X{
  1749. X    Widget frame_w;
  1750. X    Widget f_w, fr_w;
  1751. X    Widget w;
  1752. X    XmString str;
  1753. X    Arg args[20];
  1754. X    int n;
  1755. X
  1756. X    /* create master form */
  1757. X    n = 0;
  1758. X    XtSetArg (args[n], XmNautoUnmanage, False); n++;
  1759. X    XtSetArg (args[n], XmNhorizontalSpacing, 5); n++;
  1760. X    XtSetArg (args[n], XmNverticalSpacing, 5); n++;
  1761. X    XtSetArg (args[n], XmNdefaultPosition, False); n++;
  1762. X    mform_w = XmCreateFormDialog (toplevel_w, "Moon", args, n);
  1763. X
  1764. X    /* set some stuff in the parent DialogShell.
  1765. X     * setting XmNdialogTitle in the Form didn't work..
  1766. X     */
  1767. X    n = 0;
  1768. X    XtSetArg (args[n], XmNtitle, "xephem Moon View"); n++;
  1769. X    XtSetValues (XtParent(mform_w), args, n);
  1770. X
  1771. X    /* make a Form to hold the bottom controls */
  1772. X
  1773. X    n = 0;
  1774. X    XtSetArg (args[n], XmNfractionBase, 13); n++;
  1775. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1776. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1777. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1778. X    f_w = XmCreateForm (mform_w, "MoonCtlForm", args, n);
  1779. X    XtManageChild (f_w);
  1780. X
  1781. X        /* make the close button */
  1782. X
  1783. X        n = 0;
  1784. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1785. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1786. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  1787. X        XtSetArg (args[n], XmNleftPosition, 1); n++;
  1788. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  1789. X        XtSetArg (args[n], XmNrightPosition, 4); n++;
  1790. X        w = XmCreatePushButton (f_w, "Close", args, n);
  1791. X        XtAddCallback (w, XmNactivateCallback, m_close_cb, 0);
  1792. X        XtManageChild (w);
  1793. X
  1794. X        /* make the earthshine toggle button in a frame */
  1795. X
  1796. X        n = 0;
  1797. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1798. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1799. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  1800. X        XtSetArg (args[n], XmNleftPosition, 5); n++;
  1801. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  1802. X        XtSetArg (args[n], XmNrightPosition, 8); n++;
  1803. X        fr_w = XmCreateFrame (f_w, "EarthshineFr", args, n);
  1804. X        XtManageChild (fr_w);
  1805. X        eshine_w = XmCreateToggleButton (fr_w, "Earthshine", args, n);
  1806. X        XtAddCallback (eshine_w, XmNvalueChangedCallback, m_eshine_cb, 0);
  1807. X        XtManageChild (eshine_w);
  1808. X
  1809. X        /* make the view option toggle button in a frame */
  1810. X
  1811. X        n = 0;
  1812. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1813. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1814. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  1815. X        XtSetArg (args[n], XmNleftPosition, 9); n++;
  1816. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  1817. X        XtSetArg (args[n], XmNrightPosition, 12); n++;
  1818. X        fr_w = XmCreateFrame(f_w,"MMapViewFr", args, n);
  1819. X        XtManageChild (fr_w);
  1820. X        str = XmStringCreate("Bitmap View", XmSTRING_DEFAULT_CHARSET);
  1821. X        n = 0;
  1822. X        XtSetArg (args[n], XmNlabelString, str); n++;
  1823. X        mapvw_w = XmCreateToggleButton(fr_w, "BitmapView", args, n);
  1824. X        XtAddCallback(mapvw_w, XmNvalueChangedCallback, m_mapvw_cb, 0);
  1825. X        XtManageChild (mapvw_w);
  1826. X        XmStringFree (str);
  1827. X
  1828. X    /* make a label for the date stamp */
  1829. X
  1830. X    n = 0;
  1831. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1832. X    XtSetArg (args[n], XmNbottomWidget, f_w); n++;
  1833. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1834. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1835. X    XtSetArg (args[n], XmNrecomputeSize, False); n++;
  1836. X    dt_w = XmCreateLabel (mform_w, "DateStamp", args, n);
  1837. X    timestamp (mm_get_now(), dt_w);    /* sets initial size */
  1838. X    XtManageChild (dt_w);
  1839. X
  1840. X    /* make a frame for the drawing area */
  1841. X
  1842. X    n = 0;
  1843. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1844. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1845. X    XtSetArg (args[n], XmNbottomWidget, dt_w); n++;
  1846. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1847. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1848. X    XtSetArg (args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
  1849. X    frame_w = XmCreateFrame (mform_w, "MoonFrame", args, n);
  1850. X    XtManageChild (frame_w);
  1851. X
  1852. X    /* make a drawing area in the frame for the sky */
  1853. X    n = 0;
  1854. X    XtSetArg (args[n], XmNwidth, MAPVW_W); n++;
  1855. X    XtSetArg (args[n], XmNheight, MAPVW_H); n++;
  1856. X    XtSetArg (args[n], XmNmarginWidth, 0); n++;
  1857. X    XtSetArg (args[n], XmNmarginHeight, 0); n++;
  1858. X    mda_w = XmCreateDrawingArea (frame_w, "MoonDA", args, n);
  1859. X    XtManageChild (mda_w);
  1860. X    XtAddCallback (mda_w, XmNexposeCallback, m_da_exp_cb, 0);
  1861. X}
  1862. X
  1863. X/* callback from the Close button.
  1864. X */
  1865. X/* ARGSUSED */
  1866. Xstatic void
  1867. Xm_close_cb (w, client, call)
  1868. XWidget w;
  1869. XXtPointer client;
  1870. XXtPointer call;
  1871. X{
  1872. X    XtUnmanageChild (mform_w);
  1873. X}
  1874. X
  1875. X/* callback from the Map view toggle button.
  1876. X */
  1877. X/* ARGSUSED */
  1878. Xstatic void
  1879. Xm_mapvw_cb (w, client, call)
  1880. XWidget w;
  1881. XXtPointer client;
  1882. XXtPointer call;
  1883. X{
  1884. X    m_update (mm_get_now(), 1);
  1885. X}
  1886. X
  1887. X/* callback from the earthshine toggle button.
  1888. X */
  1889. X/* ARGSUSED */
  1890. Xstatic void
  1891. Xm_eshine_cb (w, client, call)
  1892. XWidget w;
  1893. XXtPointer client;
  1894. XXtPointer call;
  1895. X{
  1896. X    m_update (mm_get_now(), 1);
  1897. X}
  1898. X
  1899. X/* expose (or reconfig) of moon drawing area.
  1900. X * just redraw the scene to the current window size.
  1901. X */
  1902. X/* ARGSUSED */
  1903. Xstatic void
  1904. Xm_da_exp_cb (w, client, call)
  1905. XWidget w;
  1906. XXtPointer client;
  1907. XXtPointer call;
  1908. X{
  1909. X    XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
  1910. X
  1911. X    switch (c->reason) {
  1912. X    case XmCR_EXPOSE: {
  1913. X        /* turn off gravity so we get expose events for either shrink or
  1914. X         * expand.
  1915. X         */
  1916. X        static before;
  1917. X        XExposeEvent *e = &c->event->xexpose;
  1918. X
  1919. X        if (!before) {
  1920. X        XSetWindowAttributes swa;
  1921. X        swa.bit_gravity = ForgetGravity;
  1922. X        XChangeWindowAttributes (e->display, e->window,
  1923. X                                CWBitGravity, &swa);
  1924. X        before = 1;
  1925. X        }
  1926. X        /* wait for the last in the series */
  1927. X        if (e->count != 0)
  1928. X        return;
  1929. X        break;
  1930. X        }
  1931. X    default:
  1932. X        printf ("Unexpected mda_w event. type=%d\n", c->reason);
  1933. X        exit(1);
  1934. X    }
  1935. X
  1936. X    m_update (mm_get_now(), 1);
  1937. X}
  1938. X
  1939. X/* draw moon, always if force or scene has changed.
  1940. X */
  1941. Xstatic void
  1942. Xm_draw (force)
  1943. Xint force;
  1944. X{
  1945. X    static double last_el;
  1946. X    Obj *op;
  1947. X    double el;
  1948. X
  1949. X    /* get new elongation */
  1950. X    op = db_basic (MOON);
  1951. X    db_update (op);
  1952. X    el = degrad(op->s_elong);
  1953. X
  1954. X    /* don't bother if not forcing and hasn't changed 1 degree */
  1955. X    if (!force && fabs (el - last_el) < degrad(1.0))
  1956. X        return;
  1957. X    last_el = el;
  1958. X
  1959. X    if (XmToggleButtonGetState(mapvw_w)) {
  1960. X        /* drawing pixmap view so insure a good initial size at least
  1961. X         */
  1962. X        Arg args[20];
  1963. X        int n;
  1964. X
  1965. X        n = 0;
  1966. X        XtSetArg (args[n], XmNwidth, MAPVW_W); n++;
  1967. X        XtSetArg (args[n], XmNheight, MAPVW_H); n++;
  1968. X        XtSetValues (mda_w, args, n);
  1969. X        XtManageChild (XtParent(eshine_w));
  1970. X        XtManageChild (eshine_w);
  1971. X        m_draw_mapview (el);
  1972. X    } else {
  1973. X        /* want graphical view */
  1974. X        XtUnmanageChild (eshine_w);
  1975. X        XtUnmanageChild (XtParent(eshine_w));
  1976. X        m_draw_grview (el);
  1977. X    }
  1978. X}
  1979. X
  1980. X/* version that draws moon using genuine bitmap image. */
  1981. Xstatic void
  1982. Xm_draw_mapview (el)
  1983. Xdouble el;
  1984. X{
  1985. X    static GC m_fgc;
  1986. X    Display *dsp = XtDisplay (mda_w);
  1987. X    Window win = XtWindow (mda_w);
  1988. X    double cosel;
  1989. X    XImage *xim;
  1990. X    unsigned char *m;
  1991. X    int y;    /* y coord: 0 is center, up is + */
  1992. X    int earthshine = XmToggleButtonGetState(eshine_w);
  1993. X
  1994. X    if (!m_fgc) {
  1995. X        /* make gc from MoonDA colors
  1996. X         */
  1997. X        XGCValues gcv;
  1998. X        unsigned int gcm;
  1999. X
  2000. X        gcm = GCForeground | GCBackground;
  2001. X        get_something (mda_w, XmNforeground, (char *)&gcv.background);
  2002. X        get_something (mda_w, XmNbackground, (char *)&gcv.foreground);
  2003. X
  2004. X        m_fgc = XCreateGC (dsp, win, gcm, &gcv);
  2005. X    }
  2006. X
  2007. X    /* make a copy so we can darken some of it */
  2008. X    m = (unsigned char *)XtMalloc(smallfm_width*smallfm_height/8);
  2009. X    (void) memcpy (m, smallfm_bits, smallfm_width*smallfm_height/8);
  2010. X
  2011. X    cosel = cos(el);
  2012. X    for (y = MRAD; y > -MRAD; y--) {
  2013. X        int lx, rx;    /* left and right edge of scan line to darken */
  2014. X        int r, c;    /* X row/col coords */
  2015. X        lx = -sqrt((double)(MRAD*MRAD - y*y));
  2016. X        rx = -lx * cosel;
  2017. X        if (el < 0) {
  2018. X        int tmp = rx;
  2019. X        rx = -lx;
  2020. X        lx = -tmp;
  2021. X        }
  2022. X        r = TOPMAR + MRAD - y;
  2023. X        for (c = LEFTMAR + MRAD + lx; c < LEFTMAR + MRAD + rx; c++)
  2024. X        if (!earthshine || (c & 3) != 3 || (y & 3) != 3)
  2025. X            m[r*smallfm_width/8 + c/8] |= (1 << (c%8)); /* 1 is bkgnd */
  2026. X    }
  2027. X
  2028. X    xim = XCreateImage (dsp, XDefaultVisual (dsp, 0),
  2029. X        /* depth */        1,
  2030. X        /* format */    XYBitmap, 
  2031. X        /* offset */    0,
  2032. X        /* data */        (char *)m,
  2033. X        /* width */        smallfm_width, 
  2034. X        /* height */    smallfm_height,
  2035. X        /* pad */        8,
  2036. X        /* bpl */        0);
  2037. X    xim->bitmap_bit_order = LSBFirst;
  2038. X    xim->byte_order = LSBFirst;
  2039. X
  2040. X    XPutImage (dsp, win, m_fgc, xim, 0, 0, 0, 0,
  2041. X                        smallfm_width, smallfm_height);
  2042. X    XDestroyImage (xim);    /* also frees m */
  2043. X}
  2044. X
  2045. X/* version that draws moon using just simple graphics */
  2046. Xstatic void
  2047. Xm_draw_grview (el)
  2048. Xdouble el;
  2049. X{
  2050. X    static GC m_fgc, m_bgc;
  2051. X    static XPoint *stars;
  2052. X    static int last_w, last_h;
  2053. X    Display *dsp = XtDisplay (mda_w);
  2054. X    Window win = XtWindow (mda_w);
  2055. X    Window root;
  2056. X    int x, y;
  2057. X    unsigned int bw, d;
  2058. X    unsigned w, h;        /* actual size of drawing area window */
  2059. X    unsigned md;        /* moon circle diameter */
  2060. X    int la1, la2, ta1, ta2; /* limb and terminator start and extent */
  2061. X    int wid;        /* distance from meridian to terminator */
  2062. X    int xb, yb;        /* x and y borders, eg, (w-nx)/2 */
  2063. X    Pixmap pm;
  2064. X
  2065. X    if (!m_fgc) {
  2066. X        /* make gcs from MoonDA colors
  2067. X         */
  2068. X        XGCValues gcv;
  2069. X        unsigned int gcm;
  2070. X
  2071. X        gcm = GCForeground | GCBackground;
  2072. X        get_something (mda_w, XmNforeground, (char *)&gcv.foreground);
  2073. X        get_something (mda_w, XmNbackground, (char *)&gcv.background);
  2074. X        m_fgc = XCreateGC (dsp, win, gcm, &gcv);
  2075. X
  2076. X        get_something (mda_w, XmNbackground, (char *)&gcv.foreground);
  2077. X        get_something (mda_w, XmNforeground, (char *)&gcv.background);
  2078. X        m_bgc = XCreateGC (dsp, win, gcm, &gcv);
  2079. X    }
  2080. X
  2081. X
  2082. X    /* get size of window now and make a fresh pixmap to match.
  2083. X     * we draw the scene in the pixmap then copy it to the window.
  2084. X     * otherwise, you can see it drawing and it flashes and looks ugly.
  2085. X     */
  2086. X    XGetGeometry (dsp, win, &root, &x, &y, &w, &h, &bw, &d);
  2087. X    pm = XCreatePixmap (dsp, win, w, h, d);
  2088. X    XFillRectangle (dsp, pm, m_bgc, 0, 0, w, h);
  2089. X
  2090. X    /* set moon diameter so it is centered within the bounding rectangle
  2091. X     * of the window.
  2092. X     * this code sets it to match the borders of the map view and makes
  2093. X     * the diameter even so it divides evenly.
  2094. X     */
  2095. X    md = ((w > h) ? MRAD*h/(MRAD+TOPMAR) : MRAD*w/(MRAD+LEFTMAR)) & (~1);
  2096. X    xb = (w - md)/2;
  2097. X    yb = (h - md)/2;
  2098. X
  2099. X    la1 = el >= 0.0 ? -90*64 : 90*64;
  2100. X    la2 = 180*64;
  2101. X    wid = fabs(md/2*cos(el))+0.5;
  2102. X    ta1 = el >= PI/2 || (el <= 0 && el >= -PI/2) ? 90*64 : -90*64;
  2103. X    ta2 = 180*64;
  2104. X
  2105. X    /* dsp, win, gc, x, y, w, h, start_ang, ang_extent */
  2106. X    /* draw the lit hemisphere to the limb */
  2107. X    XFillArc (dsp, pm, m_fgc, xb, yb, md, md, la1, la2);
  2108. X
  2109. X    /* draw the portion from the terminator to the meridian */
  2110. X    if (la1 < 0 && ta1 < 0 || la1 > 0 && ta1 > 0) {
  2111. X        /* crescent, so draw in background color */
  2112. X        XFillArc (dsp, pm, m_bgc, md/2-wid+xb, yb, 2*wid, md, ta1, ta2);
  2113. X    } else {
  2114. X        /* gibbous, so draw in foreground color */
  2115. X        XFillArc (dsp, pm, m_fgc, md/2-wid+xb, yb, 2*wid, md, ta1, ta2);
  2116. X    }
  2117. X
  2118. X    /* add in the background stars */
  2119. X    if (!stars || last_w != w || last_h != h) {
  2120. X        /* sprinkle NSTARS stars outside the moon's circle of radius r.
  2121. X         */
  2122. X        double rr = 0.25*md*md; /* = (md/2)*(md/2); */
  2123. X        int i;
  2124. X        if (stars)
  2125. X        XtFree ((char *)stars);
  2126. X        stars = (XPoint *) XtMalloc (NSTARS * sizeof(XPoint));
  2127. X        for (i = 0; i < NSTARS; ) {
  2128. X        x = ((rand() >> 2) & 0xfff) * (w-1) / 0xfff;
  2129. X        y = ((rand() >> 2) & 0xfff) * (h-1) / 0xfff;
  2130. X        /* compare the candidate y with the y on the ellipse at the
  2131. X         * candidate x to decide whether to draw the point.
  2132. X         */
  2133. X#define        SQR(x) ((x)*(x))
  2134. X        if (SQR(y-h/2) > rr - SQR(x-w/2)) {
  2135. X            stars[i].x = (short)x;
  2136. X            stars[i].y = (short)y;
  2137. X            i++;
  2138. X        }
  2139. X        }
  2140. X    }
  2141. X    XDrawPoints (dsp, pm, m_fgc, stars, NSTARS, CoordModeOrigin);
  2142. X
  2143. X    XCopyArea (dsp, pm, win, m_fgc, 0, 0, w, h, 0, 0);
  2144. X    XFreePixmap (dsp, pm);
  2145. X
  2146. X    last_w = w;
  2147. X    last_h = h;
  2148. X}
  2149. END_OF_FILE
  2150.   if test 14914 -ne `wc -c <'moonmenu.c'`; then
  2151.     echo shar: \"'moonmenu.c'\" unpacked with wrong size!
  2152.   fi
  2153.   # end of 'moonmenu.c'
  2154. fi
  2155. if test -f 'versionmenu.c' -a "${1}" != "-c" ; then 
  2156.   echo shar: Will not clobber existing file \"'versionmenu.c'\"
  2157. else
  2158.   echo shar: Extracting \"'versionmenu.c'\" \(15208 characters\)
  2159.   sed "s/^X//" >'versionmenu.c' <<'END_OF_FILE'
  2160. X/* code to manage the stuff on the version display.
  2161. X * first thing is our modification history, then code to put up the dialog.
  2162. X */
  2163. X
  2164. X/* add a note after each change.
  2165. X */
  2166. X
  2167. X/*
  2168. X * 2.4b 5/10    changed to using memcpy() instead of struct assign (for Alpha).
  2169. X * 2.4a 4/23    changed usage of time() (just needed for DEC's Alpha CPUs)
  2170. X * 2.4 4/21     fixed blank jup and sat views (unsigned).
  2171. X * 2.3 4/12    add ecliptic option to sky view.
  2172. X *     4/15    ephem.db: fix Yale names and improve asteroid a/n accuracy.
  2173. X *     4/20    add cursor location tracking to sky view.
  2174. X *        add "All labels" to sky view.
  2175. X *     4/21    add central cross-hair to Earth subsolar view.
  2176. X * 2.2 4/3/93    fixed infinite loop when assigning new objx/y with trails on.
  2177. X *        removed erroneous grid lines at some pointing directions.
  2178. X *        reinstate neglected nutation correction (!) cir_sky().
  2179. X *        just show blanks for sun's SnDst and Phase.
  2180. X *        fast buttons for 00:00:00 for UT and "Today" under the calendar.
  2181. X *        change Epoch-of-date prompts a bit.
  2182. X *        cleaned up type casting and add function prototypes.
  2183. X *        fixed bad mix of malloc() with XtFree() in db.c
  2184. X *     4/5    use pixmap in skyview for much smoother display.
  2185. X *     4/6    fix bug that pops up skyfilt when pop down skyview from main.
  2186. X *     4/7    improve conversion from helio period to daily motion.
  2187. X *     4/8    all datamenu fields are now fixed-width for more stable sizing.
  2188. X * 2.1 3/17/93    fixed bug in reading dates from the database.
  2189. X *              main menu fields are fixed-width for more stable size.
  2190. X * 2.0 3/15/93    major release
  2191. X * 2.0A 2/16/93    2.0 alpha put on export and notice posted to sci.astro.
  2192. X * 1.1        update sent to export.lcs.mit.edu
  2193. X * 1.0 2/24/92    baseline release to comp.sources.x and export.
  2194. X * 0.1 12/13/90 first viable beginnings. main three menus working ok.
  2195. X */
  2196. X
  2197. X#include <stdio.h>
  2198. X#include <ctype.h>
  2199. X#include <math.h>
  2200. X#if defined(__STDC__)
  2201. X#include <stdlib.h>
  2202. X#endif
  2203. X#include <X11/Xlib.h>
  2204. X#include <X11/keysym.h>
  2205. X#include <Xm/Xm.h>
  2206. X#include <Xm/Form.h>
  2207. X#include <Xm/Frame.h>
  2208. X#include <Xm/DrawingA.h>
  2209. X#include <Xm/Label.h>
  2210. X#include <Xm/PushB.h>
  2211. X#include <Xm/ToggleB.h>
  2212. X#include <Xm/Text.h>
  2213. X#include <Xm/Scale.h>
  2214. X#include "astro.h"
  2215. X#include "circum.h"
  2216. X#include "patchlevel.h"
  2217. X
  2218. X#if defined(__STDC__) || defined(__cplusplus)
  2219. X#define P_(s) s
  2220. X#else
  2221. X#define P_(s) ()
  2222. X#endif
  2223. X
  2224. Xextern void set_something P_((Widget w, char *resource, char *value));
  2225. Xextern void get_something P_((Widget w, char *resource, char *value));
  2226. X
  2227. Xvoid version P_((void));
  2228. Xvoid v_cursor P_((Cursor c));
  2229. Xstatic void v_makew P_((void));
  2230. Xstatic void fill_msg P_((Widget w));
  2231. Xstatic void v_unmap_cb P_((Widget w, XtPointer client, XtPointer call));
  2232. Xstatic void v_da_exp_cb P_((Widget w, XtPointer client, XtPointer call));
  2233. Xstatic void v_draw P_((void));
  2234. Xstatic void v_timer_cb P_((XtPointer client, XtIntervalId *id));
  2235. Xstatic void drawComet P_((Display *dsp, Window win, GC gc, double ang, int rad, int tlen, int w, int h));
  2236. Xstatic void drawPlanet P_((Display *dsp, Window win, GC gc, int sx, int sy, int w, int h));
  2237. Xstatic void v_define_fgc P_((void));
  2238. X
  2239. X#undef P_
  2240. X
  2241. Xextern Widget toplevel_w;
  2242. Xextern XtAppContext xe_app;
  2243. X
  2244. Xstatic char *msg[] = {
  2245. X"xephem - An Interactive Astronomical Ephemeris Program for X",
  2246. XPATCHLEVEL,
  2247. X"",
  2248. X"Copyright (c) 1990,1991,1992,1993 by Elwood Charles Downey",
  2249. X"",
  2250. X"Permission is granted to make and distribute copies of this program free of",
  2251. X"charge, provided the copyright notice and this permission notice are",
  2252. X"preserved on all copies.  All other rights reserved.  No representation is",
  2253. X"made about the suitability of this software for any purpose.  It is provided",
  2254. X"\"as is\" without express or implied warranty, to the extent permitted by",
  2255. X"applicable law.",
  2256. X};
  2257. X
  2258. X
  2259. X#define    NMSGR    (sizeof(msg)/sizeof(msg[0]))
  2260. X
  2261. X/* generate a random number between min and max, of the same type as the
  2262. X * highest type of either.
  2263. X */
  2264. X#define    RAND(min,max)    (((rand() & 0xfff)*((max)-(min))/0xfff) + min)
  2265. X
  2266. Xstatic Widget v_w;
  2267. Xstatic Widget vda_w;
  2268. Xstatic XtIntervalId v_timer_id;
  2269. Xstatic GC v_fgc;
  2270. Xstatic double rotrate;    /* rotation rate constant - filled on first manage */
  2271. X
  2272. X/* table of circular orbit radii to portray and the last screen coords.
  2273. X * the real solar system has planet radii from .3 to 30, but the 100:1 ratio is
  2274. X * so large we don't try and include everything.
  2275. X */
  2276. Xtypedef struct {
  2277. X    double r;        /* radius, AU */
  2278. X    double theta;    /* angle */
  2279. X    int x, y;        /* last X x,y coord drawn */
  2280. X} Orbit;
  2281. X
  2282. X#define    UNDEFX    (-1)        /* value of x when never drawn yet */
  2283. Xstatic Orbit orbit[] = {
  2284. X    {1.6, 0.0, UNDEFX, 0},
  2285. X    {5.4, 0.0, UNDEFX, 0},
  2286. X    {10., 0.0, UNDEFX, 0},
  2287. X    {19., 0.0, UNDEFX, 0},
  2288. X    {30., 0.0, UNDEFX, 0}
  2289. X};
  2290. X#define NORBIT    (sizeof(orbit)/sizeof(orbit[0]))
  2291. X#define    MAXRAD    (orbit[NORBIT-1].r)    /* N.B.use orbit[] with largest radius*/
  2292. X#define    MINRAD    (orbit[0].r)    /* N.B. use orbit[] with smallest radius */
  2293. X#define PR     4        /* radius of planet, pixels */
  2294. X#define    DT    100        /* pause between screen steps, ms */
  2295. X#define    NSTARS    100        /* number of background stars to sprinkle in */
  2296. X#define    DPI    30        /* inner orbit motion per step, degrees*/
  2297. X
  2298. X/* comet state and info */
  2299. X#define    CMAXPERI 30        /* max comet perihelion, pixels */
  2300. X#define    CMAXTAIL 50        /* max comet tail length, pixels */
  2301. X#define    CMINTAIL 3        /* min comet tail length, pixels */
  2302. X#define    CMAXDELA 20        /* max comet area per step, sqr pixels */
  2303. X#define    CMINDELA 10        /* min comet area per step, sqr pixels */
  2304. X
  2305. Xstatic double angle;        /* angle ccw from straight right, rads */
  2306. Xstatic double rotation;        /* whole scene rot, rads */
  2307. Xstatic int radius;        /* dist from sun, pixels (0 means undefined) */
  2308. Xstatic int taillen;        /* tail length, pixels */
  2309. Xstatic int delta_area;        /* change in area per step, sqr pixels */
  2310. Xstatic int perihelion;        /* min dist from sun, pixels */
  2311. Xstatic int maxtail;        /* max tail len (ie, tail@peri), pixels */
  2312. X
  2313. X/* called when mainmenu "on Version" help is selected.
  2314. X */
  2315. Xvoid
  2316. Xversion()
  2317. X{
  2318. X    /* make the version form if this is our first time.
  2319. X     * also take this opportunity to do things once to init the
  2320. X     * planet locations and set the rotation rate.
  2321. X     */
  2322. X    if (!v_w) {
  2323. X        int i;
  2324. X        v_makew();
  2325. X        for (i = 0; i < NORBIT; i++)
  2326. X        orbit[i].theta = RAND(0,2*PI);
  2327. X        rotrate = degrad(DPI)/pow(MINRAD/MAXRAD, -3./2.);
  2328. X    }
  2329. X        
  2330. X    /* toggle whether up now.
  2331. X     * autoUnmanage can bring back down too.
  2332. X     */
  2333. X    if (XtIsManaged(v_w))
  2334. X        XtUnmanageChild (v_w);
  2335. X    else
  2336. X        XtManageChild (v_w);
  2337. X}
  2338. X
  2339. X/* called to put up or remove the watch cursor.  */
  2340. Xvoid
  2341. Xv_cursor (c)
  2342. XCursor c;
  2343. X{
  2344. X    Window win;
  2345. X
  2346. X    if (v_w && (win = XtWindow(v_w))) {
  2347. X        Display *dsp = XtDisplay(v_w);
  2348. X        if (c)
  2349. X        XDefineCursor (dsp, win, c);
  2350. X        else
  2351. X        XUndefineCursor (dsp, win);
  2352. X    }
  2353. X}
  2354. X
  2355. X/* make the v_w widget.
  2356. X */
  2357. Xstatic void
  2358. Xv_makew()
  2359. X{
  2360. X    Widget ok_w;
  2361. X    Widget frame_w;
  2362. X    Widget text_w;
  2363. X    XmString str;
  2364. X    Arg args[20];
  2365. X    int n;
  2366. X
  2367. X    /* create form */
  2368. X    n = 0;
  2369. X    XtSetArg (args[n], XmNresizePolicy, XmRESIZE_ANY); n++;
  2370. X    XtSetArg (args[n], XmNautoUnmanage, True); n++;
  2371. X    XtSetArg (args[n], XmNhorizontalSpacing, 5); n++;
  2372. X    XtSetArg (args[n], XmNverticalSpacing, 5); n++;
  2373. X    v_w = XmCreateFormDialog (toplevel_w, "Version", args, n);
  2374. X    XtAddCallback (v_w, XmNunmapCallback, v_unmap_cb, 0);
  2375. X
  2376. X    /* set some stuff in the parent DialogShell.
  2377. X     * setting XmNdialogTitle in the Form didn't work..
  2378. X     */
  2379. X    n = 0;
  2380. X    XtSetArg (args[n], XmNtitle, "xephem Version"); n++;
  2381. X    XtSetValues (XtParent(v_w), args, n);
  2382. X
  2383. X    /* make text widget for the version info */
  2384. X
  2385. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2386. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  2387. X    XtSetArg (args[n], XmNbottomPosition, 50); n++;
  2388. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2389. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2390. X    XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
  2391. X    XtSetArg (args[n], XmNeditable, False); n++;
  2392. X    XtSetArg (args[n], XmNcolumns, 80); n++;
  2393. X    XtSetArg (args[n], XmNrows, NMSGR); n++;
  2394. X    text_w = XmCreateScrolledText (v_w, "VText", args, n);
  2395. X    fill_msg (text_w);
  2396. X    XtManageChild (text_w);
  2397. X
  2398. X    /* make the "Ok" push button */
  2399. X
  2400. X    str = XmStringCreate("Ok", XmSTRING_DEFAULT_CHARSET);
  2401. X    n = 0;
  2402. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2403. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2404. X    XtSetArg (args[n], XmNshowAsDefault, True); n++;
  2405. X    XtSetArg (args[n], XmNlabelString, str); n++;
  2406. X    ok_w = XmCreatePushButton (v_w, "VOk", args, n);
  2407. X    XtManageChild (ok_w);
  2408. X    XmStringFree (str);
  2409. X    set_something (v_w, XmNdefaultButton, (char *)ok_w);
  2410. X
  2411. X    /* make a frame for the drawing area */
  2412. X
  2413. X    n = 0;
  2414. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2415. X    XtSetArg (args[n], XmNtopWidget, XtParent(text_w)); n++;
  2416. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  2417. X    XtSetArg (args[n], XmNbottomWidget, ok_w); n++;
  2418. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  2419. X    XtSetArg (args[n], XmNleftPosition, 20); n++;
  2420. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  2421. X    XtSetArg (args[n], XmNrightPosition, 80); n++;
  2422. X    XtSetArg (args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
  2423. X    frame_w = XmCreateFrame (v_w, "VFrame", args, n);
  2424. X    XtManageChild (frame_w);
  2425. X
  2426. X    /* make a drawing area for drawing the solar system */
  2427. X
  2428. X    n = 0;
  2429. X    vda_w = XmCreateDrawingArea (frame_w, "VersionMap", args, n);
  2430. X    XtAddCallback (vda_w, XmNexposeCallback, v_da_exp_cb, 0);
  2431. X    XtAddCallback (vda_w, XmNresizeCallback, v_da_exp_cb, 0);
  2432. X    XtManageChild (vda_w);
  2433. X}
  2434. X
  2435. Xstatic void
  2436. Xfill_msg (w)
  2437. XWidget w;
  2438. X{
  2439. X    char m[100*NMSGR], *mp = m;
  2440. X    int i;
  2441. X
  2442. X    /* Generate message to display as one string */
  2443. X    for (i = 0; i < NMSGR; i++) {
  2444. X        (void) sprintf (mp, "%*s%s\n", (78 - (int)strlen(msg[i]))/2, "",
  2445. X                                    msg[i]);
  2446. X        mp += strlen(mp);
  2447. X    }
  2448. X
  2449. X    /* remove final \n to avoid extra blank line at end */
  2450. X    *--mp = '\0';
  2451. X
  2452. X    XmTextSetString (w, m);
  2453. X}
  2454. X
  2455. X/* version dialog is going away.
  2456. X * stop the rotation timer.
  2457. X */
  2458. X/* ARGSUSED */
  2459. Xstatic void
  2460. Xv_unmap_cb (w, client, call)
  2461. XWidget w;
  2462. XXtPointer client;
  2463. XXtPointer call;
  2464. X{
  2465. X    if (v_timer_id) {
  2466. X        XtRemoveTimeOut (v_timer_id);
  2467. X        v_timer_id = 0;
  2468. X    }
  2469. X}
  2470. X
  2471. X/* expose version drawing area.
  2472. X * redraw the scene to the (new?) size.
  2473. X */
  2474. X/* ARGSUSED */
  2475. Xstatic void
  2476. Xv_da_exp_cb (w, client, call)
  2477. XWidget w;
  2478. XXtPointer client;
  2479. XXtPointer call;
  2480. X{
  2481. X    XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
  2482. X
  2483. X    switch (c->reason) {
  2484. X    case XmCR_RESIZE:
  2485. X        /* seems we can get one resize before the first expose.
  2486. X         * hence, we don't have a good window to use yet. just let it
  2487. X         * go; we'll get the expose soon.
  2488. X         */
  2489. X        if (!XtWindow(w))
  2490. X        return;
  2491. X        break;
  2492. X    case XmCR_EXPOSE: {
  2493. X        XExposeEvent *e = &c->event->xexpose;
  2494. X        /* wait for the last in the series */
  2495. X        if (e->count != 0)
  2496. X        return;
  2497. X        break;
  2498. X        }
  2499. X    default:
  2500. X        printf ("Unexpected v_w event. type=%d\n", c->reason);
  2501. X        exit(1);
  2502. X    }
  2503. X
  2504. X    v_draw();
  2505. X}
  2506. X
  2507. Xstatic void
  2508. Xv_draw()
  2509. X{
  2510. X    Display *dsp = XtDisplay(vda_w);
  2511. X    Window win = XtWindow(vda_w);
  2512. X    unsigned int w, h;
  2513. X    Window root;
  2514. X    int x, y;
  2515. X    unsigned int bw, d;
  2516. X    int i;
  2517. X
  2518. X    if (!v_fgc)
  2519. X        v_define_fgc();
  2520. X
  2521. X    XGetGeometry(dsp, win, &root, &x, &y, &w, &h, &bw, &d);
  2522. X    XClearWindow (dsp, win);
  2523. X
  2524. X    /* draw the orbit ellipsii and forget last drawn locs */
  2525. X    for (i = 0; i < NORBIT; i++) {
  2526. X        int lx, ty;    /* left and top x */
  2527. X        int nx, ny; /* width and height */
  2528. X        lx = w/2 - orbit[i].r/MAXRAD*w/2 + 0.5;
  2529. X        nx = orbit[i].r/MAXRAD*w + 0.5;
  2530. X        ty = h/2 - orbit[i].r/MAXRAD*h/2 + 0.5;
  2531. X        ny = orbit[i].r/MAXRAD*h + 0.5;
  2532. X        XDrawArc (dsp, win, v_fgc, lx, ty, nx-1, ny-1, 0, 360*64);
  2533. X        orbit[i].x = UNDEFX;
  2534. X    }
  2535. X
  2536. X    /* forget the comet */
  2537. X    radius = 0;
  2538. X
  2539. X    /* draw sun at the center */
  2540. X    drawPlanet (dsp, win, v_fgc, w/2-PR, h/2-PR, 2*PR-1, 2*PR-1);
  2541. X
  2542. X    /* draw some background stars */
  2543. X    for (i = 0; i < NSTARS; i++) {
  2544. X        int sx, sy;
  2545. X        sx = RAND(0,w-1);
  2546. X        sy = RAND(0,h-1);
  2547. X        XDrawPoint (dsp, win, v_fgc, sx, sy);
  2548. X    }
  2549. X
  2550. X    if (!v_timer_id)
  2551. X        v_timer_cb (0, 0);
  2552. X
  2553. X}
  2554. X
  2555. X/* called whenever the timer goes off.
  2556. X * we advance all the planets, draw any that have moved at least a few
  2557. X * pixels, and restart a timer.
  2558. X */
  2559. X/* ARGSUSED */
  2560. Xstatic void
  2561. Xv_timer_cb (client, id)
  2562. XXtPointer client;
  2563. XXtIntervalId *id;
  2564. X{
  2565. X    Display *dsp = XtDisplay(vda_w);
  2566. X    Window win = XtWindow(vda_w);
  2567. X    unsigned int w, h;
  2568. X    Window root;
  2569. X    int x, y;
  2570. X    unsigned int bw, d;
  2571. X    int i;
  2572. X
  2573. X    XGetGeometry(dsp, win, &root, &x, &y, &w, &h, &bw, &d);
  2574. X
  2575. X    for (i = 0; i < NORBIT; i++) {
  2576. X        int px, py;    /* planets new center position */
  2577. X        double f = orbit[i].r/MAXRAD;    /* fraction of largest radius */
  2578. X        orbit[i].theta += rotrate*pow(f, -3./2.);
  2579. X        px = w/2 + cos(orbit[i].theta)*w*f/2 + 0.5;
  2580. X        py = h/2 - sin(orbit[i].theta)*h*f/2 + 0.5;
  2581. X        if (px != orbit[i].x || py != orbit[i].y) {
  2582. X        /* erase then redraw at new pos, using the XOR GC */
  2583. X        if (orbit[i].x != UNDEFX)
  2584. X            drawPlanet (dsp, win, v_fgc,
  2585. X                orbit[i].x-PR, orbit[i].y-PR, 2*PR-1, 2*PR-1);
  2586. X        drawPlanet (dsp, win, v_fgc, px-PR, py-PR, 2*PR-1, 2*PR-1);
  2587. X        orbit[i].x = px;
  2588. X        orbit[i].y = py;
  2589. X        }
  2590. X    }
  2591. X
  2592. X    /* erase last comet position.
  2593. X     * N.B. use radius == 0 to mean the very first loop.
  2594. X     */
  2595. X    if (radius != 0)
  2596. X        drawComet (dsp, win, v_fgc, angle, radius, taillen, w, h);
  2597. X
  2598. X    /* comet is definitely outside scene, set fresh initial conditions.
  2599. X     */
  2600. X    if (radius <= 0 || radius > (w+h)/2) {
  2601. X        radius = (w+h)/2;
  2602. X        rotation = RAND(0,2*PI);
  2603. X        perihelion = RAND(PR,CMAXPERI);
  2604. X        maxtail = RAND(CMINTAIL,CMAXTAIL);
  2605. X        delta_area = RAND(CMINDELA,CMAXDELA);
  2606. X        angle = acos(1.0 - 2.0*perihelion/radius) + rotation;
  2607. X#if 0
  2608. X        printf ("initial rad=%d rot=%g peri=%d maxt=%d da=%d angle=%g\n",
  2609. X            radius, rotation, perihelion, maxtail, delta_area, angle);
  2610. X#endif
  2611. X    }
  2612. X
  2613. X    /* recompute next step location and draw new comet
  2614. X     */
  2615. X#if 0
  2616. X    printf ("rad=%d rot=%g peri=%d maxt=%d da=%d angle=%g\n",
  2617. X            radius, rotation, perihelion, maxtail, delta_area, angle);
  2618. X#endif
  2619. X    angle += (double)delta_area/(radius*radius);
  2620. X    radius = 2*perihelion/(1.0 - cos(angle - rotation));
  2621. X    taillen = (maxtail*perihelion*perihelion)/(radius*radius);
  2622. X    drawComet (dsp, win, v_fgc, angle, radius, taillen, w, h);
  2623. X
  2624. X    v_timer_id = XtAppAddTimeOut (xe_app, DT, v_timer_cb, 0);
  2625. X}
  2626. X
  2627. X/* draw the comet
  2628. X */
  2629. Xstatic void
  2630. XdrawComet (dsp, win, gc, ang, rad, tlen, w, h)
  2631. XDisplay *dsp;
  2632. XWindow win;
  2633. XGC gc;
  2634. Xdouble ang;    /* desired angle ccw from +x, in rads */
  2635. Xint rad;    /* in pixels from center */
  2636. Xint tlen;    /* length of tail, in pixels */
  2637. Xint w, h;    /* window width and height */
  2638. X{
  2639. X    double ca, sa;
  2640. X    int sx, sy;
  2641. X    int ex, ey;
  2642. X
  2643. X    if (tlen < CMINTAIL)
  2644. X        tlen = CMINTAIL;
  2645. X
  2646. X    /* angle is made <0 to get ccw rotation with X's y-down coord system */
  2647. X    ang = -ang;
  2648. X    ca = cos(ang);
  2649. X    sa = sin(ang);
  2650. X
  2651. X    sx = w/2 + rad * ca;
  2652. X    sy = h/2 + rad * sa;
  2653. X    ex = w/2 + (rad+tlen) * ca;
  2654. X    ey = h/2 + (rad+tlen) * sa;
  2655. X
  2656. X    XDrawLine (dsp, win, gc, sx, sy, ex, ey);
  2657. X}
  2658. X
  2659. X/* draw the planet.
  2660. X */
  2661. Xstatic void
  2662. XdrawPlanet (dsp, win, gc, sx, sy, w, h)
  2663. XDisplay *dsp;
  2664. XWindow win;
  2665. XGC gc;
  2666. Xint sx, sy, w, h;
  2667. X{
  2668. X    XFillArc (dsp, win, gc, sx, sy, w, h, 0, 360*64);
  2669. X}
  2670. X
  2671. Xstatic void
  2672. Xv_define_fgc()
  2673. X{
  2674. X    Display *dsp = XtDisplay(vda_w);
  2675. X    Window win = XtWindow(vda_w);
  2676. X    XGCValues gcv;
  2677. X    unsigned int gcm;
  2678. X    Pixel fg, bg;
  2679. X
  2680. X    gcm = GCForeground | GCFunction;
  2681. X    get_something (vda_w, XmNforeground, (char *)&fg);
  2682. X    get_something (vda_w, XmNbackground, (char *)&bg);
  2683. X    gcv.foreground = fg ^ bg;
  2684. X    gcv.function = GXxor;
  2685. X    v_fgc = XCreateGC (dsp, win, gcm, &gcv);
  2686. X}
  2687. END_OF_FILE
  2688.   if test 15208 -ne `wc -c <'versionmenu.c'`; then
  2689.     echo shar: \"'versionmenu.c'\" unpacked with wrong size!
  2690.   fi
  2691.   # end of 'versionmenu.c'
  2692. fi
  2693. echo shar: End of archive 20 \(of 21\).
  2694. cp /dev/null ark20isdone
  2695. MISSING=""
  2696. 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
  2697.     if test ! -f ark${I}isdone ; then
  2698.     MISSING="${MISSING} ${I}"
  2699.     fi
  2700. done
  2701. if test "${MISSING}" = "" ; then
  2702.     echo You have unpacked all 21 archives.
  2703.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2704.     echo Building ephem.db
  2705.     cat > ephem.db.Z.uu ephem.db.Z.uu.?
  2706.     uudecode ephem.db.Z.uu
  2707.     rm ephem.db.Z.uu ephem.db.Z.uu.?
  2708.     uncompress ephem.db.Z
  2709.     echo Building skyviewmenu.c
  2710.     cat > skyviewmenu.c skyviewmenu.c.?
  2711.     rm skyviewmenu.c.?
  2712.     echo Building smallfm.xbm
  2713.     cat > smallfm.xbm smallfm.xbm.?
  2714.     rm smallfm.xbm.?
  2715. else
  2716.     echo You still must unpack the following archives:
  2717.     echo "        " ${MISSING}
  2718. fi
  2719. exit 0
  2720. exit 0 # Just in case...
  2721. -- 
  2722.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  2723. \X/  Amiga - The only way to fly!      |
  2724.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  2725.   casual observer..."                  |
  2726.