home *** CD-ROM | disk | FTP | other *** search
- /* code to manage the stuff on the "plot" menu.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #if defined(__STDC__)
- #include <stdlib.h>
- #endif
- #include <X11/Xlib.h>
- #include <Xm/Xm.h>
- #include <Xm/Form.h>
- #include <Xm/Frame.h>
- #include <Xm/DrawingA.h>
- #include <Xm/Label.h>
- #include <Xm/PushB.h>
- #include <Xm/ToggleB.h>
- #include <Xm/RowColumn.h>
- #include <Xm/Separator.h>
- #include <Xm/Text.h>
-
- #if defined(__STDC__) || defined(__cplusplus)
- #define P_(s) s
- #else
- #define P_(s) ()
- #endif
-
- extern int plot_cartesian P_((FILE *pfp, Widget widget, unsigned int nx, unsigned int ny, int flipx, int flipy, int grid));
- extern void all_selection_mode P_((int whether));
- extern void f_string P_((Widget w, char *s));
- extern void get_something P_((Widget w, char *resource, char *value));
- extern void hlp_dialog P_((char *tag, char *deflt[], int ndeflt));
- extern void query P_((Widget tw, char *msg, char *label1, char *label2, char *label3, void (*func1)(), void (*func2)(), void (*func3)()));
- extern void set_something P_((Widget w, char *resource, char *value));
- extern void set_xmstring P_((Widget w, char *resource, char *txt));
- extern void xe_msg P_((char *msg, int app_modal));
-
- void plot_manage P_((void));
- void plt_selection P_((char *name));
- void plt_log P_((char *name, double value));
- void plot P_((void));
- int plot_ison P_((void));
- void plt_cursor P_((Cursor c));
- static void plt_select P_((int whether));
- static void plot_create_form P_((void));
- static void plt_activate_cb P_((Widget w, XtPointer client, XtPointer call));
- static void plt_close_cb P_((Widget w, XtPointer client, XtPointer call));
- static void plt_help_cb P_((Widget w, XtPointer client, XtPointer call));
- static void plt_reset P_((void));
- static void plt_stop_selecting P_((void));
- static void plt_turn_off P_((void));
- static void init_next_tag P_((void));
- static void plt_try_append P_((void));
- static void plt_try_overwrite P_((void));
- static void plt_try_cancel P_((void));
- static void plt_try_turn_on P_((void));
- static void plt_turn_on P_((char *how));
- static void plt_da_manage P_((void));
- static void plt_da_destroy P_((Widget daform_w));
- static void plt_daform_map_cb P_((Widget w, XtPointer client, XtPointer call));
- static void plt_da_close_cb P_((Widget w, XtPointer client, XtPointer call));
- static void plt_da_flipx_cb P_((Widget w, XtPointer client, XtPointer call));
- static void plt_da_flipy_cb P_((Widget w, XtPointer client, XtPointer call));
- static void plt_da_grid_cb P_((Widget w, XtPointer client, XtPointer call));
- static void plt_da_exp_cb P_((Widget da_w, XtPointer client, XtPointer call));
-
- #undef P_
-
- extern int access();
- extern Widget toplevel_w;
- #define XtD XtDisplay(toplevel_w)
-
- #ifdef VMS
- #include <perror.h>
- #include <errno.h>
- #else
- extern char *sys_errlist[];
- extern errno;
- #endif
-
- #define errsys (sys_errlist[errno])
-
- /* max number of things we can keep track of at once to plot */
- #define MAXPLTLINES 10
- #define MAXFLDNAM 32 /* longest allowed field name */
-
- static Widget plotform_w;
- static Widget select_w, active_w, prompt_w;
- static Widget title_w, filename_w;
- static Widget table_w[MAXPLTLINES][3]; /* column indeces follow.. */
- static int selecting_xy; /* also one of ... */
- #define T 0
- #define X 1
- #define Y 2
-
- #define DEF_PLTFN "ephem.plt" /* default plot file name */
- static FILE *plt_fp; /* the plot file; == 0 means don't plot */
-
-
- /* plt_activate_cb client values. */
- enum { SELECT, ACTIVE, SHOW};
-
- /* store the name of each x and y line to track and their values.
- * we get the label straight from the Text widget in the table as needed.
- */
- typedef struct {
- char pl_xn[MAXFLDNAM]; /* name of x field, or 0 if none */
- double pl_xv; /* last known value of x field */
- char pl_yn[MAXFLDNAM]; /* name of y field, or 0 if none */
- double pl_yv; /* last known value of x field */
- } PltLine;
- static PltLine pltlines[MAXPLTLINES];
- static int npltlines; /* number of pltlines[] in actual use */
-
- /* one of these gets malloced and passed to the drawing area expose callback via
- * its client parameter. be sure to free it when the parent FormDialog goes
- * away too.
- * by doing this, we can have lots of different plots up at once and yet we
- * don't have to keep track of them - they track themselves.
- */
- typedef struct {
- char *filename; /* name of file being plotted (also malloced) */
- FILE *fp; /* FILE pointer for the file */
- int flipx, flipy; /* flip state for this instance */
- int grid; /* whether to include a grid */
- } DrawInfo;
-
- /* called when the plot menu is activated via the main menu pulldown.
- * if never called before, create and manage all the widgets as a child of a
- * form. otherwise, just toggle whether the form is managed.
- */
- void
- plot_manage ()
- {
- if (!plotform_w)
- plot_create_form();
-
- if (XtIsManaged(plotform_w))
- XtUnmanageChild (plotform_w);
- else
- XtManageChild (plotform_w);
- }
-
- /* called by the other menus (data, etc) as their buttons are
- * selected to inform us that that button is to be included in a plot.
- */
- void
- plt_selection (name)
- char *name;
- {
- Widget tw;
-
- if (!plotform_w
- || !XtIsManaged(plotform_w)
- || !XmToggleButtonGetState(select_w))
- return;
-
- tw = table_w[npltlines][selecting_xy];
- set_xmstring (tw, XmNlabelString, name);
- XtManageChild (tw);
-
- if (selecting_xy == X) {
- (void) strncpy (pltlines[npltlines].pl_xn, name, MAXFLDNAM-1);
- selecting_xy = Y;
- XtManageChild (prompt_w);
- f_string (prompt_w, "Select quantity for Y..");
- } else {
- (void) strncpy (pltlines[npltlines].pl_yn, name, MAXFLDNAM-1);
- if (++npltlines == MAXPLTLINES)
- plt_stop_selecting();
- else {
- selecting_xy = X;
- init_next_tag();
- }
- }
- }
-
- /* called as each different field is written -- just save in pltlines[]
- * if we are interested in it.
- * might have the same field listed more than once so can't stop if find one.
- */
- void
- plt_log (name, value)
- char *name;
- double value;
- {
- if (plt_fp) {
- PltLine *plp;
- for (plp = pltlines; plp < &pltlines[npltlines]; plp++) {
- if (strcmp (name, plp->pl_xn) == 0)
- plp->pl_xv = value;
- if (strcmp (name, plp->pl_yn) == 0)
- plp->pl_yv = value;
- }
- }
- }
-
- /* called when all fields have been updated and it's time to
- * write the active plotfields to the current plot file, if one is open.
- */
- void
- plot()
- {
- if (plt_fp) {
- /* plot in order of original selection */
- PltLine *plp;
- for (plp = pltlines; plp < &pltlines[npltlines]; plp++) {
- char *lbl = XmTextGetString (table_w[plp-pltlines][T]);
- (void) fprintf (plt_fp, "%c,%.12g,%.12g\n", lbl[0],
- plp->pl_xv, plp->pl_yv);
- XtFree (lbl);
- }
- }
- }
-
- plot_ison()
- {
- return (plt_fp != 0);
- }
-
- /* called to put up or remove the watch cursor. */
- void
- plt_cursor (c)
- Cursor c;
- {
- Window win;
-
- if (plotform_w && (win = XtWindow(plotform_w))) {
- Display *dsp = XtDisplay(plotform_w);
- if (c)
- XDefineCursor (dsp, win, c);
- else
- XUndefineCursor (dsp, win);
- }
- }
-
- /* inform the other menues whether we are setting up for them to tell us
- * what fields to plot.
- */
- static void
- plt_select(whether)
- int whether;
- {
- all_selection_mode(whether);
- }
-
- static void
- plot_create_form()
- {
- static struct {
- char *title;
- int cb_data;
- Widget *wp;
- } tbs[] = {
- {"Select fields", SELECT, &select_w},
- {"Plot to file", ACTIVE, &active_w},
- {"Show plot file", SHOW, NULL},
- };
- XmString str;
- Widget f_w, rc_w;
- Widget w;
- char *deffn;
- Arg args[20];
- int i, n;
-
- /* create the main dialog */
-
- n = 0;
- XtSetArg (args[n], XmNautoUnmanage, False); n++;
- XtSetArg (args[n], XmNdefaultPosition, False); n++;
- plotform_w = XmCreateFormDialog (toplevel_w, "Plot", args, n);
-
- n = 0;
- XtSetArg (args[n], XmNtitle, "xephem Plot Control"); n++;
- XtSetValues (XtParent(plotform_w), args, n);
-
- /* make a RowColumn to hold everything */
-
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNisAligned, False); n++;
- XtSetArg (args[n], XmNadjustMargin, False); n++;
- rc_w = XmCreateRowColumn(plotform_w, "PlotRC", args, n);
- XtManageChild (rc_w);
-
- /* make the control toggle buttons */
-
- for (i = 0; i < XtNumber(tbs); i++) {
- str = XmStringCreate(tbs[i].title, XmSTRING_DEFAULT_CHARSET);
- n = 0;
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- XtSetArg (args[n], XmNlabelString, str); n++;
- w = XmCreateToggleButton(rc_w, "PlotTB", args, n);
- XmStringFree (str);
- XtManageChild (w);
- XtAddCallback(w, XmNvalueChangedCallback, plt_activate_cb,
- (XtPointer)tbs[i].cb_data);
- if (tbs[i].wp)
- *tbs[i].wp = w;
- }
-
- /* create filename text area and its label */
-
- n = 0;
- str = XmStringCreate("File name:", XmSTRING_DEFAULT_CHARSET);
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- XtSetArg (args[n], XmNlabelString, str); n++;
- w = XmCreateLabel (rc_w, "PlotFnL", args, n);
- XmStringFree (str);
- XtManageChild (w);
-
- n = 0;
- filename_w = XmCreateText (rc_w, "Filename", args, n);
- deffn = XmTextGetString (filename_w);
- if (strlen(deffn) == 0)
- XmTextSetString (filename_w, DEF_PLTFN);
- XtFree (deffn);
- XtManageChild (filename_w);
-
- /* create title text area and its label */
-
- n = 0;
- str = XmStringCreate("Title:", XmSTRING_DEFAULT_CHARSET);
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- XtSetArg (args[n], XmNlabelString, str); n++;
- w = XmCreateLabel (rc_w, "PlotTL", args, n);
- XtManageChild (w);
- XmStringFree (str);
-
- n = 0;
- title_w = XmCreateText (rc_w, "PlotTitle", args, n);
- XtManageChild (title_w);
-
- /* create prompt line -- it will be managed as necessary */
-
- n = 0;
- XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
- prompt_w = XmCreateLabel (rc_w, "PlotPrompt", args, n);
-
- /* create the table.
- * each row is in a form to control its shape.
- * loop index of -1 is used to make the column headings.
- * the table entries are not managed at this time.
- */
-
- for (i = -1; i < MAXPLTLINES; i++) {
- n = 0;
- XtSetArg (args[n], XmNfractionBase, 9); n++;
- f_w = XmCreateForm (rc_w, "PlotTF", args, n);
- XtManageChild (f_w);
-
- 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, 0); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 1); n++;
- if (i == -1) {
- w = XmCreateLabel (f_w, "Tag", args, n);
- XtManageChild (w);
- } else {
- XtSetArg (args[n], XmNmaxLength, 1); n++;
- XtSetArg (args[n], XmNcolumns, 1); n++;
- table_w[i][T] = XmCreateText (f_w, "PlotTag", args, n);
- }
-
- 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++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 5); n++;
- if (i == -1) {
- w = XmCreateLabel (f_w, "X", args, n);
- XtManageChild (w);
- } else {
- table_w[i][X] = XmCreateLabel (f_w, "PlotX", args, n);
- }
-
- 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, 6); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 9); n++;
- if (i == -1) {
- w = XmCreateLabel (f_w, "Y", args, n);
- XtManageChild (w);
- } else {
- table_w[i][Y] = XmCreateLabel (f_w, "PlotY", args, n);
- }
- }
-
- /* create a separator */
-
- n = 0;
- w = XmCreateSeparator (rc_w, "Sep", args, n);
- XtManageChild (w);
-
- /* make a form to hold the close and help buttons evenly */
-
- n = 0;
- XtSetArg (args[n], XmNfractionBase, 7); n++;
- f_w = XmCreateForm (rc_w, "PlotCF", args, n);
- XtManageChild(f_w);
-
- 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, 1); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 3); n++;
- w = XmCreatePushButton (f_w, "Close", args, n);
- XtAddCallback (w, XmNactivateCallback, plt_close_cb, 0);
- XtManageChild (w);
-
- 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, 4); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 6); n++;
- w = XmCreatePushButton (f_w, "Help", args, n);
- XtAddCallback (w, XmNactivateCallback, plt_help_cb, 0);
- XtManageChild (w);
- }
-
- /* callback from any of the plot menu toggle buttons being activated.
- */
- /* ARGSUSED */
- static void
- plt_activate_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
- int what = (int) client;
-
- switch (what) {
- case SELECT:
- if (t->set) {
- /* first turn off plotting, if on, while we change things */
- if (XmToggleButtonGetState(active_w))
- XmToggleButtonSetState(active_w, False, True);
- plt_reset(); /* reset pltlines array and unmanage the table*/
- plt_select(1); /* inform other menus to inform us of fields */
- init_next_tag();/* set first tag to something and show it */
- selecting_xy = X;
- } else
- plt_stop_selecting();
- break;
- case ACTIVE:
- if (t->set) {
- /* first turn off selecting, if on */
- if (XmToggleButtonGetState(select_w))
- XmToggleButtonSetState(select_w, False, True);
- plt_try_turn_on();
- } else
- plt_turn_off();
- break;
- case SHOW:
- /* turn off plotting, if on, to make sure file is complete. */
- if (XmToggleButtonGetState(active_w))
- XmToggleButtonSetState(active_w, False, True);
- plt_da_manage();
- /* we want this to work like it was a pushbutton, really */
- XmToggleButtonSetState(w, False, False);
- break;
- }
- }
-
- /* callback from the Close button.
- */
- /* ARGSUSED */
- static void
- plt_close_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XtUnmanageChild (plotform_w);
- }
-
- /* callback from the Help button.
- */
- /* ARGSUSED */
- static void
- plt_help_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- static char *help_msg[] = {
- "This menu controls the plot generation and display functionality of xephem.",
- "Select fields to form x/y pairs, enable plotting to write them to a file on",
- "each xephem iteration step, then view. Each file may be titled, as desired."
- };
- hlp_dialog ("Plot", help_msg, sizeof(help_msg)/sizeof(help_msg[0]));
- }
-
- /* forget our list, and unmanage the table.
- */
- static void
- plt_reset()
- {
- int i;
-
- for (i = 0; i < npltlines; i++) {
- XtUnmanageChild (table_w[i][T]);
- XtUnmanageChild (table_w[i][X]);
- XtUnmanageChild (table_w[i][Y]);
- }
-
- npltlines = 0;
- }
-
- /* stop selecting: unmanage a partitially filled in line specs; tell
- * everybody else to drop their buttons, make sure toggle is off.
- */
- static void
- plt_stop_selecting()
- {
- /* harmless to unmanage something already unmanaged so do them all */
- if (npltlines < MAXPLTLINES) {
- XtUnmanageChild (table_w[npltlines][T]);
- XtUnmanageChild (table_w[npltlines][X]);
- XtUnmanageChild (table_w[npltlines][Y]);
- }
-
- XmToggleButtonSetState (select_w, False, False);
- plt_select(0);
- XtUnmanageChild (prompt_w);
- }
-
- static void
- plt_turn_off ()
- {
- if (plt_fp) {
- (void) fclose (plt_fp);
- plt_fp = 0;
- }
- }
-
- static void
- init_next_tag()
- {
- char buf[100];
- Widget w = table_w[npltlines][T];
-
- XtManageChild (prompt_w);
- f_string (prompt_w, "Select quantity for X..");
- (void) sprintf (buf, "%c", 'A' + npltlines);
- XmTextSetString (w, buf);
- XtManageChild (w);
- }
-
- /* called from the query routine when want to append to an existing plot file.*/
- static void
- plt_try_append()
- {
- plt_turn_on("a");
- }
-
- /* called from the query routine when want to overwrite to an existing plot
- * file.
- */
- static void
- plt_try_overwrite()
- {
- plt_turn_on("w");
- }
-
- /* called from the query routine when want decided not to make a plot file. */
- static void
- plt_try_cancel()
- {
- XmToggleButtonSetState (active_w, False, False);
- }
-
- /* attempt to open file for use as a plot file.
- * if it doesn't exist, then go ahead and make it.
- * but if it does, first ask wheher to append or overwrite.
- */
- static void
- plt_try_turn_on()
- {
- char *txt = XmTextGetString (filename_w);
- if (access (txt, 0) == 0) {
- char *buf;
- buf = XtMalloc (strlen(txt)+100);
- (void) sprintf (buf, "%s exists: Append or Overwrite?", txt);
- query (toplevel_w, buf, "Append", "Overwrite", "Cancel",
- plt_try_append, plt_try_overwrite, plt_try_cancel);
- XtFree (buf);
- } else
- plt_turn_on("w");
- XtFree (txt);
- }
-
- /* turn on plotting.
- * establish a file to use (and thereby set plt_fp, the plotting_is_on flag).
- */
- static void
- plt_turn_on (how)
- char *how; /* fopen how argument */
- {
- char *txt;
-
- /* plotting is on if file opens ok */
- txt = XmTextGetString (filename_w);
- plt_fp = fopen (txt, how);
- if (!plt_fp) {
- char *buf;
- XmToggleButtonSetState (active_w, False, False);
- buf = XtMalloc (strlen(txt)+100);
- (void) sprintf (buf, "Can not open %s: %s", txt, errsys);
- xe_msg (buf, 1);
- XtFree (buf);
- }
- XtFree (txt);
-
- if (plt_fp) {
- /* add a title if it's not null */
- txt = XmTextGetString (title_w);
- if (txt[0] != '\0')
- (void) fprintf (plt_fp, "* %s\n", txt);
- XtFree (txt);
- }
- }
-
- /* make a new drawing area widget and manage it. it's unmanaged and destroyed
- * from the Close button or if something goes wrong during plotting.
- * open the plot file and save it, the current state of the flipx/flipy/grid
- * buttons and the filename in a DrawInfo struct in the userData resource
- * for the FormDialog where the drawingarea callback can get at it each time.
- * this way, we can have lots of different plots up at once yet we don't
- * have to keep track of them.
- * by leaving the file open, we gain some protection against it being removed
- * or renamed.
- */
- static void
- plt_da_manage()
- {
- Widget daform_w;
- Widget da_w, w;
- Widget ctl_w;
- Widget fr_w;
- XmString str;
- Arg args[20];
- char titlebuf[64];
- int n;
- DrawInfo *di;
- FILE *fp;
- char *fn;
-
- /* first make sure we can open the plot file */
- fn = XmTextGetString (filename_w);
- fp = fopen (fn, "r");
- if (!fp) {
- char *buf;
- buf = XtMalloc (strlen(fn)+100);
- (void) sprintf (buf, "Can not open %s: %s", fn, errsys);
- xe_msg (buf, 1);
- XtFree (buf);
- XtFree (fn);
- return;
- }
-
- /* create the form dialog parent.
- * arrange for it to be square when it first comes up.
- */
- n = 0;
- daform_w = XmCreateFormDialog (toplevel_w, "PlotD", args, n);
- XtAddCallback (daform_w, XmNmapCallback, plt_daform_map_cb, NULL);
-
- /* set some stuff in the parent DialogShell.
- * setting XmNdialogTitle in the Form didn't work..
- */
- (void) sprintf (titlebuf, "xephem Plot of `%.*s'", sizeof(titlebuf)-20,
- fn);
- n = 0;
- XtSetArg (args[n], XmNtitle, titlebuf); n++;
- XtSetValues (XtParent(daform_w), args, n);
-
- /* make the DrawInfo structure and save it in the userData of the Form.
- * the memory gets freed when the the dialog is closed/unmanaged.
- */
- di = (DrawInfo *) XtMalloc (sizeof(DrawInfo));
- di->filename = fn;
- di->fp = fp;
- di->flipx = 0;
- di->flipy = 0;
- di->grid = 0;
- set_something (daform_w, XmNuserData, (char *)di);
-
- /* make a form for the bottom controls */
-
- n = 0;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNverticalSpacing, 5); n++;
- XtSetArg (args[n], XmNfractionBase, 17); n++;
- ctl_w = XmCreateForm (daform_w, "CtlF", args, n);
- XtManageChild (ctl_w);
-
- /* create the drawing area and connect plt_da_exp_cb().
- * N.B. be sure this guys parent is the FormDialog so exp_cb can find
- * the DrawInfo by looking there at its userData.
- * make this as high as it is wide when it is first mapped.
- * N.B. if ever want this is a frame beware that other functions
- * assume that the daform_w is the parent of the DrawingArea.
- */
- n = 0;
- XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
- XtSetArg (args[n], XmNbottomWidget, ctl_w); n++;
- XtSetArg (args[n], XmNbottomOffset, 2); n++;
- XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg (args[n], XmNmarginWidth, 0); n++;
- XtSetArg (args[n], XmNmarginHeight, 0); n++;
- da_w = XmCreateDrawingArea (daform_w, "PlotDA", args, n);
- XtAddCallback (da_w, XmNexposeCallback, plt_da_exp_cb, NULL);
- XtManageChild (da_w);
-
- /* make the flipx/y and grid toggle buttons (within frames) and the
- * close button in the control form
- */
-
- 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, 1); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 4); n++;
- fr_w = XmCreateFrame (ctl_w, "FlipXF", args, n);
- XtManageChild (fr_w);
- str = XmStringCreate("Flip X", XmSTRING_DEFAULT_CHARSET);
- n = 0;
- XtSetArg (args[n], XmNlabelString, str); n++;
- XtSetArg (args[n], XmNset, di->flipx); n++;
- w = XmCreateToggleButton(fr_w, "FlipX", args, n);
- XmStringFree (str);
- XtAddCallback (w, XmNvalueChangedCallback, plt_da_flipx_cb, da_w);
- XtManageChild (w);
-
- 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, 5); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 8); n++;
- fr_w = XmCreateFrame (ctl_w, "FlipYF", args, n);
- XtManageChild (fr_w);
- str = XmStringCreate("Flip Y", XmSTRING_DEFAULT_CHARSET);
- n = 0;
- XtSetArg (args[n], XmNlabelString, str); n++;
- XtSetArg (args[n], XmNset, di->flipy); n++;
- w = XmCreateToggleButton(fr_w, "FlipY", args, n);
- XmStringFree (str);
- XtAddCallback (w, XmNvalueChangedCallback, plt_da_flipy_cb, da_w);
- XtManageChild (w);
-
- 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, 9); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 12); n++;
- fr_w = XmCreateFrame (ctl_w, "GridF", args, n);
- XtManageChild (fr_w);
- n = 0;
- XtSetArg (args[n], XmNset, di->grid); n++;
- w = XmCreateToggleButton(fr_w, "Grid", args, n);
- XtAddCallback (w, XmNvalueChangedCallback, plt_da_grid_cb, da_w);
- XtManageChild (w);
-
- /* create a "Close" button.
- * it destroys the dialog and frees the DrawInfo struct.
- */
- 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, 13); n++;
- XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
- XtSetArg (args[n], XmNrightPosition, 16); n++;
- w = XmCreatePushButton (ctl_w, "Close", args, n);
- XtAddCallback (w, XmNactivateCallback, plt_da_close_cb, daform_w);
- XtManageChild (w);
-
- /* go. the expose will do the actual plotting */
- XtManageChild (daform_w);
- }
-
- /* called when finished with a plot with its FormDialog widget.
- * reclaim all memory in the userData DrawInfo and destroy it.
- * N.B. caller's daform_w is useless when this returns.
- */
- static void
- plt_da_destroy (daform_w)
- Widget daform_w;
- {
- DrawInfo *di;
-
- get_something (daform_w, XmNuserData, (char *)&di);
- (void) fclose (di->fp);
- XtFree(di->filename);
- XtFree((char *)di);
- XtDestroyWidget(daform_w);
- }
-
- /* called when a plot dialog is mapped.
- * set the height equal to the width.
- */
- /* ARGSUSED */
- static void
- plt_daform_map_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- Widget shell_w = XtParent(w);
- Dimension width;
- int iwidth;
-
- get_something (shell_w, XmNwidth, (char *)&width);
- iwidth = width;
- set_something (shell_w, XmNheight, (char *)iwidth);
- }
-
-
- /* called when the Close button is pushed on a plot.
- * free the DrawInfo and destroy the dialog (passed as client).
- */
- /* ARGSUSED */
- static void
- plt_da_close_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- plt_da_destroy ((Widget)client);
- }
-
- /* callback from the Flip X toggle button within the drawing FormDiag itself.
- * toggle the x bit in the parent's DrawInfo structure and fake an expose.
- * client is the DrawingArea widget.
- */
- /* ARGSUSED */
- static void
- plt_da_flipx_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
- Widget da_w = (Widget) client;
- Widget daform_w = XtParent(da_w);
- Display *dsp = XtDisplay(da_w);
- Window win = XtWindow(da_w);
- DrawInfo *di;
- XExposeEvent ev;
- Window root;
- int x, y;
- unsigned int nx, ny, bw, d;
-
- get_something (daform_w, XmNuserData, (char *)&di);
- di->flipx = t->set;
-
- XGetGeometry(dsp, win, &root, &x, &y, &nx, &ny, &bw, &d);
-
- ev.type = Expose;
- ev.send_event = 1; /* gets set anyways */
- ev.display = dsp;
- ev.window = win;
- ev.x = ev.y = 0;
- ev.width = nx;
- ev.height = ny;
- ev.count = 0;
-
- XSendEvent (dsp, win, /*propagate*/False, ExposureMask, (XEvent *)&ev);
- }
-
- /* callback from the Flip Y toggle button within the drawing FormDiag itself.
- * toggle the y bit in the parent's DrawInfo structure and fake an expose.
- * client is the DrawingArea widget.
- */
- /* ARGSUSED */
- static void
- plt_da_flipy_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
- Widget da_w = (Widget) client;
- Widget daform_w = XtParent(da_w);
- Display *dsp = XtDisplay(da_w);
- Window win = XtWindow(da_w);
- DrawInfo *di;
- XExposeEvent ev;
- Window root;
- int x, y;
- unsigned int nx, ny, bw, d;
-
- get_something (daform_w, XmNuserData, (char *)&di);
- di->flipy = t->set;
-
- XGetGeometry(dsp, win, &root, &x, &y, &nx, &ny, &bw, &d);
-
- ev.type = Expose;
- ev.send_event = 1; /* gets set anyways */
- ev.display = dsp;
- ev.window = win;
- ev.x = ev.y = 0;
- ev.width = nx;
- ev.height = ny;
- ev.count = 0;
-
- XSendEvent (dsp, win, /*propagate*/False, ExposureMask, (XEvent *)&ev);
- }
-
- /* callback from the grid toggle button within the drawing FormDiag itself.
- * toggle the grid flag in the parent's DrawInfo structure and fake an expose.
- * client is the DrawingArea widget.
- */
- /* ARGSUSED */
- static void
- plt_da_grid_cb (w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- XmToggleButtonCallbackStruct *t = (XmToggleButtonCallbackStruct *) call;
- Widget da_w = (Widget) client;
- Widget daform_w = XtParent(da_w);
- Display *dsp = XtDisplay(da_w);
- Window win = XtWindow(da_w);
- DrawInfo *di;
- XExposeEvent ev;
- Window root;
- int x, y;
- unsigned int nx, ny, bw, d;
-
- get_something (daform_w, XmNuserData, (char *)&di);
- di->grid = t->set;
-
- XGetGeometry(dsp, win, &root, &x, &y, &nx, &ny, &bw, &d);
-
- ev.type = Expose;
- ev.send_event = 1; /* gets set anyways */
- ev.display = dsp;
- ev.window = win;
- ev.x = ev.y = 0;
- ev.width = nx;
- ev.height = ny;
- ev.count = 0;
-
- XSendEvent (dsp, win, /*propagate*/False, ExposureMask, (XEvent *)&ev);
- }
-
- /* plot drawing area's expose callback.
- * redraw the graph to the (new?) size.
- * get a DrawInfo from our parent's userData.
- */
- /* ARGSUSED */
- static void
- plt_da_exp_cb (da_w, client, call)
- Widget da_w;
- XtPointer client;
- XtPointer call;
- {
- XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
- DrawInfo *di;
- Widget daform_w;
- XWindowAttributes xwa;
-
- switch (c->reason) {
- case XmCR_EXPOSE: {
- /* turn off gravity so we get expose events for either shrink or
- * expand if we have never seen this window before.
- */
- XExposeEvent *e = &c->event->xexpose;
-
- /* wait for the last in the series */
- if (e->count != 0)
- return;
-
- XGetWindowAttributes (e->display, e->window, &xwa);
- if (xwa.bit_gravity != ForgetGravity) {
- /* first expose for this window -- set no gravity */
- XSetWindowAttributes swa;
- swa.bit_gravity = ForgetGravity;
- XChangeWindowAttributes (e->display, e->window,
- CWBitGravity, &swa);
- }
- break;
- }
- default:
- printf ("Unexpected da_w event. type=%d\n", c->reason);
- exit(1);
- }
-
- /* use xwa for the drawing area window size.
- * get di from the FormDiaglog parent and plot fresh.
- */
-
- daform_w = XtParent(da_w);
- get_something (daform_w, XmNuserData, (char *)&di);
- XClearWindow (XtDisplay(da_w), XtWindow(da_w));
- rewind (di->fp);
- if (plot_cartesian (di->fp, da_w, xwa.width, xwa.height,
- di->flipx, di->flipy, di->grid) < 0) {
- /* had trouble, so done with this FormDialog.
- */
- char buf[128];
- (void) sprintf (buf, "Error plotting `%.*s'\n", sizeof(buf)-20,
- di->filename);
- xe_msg (buf, 0);
- plt_da_destroy (daform_w);
- }
- }
-