home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume16 / xephem / part09 < prev    next >
Encoding:
Text File  |  1992-03-05  |  50.2 KB  |  1,624 lines

  1. Newsgroups: comp.sources.x
  2. Path: uunet!think.com!mips!msi!dcmartin
  3. From: e_downey@hwking.cca.cr.rockwell.com (Elwood Downey)
  4. Subject: v16i120: xephem - astronomical ephemeris program., Part09/24
  5. Message-ID: <1992Mar6.135407.2348@msi.com>
  6. Originator: dcmartin@fascet
  7. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  8. Organization: Molecular Simulations, Inc.
  9. References: <csx-16i112-xephem@uunet.UU.NET>
  10. Date: Fri, 6 Mar 1992 13:54:07 GMT
  11. Approved: dcmartin@msi.com
  12.  
  13. Submitted-by: e_downey@hwking.cca.cr.rockwell.com (Elwood Downey)
  14. Posting-number: Volume 16, Issue 120
  15. Archive-name: xephem/part09
  16.  
  17. # this is part.09 (part 9 of a multipart archive)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file risetmenu.c continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 9; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping risetmenu.c'
  35. else
  36. echo 'x - continuing file risetmenu.c'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'risetmenu.c' &&
  38. X        str = XmStringCreate ("Toggle On/off", XmSTRING_DEFAULT_CHARSET);
  39. X        n = 0;
  40. X        XtSetArg (args[n], XmNlabelString, str); n++;
  41. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  42. X        XtSetArg (args[n], XmNtopPosition, r2ypos(R_CONTROL)); n++;
  43. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  44. X        XtSetArg (args[n], XmNleftPosition, 650); n++;
  45. X        XtSetArg(args[n], XmNrecomputeSize, False); n++;
  46. X        w = XmCreatePushButtonGadget (risetform_w, "RisetToggle", args, n);
  47. X        XtAddCallback (w, XmNactivateCallback, rm_toggle_cb, 0);
  48. X        XtManageChild (w);
  49. X        XmStringFree (str);
  50. X
  51. X        /* make the help button */
  52. X        str = XmStringCreate ("Help", XmSTRING_DEFAULT_CHARSET);
  53. X        n = 0;
  54. X        XtSetArg (args[n], XmNlabelString, str); n++;
  55. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  56. X        XtSetArg (args[n], XmNtopPosition, r2ypos(R_CONTROL)); n++;
  57. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  58. X        XtSetArg (args[n], XmNrightPosition, 1000); n++;
  59. X        w = XmCreatePushButtonGadget (risetform_w, "RisetHelp", args, n);
  60. X        XtAddCallback (w, XmNactivateCallback, rm_help_cb, 0);
  61. X        XtManageChild (w);
  62. X        XmStringFree (str);
  63. X    }
  64. X    
  65. X    if (XtIsManaged(risetform_w))
  66. X        XtUnmanageChild (risetform_w);
  67. X    else {
  68. X        XtManageChild (risetform_w);
  69. X        rm_update (mm_get_now(), 1);
  70. X        rm_set_buttons(rm_selecting);
  71. X    }
  72. }
  73. X
  74. /* used by main to set the initial state of the objects to be on. */
  75. rm_set_objs_on (mask)
  76. int mask;
  77. {
  78. X    objs_on = mask;
  79. }
  80. X
  81. /* called by other menus as they want to hear from our buttons or not.
  82. X * the "on"s and "off"s stack - only really redo the buttons if it's the
  83. X * first on or the last off.
  84. X */
  85. rm_selection_mode (whether)
  86. int whether;    /* whether setting up for plotting or for not plotting */
  87. {
  88. X    rm_selecting += whether ? 1 : -1;
  89. X
  90. X    if (risetform_w && XtIsManaged(risetform_w))
  91. X        if (whether && rm_selecting == 1     /* first one to want on */
  92. X        || !whether && rm_selecting == 0 /* last one to want off */)
  93. X        rm_set_buttons (whether);
  94. }
  95. X
  96. /* go through all the buttons just pickable for plotting and set whether they
  97. X * should appear to look like buttons or just flat labels.
  98. X */
  99. static
  100. rm_set_buttons (whether)
  101. int whether;
  102. {
  103. X    static Arg look_like_button[] = {
  104. X        {XmNshadowThickness, (XtArgVal) 2},
  105. X        {XmNfillOnArm, (XtArgVal) True},
  106. X    };
  107. X    static Arg look_like_label[] = {
  108. X        {XmNshadowThickness, (XtArgVal) 0},
  109. X        {XmNfillOnArm, (XtArgVal) False},
  110. X    };
  111. X    FieldMap *fp;
  112. X
  113. X    for (fp = rm_field_map; fp < LFM; fp++)
  114. X        if (whether && fp->how & PLT || !whether && fp->how & CHG)
  115. X        XtSetValues (fp->w,look_like_button,XtNumber(look_like_button));
  116. X        else
  117. X        XtSetValues (fp->w,look_like_label,XtNumber(look_like_label));
  118. }
  119. X
  120. /* callback from any of the riset menu buttons being activated.
  121. X * if it's a CHGable field, ask op for a new setting.
  122. X */
  123. void
  124. rm_activate_cb (w, client, call)
  125. Widget w;
  126. caddr_t client;
  127. caddr_t call;
  128. {
  129. X    FieldMap *fp = (FieldMap *)client;
  130. X
  131. X    if (rm_selecting) {
  132. X        plt_selection (fp);
  133. X        lst_selection (fp);
  134. X        srch_selection (fp);
  135. X    }
  136. }
  137. X
  138. /* callback from the "toggle on/off" push button.
  139. X * toggle each object on or off.
  140. X * basically we just force set all the planet buttons and let their callbacks
  141. X *   do the real work.
  142. X */
  143. static void
  144. rm_toggle_cb (w, client, call)
  145. Widget w;
  146. caddr_t client;
  147. caddr_t call;
  148. {
  149. X    int p;
  150. X
  151. X    for (p = nxtbody(-1); p != -1; p = nxtbody(p)) {
  152. X        int state = XmToggleButtonGadgetGetState (objs_w[p]);
  153. X        XmToggleButtonGadgetSetState (objs_w[p], !state, True/*invoke cb*/);
  154. X    }
  155. }
  156. X
  157. /* callback from the Close button.
  158. X */
  159. void
  160. rm_close_cb (w, client, call)
  161. Widget w;
  162. caddr_t client;
  163. caddr_t call;
  164. {
  165. X    XtUnmanageChild (risetform_w);
  166. }
  167. X
  168. /* callback from the Help button.
  169. X */
  170. void
  171. rm_help_cb (w, client, call)
  172. Widget w;
  173. caddr_t client;
  174. caddr_t call;
  175. {
  176. X    static char *msg[] = {
  177. "This view displays the rise, transit and set times and the rise and setting",
  178. "azimuths of each object. Rise and set events are defined when the upper limb",
  179. "of the object is at the horizon.",
  180. "",
  181. "The \"Adaptive\" model is an iteration based on altitude. The \"Standard\"",
  182. "model uses a nominal 32 arc minutes refraction correction."
  183. };
  184. X
  185. X    hlp_dialog ("Rise/Set Table", msg, sizeof(msg)/sizeof(msg[0]));
  186. }
  187. X
  188. /* callback for the horizon model radiobox.
  189. X */
  190. void
  191. rm_hzn_cb (w, client, call)
  192. Widget w;
  193. caddr_t client;
  194. caddr_t call;
  195. {
  196. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  197. X    if (t->set && hzn != (int)client) {
  198. X        hzn = (int)client;
  199. X        rm_update (mm_get_now(), 1);
  200. X    }
  201. }
  202. X
  203. static
  204. rm_erase_obj (p)
  205. int p;
  206. {
  207. X    FieldMap *fp;
  208. X    int r = bodyrow[p];
  209. X
  210. X    for (fp = rm_field_map; fp < LFM; fp++)
  211. X        if (f2r(fp->id) == r)
  212. X        f_string (fp->w, "");
  213. }
  214. X
  215. /* callback for each of the object on/off toggle buttons.
  216. X */
  217. void
  218. rm_obj_cb (w, client, call)
  219. Widget w;
  220. caddr_t client;
  221. caddr_t call;
  222. {
  223. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  224. X    int p = (int)client;
  225. X
  226. X    if (t->set && !(objs_on & (1<<p))) {
  227. X        objs_on |= 1<<p;
  228. X        rm_compute (p, 1, mm_get_now());
  229. X    } else if (!t->set && (objs_on & (1<<p))) {
  230. X        objs_on &= ~(1<<p);
  231. X        rm_erase_obj (p);
  232. X    }
  233. }
  234. X
  235. /* called to recompute and fill in values for the menu.
  236. X * don't bother if it doesn't exist or is unmanaged now.
  237. X * TODO: when figure out how to leave loc unchanged, do this unmanaged.
  238. X */
  239. rm_update (np, how_much)
  240. Now *np;
  241. int how_much;
  242. {
  243. X    int p;
  244. X    if (risetform_w && (how_much || XtIsManaged(risetform_w)))
  245. X        for (p = nxtbody(-1); p != -1; p = nxtbody(p))
  246. X        if (objs_on & 1<<p)
  247. X            rm_compute (p, how_much, np);
  248. }
  249. X
  250. X
  251. /* compute and print body info in riset menu format */
  252. static
  253. rm_compute (p, force, np)
  254. int p;        /* which body, as in astro.h/moreobjs.h defines */
  255. int force;    /* whether to print for sure or only if things have changed */
  256. Now *np;
  257. {
  258. X    static char plus[] = "+";
  259. X    double ltr, lts, ltt, azr, azs, altt;
  260. X    int row = bodyrow[p];
  261. X    int status;
  262. X    double tmp;
  263. X    int today_tup = 0;
  264. X
  265. X    /* always recalc OBJX and Y since we don't know it's the same object */
  266. X    if (!riset_cir (p, np, p==OBJX || p==OBJY, hzn,
  267. X        <r, <s, <t, &azr, &azs, &altt, &status) && !force)
  268. X        return;
  269. X
  270. X    rm_erase_obj (p);
  271. X
  272. X    if (status & RS_ERROR) {
  273. X        /* can not find where body is! */
  274. X        f_string (fw(row,C_RISETM), "Error");
  275. X        return;
  276. X    }
  277. X    if (status & RS_CIRCUMPOLAR) {
  278. X        /* body is up all day */
  279. X        f_string (fw(row,C_RISETM), "CPolr");
  280. X        if (status & RS_NOTRANS)
  281. X        f_string (fw(row,C_TRANSTM), "NoTrn");
  282. X        else {
  283. X        f_mtime (fw(row,C_TRANSTM), ltt);
  284. X        if (status & RS_2TRANS)
  285. X            f_string (fw(row,C_TRANSTM+TIME_WIDTH), plus);
  286. X        f_angle (fw(row,C_TRANSALT), altt);
  287. X        }
  288. X        f_string (fw(row,C_TUP), "24:00"); /*f_mtime() changes to 0:00 */
  289. X        return;
  290. X    }
  291. X    if (status & RS_NEVERUP) {
  292. X        /* body never up at all today */
  293. X        f_string (fw(row,C_RISETM), "NvrUp");
  294. X        f_mtime (fw(row,C_TUP), 0.0);
  295. X        return;
  296. X    }
  297. X
  298. X    if (status & RS_NORISE) {
  299. X        /* object does not rise as such today */
  300. X        f_string (fw(row,C_RISETM), "NvrRs");
  301. X        ltr = 0.0; /* for TUP */
  302. X        today_tup = 1;
  303. X    } else {
  304. X        f_mtime (fw(row,C_RISETM), ltr);
  305. X        if (status & RS_2RISES) {
  306. X        /* object rises more than once today */
  307. X        f_string (fw(row,C_RISETM+TIME_WIDTH), plus);
  308. X        }
  309. X        f_angle (fw(row,C_RISEAZ), azr);
  310. X    }
  311. X
  312. X    if (status & RS_NOTRANS)
  313. X        f_string (fw(row,C_TRANSTM), "NoTrn");
  314. X    else {
  315. X        f_mtime (fw(row,C_TRANSTM), ltt);
  316. X        if (status & RS_2TRANS)
  317. X        f_string (fw(row,C_TRANSTM+TIME_WIDTH), plus);
  318. X        f_angle (fw(row,C_TRANSALT), altt);
  319. X    }
  320. X
  321. X    if (status & RS_NOSET) {
  322. X        /* object does not set as such today */
  323. X        f_string (fw(row,C_SETTM), "NvrSt");
  324. X        lts = 24.0;    /* for TUP */
  325. X        today_tup = 1;
  326. X    } else {
  327. X        f_mtime (fw(row,C_SETTM), lts);
  328. X        if (status & RS_2SETS)
  329. X        f_string (fw(row,C_SETTM+TIME_WIDTH), plus);
  330. X        f_angle (fw(row,C_SETAZ), azs);
  331. X    }
  332. X
  333. X    tmp = lts - ltr;
  334. X    if (tmp < 0)
  335. X        tmp = 24.0 + tmp;
  336. X    f_mtime (fw(row,C_TUP), tmp);
  337. X    if (today_tup)
  338. X        f_string (fw(row,C_TUP+TIME_WIDTH), plus);
  339. }
  340. SHAR_EOF
  341. echo 'File risetmenu.c is complete' &&
  342. chmod 0644 risetmenu.c ||
  343. echo 'restore of risetmenu.c failed'
  344. Wc_c="`wc -c < 'risetmenu.c'`"
  345. test 23357 -eq "$Wc_c" ||
  346.     echo 'risetmenu.c: original size 23357, current size' "$Wc_c"
  347. rm -f _shar_wnt_.tmp
  348. fi
  349. # ============= sepmenu.c ==============
  350. if test -f 'sepmenu.c' -a X"$1" != X"-c"; then
  351.     echo 'x - skipping sepmenu.c (File already exists)'
  352.     rm -f _shar_wnt_.tmp
  353. else
  354. > _shar_wnt_.tmp
  355. echo 'x - extracting sepmenu.c (Text)'
  356. sed 's/^X//' << 'SHAR_EOF' > 'sepmenu.c' &&
  357. /* code to manage the stuff on the "separations" menu.
  358. X */
  359. X
  360. #include <stdio.h>
  361. #include <ctype.h>
  362. #include <math.h>
  363. #ifdef VMS
  364. #include <stdlib.h>
  365. #endif
  366. #include <X11/Xlib.h>
  367. #include <Xm/Xm.h>
  368. #include <Xm/Form.h>
  369. #include <Xm/LabelG.h>
  370. #include <Xm/PushBG.h>
  371. #include <Xm/ToggleBG.h>
  372. #include <Xm/RowColumn.h>
  373. #include "fieldmap.h"
  374. #include "astro.h"
  375. #include "circum.h"
  376. #include "moreobjs.h"
  377. X
  378. extern char *strncpy();
  379. extern char *getenv();
  380. extern Now *mm_get_now();
  381. extern char *objname[];
  382. extern Widget toplevel_w;
  383. extern XmString str_width();
  384. #define    XtD    XtDisplay(toplevel_w)
  385. X
  386. /* locations of each field.
  387. X * these are in terms of a 1-based row/col on a 24x80 alpha screen, for
  388. X * historical reasons.
  389. X */
  390. #define    NR    14
  391. #define    NC    102
  392. X
  393. /* planet rows */
  394. #define    R_PLANTAB    (1)
  395. #define    R_SUN        (R_PLANTAB+1)
  396. #define    R_MOON        (R_PLANTAB+2)
  397. #define    R_MERCURY    (R_PLANTAB+3)
  398. #define    R_VENUS        (R_PLANTAB+4)
  399. #define    R_MARS        (R_PLANTAB+5)
  400. #define    R_JUPITER    (R_PLANTAB+6)
  401. #define    R_SATURN    (R_PLANTAB+7)
  402. #define    R_URANUS    (R_PLANTAB+8)
  403. #define    R_NEPTUNE    (R_PLANTAB+9)
  404. #define    R_PLUTO        (R_PLANTAB+10)
  405. #define    R_OBJX        (R_PLANTAB+11)
  406. #define    R_OBJY        (R_PLANTAB+12)
  407. #define    R_CONTROL    (R_PLANTAB+13)
  408. X
  409. #define    C_OBJ        1
  410. X
  411. /* menu 3 items */
  412. #define    C_SUN        5
  413. #define    C_MOON        13
  414. #define    C_MERCURY    21
  415. #define    C_VENUS        29
  416. #define    C_MARS        37
  417. #define    C_JUPITER    45
  418. #define    C_SATURN    53
  419. #define    C_URANUS    61
  420. #define    C_NEPTUNE    69
  421. #define    C_PLUTO        77
  422. #define    C_OBJX        85
  423. #define    C_OBJY        93
  424. X
  425. #define    SEP_WIDTH    6
  426. X
  427. static FieldMap sm_field_map[] = {
  428. X    {mkid(R_JUPITER,C_MARS), PLT, SEP_WIDTH, 0, "Jup.Mars"},
  429. X    {mkid(R_JUPITER,C_MERCURY), PLT, SEP_WIDTH, 0, "Jup.Merc"},
  430. X    {mkid(R_JUPITER,C_MOON), PLT, SEP_WIDTH, 0, "Jup.Moon"},
  431. X    {mkid(R_JUPITER,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Jup.Nep"},
  432. X    {mkid(R_JUPITER,C_OBJX), PLT, SEP_WIDTH, 0, "Jup.ObjX"},
  433. X    {mkid(R_JUPITER,C_OBJY), PLT, SEP_WIDTH, 0, "Jup.ObjY"},
  434. X    {mkid(R_JUPITER,C_PLUTO), PLT, SEP_WIDTH, 0, "Jup.Pluto"},
  435. X    {mkid(R_JUPITER,C_SATURN), PLT, SEP_WIDTH, 0, "Jup.Sat"},
  436. X    {mkid(R_JUPITER,C_SUN), PLT, SEP_WIDTH, 0, "Jup.Sun"},
  437. X    {mkid(R_JUPITER,C_URANUS), PLT, SEP_WIDTH, 0, "Jup.Uranus"},
  438. X    {mkid(R_JUPITER,C_VENUS), PLT, SEP_WIDTH, 0, "Jup.Ven"},
  439. X    {mkid(R_MARS,C_JUPITER), PLT, SEP_WIDTH, 0, "Mars.Jup"},
  440. X    {mkid(R_MARS,C_MERCURY), PLT, SEP_WIDTH, 0, "Mars.Merc"},
  441. X    {mkid(R_MARS,C_MOON), PLT, SEP_WIDTH, 0, "Mars.Moon"},
  442. X    {mkid(R_MARS,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Mars.Nep"},
  443. X    {mkid(R_MARS,C_OBJX), PLT, SEP_WIDTH, 0, "Mars.ObjX"},
  444. X    {mkid(R_MARS,C_OBJY), PLT, SEP_WIDTH, 0, "Mars.ObjY"},
  445. X    {mkid(R_MARS,C_PLUTO), PLT, SEP_WIDTH, 0, "Mars.Pluto"},
  446. X    {mkid(R_MARS,C_SATURN), PLT, SEP_WIDTH, 0, "Mars.Sat"},
  447. X    {mkid(R_MARS,C_SUN), PLT, SEP_WIDTH, 0, "Mars.Sun"},
  448. X    {mkid(R_MARS,C_URANUS), PLT, SEP_WIDTH, 0, "Mars.Uranus"},
  449. X    {mkid(R_MARS,C_VENUS), PLT, SEP_WIDTH, 0, "Mars.Ven"},
  450. X    {mkid(R_MERCURY,C_JUPITER), PLT, SEP_WIDTH, 0, "Merc.Jup"},
  451. X    {mkid(R_MERCURY,C_MARS), PLT, SEP_WIDTH, 0, "Merc.Mars"},
  452. X    {mkid(R_MERCURY,C_MOON), PLT, SEP_WIDTH, 0, "Merc.Moon"},
  453. X    {mkid(R_MERCURY,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Merc.Nep"},
  454. X    {mkid(R_MERCURY,C_OBJX), PLT, SEP_WIDTH, 0, "Merc.ObjX"},
  455. X    {mkid(R_MERCURY,C_OBJY), PLT, SEP_WIDTH, 0, "Merc.ObjY"},
  456. X    {mkid(R_MERCURY,C_PLUTO), PLT, SEP_WIDTH, 0, "Merc.Pluto"},
  457. X    {mkid(R_MERCURY,C_SATURN), PLT, SEP_WIDTH, 0, "Merc.Sat"},
  458. X    {mkid(R_MERCURY,C_SUN), PLT, SEP_WIDTH, 0, "Merc.Sun"},
  459. X    {mkid(R_MERCURY,C_URANUS), PLT, SEP_WIDTH, 0, "Merc.Uranus"},
  460. X    {mkid(R_MERCURY,C_VENUS), PLT, SEP_WIDTH, 0, "Merc.Ven"},
  461. X    {mkid(R_MOON,C_JUPITER), PLT, SEP_WIDTH, 0, "Moon.Jup"},
  462. X    {mkid(R_MOON,C_MARS), PLT, SEP_WIDTH, 0, "Moon.Mars"},
  463. X    {mkid(R_MOON,C_MERCURY), PLT, SEP_WIDTH, 0, "Moon.Merc"},
  464. X    {mkid(R_MOON,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Moon.Nep"},
  465. X    {mkid(R_MOON,C_OBJX), PLT, SEP_WIDTH, 0, "Moon.ObjX"},
  466. X    {mkid(R_MOON,C_OBJY), PLT, SEP_WIDTH, 0, "Moon.ObjY"},
  467. X    {mkid(R_MOON,C_PLUTO), PLT, SEP_WIDTH, 0, "Moon.Pluto"},
  468. X    {mkid(R_MOON,C_SATURN), PLT, SEP_WIDTH, 0, "Moon.Sat"},
  469. X    {mkid(R_MOON,C_SUN), PLT, SEP_WIDTH, 0, "Moon.Sun"},
  470. X    {mkid(R_MOON,C_URANUS), PLT, SEP_WIDTH, 0, "Moon.Uranus"},
  471. X    {mkid(R_MOON,C_VENUS), PLT, SEP_WIDTH, 0, "Moon.Ven"},
  472. X    {mkid(R_NEPTUNE,C_JUPITER), PLT, SEP_WIDTH, 0, "Nep.Jup"},
  473. X    {mkid(R_NEPTUNE,C_MARS), PLT, SEP_WIDTH, 0, "Nep.Mars"},
  474. X    {mkid(R_NEPTUNE,C_MERCURY), PLT, SEP_WIDTH, 0, "Nep.Merc"},
  475. X    {mkid(R_NEPTUNE,C_MOON), PLT, SEP_WIDTH, 0, "Nep.Moon"},
  476. X    {mkid(R_NEPTUNE,C_OBJX), PLT, SEP_WIDTH, 0, "Nep.ObjX"},
  477. X    {mkid(R_NEPTUNE,C_OBJY), PLT, SEP_WIDTH, 0, "Nep.ObjY"},
  478. X    {mkid(R_NEPTUNE,C_PLUTO), PLT, SEP_WIDTH, 0, "Nep.Pluto"},
  479. X    {mkid(R_NEPTUNE,C_SATURN), PLT, SEP_WIDTH, 0, "Nep.Sat"},
  480. X    {mkid(R_NEPTUNE,C_SUN), PLT, SEP_WIDTH, 0, "Nep.Sun"},
  481. X    {mkid(R_NEPTUNE,C_URANUS), PLT, SEP_WIDTH, 0, "Nep.Uranus"},
  482. X    {mkid(R_NEPTUNE,C_VENUS), PLT, SEP_WIDTH, 0, "Nep.Ven"},
  483. X    {mkid(R_OBJX,C_JUPITER), PLT, SEP_WIDTH, 0, "ObjX.Jup"},
  484. X    {mkid(R_OBJX,C_MARS), PLT, SEP_WIDTH, 0, "ObjX.Mars"},
  485. X    {mkid(R_OBJX,C_MERCURY), PLT, SEP_WIDTH, 0, "ObjX.Merc"},
  486. X    {mkid(R_OBJX,C_MOON), PLT, SEP_WIDTH, 0, "ObjX.Moon"},
  487. X    {mkid(R_OBJX,C_NEPTUNE), PLT, SEP_WIDTH, 0, "ObjX.Nep"},
  488. X    {mkid(R_OBJX,C_OBJY), PLT, SEP_WIDTH, 0, "ObjX.ObjY"},
  489. X    {mkid(R_OBJX,C_PLUTO), PLT, SEP_WIDTH, 0, "ObjX.Pluto"},
  490. X    {mkid(R_OBJX,C_SATURN), PLT, SEP_WIDTH, 0, "ObjX.Sat"},
  491. X    {mkid(R_OBJX,C_SUN), PLT, SEP_WIDTH, 0, "ObjX.Sun"},
  492. X    {mkid(R_OBJX,C_URANUS), PLT, SEP_WIDTH, 0, "ObjX.Uranus"},
  493. X    {mkid(R_OBJX,C_VENUS), PLT, SEP_WIDTH, 0, "ObjX.Ven"},
  494. X    {mkid(R_OBJY,C_JUPITER), PLT, SEP_WIDTH, 0, "ObjY.Jup"},
  495. X    {mkid(R_OBJY,C_MARS), PLT, SEP_WIDTH, 0, "ObjY.Mars"},
  496. X    {mkid(R_OBJY,C_MERCURY), PLT, SEP_WIDTH, 0, "ObjY.Merc"},
  497. X    {mkid(R_OBJY,C_MOON), PLT, SEP_WIDTH, 0, "ObjY.Moon"},
  498. X    {mkid(R_OBJY,C_NEPTUNE), PLT, SEP_WIDTH, 0, "ObjY.Nep"},
  499. X    {mkid(R_OBJY,C_OBJX), PLT, SEP_WIDTH, 0, "ObjY.ObjX"},
  500. X    {mkid(R_OBJY,C_PLUTO), PLT, SEP_WIDTH, 0, "ObjY.Pluto"},
  501. X    {mkid(R_OBJY,C_SATURN), PLT, SEP_WIDTH, 0, "ObjY.Sat"},
  502. X    {mkid(R_OBJY,C_SUN), PLT, SEP_WIDTH, 0, "ObjY.Sun"},
  503. X    {mkid(R_OBJY,C_URANUS), PLT, SEP_WIDTH, 0, "ObjY.Uranus"},
  504. X    {mkid(R_OBJY,C_VENUS), PLT, SEP_WIDTH, 0, "ObjY.Ven"},
  505. X    {mkid(R_PLUTO,C_JUPITER), PLT, SEP_WIDTH, 0, "Pluto.Jup"},
  506. X    {mkid(R_PLUTO,C_MARS), PLT, SEP_WIDTH, 0, "Pluto.Mars"},
  507. X    {mkid(R_PLUTO,C_MERCURY), PLT, SEP_WIDTH, 0, "Pluto.Merc"},
  508. X    {mkid(R_PLUTO,C_MOON), PLT, SEP_WIDTH, 0, "Pluto.Moon"},
  509. X    {mkid(R_PLUTO,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Pluto.Nep"},
  510. X    {mkid(R_PLUTO,C_OBJX), PLT, SEP_WIDTH, 0, "Pluto.ObjX"},
  511. X    {mkid(R_PLUTO,C_OBJY), PLT, SEP_WIDTH, 0, "Pluto.ObjY"},
  512. X    {mkid(R_PLUTO,C_SATURN), PLT, SEP_WIDTH, 0, "Pluto.Sat"},
  513. X    {mkid(R_PLUTO,C_SUN), PLT, SEP_WIDTH, 0, "Pluto.Sun"},
  514. X    {mkid(R_PLUTO,C_URANUS), PLT, SEP_WIDTH, 0, "Pluto.Uranus"},
  515. X    {mkid(R_PLUTO,C_VENUS), PLT, SEP_WIDTH, 0, "Pluto.Ven"},
  516. X    {mkid(R_SATURN,C_JUPITER), PLT, SEP_WIDTH, 0, "Sat.Jup"},
  517. X    {mkid(R_SATURN,C_MARS), PLT, SEP_WIDTH, 0, "Sat.Mars"},
  518. X    {mkid(R_SATURN,C_MERCURY), PLT, SEP_WIDTH, 0, "Sat.Merc"},
  519. X    {mkid(R_SATURN,C_MOON), PLT, SEP_WIDTH, 0, "Sat.Moon"},
  520. X    {mkid(R_SATURN,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Sat.Nep"},
  521. X    {mkid(R_SATURN,C_OBJX), PLT, SEP_WIDTH, 0, "Sat.ObjX"},
  522. X    {mkid(R_SATURN,C_OBJY), PLT, SEP_WIDTH, 0, "Sat.ObjY"},
  523. X    {mkid(R_SATURN,C_PLUTO), PLT, SEP_WIDTH, 0, "Sat.Pluto"},
  524. X    {mkid(R_SATURN,C_SUN), PLT, SEP_WIDTH, 0, "Sat.Sun"},
  525. X    {mkid(R_SATURN,C_URANUS), PLT, SEP_WIDTH, 0, "Sat.Uranus"},
  526. X    {mkid(R_SATURN,C_VENUS), PLT, SEP_WIDTH, 0, "Sat.Ven"},
  527. X    {mkid(R_SUN,C_JUPITER), PLT, SEP_WIDTH, 0, "Sun.Jup"},
  528. X    {mkid(R_SUN,C_MARS), PLT, SEP_WIDTH, 0, "Sun.Mars"},
  529. X    {mkid(R_SUN,C_MERCURY), PLT, SEP_WIDTH, 0, "Sun.Merc"},
  530. X    {mkid(R_SUN,C_MOON), PLT, SEP_WIDTH, 0, "Sun.Moon"},
  531. X    {mkid(R_SUN,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Sun.Nep"},
  532. X    {mkid(R_SUN,C_OBJX), PLT, SEP_WIDTH, 0, "Sun.ObjX"},
  533. X    {mkid(R_SUN,C_OBJY), PLT, SEP_WIDTH, 0, "Sun.ObjY"},
  534. X    {mkid(R_SUN,C_PLUTO), PLT, SEP_WIDTH, 0, "Sun.Pluto"},
  535. X    {mkid(R_SUN,C_SATURN), PLT, SEP_WIDTH, 0, "Sun.Sat"},
  536. X    {mkid(R_SUN,C_URANUS), PLT, SEP_WIDTH, 0, "Sun.Uranus"},
  537. X    {mkid(R_SUN,C_VENUS), PLT, SEP_WIDTH, 0, "Sun.Ven"},
  538. X    {mkid(R_URANUS,C_JUPITER), PLT, SEP_WIDTH, 0, "Uranus.Jup"},
  539. X    {mkid(R_URANUS,C_MARS), PLT, SEP_WIDTH, 0, "Uranus.Mars"},
  540. X    {mkid(R_URANUS,C_MERCURY), PLT, SEP_WIDTH, 0, "Uranus.Merc"},
  541. X    {mkid(R_URANUS,C_MOON), PLT, SEP_WIDTH, 0, "Uranus.Moon"},
  542. X    {mkid(R_URANUS,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Uranus.Nep"},
  543. X    {mkid(R_URANUS,C_OBJX), PLT, SEP_WIDTH, 0, "Uranus.ObjX"},
  544. X    {mkid(R_URANUS,C_OBJY), PLT, SEP_WIDTH, 0, "Uranus.ObjY"},
  545. X    {mkid(R_URANUS,C_PLUTO), PLT, SEP_WIDTH, 0, "Uranus.Pluto"},
  546. X    {mkid(R_URANUS,C_SATURN), PLT, SEP_WIDTH, 0, "Uranus.Sat"},
  547. X    {mkid(R_URANUS,C_SUN), PLT, SEP_WIDTH, 0, "Uranus.Sun"},
  548. X    {mkid(R_URANUS,C_VENUS), PLT, SEP_WIDTH, 0, "Uranus.Ven"},
  549. X    {mkid(R_VENUS,C_JUPITER), PLT, SEP_WIDTH, 0, "Ven.Jup"},
  550. X    {mkid(R_VENUS,C_MARS), PLT, SEP_WIDTH, 0, "Ven.Mars"},
  551. X    {mkid(R_VENUS,C_MERCURY), PLT, SEP_WIDTH, 0, "Ven.Merc"},
  552. X    {mkid(R_VENUS,C_MOON), PLT, SEP_WIDTH, 0, "Ven.Moon"},
  553. X    {mkid(R_VENUS,C_NEPTUNE), PLT, SEP_WIDTH, 0, "Ven.Nep"},
  554. X    {mkid(R_VENUS,C_OBJX), PLT, SEP_WIDTH, 0, "Ven.ObjX"},
  555. X    {mkid(R_VENUS,C_OBJY), PLT, SEP_WIDTH, 0, "Ven.ObjY"},
  556. X    {mkid(R_VENUS,C_PLUTO), PLT, SEP_WIDTH, 0, "Ven.Pluto"},
  557. X    {mkid(R_VENUS,C_SATURN), PLT, SEP_WIDTH, 0, "Ven.Sat"},
  558. X    {mkid(R_VENUS,C_SUN), PLT, SEP_WIDTH, 0, "Ven.Sun"},
  559. X    {mkid(R_VENUS,C_URANUS), PLT, SEP_WIDTH, 0, "Ven.Uranus"},
  560. X
  561. X    {mkid(R_PLANTAB,C_OBJ), 0, 0, "Ob"},
  562. X    {mkid(R_PLANTAB,C_SUN), 0, 0, " Sun"},
  563. X    {mkid(R_PLANTAB,C_MOON), 0, 0, "Moon"},
  564. X    {mkid(R_PLANTAB,C_MERCURY), 0, 0, "Merc"},
  565. X    {mkid(R_PLANTAB,C_VENUS), 0, 0, "Venus"},
  566. X    {mkid(R_PLANTAB,C_MARS), 0, 0, "Mars"},
  567. X    {mkid(R_PLANTAB,C_JUPITER), 0, 0, " Jup"},
  568. X    {mkid(R_PLANTAB,C_SATURN), 0, 0, " Sat"},
  569. X    {mkid(R_PLANTAB,C_URANUS), 0, 0, "Uranus"},
  570. X    {mkid(R_PLANTAB,C_NEPTUNE), 0, 0, " Nep"},
  571. X    {mkid(R_PLANTAB,C_PLUTO), 0, 0, "Pluto"},
  572. X    {mkid(R_PLANTAB,C_OBJX), 0, 0, "  X"},
  573. X    {mkid(R_PLANTAB,C_OBJY), 0, 0, "  Y"},
  574. };
  575. #define    NFM    (sizeof(sm_field_map)/sizeof(sm_field_map[0]))
  576. #define    LFM    (&sm_field_map[NFM])
  577. #define    fw(r,c)    (fm(r,c)->w)
  578. X
  579. static short bodyrow[NOBJ] = {
  580. X    R_MERCURY, R_VENUS, R_MARS, R_JUPITER, R_SATURN,
  581. X    R_URANUS, R_NEPTUNE, R_PLUTO, R_SUN, R_MOON, R_OBJX, R_OBJY
  582. };
  583. X
  584. /* table of screen cols for third menu format, given body #define ... */
  585. static short bodycol[NOBJ] = {
  586. X    C_MERCURY, C_VENUS, C_MARS, C_JUPITER, C_SATURN,
  587. X    C_URANUS, C_NEPTUNE, C_PLUTO, C_SUN, C_MOON, C_OBJX, C_OBJY
  588. };
  589. X
  590. static Widget sepform_w;
  591. static Widget objs_w[NOBJ];    /* object selector toggle buttons */
  592. static unsigned objs_on;    /* (1<<<OBJ>) when object is active */
  593. static int sm_selecting;        /* set while our fields are being selected */
  594. X
  595. #define    GEO_CEN        0
  596. #define    TOPO_CEN    1
  597. static int sep_centric = TOPO_CEN;    /* must match the initial True TB */
  598. X
  599. static FieldMap *
  600. fm(r,c)
  601. int r, c;
  602. {
  603. X    FieldMap *fp;
  604. X    int id = mkid(r,c);
  605. X
  606. X    for (fp = sm_field_map; fp < LFM; fp++)
  607. X        if (fp->id == id)
  608. X        return (fp);
  609. X    printf ("fm: can't find id 0x%x (%d,%d)\n", id, r, c);
  610. X    exit (1);
  611. X    return(0);    /* for lint */
  612. }
  613. X
  614. /* method by which another module can access our field map.
  615. X * this is used by the search compiler.
  616. X */
  617. sm_getfieldmap (fmpp)
  618. FieldMap **fmpp;
  619. {
  620. X    *fmpp = sm_field_map;
  621. X    return (NFM);
  622. }
  623. X
  624. /* used by main to set the initial state of the objects to be on. */
  625. sm_set_objs_on (mask)
  626. int mask;
  627. {
  628. X    objs_on = mask;
  629. }
  630. X
  631. /* called when the sep menu is activated via the main menu pulldown.
  632. X * if never called before, create and manage all the widgets as a child of a
  633. X * form. otherwise, just toggle whether the form is managed.
  634. X */
  635. sm_manage ()
  636. {
  637. X    if (!sepform_w) {
  638. X        void sm_activate_cb();
  639. X        void sm_centric_cb();
  640. X        void sm_obj_cb();
  641. X        void sm_toggle_cb();
  642. X        void sm_close_cb();
  643. X        void sm_help_cb();
  644. X        FieldMap *fp;
  645. X        XmString str;
  646. X        Arg args[20];
  647. X        int i, n;
  648. X        Widget rb_w, w;
  649. X
  650. X        /* create the form */
  651. X        n = 0;
  652. X        XtSetArg (args[n], XmNautoUnmanage, False); n++;
  653. X        XtSetArg (args[n], XmNdefaultPosition, False); n++;
  654. X        XtSetArg (args[n], XmNfractionBase, 1000); n++;
  655. X        XtSetArg (args[n], XmNallowOverlap, False); n++;
  656. X        XtSetArg (args[n], XmNwidth, char_width()*NC); n++;
  657. X        sepform_w = XmCreateFormDialog (toplevel_w, "Separation", args, n);
  658. X
  659. X        /* set some stuff in the parent DialogShell.
  660. X         * setting XmNdialogTitle in the Form didn't work..
  661. X         */
  662. X        n = 0;
  663. X        XtSetArg (args[n], XmNtitle, "xephem Separations Table"); n++;
  664. X        XtSetValues (XtParent(sepform_w), args, n);
  665. X
  666. X        /* establish the buttons and labels */
  667. X        for (fp = sm_field_map; fp < LFM; fp++) {
  668. X        int free_str;
  669. X        n = 0;
  670. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  671. X        XtSetArg (args[n], XmNtopPosition, ypos(fp->id)); n++;
  672. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  673. X        XtSetArg (args[n], XmNleftPosition, xpos(fp->id)); n++;
  674. X        free_str = 0;
  675. X        if (fp->prompt) {
  676. X            str = XmStringCreate (fp->prompt,XmSTRING_DEFAULT_CHARSET);
  677. X            free_str = 1;
  678. X        } else if (fp->width) {
  679. X            str = str_width (fp->width);
  680. X            XtSetArg(args[n], XmNrecomputeSize, False); n++;
  681. X        } else {
  682. X            str = XmStringCreate ("?",XmSTRING_DEFAULT_CHARSET);
  683. X            free_str = 1;
  684. X        }
  685. X        XtSetArg (args[n], XmNlabelString, str); n++;
  686. X        if (fp->how) {
  687. X            /* pushbutton */
  688. X            XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++;
  689. X            fp->w = XtCreateManagedWidget ("SepButton",
  690. X                xmPushButtonGadgetClass, sepform_w, args, n);
  691. X            XtAddCallback (fp->w, XmNactivateCallback, sm_activate_cb,
  692. X                                        fp);
  693. X        } else {
  694. X            /* label */
  695. X            fp->w = XtCreateManagedWidget ("SepLabel",
  696. X                    xmLabelGadgetClass, sepform_w, args, n);
  697. X        }
  698. X        if (free_str)
  699. X            XmStringFree(str);
  700. X        }
  701. X
  702. X        /* make the object control toggle buttons */
  703. X        for (i = 0; i < NOBJ; i++) {
  704. X        str = XmStringCreate (objname[i], XmSTRING_DEFAULT_CHARSET);
  705. X        n = 0;
  706. X        XtSetArg (args[n], XmNlabelString, str); n++;
  707. X        XtSetArg (args[n], XmNset, objs_on&(1<<i) ? True : False);n++;
  708. X        XtSetArg (args[n], XmNindicatorOn, False); n++;
  709. X        XtSetArg (args[n], XmNshadowThickness, 2); n++;
  710. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  711. X        XtSetArg (args[n], XmNtopPosition, r2ypos(bodyrow[i])); n++;
  712. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  713. X        XtSetArg (args[n], XmNleftPosition, c2xpos(C_OBJ)); n++;
  714. X        objs_w[i] = XmCreateToggleButtonGadget (sepform_w, "SmObjs",
  715. X                                    args, n);
  716. X        XtAddCallback(objs_w[i], XmNvalueChangedCallback, sm_obj_cb, i);
  717. X        XtManageChild (objs_w[i]);
  718. X        XmStringFree (str);
  719. X        }
  720. X
  721. X        /* make the close button */
  722. X        str = XmStringCreate("Close", XmSTRING_DEFAULT_CHARSET);
  723. X        n = 0;
  724. X        XtSetArg (args[n], XmNlabelString, str); n++;
  725. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  726. X        XtSetArg (args[n], XmNtopPosition, r2ypos(R_CONTROL)); n++;
  727. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  728. X        XtSetArg (args[n], XmNleftPosition, c2xpos(1)); n++;
  729. X        w = XmCreatePushButtonGadget (sepform_w, "SepClose", args, n);
  730. X        XtAddCallback (w, XmNactivateCallback, sm_close_cb, 0);
  731. X        XtManageChild (w);
  732. X        XmStringFree (str);
  733. X
  734. X        /* make the geo/topo-centric control radio box */
  735. X        n = 0;
  736. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  737. X        XtSetArg (args[n], XmNtopPosition, r2ypos(R_CONTROL)); n++;
  738. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  739. X        XtSetArg (args[n], XmNleftPosition, 200); n++;
  740. X        XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
  741. X        rb_w = XmCreateRadioBox (sepform_w, "CentricRadioBox", args, n);
  742. X        XtManageChild (rb_w);
  743. X
  744. X        str = XmStringCreate("Topocentric", XmSTRING_DEFAULT_CHARSET);
  745. X        n = 0;
  746. X        XtSetArg (args[n], XmNset, sep_centric == TOPO_CEN); n++;
  747. X        XtSetArg (args[n], XmNlabelString, str); n++;
  748. X        w = XmCreateToggleButtonGadget (rb_w, "TopocentricTB", args, n);
  749. X        XtAddCallback (w, XmNvalueChangedCallback,sm_centric_cb,TOPO_CEN);
  750. X        XtManageChild (w);
  751. X        XmStringFree (str);
  752. X
  753. X        str = XmStringCreate("Geocentric", XmSTRING_DEFAULT_CHARSET);
  754. X        n = 0;
  755. X        XtSetArg (args[n], XmNlabelString, str); n++;
  756. X        w = XmCreateToggleButtonGadget (rb_w, "GeocentricTB", args, n);
  757. X        XtAddCallback(w, XmNvalueChangedCallback, sm_centric_cb, GEO_CEN);
  758. X        XtManageChild (w);
  759. X        XmStringFree (str);
  760. X
  761. X        /* make the toggle on/off pushbutton */
  762. X        str = XmStringCreate ("Toggle On/off", XmSTRING_DEFAULT_CHARSET);
  763. X        n = 0;
  764. X        XtSetArg (args[n], XmNlabelString, str); n++;
  765. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  766. X        XtSetArg (args[n], XmNtopPosition, r2ypos(R_CONTROL)); n++;
  767. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  768. X        XtSetArg (args[n], XmNleftPosition, 650); n++;
  769. X        XtSetArg(args[n], XmNrecomputeSize, False); n++;
  770. X        w = XmCreatePushButtonGadget (sepform_w, "SepToggle", args, n);
  771. X        XtAddCallback (w, XmNactivateCallback, sm_toggle_cb, 0);
  772. X        XtManageChild (w);
  773. X        XmStringFree (str);
  774. X
  775. X        /* make the help pushbutton */
  776. X
  777. X        str = XmStringCreate ("Help", XmSTRING_DEFAULT_CHARSET);
  778. X        n = 0;
  779. X        XtSetArg (args[n], XmNlabelString, str); n++;
  780. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  781. X        XtSetArg (args[n], XmNtopPosition, r2ypos(R_CONTROL)); n++;
  782. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  783. X        XtSetArg (args[n], XmNrightPosition, 1000); n++;
  784. X        w = XmCreatePushButtonGadget (sepform_w, "SepHelp", args, n);
  785. X        XtAddCallback (w, XmNactivateCallback, sm_help_cb, 0);
  786. X        XtManageChild (w);
  787. X        XmStringFree (str);
  788. X    }
  789. X    
  790. X    if (XtIsManaged(sepform_w))
  791. X        XtUnmanageChild (sepform_w);
  792. X    else {
  793. X        XtManageChild (sepform_w);
  794. X        sm_update (mm_get_now(), 1);
  795. X        sm_set_buttons(sm_selecting);
  796. X    }
  797. }
  798. X
  799. /* called by other menus as they want to hear from our buttons or not.
  800. X * the "on"s and "off"s stack - only really redo the buttons if it's the
  801. X * first on or the last off.
  802. X */
  803. sm_selection_mode (whether)
  804. int whether;    /* whether setting up for plotting or for not plotting */
  805. {
  806. X    sm_selecting += whether ? 1 : -1;
  807. X
  808. X    if (sepform_w && XtIsManaged(sepform_w))
  809. X        if (whether && sm_selecting == 1     /* first one to want on */
  810. X        || !whether && sm_selecting == 0 /* last one to want off */)
  811. X        sm_set_buttons (whether);
  812. }
  813. X
  814. /* go through all the buttons just pickable for plotting and set whether they
  815. X * should appear to look like buttons or just flat labels.
  816. X */
  817. sm_set_buttons (whether)
  818. int whether;
  819. {
  820. X    static Arg look_like_button[] = {
  821. X        {XmNshadowThickness, (XtArgVal) 2},
  822. X        {XmNfillOnArm, (XtArgVal) True},
  823. X    };
  824. X    static Arg look_like_label[] = {
  825. X        {XmNshadowThickness, (XtArgVal) 0},
  826. X        {XmNfillOnArm, (XtArgVal) False},
  827. X    };
  828. X    FieldMap *fp;
  829. X
  830. X    for (fp = sm_field_map; fp < LFM; fp++)
  831. X        if (whether && fp->how & PLT || !whether && fp->how & CHG)
  832. X        XtSetValues (fp->w,look_like_button,XtNumber(look_like_button));
  833. X        else
  834. X        XtSetValues (fp->w,look_like_label,XtNumber(look_like_label));
  835. }
  836. X
  837. /* callback from any of the sep menu buttons being activated.
  838. X * if it's a CHGable field, ask op for a new setting.
  839. X */
  840. void
  841. sm_activate_cb (w, client, call)
  842. Widget w;
  843. caddr_t client;
  844. caddr_t call;
  845. {
  846. X    FieldMap *fp = (FieldMap *)client;
  847. X
  848. X    if (sm_selecting) {
  849. X        plt_selection (fp);
  850. X        lst_selection (fp);
  851. X        srch_selection (fp);
  852. X    }
  853. }
  854. X
  855. /* callback from the "toggle on/off" push button.
  856. X * toggle each object on or off.
  857. X * basically we just force set all the planet buttons and let their callbacks
  858. X *   do the real work.
  859. X */
  860. static void
  861. sm_toggle_cb (w, client, call)
  862. Widget w;
  863. caddr_t client;
  864. caddr_t call;
  865. {
  866. X    int p;
  867. X
  868. X    for (p = nxtbody(-1); p != -1; p = nxtbody(p)) {
  869. X        int state = XmToggleButtonGadgetGetState (objs_w[p]);
  870. X        XmToggleButtonGadgetSetState (objs_w[p], !state, True/*invoke cb*/);
  871. X    }
  872. }
  873. X
  874. /* callback from the Close button.
  875. X */
  876. void
  877. sm_close_cb (w, client, call)
  878. Widget w;
  879. caddr_t client;
  880. caddr_t call;
  881. {
  882. X    XtUnmanageChild (sepform_w);
  883. }
  884. X
  885. /* callback from the Help
  886. X */
  887. void
  888. sm_help_cb (w, client, call)
  889. Widget w;
  890. caddr_t client;
  891. caddr_t call;
  892. {
  893. X    static char *msg[] = {
  894. "This table displays separations between each pair of objects. You may choose",
  895. "either a perspective from the center of the Earth, \"Geocentric\", or from",
  896. "your local location, \"Topocentric.\"",
  897. "",
  898. "It is advisable to use Geocentric separations for searching because it avoids",
  899. "the local non-monotonic behavior near the horizon due to refraction."
  900. };
  901. X
  902. X    hlp_dialog ("Separations Table", msg, sizeof(msg)/sizeof(msg[0]));
  903. }
  904. X
  905. /* callback for the geo/topocentric model radiobox.
  906. X */
  907. void
  908. sm_centric_cb (w, client, call)
  909. Widget w;
  910. caddr_t client;
  911. caddr_t call;
  912. {
  913. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  914. X    if (t->set && sep_centric != (int)client) {
  915. X        sep_centric = (int)client;
  916. X        sm_update (mm_get_now(), 1);
  917. X    }
  918. }
  919. X
  920. /* callback for each of the object on/off toggle buttons.
  921. X */
  922. void
  923. sm_obj_cb (w, client, call)
  924. Widget w;
  925. caddr_t client;
  926. caddr_t call;
  927. {
  928. X    XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
  929. X    int p = (int)client;
  930. X
  931. X    if (t->set && !(objs_on & (1<<p))) {
  932. X        objs_on |= 1<<p;
  933. X        sm_compute (p, 1, mm_get_now());
  934. X    } else if (!t->set && (objs_on & (1<<p))) {
  935. X        objs_on &= ~(1<<p);
  936. X        sm_erase_obj (p);
  937. X    }
  938. }
  939. X
  940. /* erase all the buttons in the row corresponding to object p */
  941. sm_erase_obj (p)
  942. int p;
  943. {
  944. X    FieldMap *fp;
  945. X    int r = bodyrow[p];
  946. X
  947. X    for (fp = sm_field_map; fp < LFM; fp++)
  948. X        if (f2r(fp->id) == r)
  949. X        f_string (fp->w, "");
  950. }
  951. X
  952. /* called to recompute and fill in values for the sep menu.
  953. X * don't bother if it doesn't exist or is unmanaged now.
  954. X * TODO: when figure out how to leave loc unchanged, do this unmanaged.
  955. X */
  956. sm_update (np, how_much)
  957. Now *np;
  958. int how_much;
  959. {
  960. X    int p;
  961. X    if (sepform_w && (how_much || XtIsManaged(sepform_w)))
  962. X        for (p = nxtbody(-1); p != -1; p = nxtbody(p))
  963. X        if (objs_on & 1<<p)
  964. X            sm_compute (p, how_much, np);
  965. }
  966. X
  967. /* print body info in third menu format. this may be either the geocentric
  968. X *   or topocentric angular separation between object p and each of the others.
  969. X *   the latter, of course, includes effects of refraction and so can change
  970. X *   quite rapidly near the time of each planets rise or set.
  971. X * for now, we don't save old values so we always redo everything and ignore
  972. X *  the "force" argument. this isn't that bad since body_cir() has memory and
  973. X *   will avoid most computations as we hit them again in the lower triangle.
  974. X * we are limited to only 5 columns per object. to make it fit, we display
  975. X *   degrees:minutes if less than 100 degrees, otherwise just whole degrees.
  976. X */
  977. /*ARGSUSED*/
  978. static
  979. sm_compute (p, force, np)
  980. int p;        /* which body, as in astro.h/moreobjs.h defines */
  981. int force;    /* whether to print for sure or only if things have changed */
  982. Now *np;
  983. {
  984. X    int row = bodyrow[p];
  985. X    Sky skyp, skyq;
  986. X    double spy, cpy, px, *qx, *qy;
  987. X    int wantx = objs_on & (1<<OBJX);
  988. X    int wanty = objs_on & (1<<OBJY);
  989. X    double as = plot_ison() || srch_ison() ? 0.0 : 60.0;
  990. X    int q;
  991. X
  992. X    (void) body_cir (p, as, np, &skyp);
  993. X    if (sep_centric == GEO_CEN) {
  994. X        /* use ra for "x", dec for "y". */
  995. X        spy = sin (skyp.s_dec);
  996. X        cpy = cos (skyp.s_dec);
  997. X        px = skyp.s_ra;
  998. X        qx = &skyq.s_ra;
  999. X        qy = &skyq.s_dec;
  1000. X    } else {
  1001. X        /* use azimuth for "x", altitude for "y". */
  1002. X        spy = sin (skyp.s_alt);
  1003. X        cpy = cos (skyp.s_alt);
  1004. X        px = skyp.s_az;
  1005. X        qx = &skyq.s_az;
  1006. X        qy = &skyq.s_alt;
  1007. X    }
  1008. X    for (q = nxtbody(-1); q != -1; q = nxtbody(q))
  1009. X        if (q != p && (q != OBJX || wantx) && (q != OBJY || wanty)) {
  1010. X        double sep;
  1011. X        (void) body_cir (q, as, np, &skyq);
  1012. X        sep = acos(spy*sin(*qy) + cpy*cos(*qy)*cos(px-*qx));
  1013. X        f_angle (fw(row,bodycol[q]), sep);
  1014. X        }
  1015. }
  1016. SHAR_EOF
  1017. chmod 0644 sepmenu.c ||
  1018. echo 'restore of sepmenu.c failed'
  1019. Wc_c="`wc -c < 'sepmenu.c'`"
  1020. test 23823 -eq "$Wc_c" ||
  1021.     echo 'sepmenu.c: original size 23823, current size' "$Wc_c"
  1022. rm -f _shar_wnt_.tmp
  1023. fi
  1024. # ============= sex_dec.c ==============
  1025. if test -f 'sex_dec.c' -a X"$1" != X"-c"; then
  1026.     echo 'x - skipping sex_dec.c (File already exists)'
  1027.     rm -f _shar_wnt_.tmp
  1028. else
  1029. > _shar_wnt_.tmp
  1030. echo 'x - extracting sex_dec.c (Text)'
  1031. sed 's/^X//' << 'SHAR_EOF' > 'sex_dec.c' &&
  1032. #include <math.h>
  1033. X
  1034. /* given hours (or degrees), hd, minutes, m, and seconds, s, 
  1035. X * return decimal hours (or degrees), *d.
  1036. X * in the case of hours (angles) < 0, only the first non-zero element should
  1037. X *   be negative.
  1038. X */
  1039. sex_dec (hd, m, s, d)
  1040. int hd, m, s;
  1041. double *d;
  1042. {
  1043. X    int sign = 1;
  1044. X
  1045. X    if (hd < 0) {
  1046. X        sign = -1;
  1047. X        hd = -hd;
  1048. X    } else if (m < 0) {
  1049. X        sign = -1;
  1050. X        m = -m;
  1051. X    } else if (s < 0) {
  1052. X        sign = -1;
  1053. X        s = -s;
  1054. X    }
  1055. X
  1056. X    *d = (((double)s/60.0 + (double)m)/60.0 + (double)hd) * sign;
  1057. }
  1058. X
  1059. /* given decimal hours (or degrees), d.
  1060. X * return nearest hours (or degrees), *hd, minutes, *m, and seconds, *s, 
  1061. X * each always non-negative; *isneg is set to 1 if d is < 0, else to 0.
  1062. X */
  1063. dec_sex (d, hd, m, s, isneg)
  1064. double d;
  1065. int *hd, *m, *s, *isneg;
  1066. {
  1067. X    double min;
  1068. X
  1069. X    if (d < 0) {
  1070. X        *isneg = 1;
  1071. X        d = -d;
  1072. X    } else
  1073. X        *isneg = 0;
  1074. X
  1075. X    *hd = (int)d;
  1076. X    min = (d - *hd)*60.;
  1077. X    *m = (int)min;
  1078. X    *s = (int)((min - *m)*60. + 0.5);
  1079. X
  1080. X    if (*s == 60) {
  1081. X        if ((*m += 1) == 60) {
  1082. X        *hd += 1;
  1083. X        *m = 0;
  1084. X        }
  1085. X        *s = 0;
  1086. X    }
  1087. X    /* no  negative 0's */
  1088. X    if (*hd == 0 && *m == 0 && *s == 0)
  1089. X        *isneg = 0;
  1090. }
  1091. X
  1092. /* insure 0 <= *v < r.
  1093. X */
  1094. range (v, r)
  1095. double *v, r;
  1096. {
  1097. X    *v -= r*floor(*v/r);
  1098. }
  1099. SHAR_EOF
  1100. chmod 0644 sex_dec.c ||
  1101. echo 'restore of sex_dec.c failed'
  1102. Wc_c="`wc -c < 'sex_dec.c'`"
  1103. test 1183 -eq "$Wc_c" ||
  1104.     echo 'sex_dec.c: original size 1183, current size' "$Wc_c"
  1105. rm -f _shar_wnt_.tmp
  1106. fi
  1107. # ============= skydome.c ==============
  1108. if test -f 'skydome.c' -a X"$1" != X"-c"; then
  1109.     echo 'x - skipping skydome.c (File already exists)'
  1110.     rm -f _shar_wnt_.tmp
  1111. else
  1112. > _shar_wnt_.tmp
  1113. echo 'x - extracting skydome.c (Text)'
  1114. sed 's/^X//' << 'SHAR_EOF' > 'skydome.c' &&
  1115. /* code to manage the stuff on the sky dome display.
  1116. X */
  1117. X
  1118. #include <stdio.h>
  1119. #include <ctype.h>
  1120. #include <math.h>
  1121. #ifdef VMS
  1122. #include <stdlib.h>
  1123. #endif
  1124. #include <X11/Xlib.h>
  1125. #include <Xm/Xm.h>
  1126. #include <Xm/Form.h>
  1127. #include <Xm/Frame.h>
  1128. #include <Xm/DrawingA.h>
  1129. #include <Xm/LabelG.h>
  1130. #include <Xm/PushBG.h>
  1131. #include <Xm/ToggleBG.h>
  1132. #include <Xm/Text.h>
  1133. #include <Xm/Scale.h>
  1134. #include "astro.h"
  1135. #include "circum.h"
  1136. #include "moreobjs.h"
  1137. X
  1138. extern char *objname[];
  1139. extern Now *mm_get_now();
  1140. extern Widget toplevel_w;
  1141. #define    XtD    XtDisplay(toplevel_w)
  1142. X
  1143. static Widget sdform_w;        /* main sky dome form dialog */
  1144. static Widget sdda_w;        /* sky dome drawring area */
  1145. static Widget picked_name_w;    /* display name of object if picked */
  1146. static Widget objs_w[NOBJ];     /* object selection toggle buttons */
  1147. X
  1148. #define    TRAILS    1
  1149. #define    BIGDOTS    2
  1150. #define    NR    15
  1151. #define    NC    36
  1152. X
  1153. static int trails;
  1154. static int bigdots = 1;
  1155. X
  1156. /* use this string to make a label gadget appear empty.
  1157. X * using "" seems to act like unmanaging it altogether!
  1158. X */
  1159. static char no_name[] = " ";
  1160. X
  1161. static unsigned int propts;    /* mask of (1<<obj) when it is on */
  1162. X
  1163. /* alt/az coordinates, and enough info to locate it on screen */
  1164. typedef struct {
  1165. X    double alt, az;    /* alt/az coords */
  1166. X    int p;        /* object code */
  1167. X    int sx, sy;        /* screen (window) coords */
  1168. } DLoc;
  1169. X
  1170. static DLoc *points;    /* malloc'd set of points on screen now */
  1171. static int npoints;    /* number of points */
  1172. X
  1173. X
  1174. /* called when the sky dome view is activated via the main menu pulldown.
  1175. X * if never called before, create and manage all the widgets as a child of a
  1176. X * form. otherwise, just toggle whether the form is managed.
  1177. X */
  1178. sd_manage ()
  1179. {
  1180. X    if (!sdform_w) {
  1181. X        void sd_activate_cb();
  1182. X        void sd_close_cb();
  1183. X        void sd_da_exp_cb();
  1184. X        void sd_propts_cb();
  1185. X        void sd_toggle_cb();
  1186. X        Widget close_w;
  1187. X        Widget trails_w;
  1188. X        Widget toggle_w;
  1189. X        Widget w, pw;
  1190. X        Widget big_w;
  1191. X        Widget n_w, s_w, e_w, w_w;
  1192. X        XmString str;
  1193. X        Arg args[20];
  1194. X        int n;
  1195. X        int i, p;
  1196. X
  1197. X        /* create form */
  1198. X        n = 0;
  1199. X        XtSetArg (args[n], XmNautoUnmanage, False); n++;
  1200. X        XtSetArg (args[n], XmNdefaultPosition, False); n++;
  1201. X        XtSetArg (args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  1202. X        XtSetArg (args[n], XmNwidth, NC*char_width()); n++;
  1203. X        XtSetArg (args[n], XmNheight, NR*char_height()); n++;
  1204. X        sdform_w = XmCreateFormDialog (toplevel_w, "SkyDome", args, n);
  1205. X
  1206. X        /* set some stuff in the parent DialogShell.
  1207. X         * setting XmNdialogTitle in the Form didn't work..
  1208. X         */
  1209. X        n = 0;
  1210. X        XtSetArg (args[n], XmNtitle, "xephem Sky Dome"); n++;
  1211. X        XtSetValues (XtParent(sdform_w), args, n);
  1212. X
  1213. X        /* make the "close" push button */
  1214. X
  1215. X        str = XmStringCreate("Close", XmSTRING_DEFAULT_CHARSET);
  1216. X        n = 0;
  1217. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1218. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1219. X        XtSetArg (args[n], XmNlabelString, str); n++;
  1220. X        close_w = XmCreatePushButtonGadget (sdform_w, "SDClose", args, n);
  1221. X        XtAddCallback (close_w, XmNactivateCallback, sd_close_cb, 0);
  1222. X        XtManageChild (close_w);
  1223. X        XmStringFree (str);
  1224. X
  1225. X        /* make the "big dots" toggle button */
  1226. X
  1227. X        str = XmStringCreate("Big dots", XmSTRING_DEFAULT_CHARSET);
  1228. X        n = 0;
  1229. X        XtSetArg (args[n], XmNset, bigdots); n++;
  1230. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1231. X        XtSetArg (args[n], XmNbottomWidget, close_w); n++;
  1232. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1233. X        XtSetArg (args[n], XmNlabelString, str); n++;
  1234. X        big_w = XmCreateToggleButtonGadget(sdform_w, "SDBigDots",args,n);
  1235. X        XmStringFree (str);
  1236. X        XtManageChild (big_w);
  1237. X        XtAddCallback(big_w, XmNvalueChangedCallback, sd_activate_cb,
  1238. X                                    BIGDOTS);
  1239. X
  1240. X        /* "toggle on/off" push button */
  1241. X
  1242. X        str = XmStringCreate("Toggle On/off", XmSTRING_DEFAULT_CHARSET);
  1243. X        n = 0;
  1244. X        XtSetArg (args[n], XmNlabelString, str); n++;
  1245. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1246. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1247. X        toggle_w = XmCreatePushButtonGadget (sdform_w, "SDToggle", args, n);
  1248. X        XtAddCallback (toggle_w, XmNactivateCallback, sd_toggle_cb, 0);
  1249. X        XtManageChild (toggle_w);
  1250. X        XmStringFree (str);
  1251. X
  1252. X        /* make the "leave trails" toggle button */
  1253. X
  1254. X        str = XmStringCreate("Leave trails", XmSTRING_DEFAULT_CHARSET);
  1255. X        n = 0;
  1256. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1257. X        XtSetArg (args[n], XmNbottomWidget, toggle_w); n++;
  1258. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1259. X        XtSetArg (args[n], XmNlabelString, str); n++;
  1260. X        trails_w = XmCreateToggleButtonGadget(sdform_w, "SDTrails", args,n);
  1261. X        XmStringFree (str);
  1262. X        XtManageChild (trails_w);
  1263. X        XtAddCallback(trails_w, XmNvalueChangedCallback, sd_activate_cb,
  1264. X                                    TRAILS);
  1265. X
  1266. X        /* make the object selection buttons */
  1267. X
  1268. X        for (i = 0, p = nxtbody(-1); p != -1; i++, p = nxtbody(p)) {
  1269. X        str = XmStringCreate (objname[p], XmSTRING_DEFAULT_CHARSET);
  1270. X        n = 0;
  1271. X        XtSetArg (args[n], XmNlabelString, str); n++;
  1272. X        XtSetArg (args[n], XmNset, propts & (1<<p) ? True : False); n++;
  1273. X        XtSetArg (args[n], XmNindicatorOn, False); n++;
  1274. X        XtSetArg (args[n], XmNshadowThickness, 2); n++;
  1275. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1276. X        XtSetArg (args[n], XmNbottomWidget, big_w); n++;
  1277. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  1278. X        XtSetArg (args[n], XmNleftPosition, i*100/NOBJ); n++;
  1279. X        pw = XmCreateToggleButtonGadget (sdform_w, "SDPropts", args, n);
  1280. X        XtAddCallback(pw, XmNvalueChangedCallback, sd_propts_cb, p);
  1281. X        XtManageChild (pw);
  1282. X        objs_w[p] = pw;
  1283. X        XmStringFree (str);
  1284. X        }
  1285. X
  1286. X        /* make the picked object label */
  1287. X
  1288. X        str = XmStringCreate(no_name, XmSTRING_DEFAULT_CHARSET);
  1289. X        n = 0;
  1290. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1291. X        XtSetArg (args[n], XmNbottomWidget, pw); n++;
  1292. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1293. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1294. X        XtSetArg (args[n], XmNlabelString, str); n++;
  1295. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1296. X        picked_name_w = XmCreateLabelGadget (sdform_w, "SDPickedName",
  1297. X                                    args, n);
  1298. X        XtManageChild (picked_name_w);
  1299. X        XmStringFree (str);
  1300. X
  1301. X        /* make the orientation labels */
  1302. X
  1303. X        n = 0;
  1304. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1305. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1306. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1307. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1308. X        n_w = XmCreateLabelGadget (sdform_w, "North", args, n);
  1309. X        XtManageChild (n_w);
  1310. X        n = 0;
  1311. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  1312. X        XtSetArg (args[n], XmNtopPosition, 35); n++;
  1313. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1314. X        e_w = XmCreateLabelGadget (sdform_w, "E", args, n);
  1315. X        XtManageChild (e_w);
  1316. X        n = 0;
  1317. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  1318. X        XtSetArg (args[n], XmNtopPosition, 35); n++;
  1319. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1320. X        w_w = XmCreateLabelGadget (sdform_w, "W", args, n);
  1321. X        XtManageChild (w_w);
  1322. X        n = 0;
  1323. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1324. X        XtSetArg (args[n], XmNbottomWidget, picked_name_w); n++;
  1325. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1326. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1327. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  1328. X        s_w = XmCreateLabelGadget (sdform_w, "South", args, n);
  1329. X        XtManageChild (s_w);
  1330. X
  1331. X        /* make a drawing area for drawing the solar system */
  1332. X
  1333. X        n = 0;
  1334. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1335. X        XtSetArg (args[n], XmNtopWidget, n_w); n++;
  1336. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  1337. X        XtSetArg (args[n], XmNbottomWidget, s_w); n++;
  1338. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  1339. X        XtSetArg (args[n], XmNleftWidget, e_w); n++;
  1340. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  1341. X        XtSetArg (args[n], XmNrightWidget, w_w); n++;
  1342. X        sdda_w = XmCreateDrawingArea (sdform_w, "SkyDomeMap", args, n);
  1343. X        XtAddCallback (sdda_w, XmNexposeCallback, sd_da_exp_cb, 0);
  1344. X        XtAddCallback (sdda_w, XmNresizeCallback, sd_da_exp_cb, 0);
  1345. X        XtAddCallback (sdda_w, XmNinputCallback, sd_da_exp_cb, 0);
  1346. X        XtManageChild (sdda_w);
  1347. X    }
  1348. X    
  1349. X    if (XtIsManaged(sdform_w))
  1350. X        XtUnmanageChild (sdform_w);
  1351. X    else {
  1352. X        XtManageChild (sdform_w);
  1353. X        sd_update (mm_get_now(), 1);
  1354. X    }
  1355. }
  1356. X
  1357. sd_set_objs_on(mask)
  1358. int mask;
  1359. {
  1360. X    propts = mask;
  1361. }
  1362. X
  1363. sd_ison()
  1364. {
  1365. X    return (sdform_w && XtIsManaged(sdform_w));
  1366. }
  1367. X
  1368. /* called when we are to update our view.
  1369. X * don't bother if we are unmanaged unless trails is on - in that case,
  1370. X * compute the new locations but don't display them.
  1371. X */
  1372. sd_update (np, how_much)
  1373. Now *np;
  1374. int how_much;
  1375. {
  1376. X    double as = how_much ? 0.0 : 3600.0;
  1377. X    Sky sky;
  1378. X    DLoc *lp;
  1379. X    int up;
  1380. X    int p;
  1381. X
  1382. X    up = sdform_w && XtIsManaged(sdform_w);
  1383. X    if (!up && !trails)
  1384. X        return;
  1385. X
  1386. X    if (!trails) {
  1387. X        if (points)
  1388. X        XtFree ((char*)points);
  1389. X        points = 0;
  1390. X        npoints = 0;
  1391. X    }
  1392. X
  1393. X    for (p = nxtbody(-1); p != -1; p = nxtbody(p)) {
  1394. X        if ((p==OBJX || p==OBJY) && !obj_ison(p))
  1395. X        continue;
  1396. X        (void) body_cir (p, as, np, &sky);
  1397. X        if (sky.s_alt <= 0.0)
  1398. X        continue;
  1399. X        npoints++;
  1400. X        points = (DLoc *) XtRealloc ((char *)points, npoints*sizeof(DLoc));
  1401. X        lp = &points[npoints-1];
  1402. X        lp->alt = sky.s_alt;
  1403. X        lp->az = sky.s_az;
  1404. X        lp->p = p;
  1405. X    }
  1406. X
  1407. X    if (up)
  1408. X        sd_all(!trails);
  1409. X        
  1410. }
  1411. X
  1412. /* callback from the toggle buttons
  1413. X */
  1414. void
  1415. sd_activate_cb (w, client, call)
  1416. Widget w;
  1417. caddr_t client;
  1418. caddr_t call;
  1419. {
  1420. X    int what = (int) client;
  1421. X
  1422. X    switch (what) {
  1423. X    case TRAILS:
  1424. X        trails = XmToggleButtonGadgetGetState(w);
  1425. X        break;
  1426. X    case BIGDOTS:
  1427. X        bigdots = XmToggleButtonGadgetGetState(w);
  1428. X        sd_all (1);
  1429. X        break;
  1430. X    default:
  1431. X        printf ("unknown toggle button\n");
  1432. X        break;
  1433. X    }
  1434. }
  1435. X
  1436. /* callback from the toggle on/off button
  1437. X */
  1438. void
  1439. sd_toggle_cb (w, client, call)
  1440. Widget w;
  1441. caddr_t client;
  1442. caddr_t call;
  1443. {
  1444. X    int p;
  1445. X
  1446. X    for (p = nxtbody(-1); p != -1; p = nxtbody(p)) {
  1447. X        int s = XmToggleButtonGadgetGetState(objs_w[p]);
  1448. X        if (s) propts &= ~(1<<p);
  1449. X        else   propts |= 1<<p;
  1450. X        XmToggleButtonGadgetSetState(objs_w[p], !s, False /*don't invoke*/);
  1451. X     }
  1452. X     sd_all (1);
  1453. }
  1454. X
  1455. /* callback from the toggle buttons for each object.
  1456. X * set the onoff flag in the points array for the planet whose code is in
  1457. X * client, then redraw.
  1458. X */
  1459. void
  1460. sd_propts_cb (w, client, call)
  1461. Widget w;
  1462. caddr_t client;
  1463. caddr_t call;
  1464. {
  1465. X    int p = (int) client;
  1466. X
  1467. X    if (XmToggleButtonGadgetGetState(w))    propts |= 1<<p;
  1468. X    else                        propts &= ~(1<<p);
  1469. X    sd_all (1);
  1470. }
  1471. X
  1472. /* callback from the Close button.
  1473. X */
  1474. void
  1475. sd_close_cb (w, client, call)
  1476. Widget w;
  1477. caddr_t client;
  1478. caddr_t call;
  1479. {
  1480. X    XtUnmanageChild (sdform_w);
  1481. }
  1482. X
  1483. /* expose (or reconfig) of sky dome drawing area.
  1484. X * just redraw the scene to the current window size.
  1485. X * also, input callback when picking a dot for identification.
  1486. X */
  1487. static void
  1488. sd_da_exp_cb (w, client, call)
  1489. Widget w;
  1490. caddr_t client;
  1491. caddr_t call;
  1492. {
  1493. X    XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
  1494. X
  1495. X    switch (c->reason) {
  1496. X    case XmCR_RESIZE:
  1497. X        /* seems we can get one resize before the first expose.
  1498. X         * hence, we don't have a good window to use yet. just let it
  1499. X         * go; we'll get the expose soon.
  1500. X         */
  1501. X        if (!XtWindow(w))
  1502. X        return;
  1503. X        break;
  1504. X    case XmCR_EXPOSE: {
  1505. X        XExposeEvent *e = &c->event->xexpose;
  1506. X        /* wait for the last in the series */
  1507. X        if (e->count != 0)
  1508. X        return;
  1509. X        break;
  1510. X        }
  1511. X    case XmCR_INPUT:
  1512. X        sd_identify (c->event);
  1513. X        return;
  1514. X    default:
  1515. X        printf ("Unexpected sdda_w event. type=%d\n", c->reason);
  1516. X        return;
  1517. X    }
  1518. X
  1519. X    /* have to be sure the entire background is cleared out, not just
  1520. X     * the horizon circle, since it probably has changed size now.
  1521. X     */
  1522. X    XClearWindow (XtDisplay(w), XtWindow(w));
  1523. X    sd_update (mm_get_now(), 1);
  1524. }
  1525. X
  1526. /* a dot has been picked: find what it is and report it. */
  1527. static
  1528. sd_identify (ev)
  1529. XXEvent *ev;
  1530. {
  1531. #define    PICKRANGE    36    /* sqr of dist allowed from pointer */
  1532. X    int x, y, mind, mini;
  1533. X    int i;
  1534. X    char *name;
  1535. X
  1536. X    switch (ev->type) {
  1537. X    case ButtonPress:
  1538. X        x = ((XButtonPressedEvent *)ev)->x;
  1539. X        y = ((XButtonPressedEvent *)ev)->y;
  1540. X        mini = -1;
  1541. X        for (i = 0; i < npoints; i++) {
  1542. X            if (propts & (1<<points[i].p)) {
  1543. X            int d = (x-points[i].sx)*(x-points[i].sx) +
  1544. X                        (y-points[i].sy)*(y-points[i].sy);
  1545. X            if (mini < 0 || d < mind) {
  1546. X            mini = i;
  1547. X            mind = d;
  1548. X            }
  1549. X        }
  1550. X        }
  1551. X        if (mini >= 0 && mind <= PICKRANGE) {
  1552. X        extern char *obj_getname();
  1553. X        static char *onames[] = {
  1554. X            /* NB: these must correspond to the astro/morobj defines */
  1555. X            "Mercury", "Venus", "Mars", "Jupiter", "Saturn",
  1556. X            "Uranus", "Neptune", "Pluto", "Sun", "Moon"
  1557. X        };
  1558. X        int p = points[mini].p;
  1559. X        if (p >= MERCURY && p <= MOON)
  1560. X            name = onames[p];
  1561. X        else if (p == OBJX || p == OBJY)
  1562. X            name = obj_getname(p);
  1563. X        else
  1564. X            name = "?";
  1565. X        } else
  1566. X        name = no_name;
  1567. X        f_string (picked_name_w, name);
  1568. X        break;
  1569. X    }
  1570. }
  1571. X
  1572. /* draw everything in the points array to the current screen size.
  1573. X * redraw the background too if preclr is set.
  1574. X */
  1575. static
  1576. sd_all(preclr)
  1577. int preclr;
  1578. {
  1579. X    static GC sd_fgc, sd_bgc;
  1580. X    unsigned int nx, ny;
  1581. X    Window root;
  1582. X    int x, y;
  1583. X    unsigned int bw, d;
  1584. X    Display *dsp = XtDisplay(sdda_w);
  1585. X    Window win = XtWindow(sdda_w);
  1586. X    int i;
  1587. X
  1588. X    if (!sd_fgc) {
  1589. X        XGCValues gcv;
  1590. X        unsigned int gcm;
  1591. X        unsigned pixel;
  1592. X
  1593. X        /* user set the foreground and background resources for the
  1594. X         * SkyDomeMap. we use these for our gc's in drawing the circle
  1595. X         * and the planets but reset the background to the rest of the
  1596. X         * region.
  1597. X         */
  1598. X        gcm = GCForeground;
  1599. X        get_something (sdda_w, XmNforeground, (char *)&gcv.foreground);
  1600. X        sd_fgc = XCreateGC (dsp, win, gcm, &gcv);
  1601. X        get_something (sdda_w, XmNbackground, (char *)&gcv.foreground);
  1602. X        sd_bgc = XCreateGC (dsp, win, gcm, &gcv);
  1603. X        get_something (sdform_w, XmNbackground, &pixel);
  1604. X        set_something (sdda_w, XmNbackground, pixel);
  1605. X
  1606. X    }
  1607. X
  1608. X    XGetGeometry (dsp, win, &root, &x, &y, &nx, &ny, &bw, &d);
  1609. X
  1610. X    if (preclr) {
  1611. X        /*XFillArc (dsp, win, sd_bgc, 0, 0, nx, ny, 0, 360*64);*/
  1612. SHAR_EOF
  1613. true || echo 'restore of skydome.c failed'
  1614. fi
  1615. echo 'End of  part 9'
  1616. echo 'File skydome.c is continued in part 10'
  1617. echo 10 > _shar_seq_.tmp
  1618. exit 0
  1619. -- 
  1620. --
  1621. Molecular Simulations, Inc.            mail: dcmartin@msi.com
  1622. 796 N. Pastoria Avenue                uucp: uunet!dcmartin
  1623. Sunnyvale, California 94086            at&t: 408/522-9236
  1624.