e4758af2e41ee3826ad6967f54aa9a35c535d0fb
[platform/upstream/xlsatoms.git] / xlsatoms.c
1 /*
2  * $Xorg: xlsatoms.c,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $
3  *
4 Copyright 1989, 1998  The Open Group
5
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
25  *
26  * Author:  Jim Fulton, MIT X Consortium
27  */
28 /* $XFree86$ */
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
37 char *ProgramName;
38
39 static void do_name ( Display *dpy, char *format, char *name );
40 static int parse_range ( char *range, long *lowp, long *highp );
41 static void do_range ( Display *dpy, char *format, char *range );
42 static int catcher ( Display *dpy, XErrorEvent *err );
43 static void list_atoms ( Display *dpy, char *format, int mask, 
44                          long low, long high );
45
46 static void 
47 usage(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
63 int
64 main(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
122 static void
123 do_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
140 static int 
141 parse_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
175 static void
176 do_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
186 static int 
187 catcher(Display *dpy, XErrorEvent *err)
188 {
189     if (err->request_code != X_GetAtomName) {
190         XmuPrintDefaultErrorMessage (dpy, err, stderr);
191     }
192     return 0;
193 }
194
195 static void
196 list_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 }