home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / viewres / viewres.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-23  |  34.2 KB  |  1,216 lines

  1. /*
  2.  * $XConsortium: viewres.c,v 1.72 91/07/23 21:04:33 converse Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted, provided
  8.  * that the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising
  11.  * or publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Jim Fulton, MIT X Consortium
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <X11/StringDefs.h>
  28. #include <X11/IntrinsicP.h>
  29. #include <X11/Xaw/Cardinals.h>
  30. #include <X11/Xaw/Box.h>
  31. #include <X11/Xaw/Form.h>
  32. #include <X11/Xaw/Command.h>
  33. #include <X11/Xaw/MenuButton.h>
  34. #include <X11/Xaw/SimpleMenu.h>
  35. #include <X11/Xaw/Sme.h>
  36. #include <X11/Xaw/SmeBSB.h>
  37. #include <X11/Xaw/SmeLine.h>
  38. #include <X11/Xaw/Paned.h>
  39. #include <X11/Xaw/Porthole.h>
  40. #include <X11/Xaw/Toggle.h>
  41. #include <X11/Xaw/Text.h>
  42. #include <X11/Xaw/List.h>
  43. #include <X11/Xaw/Scrollbar.h>
  44. #include <X11/Xaw/Panner.h>
  45. #include <X11/Xaw/Tree.h>
  46. #include <X11/Xmu/Converters.h>
  47. #include <X11/Xmu/CharSet.h>
  48. #include <X11/Xmu/WidgetNode.h>
  49. #include <X11/Xaw/AllWidgets.h>
  50.  
  51. extern char *malloc(), *calloc();
  52.  
  53. #define widget_list XawWidgetArray  /* or motif or ol or ... */
  54. #define nwidgets XawWidgetCount
  55.  
  56. typedef struct {
  57.     char **resource_labels;        /* names of res added by widget */
  58.     Cardinal nnewresources;        /* number res added by widget */
  59.     Cardinal nnewconstraints;        /* number res added by widget */
  60.     Cardinal nnew;            /* number new */
  61.     Widget instance;            /* Label widget in box in tree */
  62.     Widget resource_lw;            /* List widget showing resources */
  63.     int selection_index;        /* -1 or index into selection_list */
  64. } ViewresData;
  65.  
  66. #define VData(node) ((ViewresData *) (node)->data)
  67.  
  68.  
  69. #define IsShowing(node) (VData(node)->resource_lw && \
  70.              XtIsManaged(VData(node)->resource_lw))
  71.  
  72.  
  73. struct {
  74.     int n_elements;
  75.     int max_elements;
  76.     XmuWidgetNode **elements;
  77. } selected_list = { 0, 0, (XmuWidgetNode **) NULL };
  78.  
  79. #define INSERT_NODE(node,i) \
  80.   selected_list.elements[VData(node)->selection_index = (i)] = (node)
  81.  
  82. #define REMOVE_NODE(node) \
  83.   selected_list.elements[VData(node)->selection_index] = \
  84.   (XmuWidgetNode *) NULL; VData(node)->selection_index = (-1)
  85.  
  86. char *ProgramName;
  87. static int NumberShowing = 0;
  88.  
  89. static Arg sensitiveargs[2] = {{ XtNsensitive, (XtArgVal) FALSE },
  90.                    { XtNsensitive, (XtArgVal) TRUE }};
  91.  
  92. static char *help_message[] = {
  93.     "-top name        object to be top of tree",
  94.     "-variable        show variable name instead of class name",
  95.     "-vertical        list the tree vertically",
  96.     (char *) NULL
  97. };
  98.  
  99. static XrmOptionDescRec Options[] = {
  100.     { "-top", "*topObject", XrmoptionSepArg, (XPointer) NULL },
  101.     { "-variable", "*showVariable", XrmoptionNoArg, (XPointer) "on" },
  102.     { "-vertical", "*Tree.Gravity", XrmoptionNoArg, (XPointer) "north" }
  103. };
  104.  
  105.  
  106. typedef struct {
  107.     char *top_object;
  108.     Boolean show_variable;
  109. } OptionsRec;
  110.  
  111. static OptionsRec options;
  112.  
  113. #define Offset(field) XtOffsetOf(OptionsRec, field)
  114.  
  115. static XtResource Resources[] = {
  116.     { "topObject", "TopObject", XtRString, sizeof(char *),
  117.     Offset(top_object), XtRString, (XtPointer) "object" },
  118.     { "showVariable", "ShowVariable", XtRBoolean, sizeof(Boolean),
  119.     Offset(show_variable), XtRImmediate, (XtPointer) FALSE },
  120. };
  121.  
  122. #undef Offset
  123.  
  124. static char *fallback_resources[] = {
  125.     "*allowShellResize: true",
  126.     "*Porthole.top: ChainTop",
  127.     "*Porthole.left: ChainLeft",
  128.     "*Porthole.bottom: ChainBottom",
  129.     "*Porthole.right:  ChainRight",
  130.     "*Porthole.resizable: on",
  131.     "*Panner.top: ChainTop",
  132.     "*Panner.left: ChainLeft",
  133.     "*Panner.bottom: ChainTop",
  134.     "*Panner.right:  ChainLeft",
  135.     "*Panner.resizable: on",
  136.     "*Tree*ShapeStyle: rectangle",
  137.     "*Tree*Toggle*BorderWidth: 0",
  138.     "*Porthole*Box.BorderWidth: 0",
  139.     "*Porthole*Box.HSpace: 0",
  140.     "*Porthole*Box.VSpace: 0",
  141.     "*Paned*allowResize: true",
  142.     "*buttonbox.quit.Translations:  #override \\n <Btn1Down>,<Btn1Up>: Quit() unset()",
  143.     "*Toggle.Translations: #augment \\n <Btn2Down>,<Btn2Up>: set() notify() Resources(toggle)",
  144.     (char *) NULL
  145. };
  146.  
  147. static void ActionQuit(), ActionSetLableType(), ActionSetOrientation();
  148. static void ActionSelect(), ActionResources();
  149. static void set_labeltype_menu(), set_orientation_menu();
  150. static void build_tree(), set_node_labels();
  151.  
  152. static XtActionsRec viewres_actions[] = {
  153.     { "Quit", ActionQuit },
  154.     { "SetLabelType", ActionSetLableType },
  155.     { "SetOrientation", ActionSetOrientation },
  156.     { "Select", ActionSelect },
  157.     { "Resources", ActionResources },
  158. };
  159.  
  160. static Atom wm_delete_window;
  161.  
  162. #define BOOL_OFF 0
  163. #define BOOL_ON 1
  164. #define BOOL_TOGGLE 2
  165.  
  166. #define VIEW_HORIZONTAL 0
  167. #define VIEW_VERTICAL 1
  168. #define VIEW_VARIABLES 2
  169. #define VIEW_CLASSES 3
  170. #define VIEW_SHOW_RESOURCES 4
  171. #define VIEW_HIDE_RESOURCES 5
  172. #define VIEW_number 6
  173.  
  174. #define SELECT_NOTHING 0
  175. #define SELECT_ALL 1
  176. #define SELECT_INVERT 2
  177. #define SELECT_PARENT 3
  178. #define SELECT_ANCESTORS 4
  179. #define SELECT_CHILDREN 5
  180. #define SELECT_DESCENDANTS 6
  181. #define SELECT_HAS_RESOURCES 7
  182. #define SELECT_SHOWN_RESOURCES 8
  183. #define SELECT_number 9
  184.  
  185. static struct _nametable {
  186.     char *name;
  187.     int value;
  188. } select_nametable[] = {
  189.     { "nothing", SELECT_NOTHING },
  190.     { "all", SELECT_ALL },
  191.     { "invert", SELECT_INVERT },
  192.     { "parent", SELECT_PARENT },
  193.     { "ancestors", SELECT_ANCESTORS },
  194.     { "children", SELECT_CHILDREN },
  195.     { "descendants", SELECT_DESCENDANTS },
  196.     { "resources", SELECT_HAS_RESOURCES },
  197.     { "shown", SELECT_SHOWN_RESOURCES },
  198. }, boolean_nametable[] = {
  199.     { "off", BOOL_OFF },
  200.     { "false", BOOL_OFF },
  201.     { "no", BOOL_OFF },
  202.     { "on", BOOL_ON },
  203.     { "true", BOOL_ON },
  204.     { "yes", BOOL_ON },
  205.     { "toggle", BOOL_TOGGLE },
  206. };
  207.  
  208. static Widget treeWidget;
  209. static Widget quitButton, viewButton, viewMenu, selectButton, selectMenu;
  210. static Widget view_widgets[VIEW_number];
  211. static Widget select_widgets[SELECT_number];
  212. static XmuWidgetNode *topnode;
  213.  
  214. static Arg false_args[1] = {{ XtNstate, (XtArgVal) FALSE }};
  215. static Arg true_args[1] = {{ XtNstate, (XtArgVal) TRUE }};
  216.  
  217.  
  218. /*
  219.  * routines
  220.  */
  221. static void usage ()
  222. {
  223.     char **cpp;
  224.     fprintf (stderr, "usage:  %s [-options...]\n", ProgramName);
  225.     fprintf(stderr, "\nwhere options include:\n");
  226.     for (cpp = help_message; *cpp; cpp++) {
  227.     fprintf (stderr, "    %s\n", *cpp);
  228.     }
  229.     fprintf(stderr, "\n");
  230.     exit (1);
  231. }
  232.  
  233.  
  234. static XmuWidgetNode *widget_to_node (gw)
  235.     register Widget gw;
  236. {
  237.     register XmuWidgetNode *node;
  238.     register int i;
  239.  
  240.     if (XtIsSubclass (gw, toggleWidgetClass)) {
  241.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  242.         if (VData(node)->instance == gw) return node;
  243.     }
  244.     } else if (XtIsSubclass (gw, listWidgetClass)) {
  245.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  246.         if (VData(node)->resource_lw == gw) return node;
  247.     }
  248.     }
  249.     return (XmuWidgetNode *) NULL;
  250. }
  251.  
  252.  
  253. static void initialize_widgetnode_list (listp, sizep, n)
  254.     XmuWidgetNode ***listp;
  255.     int *sizep;
  256.     int n;
  257. {
  258.     register int i;
  259.     register XmuWidgetNode **l;
  260.  
  261.     if (!*listp) {
  262.         *listp = (XmuWidgetNode **)
  263.       XtCalloc ((unsigned int) n, (unsigned int)sizeof(XmuWidgetNode **));
  264.         *sizep = ((*listp) ? n : 0);
  265.         return;
  266.     }
  267.     if (n > *sizep) {
  268.         *listp = (XmuWidgetNode **) XtRealloc ((char *) *listp,
  269.                            (unsigned int) 
  270.                            (n * sizeof(XmuWidgetNode **)));
  271.     if (!*listp) {
  272.         *sizep = 0;
  273.         return;
  274.     }
  275.     for (i = *sizep, l = (*listp) + i; i < n; i++, l++) *l =
  276.       (XmuWidgetNode *) NULL;
  277.     *sizep = n;
  278.     }
  279.     return;
  280. }
  281.  
  282.  
  283. static Boolean set_resource_labels (node)
  284.     XmuWidgetNode *node;
  285. {
  286.     int i;
  287.     char **cur;
  288.     XtResourceList res;
  289.     XmuWidgetNode **wn;
  290.     ViewresData *d = VData(node);
  291.  
  292.     if (!d->resource_labels) {
  293.     d->resource_labels =
  294.       (char **) calloc ((unsigned) d->nnew * 3,
  295.                 (unsigned) sizeof (char *));
  296.     if (!d->resource_labels) return FALSE;
  297.     }
  298.  
  299.     cur = d->resource_labels;
  300.     res = node->resources;
  301.     wn = node->resourcewn;
  302.     for (i = 0; i < node->nresources; i++, res++, wn++) {
  303.     if (*wn == node) {        /* should match nnew */
  304.         *cur++ = res->resource_name;
  305.         *cur++ = res->resource_class;
  306.         *cur++ = res->resource_type;
  307.     }
  308.     }
  309.     if (d->nnewconstraints > 0) {
  310.     char *s;
  311.  
  312.     *cur++ = s = "";
  313.     *cur++ = s;
  314.     *cur++ = s;
  315.     }
  316.     res = node->constraints;
  317.     wn = node->constraintwn;
  318.     for (i = 0; i < node->nconstraints; i++, res++, wn++) {
  319.     if (*wn == node) {        /* should match nnew */
  320.         *cur++ = res->resource_name;
  321.         *cur++ = res->resource_class;
  322.         *cur++ = res->resource_type;
  323.     }
  324.     }
  325.     return TRUE;
  326. }
  327.  
  328.  
  329. static ViewresData *create_viewres_data (node)
  330.     XmuWidgetNode *node;
  331. {
  332.     register ViewresData *d =
  333.       (ViewresData *) malloc ((unsigned) sizeof(ViewresData));
  334.  
  335.     if (d) {
  336.     d->resource_labels = (char **) NULL;
  337.     d->nnewresources = XmuWnCountOwnedResources (node, node, False);
  338.     d->nnewconstraints = XmuWnCountOwnedResources (node, node, True);
  339.     d->nnew = (d->nnewresources + (d->nnewconstraints 
  340.                        ? d->nnewconstraints + 1 : 0));
  341.     d->instance = (Widget) NULL;
  342.     d->resource_lw = (Widget) NULL;
  343.     d->selection_index = -1;
  344.     }
  345.     return d;
  346. }
  347.  
  348. static int copydown (start)
  349.     register int start;
  350. {
  351.     register XmuWidgetNode **src = &selected_list.elements[start];
  352.     register XmuWidgetNode **dst = src;
  353.     register int cur;
  354.  
  355.     for (cur = start; start < selected_list.n_elements; start++, src++) {
  356.     if (*src) {
  357.         VData((*src))->selection_index = cur++;
  358.         *dst++ = *src;
  359.     }
  360.     }
  361.     return (start - cur);
  362. }
  363.  
  364.  
  365. static void add_to_selected_list (node, updatewidget)
  366.     XmuWidgetNode *node;
  367.     Boolean updatewidget;
  368. {
  369.     ViewresData *d = VData(node);
  370.     if (!d->instance || d->selection_index >= 0) return;
  371.  
  372.     if (selected_list.n_elements >= selected_list.max_elements) {
  373.     initialize_widgetnode_list (&selected_list.elements,
  374.                     &selected_list.max_elements, 
  375.                     (selected_list.max_elements * 3) / 2);
  376.     }
  377.     INSERT_NODE (node, selected_list.n_elements);
  378.     selected_list.n_elements++;
  379.  
  380.     if (updatewidget) XtSetValues (d->instance, true_args, ONE);
  381. }
  382.  
  383. static Boolean remove_from_selected_list (node, updatewidget)
  384.     XmuWidgetNode *node;
  385.     Boolean updatewidget;
  386. {
  387.     int i, skips;
  388.     ViewresData *d = VData(node);
  389.  
  390.     if ((i = d->selection_index) < 0) return FALSE;
  391.  
  392.     REMOVE_NODE (node);
  393.  
  394.     /* copy down */
  395.     if (selected_list.n_elements > 1) {
  396.     skips = copydown (i);
  397.     } else {
  398.     skips = 1;
  399.     }
  400.     selected_list.n_elements -= skips;
  401.  
  402.     if (updatewidget) XtSetValues (d->instance, false_args, ONE);
  403.     return TRUE;
  404. }
  405.  
  406. static void remove_nodes_from_selected_list (start, count, updatewidget)
  407.     int start, count;
  408.     Boolean updatewidget;
  409. {
  410.     int i;
  411.  
  412.     for (i = 0; i < count; i++) {
  413.     register XmuWidgetNode *p = selected_list.elements[start+i];
  414.     ViewresData *d = VData(p);
  415.     REMOVE_NODE (p);
  416.     if (updatewidget) XtSetValues (d->instance, false_args, ONE);
  417.     }
  418.     selected_list.n_elements -= copydown (start);
  419. }
  420.         
  421. static void add_subtree_to_selected_list (node, updatewidget)
  422.     XmuWidgetNode *node;
  423.     Boolean updatewidget;
  424. {
  425.     if (!node) return;
  426.  
  427.     add_to_selected_list (node, updatewidget);
  428.     for (node = node->children; node; node = node->siblings) {
  429.     add_subtree_to_selected_list (node, updatewidget);
  430.     }
  431. }
  432.  
  433.  
  434. /* ARGSUSED */
  435. static void variable_labeltype_callback (gw, closure, data)
  436.     Widget gw;
  437.     XtPointer closure;            /* TRUE or FALSE */
  438.     XtPointer data;
  439. {
  440.     set_labeltype_menu ((Boolean) closure, True);
  441. }
  442.  
  443. /* ARGSUSED */
  444. static void gravity_callback (gw, closure, data)
  445.     Widget gw;
  446.     XtPointer closure;            /* TRUE or FALSE */
  447.     XtPointer data;
  448. {
  449.     set_orientation_menu ((XtGravity) closure, True);
  450. }
  451.  
  452.  
  453. static Boolean create_resource_lw (node)
  454.     XmuWidgetNode *node;
  455. {
  456.     Arg args[4];
  457.     Cardinal n;
  458.     ViewresData *d = VData(node);
  459.  
  460.     if (d->nnew == 0) return FALSE;
  461.  
  462.     if (!d->resource_labels &&
  463.     !set_resource_labels (node)) return FALSE;
  464.  
  465.     n = 0;
  466.     XtSetArg (args[n], XtNnumberStrings, 3 * d->nnew); n++;
  467.     XtSetArg (args[n], XtNlist, d->resource_labels); n++;
  468.     XtSetArg (args[n], XtNdefaultColumns, 3); n++;
  469.     XtSetArg (args[n], XtNforceColumns, TRUE); n++;
  470.     d->resource_lw = XtCreateManagedWidget (node->label, listWidgetClass,
  471.                         XtParent(d->instance),
  472.                         args, n);
  473.     XtRealizeWidget (d->resource_lw);
  474.     return TRUE;
  475. }
  476.  
  477. static void update_selection_items ()
  478. {
  479.     register int i;
  480.     static Arg args[1] = {{ XtNsensitive, (XtArgVal) FALSE }};
  481.     Boolean show = FALSE, hide = FALSE, ancestors = FALSE;
  482.     Boolean descendants = FALSE;
  483.  
  484.     for (i = 0; i < selected_list.n_elements; i++) {
  485.     XmuWidgetNode *node = selected_list.elements[i];
  486.     ViewresData *d = VData(node);
  487.  
  488.     /*
  489.      * If node has any new resources then may be shown (if not
  490.      * already being shown).  If node has widget and is managed,
  491.      * then may be hidden.
  492.      */
  493.     if (d->nnew > 0) {
  494.         if (IsShowing(node)) {
  495.         hide = TRUE;
  496.         } else {
  497.         show = TRUE;
  498.         }
  499.     }
  500.     if (node != topnode) ancestors = TRUE;
  501.     if (node->children) descendants = TRUE;
  502.     }
  503.         
  504.     args[0].value = (XtArgVal) show;
  505.     XtSetValues (view_widgets[VIEW_SHOW_RESOURCES], args, ONE);
  506.     args[0].value = (XtArgVal) hide;
  507.     XtSetValues (view_widgets[VIEW_HIDE_RESOURCES], args, ONE);
  508.     args[0].value = (XtArgVal) (selected_list.n_elements > 0 ? TRUE : FALSE);
  509.     XtSetValues (select_widgets[SELECT_NOTHING], args, ONE);
  510.     args[0].value = (XtArgVal) ancestors;
  511.     XtSetValues (select_widgets[SELECT_PARENT], args, ONE);
  512.     XtSetValues (select_widgets[SELECT_ANCESTORS], args, ONE);
  513.     args[0].value = (XtArgVal) descendants;
  514.     XtSetValues (select_widgets[SELECT_CHILDREN], args, ONE);
  515.     XtSetValues (select_widgets[SELECT_DESCENDANTS], args, ONE);
  516.     args[0].value = (XtArgVal) ((Boolean) (NumberShowing > 0));
  517.     XtSetValues (select_widgets[SELECT_SHOWN_RESOURCES], args, ONE);
  518. }
  519.  
  520.  
  521. static void do_resources (node, op, updatewidget)
  522.     XmuWidgetNode *node;
  523.     Boolean op;
  524.     Boolean updatewidget;
  525. {
  526.     ViewresData *d = VData(node);
  527.     if (op == BOOL_TOGGLE) op = (IsShowing(node) ? BOOL_OFF : BOOL_ON);
  528.  
  529.     if (op == BOOL_ON) {
  530.     if (d->resource_lw) {        /* if already created */
  531.         if (!XtIsManaged(d->resource_lw)) {
  532.         NumberShowing++;
  533.         XtManageChild (d->resource_lw);
  534.         }                /* else ignore it */
  535.     } else if (create_resource_lw (node))    /* create it */
  536.       NumberShowing++;
  537.     } else if (d->resource_lw) {        /* if already created */
  538.     if (XtIsManaged (d->resource_lw)) {
  539.         NumberShowing--;
  540.         XtUnmanageChild (d->resource_lw);
  541.         XawListUnhighlight (d->resource_lw);
  542.         if (updatewidget) remove_from_selected_list (node, TRUE);
  543.     }                /* else ignore it */
  544.     }
  545. }
  546.  
  547.  
  548.  
  549. /* ARGSUSED */
  550. static void show_resources_callback (gw, closure, data)
  551.     Widget gw;                /* menu or toggle button */
  552.     XtPointer closure;            /* BOOL_OFF, BOOL_ON, BOOL_TOGGLE */
  553.     XtPointer data;            /* undefined */
  554. {
  555.     int op = (int) closure;
  556.     XmuWidgetNode *node = widget_to_node (gw);
  557.  
  558.     if (node) {
  559.     XUnmapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  560.     do_resources (node, op, TRUE);
  561.     } else if (selected_list.n_elements <= 0) {
  562.     return;
  563.     } else {
  564.     int i;
  565.  
  566.     XUnmapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  567.     for (i = 0; i < selected_list.n_elements; i++) {
  568.         do_resources (selected_list.elements[i], op, FALSE);
  569.     }
  570.     }
  571.     XawTreeForceLayout (treeWidget);
  572.     XMapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  573.     update_selection_items ();
  574. }
  575.  
  576.  
  577. /* ARGSUSED */
  578. static void select_callback (gw, closure, data)
  579.     Widget gw;                /* entry widget */
  580.     XtPointer closure;            /* TRUE or FALSE */
  581.     XtPointer data;            /* undefined */
  582. {
  583.     register int i;
  584.     int nselected = selected_list.n_elements;
  585.     XmuWidgetNode *node;
  586.  
  587.     switch ((int) closure) {
  588.       case SELECT_NOTHING:        /* clear selection_list */
  589.     remove_nodes_from_selected_list (0, nselected, True);
  590.     break;
  591.  
  592.       case SELECT_ALL:            /* put everything on selection_list */
  593.     add_subtree_to_selected_list (topnode, TRUE);
  594.     break;
  595.  
  596.       case SELECT_INVERT:        /* toggle selection state */
  597.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  598.         ViewresData *d = VData(node);
  599.         if (d->selection_index < 0) add_to_selected_list (node, TRUE);
  600.     }
  601.     remove_nodes_from_selected_list (0, nselected, True);
  602.     break;
  603.  
  604.  
  605.       case SELECT_PARENT:        /* choose immediate parent */
  606.     node = widget_to_node (gw);
  607.     if (node) {
  608.         if (node->superclass)
  609.           add_to_selected_list (node->superclass, TRUE);
  610.     } else {
  611.         for (i = 0; i < nselected; i++) {
  612.         XmuWidgetNode *node = selected_list.elements[i];
  613.         if (node->superclass)
  614.           add_to_selected_list (node->superclass, TRUE);
  615.         }
  616.     }
  617.     break;
  618.  
  619.       case SELECT_ANCESTORS:        /* chain up adding to selection_list */
  620.     node = widget_to_node (gw);
  621.     if (node) {
  622.         do {
  623.         add_to_selected_list (node, TRUE);
  624.         } while (node = node->superclass);
  625.     } else {
  626.         for (i = 0; i < nselected; i++) {
  627.         XmuWidgetNode *parent = selected_list.elements[i];
  628.  
  629.         /*
  630.          * chain up the tree, but stop if we get to nodes that
  631.          * are already in the selected list.
  632.          */
  633.         while (parent = parent->superclass) {  /* do ancestors */
  634.             if (VData(parent)->selection_index >= 0) break;
  635.             add_to_selected_list (parent, TRUE);
  636.         }
  637.         }
  638.     }
  639.     break;
  640.  
  641.       case SELECT_CHILDREN:        /* all direct sub nodes */
  642.     node = widget_to_node (gw);
  643.     if (node) {
  644.         add_to_selected_list (node, TRUE);
  645.         for (node = node->children; node; node = node->siblings) {
  646.         add_to_selected_list (node, TRUE);
  647.         }
  648.     } else {
  649.         for (i = 0; i < nselected; i++) {
  650.         XmuWidgetNode *node = selected_list.elements[i];
  651.  
  652.         add_to_selected_list (node, TRUE);
  653.         for (node = node->children; node; node = node->siblings) {
  654.             add_to_selected_list (node, TRUE);
  655.         }
  656.         }
  657.     }
  658.     break;
  659.  
  660.       case SELECT_DESCENDANTS:        /* all sub nodes */
  661.     node = widget_to_node (gw);
  662.     if (node) {
  663.         add_subtree_to_selected_list (node, TRUE);
  664.     } else {
  665.         for (i = 0; i < nselected; i++) {
  666.         XmuWidgetNode *parent = selected_list.elements[i];
  667.  
  668.         add_subtree_to_selected_list (parent, TRUE);
  669.         }
  670.     }
  671.     break;
  672.  
  673.       case SELECT_HAS_RESOURCES:    /* put all w/ rescnt > 0 on sel_list */
  674.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  675.         if (VData(node)->nnew > 0)
  676.           add_to_selected_list (node, TRUE);
  677.     }
  678.     break;
  679.  
  680.       case SELECT_SHOWN_RESOURCES:
  681.     for (i = 0, node = widget_list; i < nwidgets; i++, node++) {
  682.         if (IsShowing(node)) add_to_selected_list (node, TRUE);
  683.     }
  684.     break;
  685.  
  686.       default:                /* error!!! */
  687.     XBell (XtDisplay(gw), 0);
  688.     return;
  689.     }
  690.  
  691.     update_selection_items ();
  692. }
  693.  
  694. /* ARGSUSED */
  695. static void toggle_callback (gw, closure, data)
  696.     Widget gw;
  697.     XtPointer closure;        /* XmuWidgetNode for this widget */
  698.     XtPointer data;        /* on or off */
  699. {
  700.     XmuWidgetNode *node = (XmuWidgetNode *) closure;
  701.     Boolean selected = (Boolean) data;
  702.  
  703.     if (selected) {
  704.     add_to_selected_list (node, FALSE);
  705.     } else {
  706.     (void) remove_from_selected_list (node, FALSE);
  707.     }
  708.  
  709.     update_selection_items ();
  710. }
  711.  
  712.  
  713. /*
  714.  * panner/porthole controls - called when the other changes
  715.  */
  716. /* ARGSUSED */
  717. static void panner_callback (gw, closure, data)
  718.     Widget gw;                /* panner widget */
  719.     XtPointer closure;            /* porthole widget */
  720.     XtPointer data;            /* report */
  721. {
  722.     XawPannerReport *rep = (XawPannerReport *) data;
  723.     Arg args[2];
  724.  
  725.     if (!treeWidget) return;
  726.  
  727.     XtSetArg (args[0], XtNx, -rep->slider_x);
  728.     XtSetArg (args[1], XtNy, -rep->slider_y);
  729.     XtSetValues (treeWidget, args, TWO);    /* just assume... */
  730. }
  731.  
  732. /* ARGSUSED */
  733. static void porthole_callback (gw, closure, data)
  734.     Widget gw;                /* porthole widget */
  735.     XtPointer closure;            /* panner widget */
  736.     XtPointer data;            /* report */
  737. {
  738.     Widget panner = (Widget) closure;
  739.     XawPannerReport *rep = (XawPannerReport *) data;
  740.     Arg args[6];
  741.     Cardinal n = TWO;
  742.  
  743.     XtSetArg (args[0], XtNsliderX, rep->slider_x);
  744.     XtSetArg (args[1], XtNsliderY, rep->slider_y);
  745.     if (rep->changed != (XawPRSliderX | XawPRSliderY)) {
  746.     XtSetArg (args[2], XtNsliderWidth, rep->slider_width);
  747.     XtSetArg (args[3], XtNsliderHeight, rep->slider_height);
  748.     XtSetArg (args[4], XtNcanvasWidth, rep->canvas_width);
  749.     XtSetArg (args[5], XtNcanvasHeight, rep->canvas_height);
  750.     n = SIX;
  751.     }
  752.     XtSetValues (panner, args, n);
  753. }
  754.  
  755.  
  756.  
  757. static void build_tree (node, tree, super)
  758.     XmuWidgetNode *node;
  759.     Widget tree;
  760.     Widget super;
  761. {
  762.     ViewresData *d = VData (node);
  763.     Widget box, w;            /* widget for this Class */
  764.     XmuWidgetNode *child;            /* iterator over children */
  765.     Arg args[3];            /* need to set super node */
  766.     Cardinal n;                /* count of args */
  767.     static XtCallbackRec callback_rec[2] = {{ toggle_callback, NULL },
  768.                          { NULL, NULL }};
  769.  
  770.  
  771.     n = 0;
  772.     XtSetArg (args[n], XtNtreeParent, super); n++;
  773.     box = XtCreateManagedWidget (node->label, boxWidgetClass, tree, args, n);
  774.  
  775.     n = 0;
  776.     XtSetArg (args[n], XtNlabel, (options.show_variable ?
  777.                   node->label : XmuWnClassname(node))); n++;
  778.     XtSetArg (args[n], XtNcallback, callback_rec); n++;
  779.  
  780.     callback_rec[0].closure = (XtPointer) node;
  781.     w = XtCreateManagedWidget (node->label, toggleWidgetClass, box, args, n);
  782.     d->instance = w;
  783.  
  784.     /*
  785.      * recursively build the rest of the tree
  786.      */
  787.     for (child = node->children; child; child = child->siblings) {
  788.     build_tree (child, tree, box);
  789.     }
  790. }
  791.  
  792.  
  793. static void set_node_labels (node, depth)
  794.     XmuWidgetNode *node;
  795.     int depth;
  796. {
  797.     Arg args[1];
  798.     XmuWidgetNode *child;
  799.     ViewresData *d = VData(node);
  800.  
  801.     if (!node) return;
  802.     XtSetArg (args[0], XtNlabel, (options.show_variable ?
  803.                   node->label : XmuWnClassname(node)));
  804.     XtSetValues (d->instance, args, ONE);
  805.  
  806.     for (child = node->children; child; child = child->siblings) {
  807.     set_node_labels (child, depth + 1);
  808.     }
  809. }
  810.  
  811.  
  812. static void oneof_sensitive (choosea, a, b)
  813.     Boolean choosea;
  814.     Widget a, b;
  815. {
  816.     static Arg args[1] = { XtNsensitive, (XtArgVal) NULL };
  817.  
  818.     args[0].value = (XtArgVal) TRUE;
  819.     XtSetValues (choosea ? a : b, args, ONE);
  820.     args[0].value = (XtArgVal) FALSE;
  821.     XtSetValues (choosea ? b : a, args, ONE);
  822. }
  823.  
  824. static void set_labeltype_menu (isvar, doall)
  825.     Boolean isvar;
  826.     Boolean doall;
  827. {
  828.     options.show_variable = isvar;
  829.     oneof_sensitive (isvar, view_widgets[VIEW_CLASSES],
  830.              view_widgets[VIEW_VARIABLES]);
  831.  
  832.     if (doall) {
  833.     XUnmapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  834.     set_node_labels (topnode, 0);
  835.     XawTreeForceLayout (treeWidget);
  836.     XMapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  837.     }
  838. }
  839.  
  840. static void set_orientation_menu (grav, dosetvalues)
  841.     XtGravity grav;
  842.     Boolean dosetvalues;
  843. {
  844. #define CHOOSE(val) (sensitiveargs + (grav != (val)))
  845.     XtSetValues (view_widgets[VIEW_HORIZONTAL], CHOOSE(WestGravity), ONE);
  846.     XtSetValues (view_widgets[VIEW_VERTICAL], CHOOSE(NorthGravity), ONE);
  847. #undef CHOOSE
  848.  
  849.     if (dosetvalues) {
  850.     Arg args[1];
  851.  
  852.     XtSetArg (args[0], XtNgravity, grav);
  853.     XUnmapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  854.      XtSetValues (treeWidget, args, ONE);
  855.     XMapWindow (XtDisplay(treeWidget), XtWindow(treeWidget));
  856.     }
  857. }
  858.  
  859.  
  860. /*****************************************************************************
  861.  *                                                                           *
  862.  *             viewres - visual class browser for Xt                   *
  863.  *                                                                           *
  864.  *****************************************************************************/
  865.  
  866. main (argc, argv)
  867.     int argc;
  868.     char **argv;
  869. {
  870.     Widget toplevel, pane, box, dummy, porthole, panner, form;
  871.     XtAppContext app_con;
  872.     Arg args[6];
  873.     Dimension canvasWidth, canvasHeight, sliderWidth, sliderHeight;
  874.     static XtCallbackRec callback_rec[2] = {{ NULL, NULL }, { NULL, NULL }};
  875.     XtGravity grav;
  876.     int i;
  877.  
  878.     ProgramName = argv[0];
  879.  
  880.     toplevel = XtAppInitialize (&app_con, "Viewres", 
  881.                 Options, XtNumber (Options),
  882.                 &argc, argv, fallback_resources, 
  883.                 (ArgList) NULL, ZERO);
  884.     if (argc != 1) usage ();
  885.  
  886.     initialize_widgetnode_list (&selected_list.elements,
  887.                 &selected_list.max_elements, 10);
  888.  
  889.     XtGetApplicationResources (toplevel, (XtPointer) &options,
  890.                    Resources, XtNumber(Resources), NULL, ZERO);
  891.     XmuWnInitializeNodes (widget_list, nwidgets);
  892.  
  893.     topnode = XmuWnNameToNode (widget_list, nwidgets, options.top_object);
  894.     if (!topnode) {
  895.     fprintf(stderr, "%s: no widget with name \"%s\" found.\n",
  896.         ProgramName, options.top_object);
  897.     exit(1);
  898.     }
  899.  
  900.     XtAppAddActions (app_con, viewres_actions, XtNumber (viewres_actions));
  901.     XtOverrideTranslations
  902.     (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
  903.  
  904.     /*
  905.      * create dummy widgets to initialize resources
  906.      */
  907.     XtSetArg (args[0], XtNwidth, 1);
  908.     XtSetArg (args[1], XtNheight, 1);
  909.     dummy = XtCreateWidget ("dummy", widgetClass, toplevel, args, TWO);
  910.     for (i = 0; i < nwidgets; i++) {
  911.     XmuWidgetNode *node = &widget_list[i];
  912.     XmuWnFetchResources (node, dummy, topnode);
  913.     node->data = (XtPointer) create_viewres_data (node);
  914.     }
  915.     XtDestroyWidget (dummy);
  916.  
  917.     pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
  918.                   (ArgList) NULL, ZERO);
  919.  
  920.     box = XtCreateManagedWidget ("buttonbox", boxWidgetClass, pane,
  921.                  (ArgList) NULL, ZERO);
  922.     quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
  923.                     (ArgList) NULL, ZERO);
  924.  
  925.     /*
  926.      * Format menu
  927.      */
  928.     XtSetArg (args[0], XtNmenuName, "viewMenu");
  929.     viewButton = XtCreateManagedWidget ("view", menuButtonWidgetClass, box,
  930.                     args, ONE);
  931.     viewMenu = XtCreatePopupShell ("viewMenu", simpleMenuWidgetClass, 
  932.                    viewButton, (ArgList) NULL, ZERO);
  933.     XtSetArg (args[0], XtNcallback, callback_rec);
  934.  
  935. #define MAKE_VIEW(n,v,name) \
  936.     callback_rec[0].closure = (XtPointer) v; \
  937.     view_widgets[n] = XtCreateManagedWidget (name, smeBSBObjectClass, \
  938.                          viewMenu, args, ONE)
  939.     callback_rec[0].callback = (XtCallbackProc) gravity_callback;
  940.     MAKE_VIEW (VIEW_HORIZONTAL, WestGravity, "layoutHorizontal");
  941.     MAKE_VIEW (VIEW_VERTICAL, NorthGravity, "layoutVertical");
  942.  
  943.     (void) XtCreateManagedWidget ("line1", smeLineObjectClass, viewMenu,
  944.                   (ArgList) NULL, ZERO);
  945.  
  946.     callback_rec[0].callback = (XtCallbackProc) variable_labeltype_callback;
  947.     MAKE_VIEW (VIEW_VARIABLES, TRUE, "namesVariable");
  948.     MAKE_VIEW (VIEW_CLASSES, FALSE, "namesClass");
  949.  
  950.     (void) XtCreateManagedWidget ("line2", smeLineObjectClass, viewMenu,
  951.                   (ArgList) NULL, ZERO);
  952.  
  953.     callback_rec[0].callback = (XtCallbackProc) show_resources_callback;
  954.     MAKE_VIEW (VIEW_SHOW_RESOURCES, BOOL_ON, "viewResources");
  955.     MAKE_VIEW (VIEW_HIDE_RESOURCES, BOOL_OFF, "viewNoResources");
  956. #undef MAKE_VIEW
  957.  
  958.     /*
  959.      * Select menu
  960.      */
  961.     XtSetArg (args[0], XtNmenuName, "selectMenu");
  962.     selectButton = XtCreateManagedWidget ("select", menuButtonWidgetClass, box,
  963.                       args, ONE);
  964.     selectMenu = XtCreatePopupShell ("selectMenu", simpleMenuWidgetClass, 
  965.                      selectButton, (ArgList) NULL, ZERO);
  966.     XtSetArg (args[0], XtNcallback, callback_rec);
  967.     callback_rec[0].callback = (XtCallbackProc) select_callback;
  968. #define MAKE_SELECT(n,name) \
  969.     callback_rec[0].closure = (XtPointer) n; \
  970.     select_widgets[n] = XtCreateManagedWidget (name, smeBSBObjectClass, \
  971.                            selectMenu, args, ONE)
  972.     MAKE_SELECT (SELECT_NOTHING, "unselect");
  973.     MAKE_SELECT (SELECT_ALL, "selectAll");
  974.     MAKE_SELECT (SELECT_INVERT, "selectInvert");
  975.     (void) XtCreateManagedWidget ("line1", smeLineObjectClass, selectMenu,
  976.                   (ArgList) NULL, ZERO);
  977.     MAKE_SELECT (SELECT_PARENT, "selectParent");
  978.     MAKE_SELECT (SELECT_ANCESTORS, "selectAncestors");
  979.     MAKE_SELECT (SELECT_CHILDREN, "selectChildren");
  980.     MAKE_SELECT (SELECT_DESCENDANTS, "selectDescendants");
  981.     (void) XtCreateManagedWidget ("line2", smeLineObjectClass, selectMenu,
  982.                   (ArgList) NULL, ZERO);
  983.     MAKE_SELECT (SELECT_HAS_RESOURCES, "selectHasResources");
  984.     MAKE_SELECT (SELECT_SHOWN_RESOURCES, "selectShownResources");
  985. #undef MAKE_SELECT
  986.  
  987.     form = XtCreateManagedWidget ("treeform", formWidgetClass, pane,
  988.                   (ArgList) NULL, ZERO);
  989.     /*
  990.      * create the panner and the porthole and then connect them with the
  991.      * callbacks (passing the other widget each callback)
  992.      */
  993.     XtSetArg (args[0], XtNbackgroundPixmap, None);  /* faster updates */
  994.     porthole = XtCreateManagedWidget ("porthole", portholeWidgetClass, form,
  995.                       args, ONE);
  996.     panner = XtCreateManagedWidget ("panner", pannerWidgetClass, form,
  997.                     (ArgList) NULL, ZERO);
  998.  
  999.     XtSetArg (args[0], XtNreportCallback, callback_rec);
  1000.     callback_rec[0].callback = (XtCallbackProc) panner_callback;
  1001.     callback_rec[0].closure = (XtPointer) porthole;
  1002.     XtSetValues (panner, args, ONE);
  1003.  
  1004.     callback_rec[0].callback = (XtCallbackProc) porthole_callback;
  1005.     callback_rec[0].closure = (XtPointer) panner;
  1006.     XtSetValues (porthole, args, ONE);
  1007.  
  1008.     /*
  1009.      * now that the panner and porthole are set up, insert the tree and 
  1010.      * fix up the menu, fill in the nodes
  1011.      */
  1012.     treeWidget = XtCreateManagedWidget ("tree", treeWidgetClass,
  1013.                     porthole, (ArgList) NULL, ZERO);
  1014.  
  1015.     set_labeltype_menu (options.show_variable, FALSE);
  1016.     XtSetArg (args[0], XtNgravity, &grav);
  1017.     XtGetValues (treeWidget, args, ONE);
  1018.     set_orientation_menu (grav, FALSE);
  1019.     update_selection_items ();
  1020.     build_tree (topnode, treeWidget, (Widget) NULL);
  1021.  
  1022.     /*
  1023.      * Realize the tree, but do not map it (we set mappedWhenManaged to 
  1024.      * false up above).  Get the initial size of the tree so that we can
  1025.      * size the panner appropriately.
  1026.      */
  1027.     XtRealizeWidget (toplevel);
  1028.  
  1029.     wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
  1030.                    False);
  1031.     (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
  1032.                             &wm_delete_window, 1);
  1033.  
  1034.     XtSetArg (args[0], XtNwidth, &canvasWidth);
  1035.     XtSetArg (args[1], XtNheight, &canvasHeight);
  1036.     XtGetValues (treeWidget, args, TWO);
  1037.  
  1038.     XtSetArg (args[0], XtNwidth, &sliderWidth);
  1039.     XtSetArg (args[1], XtNheight, &sliderHeight);
  1040.     XtGetValues (porthole, args, TWO);
  1041.  
  1042.     XtSetArg (args[0], XtNcanvasWidth, canvasWidth);
  1043.     XtSetArg (args[1], XtNcanvasHeight, canvasHeight);
  1044.     XtSetArg (args[2], XtNsliderWidth, sliderWidth);
  1045.     XtSetArg (args[3], XtNsliderHeight, sliderHeight);
  1046.     XtSetValues (panner, args, FOUR);
  1047.  
  1048.     XRaiseWindow (XtDisplay(panner), XtWindow(panner));
  1049.     XtAppMainLoop (app_con);
  1050. }
  1051.  
  1052.  
  1053.  
  1054. /*****************************************************************************
  1055.  *                                                                           *
  1056.  *           viewres translation table action routines                 *
  1057.  *                                                                           *
  1058.  *****************************************************************************/
  1059.  
  1060. /* ARGSUSED */
  1061. static void ActionQuit (w, event, params, num_params)
  1062.     Widget w;
  1063.     XEvent *event;
  1064.     String *params;
  1065.     Cardinal *num_params;
  1066. {
  1067.     exit (0);
  1068. }
  1069.  
  1070. /* ARGSUSED */
  1071. static void ActionSetLableType (w, event, params, num_params)
  1072.     Widget w;
  1073.     XEvent *event;
  1074.     String *params;
  1075.     Cardinal *num_params;
  1076. {
  1077.     char *cmd;
  1078.     Boolean oldvar = options.show_variable, newvar;
  1079.  
  1080.     switch (*num_params) {
  1081.       case 0:
  1082.     cmd = "toggle";
  1083.     break;
  1084.       case 1:
  1085.     cmd = params[0];
  1086.     break;
  1087.       default:
  1088.     XBell (XtDisplay(w), 0);
  1089.     return;
  1090.     }
  1091.  
  1092.     if (XmuCompareISOLatin1 (cmd, "toggle") == 0) {
  1093.     newvar = !oldvar;
  1094.     } else if (XmuCompareISOLatin1 (cmd, "variable") == 0) {
  1095.     newvar = TRUE;
  1096.     } else if (XmuCompareISOLatin1 (cmd, "class") == 0) {
  1097.     newvar = FALSE;
  1098.     } else {
  1099.     XBell (XtDisplay(w), 0);
  1100.     return;
  1101.     }
  1102.  
  1103.     if (newvar != oldvar) set_labeltype_menu (newvar, TRUE);
  1104.     return;
  1105. }
  1106.  
  1107. /* ARGSUSED */
  1108. static void ActionSetOrientation (w, event, params, num_params)
  1109.     Widget w;
  1110.     XEvent *event;
  1111.     String *params;
  1112.     Cardinal *num_params;
  1113. {
  1114.     XtGravity newgrav = ForgetGravity;
  1115.  
  1116.     if (*num_params < 1) {
  1117.     Arg arg;
  1118.     XtGravity oldgrav = ForgetGravity;
  1119.  
  1120.     XtSetArg (arg, XtNgravity, &oldgrav);
  1121.     XtGetValues (treeWidget, &arg, ONE);
  1122.     switch (oldgrav) {
  1123.       case WestGravity:  newgrav = NorthGravity; break;
  1124.       case NorthGravity:  newgrav = WestGravity; break;
  1125.       case EastGravity:  newgrav = SouthGravity; break;
  1126.       case SouthGravity:  newgrav = EastGravity; break;
  1127.       default:
  1128.         return;
  1129.     }
  1130.     } else {
  1131.     XrmValue fromval, toval;
  1132.  
  1133.     fromval.size = sizeof (String);
  1134.     fromval.addr = (XPointer) params[0];
  1135.     toval.size = sizeof (XtGravity);
  1136.     toval.addr = (XPointer) &newgrav;
  1137.     XtConvertAndStore (treeWidget, XtRString, &fromval,
  1138.                XtRGravity, &toval);
  1139.     }
  1140.  
  1141.     switch (newgrav) {
  1142.       case WestGravity: case NorthGravity: case EastGravity: case SouthGravity:
  1143.     break;
  1144.       default:
  1145.     XBell (XtDisplay(w), 0);
  1146.     return;
  1147.     }
  1148.  
  1149.     set_orientation_menu (newgrav, TRUE);
  1150.     return;
  1151. }
  1152.  
  1153.  
  1154. static void do_single_arg (w, params, nparams, table, nentries, proc)
  1155.     Widget w;
  1156.     String *params;
  1157.     Cardinal nparams;
  1158.     struct _nametable table[];
  1159.     int nentries;
  1160.     void (*proc)();
  1161. {
  1162.     int obj;
  1163.     int i;
  1164.  
  1165.     if (nparams != 1) {
  1166.     XBell (XtDisplay(w), 0);
  1167.     return;
  1168.     }
  1169.  
  1170.     for (i = 0; i < nentries; i++) {
  1171.     if (XmuCompareISOLatin1 (params[0], table[i].name) == 0) {
  1172.         obj = table[i].value;
  1173.         break;
  1174.     }
  1175.     }
  1176.     if (i == nentries) {
  1177.     XBell (XtDisplay(w), 0);
  1178.     return;
  1179.     }
  1180.  
  1181.     /*
  1182.      * use any old widget
  1183.      */
  1184.     (*proc) (w, (XtPointer) obj, (XtPointer) NULL);
  1185. }
  1186.  
  1187.  
  1188. /* ARGSUSED */
  1189. static void ActionSelect (w, event, params, num_params)
  1190.     Widget w;
  1191.     XEvent *event;
  1192.     String *params;
  1193.     Cardinal *num_params;
  1194. {
  1195.     do_single_arg (w, params, *num_params, select_nametable, 
  1196.            (int) XtNumber(select_nametable), select_callback);
  1197. }
  1198.  
  1199.  
  1200. /* ARGSUSED */
  1201. static void ActionResources (w, event, params, num_params)
  1202.     Widget w;
  1203.     XEvent *event;
  1204.     String *params;
  1205.     Cardinal *num_params;
  1206. {
  1207.     if (*num_params == 0) {
  1208.     show_resources_callback (w, (XtPointer) BOOL_TOGGLE, (XtPointer) NULL);
  1209.     } else {
  1210.     do_single_arg (w, params, *num_params, boolean_nametable,
  1211.                (int) XtNumber(boolean_nametable),
  1212.                show_resources_callback);
  1213.     }
  1214. }
  1215.  
  1216.