/* handle the history feature of skyview */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "xephem.h" extern char skycategory[]; static char skyhfn[]= "xephem_skyhist"; /* file name to store history */ #define VERSIONN 5 /* version number */ /* info to manage any number of history entries and their controls. * we destroy and recreate all the entries in the Dialog each time the * history changes, but we keep reusing the PBs in the Pulldown menu. */ typedef struct { SvHistory h; /* history */ char *ulbl; /* malloced user label */ Widget ltf_w; /* TF widget showing ulbl */ } SVHEntry; static SVHEntry *hist; /* malloced list of SVHEntry */ static int nhist; /* number of entries in nhist[] */ static Widget *pdpb_w; /* malloced list of PBs for pulldown */ static int npdpb; /* number in pdpb_w[] */ static Widget svhshell_w; /* main form shell */ static Widget pd_w; /* pulldown menu */ static Widget sw_w; /* list scrolled window */ static int autonum; /* for building a unique def ulbl */ static void svh_manage_cb (Widget w, XtPointer client, XtPointer call); static void svh_add_cb (Widget w, XtPointer client, XtPointer call); static void svh_del_cb (Widget w, XtPointer client, XtPointer call); static void svh_rep_cb (Widget w, XtPointer client, XtPointer call); static void svh_go_cb (Widget w, XtPointer client, XtPointer call); static void svh_up_cb (Widget w, XtPointer client, XtPointer call); static void svh_down_cb (Widget w, XtPointer client, XtPointer call); static void svh_cascading_cb (Widget w, XtPointer client, XtPointer call); static void svh_save_cb (Widget w, XtPointer client, XtPointer call); static void svh_load_cb (Widget w, XtPointer client, XtPointer call); static void svh_ltfc_cb (Widget w, XtPointer client, XtPointer call); static void svh_help_cb (Widget w, XtPointer client, XtPointer call); static void svh_close_cb (Widget w, XtPointer client, XtPointer call); static void show_entries (void); static void setup_1row (Widget rc_w, int i); static void setup_label (Widget lbl_w, SvHistory *hp); static FILE *openhist (char *buf, char *how); static int loadhist (FILE *histfp, char *fn, char msg[]); /* create the History pulldown off the given menubar; * and create the history control dialog; * and Apply the first history entry, if any. */ void svh_create (Widget mb_w) { Widget w; Arg args[20]; FILE *hfp; char buf[1024]; char fn[1024]; Widget svhform_w; int n; /* create the pulldown menu */ n = 0; pd_w = XmCreatePulldownMenu (mb_w, "HPD", args, n); n = 0; XtSetArg (args[n], XmNsubMenuId, pd_w); n++; XtSetArg (args[n], XmNmnemonic, 'H'); n++; w = XmCreateCascadeButton (mb_w, "History", args, n); XtAddCallback (w, XmNcascadingCallback, svh_cascading_cb, 0); wtip (w, "Manage a collection of Sky View settings"); XtManageChild (w); /* add the "Edit" PB */ n = 0; w = XmCreatePushButton (pd_w, "WPB", args, n); XtAddCallback (w, XmNactivateCallback, svh_manage_cb, NULL); wtip(w,"Open a window to manage the History list"); set_xmstring (w, XmNlabelString, "Edit..."); XtManageChild (w); /* add a separator to set off the list of entries */ n = 0; w = XmCreateSeparator (pd_w, "HSep", args, n); XtManageChild (w); /* remaining PBs are added as needed when cascading */ /* create the History shell and form */ n = 0; XtSetArg (args[n], XmNallowShellResize, True); n++; XtSetArg (args[n], XmNcolormap, xe_cm); n++; XtSetArg (args[n], XmNtitle, "Sky history"); n++; XtSetArg (args[n], XmNiconName, "Sky"); n++; XtSetArg (args[n], XmNdeleteResponse, XmUNMAP); n++; svhshell_w = XtCreatePopupShell ("SkyHist", topLevelShellWidgetClass, toplevel_w, args, n); setup_icon (svhshell_w); set_something (svhshell_w, XmNcolormap, (XtArgVal)xe_cm); sr_reg (svhshell_w, "XEphem*SkyHist.width", skycategory, 0); sr_reg (svhshell_w, "XEphem*SkyHist.height", skycategory, 0); sr_reg (svhshell_w, "XEphem*SkyHist.x", skycategory, 0); sr_reg (svhshell_w, "XEphem*SkyHist.y", skycategory, 0); n = 0; XtSetArg (args[n], XmNverticalSpacing, 10); n++; XtSetArg (args[n], XmNmarginHeight, 10); n++; XtSetArg (args[n], XmNmarginWidth, 10); n++; XtSetArg (args[n], XmNfractionBase, 30); n++; svhform_w = XmCreateForm (svhshell_w, "SVHForm", args, n); XtAddCallback (svhform_w, XmNhelpCallback, svh_help_cb, 0); XtManageChild (svhform_w); /* controls attached across the bottom */ n = 0; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNleftPosition, 4); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 6); n++; w = XmCreatePushButton (svhform_w, "Add", args, n); wtip (w, "Add the current Sky View settings to the History list"); XtAddCallback (w, XmNactivateCallback, svh_add_cb, 0); XtManageChild (w); n = 0; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNleftPosition, 9); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 11); n++; w = XmCreatePushButton (svhform_w, "Save", args, n); (void) sprintf (buf, "Save the History list to %s/%s", getPrivateDir(), skyhfn); wtip (w, XtNewString(buf)); /* must be permanent memory */ XtAddCallback (w, XmNactivateCallback, svh_save_cb, 0); XtManageChild (w); n = 0; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNleftPosition, 14); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 16); n++; w = XmCreatePushButton (svhform_w, "Load", args, n); (void) sprintf(buf,"Load the History list from %s/%s else %s/auxil/%s", getPrivateDir(), skyhfn, getShareDir(), skyhfn); wtip (w, XtNewString(buf)); /* must be permanent memory */ XtAddCallback (w, XmNactivateCallback, svh_load_cb, 0); XtManageChild (w); n = 0; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNleftPosition, 19); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 21); n++; w = XmCreatePushButton (svhform_w, "Close", args, n); wtip (w, "Close this window"); XtAddCallback (w, XmNactivateCallback, svh_close_cb, 0); XtManageChild (w); n = 0; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNleftPosition, 24); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 26); n++; w = XmCreatePushButton (svhform_w, "Help", args, n); wtip (w, "Get more info about this window."); XtAddCallback (w, XmNactivateCallback, svh_help_cb, 0); XtManageChild (w); /* SW for RC of entries stretches between top and row of controls */ n = 0; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNbottomWidget, w); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC); n++; sw_w = XmCreateScrolledWindow (svhform_w, "SW", args, n); XtManageChild (sw_w); /* add a dummy RC just so it can be replaced when add entries */ n = 0; w = XmCreateRowColumn (sw_w, "Dummy", args, n); XtManageChild (w); /* init from history file if opens ok */ hfp = openhist(fn, "r"); if (hfp) { char buf[1024]; if (loadhist (hfp, fn, buf) < 0) { xe_msg (1, "%s", buf); } else { show_entries(); xe_msg (0, "%s", buf); /* just log */ } fclose (hfp); } } /* called to put up or remove the watch cursor. */ void svh_cursor (c) Cursor c; { Window win; if (svhshell_w && (win = XtWindow(svhshell_w)) != 0) { Display *dsp = XtDisplay(svhshell_w); if (c) XDefineCursor (dsp, win, c); else XUndefineCursor (dsp, win); } } /* close the History control dialog, if any */ void svh_unmanage() { if (svhshell_w) XtPopdown (svhshell_w); } /* get current settings and assign to next position */ void svh_add_current() { char buf[32]; hist = (SVHEntry *) XtRealloc ((char*)hist, (nhist+1)*sizeof(SVHEntry)); zero_mem ((void *)(&hist[nhist]), sizeof(hist[0])); svh_get (&hist[nhist].h); (void) sprintf (buf, "New entry %d", ++autonum); hist[nhist].ulbl = XtNewString (buf); nhist++; show_entries (); } /* return the current number of history entries */ int svh_nhist() { return (nhist); } /* display each of the nhist SvHistory entries in the dialog. */ static void show_entries() { Widget ww; Arg args[20]; int i, n; /* replace workWindow with a fresh RC */ get_something (sw_w, XmNworkWindow, (XtArgVal)&ww); XtDestroyWidget (ww); /* destroys all the ltf_w too */ n = 0; XtSetArg (args[n], XmNspacing, 0); n++; ww = XmCreateRowColumn (sw_w, "CatRC", args, n); set_something (sw_w, XmNworkWindow, (XtArgVal)ww); /* fill with info */ for (i = 0; i < nhist; i++) setup_1row (ww, i); /* ok */ XtManageChild (ww); } /* using info from hist[i] create its row in the history window */ static void setup_1row (rc_w, i) Widget rc_w; int i; { Widget f_w, del_w, rep_w, go_w, up_w, down_w, lbl_w, tf_w; Arg args[20]; int n; /* create the row's form */ n = 0; XtSetArg (args[n], XmNhorizontalSpacing, 5); n++; f_w = XmCreateForm (rc_w, "HF", args, n); XtManageChild (f_w); /* PB to Apply */ n = 0; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNleftPosition, 2); n++; go_w = XmCreatePushButton (f_w, "Apply", args, n); XtAddCallback (go_w, XmNactivateCallback, svh_go_cb, (XtPointer)(long int)i); wtip (go_w, "Put this History entry into effect"); XtManageChild (go_w); /* PB to move up in list */ n = 0; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, go_w); n++; XtSetArg (args[n], XmNarrowDirection, XmARROW_UP); n++; up_w = XmCreateArrowButton (f_w, "Up", args, n); XtAddCallback (up_w, XmNactivateCallback, svh_up_cb, (XtPointer)(long int)i); wtip (up_w, "Move this History entry up one row in the list"); if (i == 0) XtSetSensitive (up_w, False); XtManageChild (up_w); /* PB to move down in list */ n = 0; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, up_w); n++; XtSetArg (args[n], XmNarrowDirection, XmARROW_DOWN); n++; down_w = XmCreateArrowButton (f_w, "Down", args, n); XtAddCallback (down_w, XmNactivateCallback, svh_down_cb, (XtPointer)(long int)i); wtip (down_w, "Move this History entry down one row in the list"); if (i == nhist-1) XtSetSensitive (down_w, False); XtManageChild (down_w); /* PB to delete */ n = 0; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, down_w); n++; del_w = XmCreatePushButton (f_w, "Delete", args, n); XtAddCallback (del_w, XmNactivateCallback, svh_del_cb, (XtPointer)(long int)i); wtip (del_w, "Delete this History entry"); XtManageChild (del_w); /* PB to replace */ n = 0; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, del_w); n++; rep_w = XmCreatePushButton (f_w, "Replace", args, n); XtAddCallback (rep_w, XmNactivateCallback, svh_rep_cb, (XtPointer)(long int)i); wtip (rep_w, "Replace this History entry with current settings"); XtManageChild (rep_w); /* label for info */ n = 0; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, rep_w); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 70); n++; XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++; lbl_w = XmCreateLabel (f_w, "TL", args, n); setup_label (lbl_w, &hist[i].h); XtManageChild (lbl_w); /* TF for label */ n = 0; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, lbl_w); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNrightPosition, 100); n++; XtSetArg (args[n], XmNvalue, hist[i].ulbl); n++; tf_w = XmCreateTextField (f_w, "Label", args, n); XtAddCallback (tf_w, XmNvalueChangedCallback, svh_ltfc_cb,(XtPointer)(long int)i); wtip (tf_w, "Your label for this entry"); XtManageChild (tf_w); hist[i].ltf_w = tf_w; XmTextFieldSetString (tf_w, hist[i].ulbl); } /* called just as the pulldown menu is cascading */ /* ARGSUSED */ static void svh_cascading_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { int i; /* assign a PB to each hist[], creating as necessary */ for (i = 0; i < nhist; i++) { Widget pb; if (i >= npdpb) { Arg args[20]; int n; n = 0; pb = XmCreatePushButton (pd_w, "HPB", args, n); XtAddCallback (pb,XmNactivateCallback, svh_go_cb, (XtPointer)(long int)i); wtip (pb, "Apply this History entry"); pdpb_w = (Widget *) XtRealloc ((char *)pdpb_w, ++npdpb*sizeof(Widget)); pdpb_w[i] = pb; } else pb = pdpb_w[i]; set_xmstring (pb, XmNlabelString, hist[i].ulbl); XtManageChild (pb); } /* unmanage any excess pulldown buttons */ while (i < npdpb) XtUnmanageChild (pdpb_w[i++]); } /* callback each time a char is typed in a ltf_w. * client is index into hist[] */ /* ARGSUSED */ static void svh_ltfc_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { int i = (long int)client; XtFree(hist[i].ulbl); hist[i].ulbl = XmTextFieldGetString (hist[i].ltf_w); } /* callback from the overall Help button. */ /* ARGSUSED */ static void svh_help_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { static char *msg[] = { "Collects and Installs collections of Sky View settings", }; hlp_dialog ("SkyView_history", msg, sizeof(msg)/sizeof(msg[0])); } /* callback from the manage PB in the pulldown */ /* ARGSUSED */ static void svh_manage_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { XtPopup (svhshell_w, XtGrabNone); set_something (svhshell_w, XmNiconic, (XtArgVal)False); } /* callback from the Close PB */ /* ARGSUSED */ static void svh_close_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { XtPopdown (svhshell_w); } /* called when the Add button is hit in the history window */ /* ARGSUSED */ static void svh_add_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { svh_add_current(); } /* used to delete history entry deli, possibly after confirming */ static int deli; static void del_i() { /* free ulbl */ XtFree (hist[deli].ulbl); /* remove deli from hist */ memcpy (&hist[deli], &hist[deli+1], (nhist-(deli+1))*sizeof(SVHEntry)); nhist--; /* show list now */ show_entries(); } /* called when a Delete button is hit in the history window. * client is index into hist[] */ /* ARGSUSED */ static void svh_del_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { /* save index */ deli = (long int)client; /* confirm */ if (confirm()) { char buf[1024]; (void) sprintf (buf, "Delete \"%s\"?", hist[deli].ulbl); query (svhshell_w, buf, "Yes -- delete", "No -- keep it", NULL, del_i, NULL, NULL); } else del_i(); } /* used to replace history entry repi, possibly after confirming */ static int repi; static void rep_i() { char *ulbl = hist[repi].ulbl; zero_mem ((void *)(&hist[repi]), sizeof(hist[0])); svh_get (&hist[repi].h); hist[repi].ulbl = ulbl; show_entries (); } /* called when a Replace button is hit in the history window. * client is index into hist[] */ /* ARGSUSED */ static void svh_rep_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { /* save index */ repi = (long int)client; /* confirm */ if (confirm()) { char buf[1024]; (void) sprintf (buf, "Replace \"%s\"?", hist[repi].ulbl); query (svhshell_w, buf, "Yes -- replace", "No -- keep it", NULL, rep_i, NULL, NULL); } else rep_i(); } /* called when a Go button is hit in the history window. * client is index into hist[] */ /* ARGSUSED */ static void svh_go_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { int i = (long int)client; svh_goto (&hist[i].h); } /* called when an Up button is hit in the history window. * client is index into hist[] */ /* ARGSUSED */ static void svh_up_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { int i = (long int)client; SVHEntry tmp; /* nothing to do if chose top already */ if (i == 0) return; /* swap up */ tmp = hist[i-1]; hist[i-1] = hist[i]; hist[i] = tmp; /* show list now */ show_entries(); } /* called when a Down button is hit in the history window. * client is index into hist[] */ /* ARGSUSED */ static void svh_down_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { int i = (long int)client; SVHEntry tmp; /* nothing to do if chose end already */ if (i >= nhist-1) return; /* swap down */ tmp = hist[i+1]; hist[i+1] = hist[i]; hist[i] = tmp; /* show list now */ show_entries(); } /* setup the label lbl_w from the given SvHistory */ static void setup_label (lbl_w, hp) Widget lbl_w; SvHistory *hp; { char *projstr = hp->cyl_proj ? "Cyl" : "Sph"; char str1[32], str2[32]; char adstr[32]; char fovstr[32]; char buf[128]; fs_sexa (fovstr, raddeg(hp->fov), 3, 60); if (hp->aa_mode) { fs_sexa (str1, raddeg(hp->altdec), 3, 60); fs_sexa (str2, raddeg(hp->azra), 3, 60); strcpy (adstr, "Alt/Az"); } else { fs_sexa (str1, radhr(hp->azra), 3, 60); fs_sexa (str2, raddeg(hp->altdec), 3, 60); strcpy (adstr, "RA/Dec"); } (void) sprintf (buf,"%s %s %s %s %s", projstr, adstr, str1,str2,fovstr); set_xmstring (lbl_w, XmNlabelString, buf); } /* called when the Save button is hit */ /* ARGSUSED */ static void svh_save_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { FILE *histfp; SvHistory *hp; int i, j; char fn[1024]; histfp = openhist(fn, "w"); if (!histfp) { xe_msg (1, "%s:\n%s", fn, syserrstr()); return; } fprintf(histfp, "# skyview history file\n"); fprintf(histfp, "Version %d\n", VERSIONN); for (i = 0; i < nhist; i++) { hp = &hist[i].h; fprintf(histfp, ":%d\n", i); fprintf(histfp, "%s\n", hist[i].ulbl); fprintf(histfp, "%g %g %g %d %d %d %d %d %d %d %d\n", hp->fov, hp->azra, hp->altdec, hp->stmag, hp->ssmag, hp->dsmag, hp->magstp, hp->grid, hp->autogrid, hp->aagrid, hp->gridlbl); fprintf(histfp, "%*s\n", GRIDLEN, hp->vgrid); fprintf(histfp, "%*s\n", GRIDLEN, hp->hgrid); fprintf(histfp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", hp->winw, hp->winh, hp->cyl_proj, hp->aa_mode, hp->flip_lr, hp->flip_tb, hp->justd, hp->eclip, hp->galac, hp->eq, hp->hznmap, hp->conf, hp->conb, hp->conn, hp->cona, hp->eyep, hp->magscale, hp->automag, hp->lbl_lst, hp->lbl_lfs, hp->lbl_lss, hp->lbl_lds, hp->lbl_bst, hp->lbl_bfs, hp->lbl_bss, hp->lbl_bds, hp->conr, hp->hznclipping); for (j=0; j < (int)NOBJTYPES; j++) fprintf(histfp, "%c", hp->type_table[j]?'1':'0'); fprintf(histfp, "\n"); for (j=0; j < (int)NCLASSES; j++) fprintf(histfp, "%c", hp->fclass_table[j]?'1':'0'); fprintf(histfp, "\n"); } fprintf(histfp, "# end\n"); (void)fclose(histfp); if (confirm()) xe_msg (1, "%s saved", fn); } /* called when the Load button is hit in the history pulldown */ /* ARGSUSED */ static void svh_load_cb (w, client, call) Widget w; XtPointer client; XtPointer call; { char fn[1024]; char buf[1024]; FILE *hfp; hfp = openhist(fn, "r"); if (hfp) { if (loadhist(hfp, fn, buf) < 0) xe_msg (1, "%s", buf); else show_entries(); fclose (hfp); } else { xe_msg (1, "%s:\n%s", fn, syserrstr()); } } /* load the history file named fn[] already open on histfp. * return 0 if ok, -1 if trouble. * some sort of message is also always in msg[]. */ static int loadhist (histfp, fn, msg) FILE *histfp; char *fn; char *msg; { char buf[1024]; char *ulbl; SvHistory hp; int i, j, n; int v; /* first look for Version */ while (fgets(buf, sizeof(buf), histfp)) if (buf[0] != '#' && buf[0] != '\n') break; if (sscanf(buf, "Version %d", &v) != 1) { sprintf (msg, "%s:\nNo Version line:\n%s\n", fn, buf); goto err; } else if (!(v <= VERSIONN && v >= VERSIONN-2)) { sprintf (msg, "%s:\nWrong version, must be %d.", fn, VERSIONN); goto err; } /* now loop over each group of lines defining one History entry */ nhist = 0; ulbl = 0; while (fgets(buf, sizeof(buf), histfp)) { if (buf[0] == '#' || buf[0] == '\n') continue; /* initial comment */ if (sscanf(buf, ":%d", &i) != 1) { sprintf (msg, "%s:\nBogus \":\" line:\n%s", fn, buf); goto err; } if (!fgets (buf, sizeof(buf), histfp)) goto err; buf[strlen(buf)-1] = '\0'; /* no \n */ ulbl = XtNewString (buf); /* malloced copy */ if (!fgets(buf, sizeof(buf), histfp)) goto err; if (sscanf(buf, "%lg %lg %lg %d %d %d %d %d %d %d %d", &hp.fov, &hp.azra, &hp.altdec, &hp.stmag, &hp.ssmag, &hp.dsmag, &hp.magstp, &hp.grid, &hp.autogrid, &hp.aagrid, &hp.gridlbl)!=11) { sprintf (msg, "%s:\nBogus fov .. \n%s", fn, buf); goto err; } if (!fgets(buf, sizeof(buf), histfp)) goto err; (void) sprintf (hp.vgrid, "%*.*s", GRIDLEN, GRIDLEN, buf); if (!fgets(buf, sizeof(buf), histfp)) goto err; (void) sprintf (hp.hgrid, "%*.*s", GRIDLEN, GRIDLEN, buf); if (!fgets(buf, sizeof(buf), histfp)) goto err; n = sscanf(buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", &hp.winw, &hp.winh, &hp.cyl_proj, &hp.aa_mode, &hp.flip_lr, &hp.flip_tb, &hp.justd, &hp.eclip, &hp.galac, &hp.eq, &hp.hznmap, &hp.conf, &hp.conb, &hp.conn, &hp.cona, &hp.eyep, &hp.magscale, &hp.automag, &hp.lbl_lst, &hp.lbl_lfs, &hp.lbl_lss, &hp.lbl_lds, &hp.lbl_bst, &hp.lbl_bfs, &hp.lbl_bss, &hp.lbl_bds, &hp.conr, &hp.hznclipping ); if (v == 4 && n == 27) { hp.hznclipping = 1; } else if (v == 3 && n == 24) { hp.lbl_bds = hp.lbl_bfs; hp.lbl_bss = hp.lbl_bst; hp.lbl_bst = hp.lbl_lds; hp.lbl_lds = hp.lbl_lss; hp.lbl_lss = hp.lbl_lfs; hp.lbl_bss = 10; hp.lbl_bds = 10; hp.conr = 0; hp.hznclipping = 1; } else if (!(v == VERSIONN && n == 28)) { sprintf (msg, "%s:\nBogus switches line .. \n%s", fn, buf); goto err; } if (!fgets(buf, sizeof(buf), histfp)) goto err; for (j = 0; j < sizeof(hp.type_table); j++) { switch (buf[j]) { case '0': hp.type_table[j] = 0; break; case '1': hp.type_table[j] = 1; break; default: goto err; } } if (!fgets(buf, sizeof(buf), histfp)) goto err; for (j = 0; j < sizeof(hp.fclass_table); j++) { switch (buf[j]) { case '0': hp.fclass_table[j] = 0; break; case '1': hp.fclass_table[j] = 1; break; default: goto err; } } /* got one! */ hist = (SVHEntry *) XtRealloc ((char *)hist, (nhist+1)*sizeof(SVHEntry)); memcpy(&hist[nhist].h, &hp, sizeof(hp)); hist[nhist].ulbl = ulbl; nhist++; } sprintf (msg, "%s:\nLoaded %d skyhistory entries.", fn, nhist); return (0); err: /* overwrite err if something more basic is wrong */ if (ferror(histfp)) sprintf (msg, "%s:\n%s", fn, syserrstr()); else if (feof(histfp)) sprintf (msg, "%s:\nUnexpected EOF\n", fn); for (i = 0; i < nhist; i++) XtFree (hist[i].ulbl); nhist = 0; return (-1); } /* fill fn with full history file name and try to open. * if opening for write try to create in PrivateDir. */ static FILE * openhist(fn, how) char *fn; char *how; { FILE *fp; /* first try local copy, r or w */ (void) sprintf (fn, "%s/%s", getPrivateDir(), skyhfn); fp = fopenh (fn, how); /* if fails try global copy if for r */ if (!fp && how[0] == 'r') { (void) sprintf (fn, "%s/auxil/%s", getShareDir(), skyhfn); fp = fopenh (fn, how); } return (fp); }