home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xephem / part19 / skyfiltmenu.c < prev   
Encoding:
C/C++ Source or Header  |  1993-05-15  |  16.4 KB  |  628 lines

  1. /* code to manage the stuff on the sky view filter display.
  2.  */
  3.  
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #include <math.h>
  7. #if defined(__STDC__)
  8. #include <stdlib.h>
  9. #endif
  10. #include <X11/Xlib.h>
  11. #include <Xm/Xm.h>
  12. #include <Xm/Form.h>
  13. #include <Xm/Frame.h>
  14. #include <Xm/DrawingA.h>
  15. #include <Xm/Label.h>
  16. #include <Xm/PushB.h>
  17. #include <Xm/RowColumn.h>
  18. #include <Xm/ToggleB.h>
  19. #include <Xm/Text.h>
  20. #include <Xm/Scale.h>
  21. #include <Xm/Separator.h>
  22. #include "astro.h"
  23. #include "circum.h"
  24.  
  25. /* info for each filter option toggle */
  26. typedef struct {
  27.     char *label;    /* label on the toggle button */
  28.     char *name;        /* name of toggle button, for resource setting */
  29.     int type;        /* as in Obj.type */
  30.     char class;        /* as in Obj.f.f_class */
  31.     char state;        /* 0 or 1 depending on whether this class is on */
  32.     Widget tbw;        /* the toggle button widget */
  33. } FilterTB;
  34.  
  35. /* info for a set of filters forming a category */
  36. typedef struct {
  37.     char *label;    /* label for this category */
  38.     FilterTB *ftb;    /* array of toggle button filters in this class */
  39.     int nftb;        /* entries in ftb[] */
  40.     Widget pbw;        /* the category "toggle" pushbutton */
  41. } FilterCat;
  42.  
  43. #if defined(__STDC__) || defined(__cplusplus)
  44. #define P_(s) s
  45. #else
  46. #define P_(s) ()
  47. #endif
  48.  
  49. extern Now *mm_get_now P_((void));
  50. extern void get_something P_((Widget w, char *resource, char *value));
  51. extern void prompt_map_cb P_((Widget w, XtPointer client, XtPointer call));
  52. extern void sv_all P_((Now *np, int preclr));
  53. extern void sv_draw_obj P_((Display *dsp, Drawable win, GC gc, Obj *op, int x, int y, int diam, int dotsonly));
  54.  
  55. void svf_create P_((void));
  56. void svf_manage_toggle P_((void));
  57. void svf_manage P_((void));
  58. void svf_unmanage P_((void));
  59. int svf_filter_ok P_((Obj *op));
  60. void svf_cursor P_((Cursor c));
  61. static void svf_create_filter P_((Widget mainrc, FilterCat *fcp));
  62. static void svf_reset P_((void));
  63. static void svf_apply P_((void));
  64. static void svf_da_cb P_((Widget w, XtPointer client, XtPointer call));
  65. static void svf_draw_symbol P_((FilterTB *ftbp, Widget daw));
  66. static void svf_apply_cb P_((Widget w, XtPointer client, XtPointer call));
  67. static void svf_ok_cb P_((Widget w, XtPointer client, XtPointer call));
  68. static void svf_close_cb P_((Widget w, XtPointer client, XtPointer call));
  69. static void svf_toggle_cb P_((Widget w, XtPointer client, XtPointer call));
  70. static void svf_all_cb P_((Widget w, XtPointer client, XtPointer call));
  71. static void svf_reset_cb P_((Widget w, XtPointer client, XtPointer call));
  72. static void svf_cat_toggle_cb P_((Widget w, XtPointer client, XtPointer call));
  73.  
  74. #undef P_
  75.  
  76. extern Widget toplevel_w;
  77. #define    XtD    XtDisplay(toplevel_w)
  78.  
  79. static FilterTB solsys_f[] = {
  80.     {"Planets",        "Planets",    PLANET,        0},
  81.     {"Elliptical",    "Elliptical",    ELLIPTICAL,    0},
  82.     {"Hyperbolic",    "Hyperbolic",    HYPERBOLIC,    0},
  83.     {"Parabolic",    "Parabolic",    PARABOLIC,    0}
  84. };
  85.  
  86. static FilterTB other_f[] = {
  87.     {"Q Quasars",     "Quasars",    FIXED,        'Q'},
  88.     {"T Stellar",    "Stellar",    FIXED,        'T'},
  89.     {"Undefined",    "Undefined",    FIXED,        '\0'}
  90. };
  91.  
  92. static FilterTB stars_f[] = {
  93.     {"S Single",    "Stars",    FIXED,        'S'},
  94.     {"B Binary",    "Binary",    FIXED,        'B'},
  95.     {"D Double",    "Double",    FIXED,        'D'},
  96.     {"M Multiple",    "Multiple",    FIXED,        'M'},
  97.     {"V Variable",    "Variable",    FIXED,        'V'}
  98. };
  99.  
  100. static FilterTB nebulea_f[] = {
  101.     {"N Bright",    "BrightNeb",    FIXED,        'N'},
  102.     {"F Diffuse",    "DiffuseNeb",    FIXED,        'F'},
  103.     {"K Dark",        "DarkNeb",    FIXED,        'K'},
  104.     {"P Planetary",    "PlanetaryNeb",    FIXED,        'P'}
  105. };
  106.  
  107. static FilterTB galaxies_f[] = {
  108.     {"G Spiral",    "SpiralGal",    FIXED,        'G'},
  109.     {"H Spherical",    "SphericalGal",    FIXED,        'H'},
  110.     {"A Clusters",    "GalClusters",    FIXED,        'A'}
  111. };
  112.  
  113. static FilterTB clusters_f[] = {
  114.     {"C Globular",    "GlobularCl",    FIXED,        'C'},
  115.     {"O Open",        "OpenCl",    FIXED,        'O'},
  116.     {"U in Nebula",    "ClInNeb",    FIXED,        'U'}
  117. };
  118.  
  119. static FilterCat filters[] = {
  120.     {"Solar System:",    solsys_f,    XtNumber(solsys_f)},
  121.     {"Clusters:",    clusters_f,    XtNumber(clusters_f)},
  122.     {"Galaxies:",    galaxies_f,    XtNumber(galaxies_f)},
  123.     {"Nebulea:",    nebulea_f,    XtNumber(nebulea_f)},
  124.     {"Stars:",        stars_f,    XtNumber(stars_f)},
  125.     {"Other:",        other_f,    XtNumber(other_f)}
  126. };
  127.  
  128. /* these form rapid lookup tables for the state of an object.
  129.  * they can be directly indexed by Obj.type and Obj.f.f_class, respectively.
  130.  */
  131. static char fclass_table[128];
  132. static char type_table[10];
  133.  
  134. static Widget filter_w;
  135.  
  136. /* create, but do not manage, the filter dialog.
  137.  * we also apply its state info immediately to the initial resource
  138.  * settings of the toggle buttons are used to set up the real filter
  139.  * right away.
  140.  */
  141. void
  142. svf_create()
  143. {
  144.     static struct {
  145.         char *name;
  146.         void (*cb)();
  147.     } ctls[] = {
  148.         {"Ok", svf_ok_cb},
  149.         {"Apply", svf_apply_cb},
  150.         {"All", svf_all_cb},
  151.         {"Toggle All", svf_toggle_cb},
  152.         {"Reset", svf_reset_cb},
  153.         {"Close", svf_close_cb}
  154.     };
  155.     Arg args[20];
  156.     XmString str;
  157.     Widget w;
  158.     Widget ctlf_w;
  159.     Widget topsep_w, botsep_w;
  160.     Widget hrc_w;
  161.     int n;
  162.     int i;
  163.  
  164.     /* create form */
  165.     n = 0;
  166.     XtSetArg (args[n], XmNautoUnmanage, False); n++;
  167.     XtSetArg (args[n], XmNdefaultPosition, False); n++;
  168.     filter_w = XmCreateFormDialog (toplevel_w, "SkyFilter", args, n);
  169.     XtAddCallback (filter_w, XmNmapCallback, prompt_map_cb, NULL);
  170.  
  171.     /* set some stuff in the parent DialogShell.
  172.      * setting XmNdialogTitle in the Form didn't work..
  173.      */
  174.     n = 0;
  175.     XtSetArg (args[n], XmNtitle, "xephem Sky view Filter"); n++;
  176.     XtSetValues (XtParent(filter_w), args, n);
  177.  
  178.     /* make a separator across the top */
  179.  
  180.     n = 0;
  181.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  182.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  183.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  184.     topsep_w = XmCreateSeparator (filter_w, "TopSep", args, n);
  185.     XtManageChild (topsep_w);
  186.  
  187.     /* make a form for bottom control panel */
  188.  
  189.     n = 0;
  190.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  191.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  192.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  193.     XtSetArg (args[n], XmNfractionBase, 25); n++;
  194.     XtSetArg (args[n], XmNverticalSpacing, 5); n++;
  195.     ctlf_w = XmCreateForm (filter_w, "SVControlF", args, n);
  196.     XtManageChild (ctlf_w);
  197.  
  198.         /* add the control buttons */
  199.  
  200.         for (i = 0; i < XtNumber(ctls); i++) {
  201.         str = XmStringCreateLtoR(ctls[i].name,XmSTRING_DEFAULT_CHARSET);
  202.         n = 0;
  203.         XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  204.         XtSetArg (args[n], XmNleftPosition, 1+i*4); n++;
  205.         XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  206.         XtSetArg (args[n], XmNrightPosition, 4+i*4); n++;
  207.         XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  208.         XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  209.         XtSetArg (args[n], XmNlabelString, str); n++;
  210.         w = XmCreatePushButton (ctlf_w, "FilterCB", args, n);
  211.         XtManageChild(w);
  212.         XmStringFree (str);
  213.         XtAddCallback (w, XmNactivateCallback, ctls[i].cb, NULL);
  214.         }
  215.  
  216.     /* put a separator on top of the control panel */
  217.  
  218.     n = 0;
  219.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  220.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  221.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  222.     XtSetArg (args[n], XmNbottomWidget, ctlf_w); n++;
  223.     botsep_w = XmCreateSeparator (filter_w, "BotSep", args, n);
  224.     XtManageChild (botsep_w);
  225.  
  226.     /* make a horizontal rowcol to contain each column */
  227.  
  228.     n = 0;
  229.     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  230.     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  231.     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  232.     XtSetArg (args[n], XmNbottomWidget, botsep_w); n++;
  233.     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  234.     XtSetArg (args[n], XmNtopWidget, topsep_w); n++;
  235.     XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
  236.     XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
  237.     XtSetArg (args[n], XmNspacing, 0); n++;
  238.     XtSetArg (args[n], XmNmarginWidth, 0); n++;
  239.     hrc_w = XmCreateRowColumn (filter_w, "CategoryTableRC", args, n);
  240.     XtManageChild (hrc_w);
  241.  
  242.     /* fill the horizontal rc with each FilterCat */
  243.  
  244.     for (i = 0; i < XtNumber(filters); i++)
  245.         svf_create_filter (hrc_w, &filters[i]);
  246.  
  247.     /* set the real filter according to the state of the toggle buttons */
  248.     svf_apply();
  249. }
  250.  
  251. /* called to toggle whether the filter dialog is up.
  252.  * whenever we are managed, reset the state of the toggle buttons back
  253.  * to the way the real filter is.
  254.  */
  255. void
  256. svf_manage_toggle ()
  257. {
  258.     if (XtIsManaged(filter_w))
  259.         svf_unmanage();
  260.     else
  261.         svf_manage();
  262. }
  263.  
  264. /* called to manage the filer dialog.
  265.  * whenever we are managed, reset the state of the toggle buttons back
  266.  * to the way the real filter is.
  267.  */
  268. void
  269. svf_manage()
  270. {
  271.     svf_reset();
  272.     XtManageChild(filter_w);
  273. }
  274.  
  275. void
  276. svf_unmanage()
  277. {
  278.     XtUnmanageChild(filter_w);
  279. }
  280.  
  281. /* return 1 if p satisfies the stuff in the filter dialog, else 0.
  282.  * N.B. because svf_apply() has to have already been called we do not need
  283.  *   to range check the type and class.
  284.  */
  285. svf_filter_ok (op)
  286. Obj *op;
  287. {
  288.     int t = op->type;
  289.  
  290.     if (t == FIXED)
  291.         return (fclass_table[op->f_class]);
  292.     else
  293.         return (type_table[t]);
  294. }
  295.  
  296. /* called to put up or remove the watch cursor.  */
  297. void
  298. svf_cursor (c)
  299. Cursor c;
  300. {
  301.     Window win;
  302.  
  303.     if (filter_w && (win = XtWindow(filter_w))) {
  304.         Display *dsp = XtDisplay(filter_w);
  305.         if (c)
  306.         XDefineCursor (dsp, win, c);
  307.         else
  308.         XUndefineCursor (dsp, win);
  309.     }
  310. }
  311.  
  312. /* create one FilterCat filter category in the given RowColumn */
  313. static void
  314. svf_create_filter (mainrc, fcp)
  315. Widget mainrc;
  316. FilterCat *fcp;
  317. {
  318.     Arg args[20];
  319.     Widget l_w;
  320.     Widget rc_w;    /* rc for the label and controls */
  321.     Widget fr_w, da_w;
  322.     Widget w;
  323.     int n;
  324.     int i;
  325.  
  326.     /* make a rc within a frame for the tb rowcol */
  327.  
  328.     n = 0;
  329.     fr_w = XmCreateFrame (mainrc, "Frame", args, n);
  330.     XtManageChild (fr_w);
  331.     n = 0;
  332.     XtSetArg (args[n], XmNmarginWidth, 0); n++;
  333.     XtSetArg (args[n], XmNisAligned, False); n++;
  334.     rc_w = XmCreateRowColumn (fr_w, "CategoryRC", args, n);
  335.     XtManageChild (rc_w);
  336.  
  337.     /* make a label for the category */
  338.  
  339.     n = 0;
  340.     XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  341.     l_w = XmCreateLabel (rc_w, fcp->label, args, n);
  342.     XtManageChild (l_w);
  343.  
  344.     /* make a pushbutton used to toggle all entries in this category */
  345.     n = 0;
  346.     XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  347.     w = XmCreatePushButton (rc_w, "Toggle", args, n);
  348.     XtAddCallback (w, XmNactivateCallback, svf_cat_toggle_cb,
  349.                                 (XtPointer)fcp);
  350.     XtManageChild (w);
  351.  
  352.     /* add each filter */
  353.  
  354.     for (i = 0; i < fcp->nftb; i++) {
  355.         Widget f_w;
  356.         Widget tb_w;
  357.         FilterTB *ftbp = &fcp->ftb[i];
  358.         XmString str;
  359.  
  360.         n = 0;
  361.         f_w = XmCreateForm (rc_w, "FTBF", args, n);
  362.         XtManageChild (f_w);
  363.  
  364.         /* create a frame around a drawing area in which to show the
  365.          * object symbol
  366.          */
  367.         n = 0;
  368.         XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  369.         XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  370.         XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  371.         XtSetArg (args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
  372.         fr_w = XmCreateFrame (f_w, "SymbolF", args, n);
  373.         XtManageChild (fr_w);
  374.         n = 0;
  375.         da_w = XmCreateDrawingArea (fr_w, "SymbolDA", args, n);
  376.         XtAddCallback (da_w, XmNexposeCallback, svf_da_cb,
  377.                                 (XtPointer)ftbp);
  378.         XtManageChild (da_w);
  379.  
  380.         /* create the filter selection toggle button */
  381.  
  382.         str = XmStringCreateLtoR (ftbp->label,XmSTRING_DEFAULT_CHARSET);
  383.         n = 0;
  384.         XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  385.         XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  386.         XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  387.         XtSetArg (args[n], XmNleftWidget, fr_w); n++;
  388.         XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  389.         XtSetArg (args[n], XmNlabelString, str); n++;
  390.         XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  391.         tb_w = XmCreateToggleButton (f_w, ftbp->name, args, n);
  392.         XmStringFree(str);
  393.         XtManageChild (tb_w);
  394.         ftbp->tbw = tb_w;
  395.     }
  396. }
  397.  
  398. /* set the toggle button states according to the real filter states.
  399.  */
  400. static void
  401. svf_reset()
  402. {
  403.     int i, j;
  404.  
  405.     for (i = 0; i < XtNumber(filters); i++) {
  406.         FilterCat *fcp = &filters[i];
  407.         for (j = 0; j < fcp->nftb; j++) {
  408.         FilterTB *ftbp = &fcp->ftb[j];
  409.         XmToggleButtonSetState (ftbp->tbw, ftbp->state, True);
  410.         }
  411.     }
  412. }
  413.  
  414. /* set the filter according to the present state of the toggle buttons.
  415.  */
  416. static void
  417. svf_apply()
  418. {
  419.     int i, j;
  420.  
  421.     for (i = 0; i < XtNumber(filters); i++) {
  422.         FilterCat *fcp = &filters[i];
  423.         for (j = 0; j < fcp->nftb; j++) {
  424.         FilterTB *ftbp = &fcp->ftb[j];
  425.         int t = ftbp->type;
  426.         if (t < 0 || t >= XtNumber(type_table)) {
  427.             printf ("svf_apply: type out of range: %d\n", t);
  428.             exit (1);
  429.         }
  430.         ftbp->state = XmToggleButtonGetState (ftbp->tbw);
  431.         if (ftbp->type == FIXED) {
  432.             int c = ftbp->class;
  433.             if (c < 0 || c >= XtNumber(fclass_table)) {
  434.             printf ("svf_apply: FIXED class out of range: %d\n", c);
  435.             exit (1);
  436.             }
  437.             fclass_table[c] = ftbp->state;
  438.         } else
  439.             type_table[t] = ftbp->state;
  440.         }
  441.     }
  442. }
  443.  
  444. /* called when a symbol drawing area is exposed.
  445.  * client is a pointer to the FilterTB.
  446.  */
  447. /* ARGSUSED */
  448. static void
  449. svf_da_cb (w, client, call)
  450. Widget w;
  451. XtPointer client;
  452. XtPointer call;
  453. {
  454.     XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
  455.     FilterTB *ftbp = (FilterTB *) client;
  456.  
  457.     switch (c->reason) {
  458.     case XmCR_EXPOSE: {
  459.         /* turn off gravity so we get expose events for either shrink or
  460.          * expand.
  461.          */
  462.         static before;
  463.         XExposeEvent *e = &c->event->xexpose;
  464.  
  465.         if (!before) {
  466.         XSetWindowAttributes swa;
  467.         swa.bit_gravity = ForgetGravity;
  468.         XChangeWindowAttributes (e->display, e->window, 
  469.                                 CWBitGravity, &swa);
  470.         before = 1;
  471.         }
  472.         /* wait for the last in the series */
  473.         if (e->count != 0)
  474.         return;
  475.         }
  476.         break;
  477.     default:
  478.         return;
  479.     }
  480.  
  481.     svf_draw_symbol(ftbp, w);
  482. }
  483.  
  484. /* draw the symbol used for the object described by ftbp into the
  485.  * DrawingArea widget daw.
  486.  */
  487. static void
  488. svf_draw_symbol(ftbp, daw)
  489. FilterTB *ftbp;
  490. Widget daw;
  491. {
  492.     static GC gc;
  493.     Display *dsp = XtDisplay(daw);
  494.     Window win = XtWindow(daw);
  495.     Obj obj;
  496.     Dimension w, h;
  497.     int diam;
  498.  
  499.     obj.type = ftbp->type;
  500.     if (ftbp->type == FIXED)
  501.         obj.f_class = ftbp->class;
  502.  
  503.     get_something (daw, XmNwidth, (char *)&w);
  504.     get_something (daw, XmNheight, (char *)&h);
  505.     diam = (w > h ? h : w) - 2;
  506.  
  507.     if (!gc) {
  508.         XGCValues gcv;
  509.         unsigned gcm;
  510.         Pixel p;
  511.  
  512.         gcm = GCForeground;
  513.         get_something (daw, XmNforeground, (char *)&p);
  514.         gcv.foreground = p;
  515.         gc = XCreateGC (dsp, win, gcm, &gcv);
  516.     }
  517.  
  518.     /* use diam-2 to allow for a little overflow on some symbols */
  519.     sv_draw_obj (dsp, win, gc, &obj, (int)w/2, (int)h/2, diam-2, 0);
  520.     sv_draw_obj (dsp, win, gc, NULL, 0, 0, 0, 0);    /* flush */
  521. }
  522.  
  523. /* called when Apply is pushed on the filter dialog */
  524. /* ARGSUSED */
  525. static void
  526. svf_apply_cb (w, client, call)
  527. Widget w;
  528. XtPointer client;
  529. XtPointer call;
  530. {
  531.     svf_apply();
  532.     sv_all(mm_get_now(), 1);
  533. }
  534.  
  535. /* called when Ok is pushed on the filter dialog */
  536. /* ARGSUSED */
  537. static void
  538. svf_ok_cb (w, client, call)
  539. Widget w;
  540. XtPointer client;
  541. XtPointer call;
  542. {
  543.     svf_apply();
  544.     sv_all(mm_get_now(), 1);
  545.     XtUnmanageChild (filter_w);
  546. }
  547.  
  548. /* called when Close is pushed on the filter dialog */
  549. /* ARGSUSED */
  550. static void
  551. svf_close_cb (w, client, call)
  552. Widget w;
  553. XtPointer client;
  554. XtPointer call;
  555. {
  556.     XtUnmanageChild (filter_w);
  557. }
  558.  
  559. /* called when Toggle is pushed on the filter dialog */
  560. /* ARGSUSED */
  561. static void
  562. svf_toggle_cb (w, client, call)
  563. Widget w;
  564. XtPointer client;
  565. XtPointer call;
  566. {
  567.     int i, j;
  568.  
  569.     for (i = 0; i < XtNumber(filters); i++) {
  570.         FilterCat *fcp = &filters[i];
  571.         for (j = 0; j < fcp->nftb; j++) {
  572.         FilterTB *ftbp = &fcp->ftb[j];
  573.         XmToggleButtonSetState (ftbp->tbw, 
  574.             !XmToggleButtonGetState(ftbp->tbw), True);
  575.         }
  576.     }
  577. }
  578.  
  579. /* called when All is pushed on the filter dialog */
  580. /* ARGSUSED */
  581. static void
  582. svf_all_cb (w, client, call)
  583. Widget w;
  584. XtPointer client;
  585. XtPointer call;
  586. {
  587.     int i, j;
  588.  
  589.     for (i = 0; i < XtNumber(filters); i++) {
  590.         FilterCat *fcp = &filters[i];
  591.         for (j = 0; j < fcp->nftb; j++) {
  592.         FilterTB *ftbp = &fcp->ftb[j];
  593.         XmToggleButtonSetState (ftbp->tbw, True, True);
  594.         }
  595.     }
  596. }
  597.  
  598. /* called when Reset is pushed on the filter dialog */
  599. /* ARGSUSED */
  600. static void
  601. svf_reset_cb (w, client, call)
  602. Widget w;
  603. XtPointer client;
  604. XtPointer call;
  605. {
  606.     svf_reset();
  607. }
  608.  
  609. /* called when the "Toggle" button is activated on a particular category.
  610.  * client is the FilterCat pointer.
  611.  */
  612. /* ARGSUSED */
  613. static void
  614. svf_cat_toggle_cb (w, client, call)
  615. Widget w;
  616. XtPointer client;
  617. XtPointer call;
  618. {
  619.     FilterCat *fcp = (FilterCat *) client;
  620.     int i;
  621.  
  622.     for (i = 0; i < fcp->nftb; i++) {
  623.         FilterTB *ftbp = &fcp->ftb[i];
  624.         XmToggleButtonSetState (ftbp->tbw, 
  625.         !XmToggleButtonGetState(ftbp->tbw), True);
  626.     }
  627. }
  628.