xlsatoms.c revision 9b41ff1a
1/*
2 * $Xorg: xlsatoms.c,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $
3 *
4Copyright 1989, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25 *
26 * Author:  Jim Fulton, MIT X Consortium
27 */
28/* $XFree86: xc/programs/xlsatoms/xlsatoms.c,v 1.5 2001/04/01 14:00:23 tsi Exp $ */
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <X11/Xos.h>
33#include <X11/Xlib.h>
34#include <X11/Xproto.h>
35#include <X11/Xmu/Error.h>
36
37static char *ProgramName;
38
39static void do_name ( Display *dpy, char *format, char *name );
40static int parse_range ( char *range, long *lowp, long *highp );
41static void do_range ( Display *dpy, char *format, char *range );
42static int catcher ( Display *dpy, XErrorEvent *err );
43static void list_atoms ( Display *dpy, char *format, int mask,
44			 long low, long high );
45
46static void
47usage(void)
48{
49    fprintf (stderr, "usage:  %s [-options...]\n\n", ProgramName);
50    fprintf (stderr, "where options include:\n");
51    fprintf (stderr,
52	     "    -display dpy            X server to which to connect\n");
53    fprintf (stderr,
54	     "    -format string          printf-style format to use\n");
55    fprintf (stderr,
56	     "    -range [num]-[num]      atom values to list\n");
57    fprintf (stderr,
58	     "    -name string            name of single atom to print\n");
59    putc ('\n', stderr);
60    exit (1);
61}
62
63int
64main(int argc, char *argv[])
65{
66    char *displayname = NULL;
67    char *format = "%lu\t%s";
68    int i, doit;
69    int didit = 0;
70    Display *dpy = NULL;
71
72    ProgramName = argv[0];
73
74    for (doit = 0; doit < 2; doit++) {	/* pre-parse to get display */
75	for (i = 1; i < argc; i++) {
76	    char *arg = argv[i];
77
78	    if (arg[0] == '-') {
79		switch (arg[1]) {
80		  case 'd':			/* -display dpy */
81		    if (++i >= argc) usage ();
82		    if (!doit) displayname = argv[i];
83		    continue;
84		  case 'f':			/* -format string */
85		    if (++i >= argc) usage ();
86		    if (doit) format = argv[i];
87		    continue;
88		  case 'r':			/* -range num-[num] */
89		    if (++i >= argc) usage ();
90		    if (doit) {
91			do_range (dpy, format, argv[i]);
92			didit = 1;
93		    }
94		    continue;
95		  case 'n':			/* -name string */
96		    if (++i >= argc) usage ();
97		    if (doit) {
98			do_name (dpy, format, argv[i]);
99			didit = 1;
100		    }
101		    continue;
102		}
103	    }
104	    usage ();
105	}
106	if (!doit) {
107	    dpy = XOpenDisplay (displayname);
108	    if (!dpy) {
109		fprintf (stderr, "%s:  unable to open display \"%s\"\n",
110			 ProgramName, XDisplayName (displayname));
111		exit (1);
112	    }
113	} else
114	    if (!didit)		/* no options, default is list all */
115		list_atoms(dpy, format, 0, 0, 0);
116    }
117
118    XCloseDisplay (dpy);
119    exit (0);
120}
121
122static void
123do_name(Display *dpy, char *format, char *name)
124{
125    Atom a = XInternAtom (dpy, name, True);
126
127    if (a != None) {
128	printf (format, (unsigned long) a, name);
129	putchar ('\n');
130    } else {
131	fprintf (stderr, "%s:  no atom named \"%s\" on server \"%s\"\n",
132		 ProgramName, name, DisplayString(dpy));
133    }
134}
135
136
137#define RangeLow (1 << 0)
138#define RangeHigh (1 << 1)
139
140static int
141parse_range(char *range, long *lowp, long *highp)
142{
143    char *dash;
144    int mask = 0;
145
146    if (!range) {			/* NULL means default */
147	*lowp = 1;
148	return RangeLow;
149    }
150
151    dash = strchr(range, '-');
152    if (!dash) dash = strchr(range, ':');
153    if (dash) {
154	if (dash == range) {		/* -high */
155	    *lowp = 1;
156	} else {			/* low-[high] */
157	    *dash = '\0';
158	    *lowp = atoi (range);
159	    *dash = '-';
160	}
161	mask |= RangeLow;
162	dash++;
163	if (*dash) {			/* [low]-high */
164	    *highp = atoi (dash);
165	    mask |= RangeHigh;
166	}
167    } else {				/* number (low == high) */
168	*lowp = *highp = atoi (range);
169	mask |= (RangeLow | RangeHigh);
170    }
171
172    return mask;
173}
174
175static void
176do_range(Display *dpy, char *format, char *range)
177{
178    int mask;
179    long low, high;
180
181    mask = parse_range (range, &low, &high);
182    list_atoms (dpy, format, mask, low, high);
183}
184
185
186static int
187catcher(Display *dpy, XErrorEvent *err)
188{
189    if (err->request_code != X_GetAtomName) {
190	XmuPrintDefaultErrorMessage (dpy, err, stderr);
191    }
192    return 0;
193}
194
195static void
196list_atoms(Display *dpy, char *format, int mask, long low, long high)
197{
198    XErrorHandler oldhandler = XSetErrorHandler (catcher);
199
200    switch (mask) {
201      case RangeHigh:
202	low = 1;
203	/* fall through */
204      case (RangeLow | RangeHigh):
205	for (; low <= high; low++) {
206	    char *s = XGetAtomName (dpy, (Atom)low);
207	    if (s) {
208		printf (format, low, s);
209		putchar ('\n');
210		XFree (s);
211	    }
212	}
213	break;
214
215      default:
216	low = 1;
217	/* fall through */
218      case RangeLow:
219	for (; ; low++) {
220	    char *s = XGetAtomName (dpy, (Atom)low);
221	    if (s) {
222		printf (format, low, s);
223		putchar ('\n');
224		XFree (s);
225	    } else {
226		break;
227	    }
228	}
229	break;
230    }
231
232    XSetErrorHandler (oldhandler);
233    return;
234}
235