1/*
2 * $XConsortium: listres.c,v 1.32 94/04/17 20:43:22 dave Exp $
3 *
4 *
5Copyright (c) 1989  X Consortium
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of the X Consortium shall not be
25used in advertising or otherwise to promote the sale, use or other dealings
26in this Software without prior written authorization from the X Consortium.
27 * *
28 * Author:  Jim Fulton, MIT X Consortium
29 */
30/* $XFree86: xc/programs/listres/listres.c,v 1.3 2000/02/17 14:00:32 dawes Exp $ */
31
32#ifdef HAVE_CONFIG_H
33# include "config.h"
34#endif
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <X11/Xos.h>
39#include <X11/StringDefs.h>
40#include <X11/IntrinsicP.h>
41#include <X11/Xaw/Cardinals.h>
42#include <X11/Core.h>
43#include <X11/Xmu/CharSet.h>
44#include <X11/Xmu/WidgetNode.h>
45#include <X11/Xaw/AllWidgets.h>
46
47#define widget_list XawWidgetArray  /* or motif or ol or ... */
48#define nwidgets XawWidgetCount
49
50
51static XrmOptionDescRec Options[] = {
52  { "-top", "*topObject", XrmoptionSepArg, (caddr_t) NULL },
53  { "-format", "*resourceFormat", XrmoptionSepArg, (caddr_t) NULL },
54  { "-tree", "*showTree", XrmoptionNoArg, (caddr_t) "on" },
55  { "-nosuper", "*showSuper", XrmoptionNoArg, (caddr_t) "off" },
56  { "-variable", "*showVariable", XrmoptionNoArg, (caddr_t) "on" },
57};
58
59typedef struct {
60    Boolean show_tree;
61    Boolean show_all;
62    Boolean show_variable;
63    Boolean show_superclass;
64    char *top_object;
65    char *format;
66  } OptionsRec;
67
68static OptionsRec options;
69
70#define Offset(field) XtOffsetOf(OptionsRec, field)
71
72static XtResource Resources[] = {
73  { "showTree", "ShowTree", XtRBoolean, sizeof(Boolean),
74      Offset(show_tree), XtRImmediate, (XtPointer) FALSE },
75  { "showSuper", "ShowSuper", XtRBoolean, sizeof(Boolean),
76      Offset(show_superclass), XtRImmediate, (caddr_t) TRUE },
77  { "showVariable", "ShowVariable", XtRBoolean, sizeof(Boolean),
78      Offset(show_variable), XtRImmediate, (caddr_t) FALSE },
79  { "topObject", "TopObject", XtRString, sizeof(char *),
80      Offset(top_object), XtRString, (caddr_t) "core" },
81  { "resourceFormat", "ResourceFormat", XtRString, sizeof(char *),
82      Offset(format), XtRString, (caddr_t) " %-16s %20s  %-20s  %s" },
83};
84
85#undef Offset
86
87static const char *ProgramName;
88
89static void
90usage (int exitval)
91{
92    fprintf(stderr, "usage:  %s [-options...]\n%s\n", ProgramName,
93	    "\nwhere options include:\n"
94	    "    -all             list all known widget and object classes\n"
95	    "    -tree            list all widgets and objects in a tree\n"
96	    "    -nosuper         do not print superclass resources\n"
97	    "    -variable        show variable name instead of class name\n"
98	    "    -top name        object to be top of tree\n"
99	    "    -format string   printf format for instance, class, type\n"
100	    "    -help            print this message and exit\n"
101	    "    -version         print version info and exit\n"
102        );
103    exit (exitval);
104}
105
106static void print_tree_level (register XmuWidgetNode *wn, register int level)
107{
108    register int i;
109
110    if (!wn) return;
111
112    for (i = 0; i < level; i++) {
113	putchar (' '); putchar (' ');
114    }
115    printf ("%d:  %s/%s\n", level, wn->label, XmuWnClassname(wn));
116    print_tree_level (wn->children, level + 1);
117    print_tree_level (wn->siblings, level);
118}
119
120static void tree_known_widgets (void)
121{
122    register int i;
123    register XmuWidgetNode *wn;
124
125    for (i = 0, wn = widget_list; i < nwidgets; i++, wn++) {
126	if (!wn->superclass) {		/* list all rooted objects */
127	    print_tree_level (wn, 0);
128	}
129    }
130}
131
132
133/*
134 * print_classname - print out the superclass-to-subclass hierarchy of names
135 * in the form super\sub\sub....
136 */
137static int print_classname (XmuWidgetNode *node, XmuWidgetNode *topnode,
138			    int level, Bool showvar)
139{
140    int retval;
141
142    if (node && node != topnode) {
143	retval = print_classname (node->superclass, topnode, level + 1,
144				  showvar);
145    } else {
146	retval = level - 1;
147    }
148    if (node)
149      printf ("%s%s", showvar ? node->label : XmuWnClassname(node),
150	      level ? "\\" : "");
151
152    return retval;
153}
154
155static void list_known_widgets (void)
156{
157    int i;
158    XmuWidgetNode *wn;
159    int width = 0;
160
161    for (i = 0, wn = widget_list; i < nwidgets; i++, wn++) {
162	int l = strlen (wn->label);
163	if (l > width) width = l;
164    }
165    for (i = 0, wn = widget_list; i < nwidgets; i++, wn++) {
166	printf ("%-*s  ", width, wn->label);
167	print_classname (wn, (XmuWidgetNode *) NULL, 0, False);
168	putchar ('\n');
169    }
170}
171
172/* ARGSUSED */
173static void print_resources (XmuWidgetNode *node, const char *format,
174			     XmuWidgetNode *topnode, Bool showsuper,
175			     Bool showvar)
176{
177    Cardinal i;
178    XtResourceList res = node->resources;
179    XmuWidgetNode **wn = node->resourcewn;
180
181    for (i = 0; i < node->nresources; i++, res++, wn++) {
182	if (!showsuper && *wn != node) continue;
183	printf (format, showvar ? (*wn)->label : XmuWnClassname(*wn),
184		res->resource_name, res->resource_class, res->resource_type);
185	putchar ('\n');
186    }
187    if (node->nconstraints > 0) {
188	printf (format, "----", "----", "----", "----");
189	putchar ('\n');
190    }
191    res = node->constraints;
192    wn = node->constraintwn;
193    for (i = 0; i < node->nconstraints; i++, res++, wn++) {
194	if (!showsuper && *wn != node) continue;
195	printf (format, showvar ? (*wn)->label : XmuWnClassname(*wn),
196		res->resource_name, res->resource_class, res->resource_type);
197	putchar ('\n');
198    }
199    return;
200}
201
202
203/*
204 * list_resources - display resources of a widget, identifying class from
205 * which they come
206 */
207static void
208list_resources (XmuWidgetNode *node, const char *format,
209		XmuWidgetNode *topnode, Widget toplevel,
210		Bool showsuper, Bool showvar)
211{
212    static Bool first = True;
213
214    XmuWnFetchResources (node, toplevel, topnode);
215    if (first) {
216	printf (format, showvar ? "Variable" : "WidgetClass",
217		"Instance", "Class", "Type");
218	putchar ('\n');
219	printf (format, showvar ? "--------" : "-----------",
220		"--------", "-----", "----");
221	putchar ('\n');
222	first = False;
223    }
224    printf ("%s:  ", node->label);
225    print_classname (node, topnode, 0, showvar);
226    putchar ('\n');
227    print_resources (node, format, topnode, showsuper, showvar);
228    putchar ('\n');
229}
230
231
232int
233main (int argc, char **argv)
234{
235    int i;
236    XtAppContext appcon;
237    XmuWidgetNode *topnode;
238    Widget toplevel, container;
239
240    ProgramName = argv[0];
241
242    XtSetLanguageProc(NULL, (XtLanguageProc) NULL, NULL);
243
244    /* Handle args that don't require opening a display */
245    for (int n = 1; n < argc; n++) {
246	const char *argn = argv[n];
247	/* accept single or double dash for -help & -version */
248	if (argn[0] == '-' && argn[1] == '-') {
249	    argn++;
250	}
251	if (strcmp(argn, "-help") == 0) {
252	    usage(0);
253	}
254	if (strcmp(argn, "-version") == 0) {
255	    puts(PACKAGE_STRING);
256	    exit(0);
257	}
258    }
259
260    toplevel = XtAppInitialize (&appcon, "Listres", Options, XtNumber(Options),
261				&argc, argv, NULL, NULL, 0);
262    container = XtCreateWidget ("dummy", widgetClass, toplevel, NULL, ZERO);
263
264    XtGetApplicationResources (toplevel, (caddr_t) &options,
265			       Resources, XtNumber(Resources), NULL, ZERO);
266    XmuWnInitializeNodes (widget_list, nwidgets);
267    if (argc == 1) {
268	if (options.show_tree) {
269	    tree_known_widgets();
270	} else {
271	    list_known_widgets();
272	}
273	exit (0);
274    }
275
276    topnode = XmuWnNameToNode (widget_list, nwidgets, options.top_object);
277    argc--, argv++;			/* skip command */
278
279    if (argc > 0 && argv[0][0] == '-') {
280	int len = strlen (argv[0]);
281	if (len >= 2 && strncmp(argv[0], "-all", len) == 0) {
282	    XmuWidgetNode *wn;
283	    for (i = 0, wn = widget_list; i < nwidgets; i++, wn++) {
284		list_resources (wn, options.format, topnode, container,
285				(Bool) options.show_superclass,
286				(Bool) options.show_variable);
287	    }
288	} else {
289	  fprintf(stderr, "Unknown argument: %s\n", argv[0]);
290	  usage(1);
291	}
292    } else {
293	for (; argc > 0; argc--, argv++) {
294	    XmuWidgetNode *node;
295
296	    if (argv[0][0] == '-') {
297		fprintf(stderr, "Unknown argument: %s\n", argv[0]);
298		usage(1);
299	    }
300	    node = XmuWnNameToNode (widget_list, nwidgets, *argv);
301	    if (!node) {
302		fprintf (stderr, "%s:  unable to find widget \"%s\"\n",
303			 ProgramName, *argv);
304		continue;
305	    }
306	    list_resources (node, options.format, topnode, container,
307			    (Bool) options.show_superclass,
308			    (Bool) options.show_variable);
309	}
310    }
311    exit (0);
312}
313