xlsatoms.c revision f5effb2e
1fdb3d228Smrg/* 2fdb3d228Smrg * 3fdb3d228SmrgCopyright 1989, 1998 The Open Group 4f5effb2eSmrgCopyright 2009 Open Text Corporation 5fdb3d228Smrg 6fdb3d228SmrgPermission to use, copy, modify, distribute, and sell this software and its 7fdb3d228Smrgdocumentation for any purpose is hereby granted without fee, provided that 8fdb3d228Smrgthe above copyright notice appear in all copies and that both that 9fdb3d228Smrgcopyright notice and this permission notice appear in supporting 10fdb3d228Smrgdocumentation. 11fdb3d228Smrg 12fdb3d228SmrgThe above copyright notice and this permission notice shall be included in 13fdb3d228Smrgall copies or substantial portions of the Software. 14fdb3d228Smrg 15fdb3d228SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16fdb3d228SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17fdb3d228SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18fdb3d228SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19fdb3d228SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20fdb3d228SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21fdb3d228Smrg 22fdb3d228SmrgExcept as contained in this notice, the name of The Open Group shall not be 23fdb3d228Smrgused in advertising or otherwise to promote the sale, use or other dealings 24fdb3d228Smrgin this Software without prior written authorization from The Open Group. 25fdb3d228Smrg * 26fdb3d228Smrg * Author: Jim Fulton, MIT X Consortium 27f5effb2eSmrg * Author: Peter Harris, Open Text Corporation 28fdb3d228Smrg */ 29fdb3d228Smrg 30fdb3d228Smrg#include <stdio.h> 31fdb3d228Smrg#include <stdlib.h> 32f5effb2eSmrg#include <string.h> 33f5effb2eSmrg#include <xcb/xcb.h> 34f5effb2eSmrg#include <xcb/xproto.h> 35f5effb2eSmrg 36f5effb2eSmrg#define ATOMS_PER_BATCH 100 /* This number can be tuned 37f5effb2eSmrg higher for fewer round-trips 38f5effb2eSmrg lower for less bandwidth wasted */ 39fdb3d228Smrg 409b41ff1aSmrgstatic char *ProgramName; 41f5effb2eSmrgstatic char *DisplayString; 42fdb3d228Smrg 43f5effb2eSmrgstatic void do_name ( xcb_connection_t *c, char *format, char *name ); 44fdb3d228Smrgstatic int parse_range ( char *range, long *lowp, long *highp ); 45f5effb2eSmrgstatic void do_range ( xcb_connection_t *c, char *format, char *range ); 46f5effb2eSmrgstatic void list_atoms ( xcb_connection_t *c, char *format, int mask, 47fdb3d228Smrg long low, long high ); 48fdb3d228Smrg 49fdb3d228Smrgstatic void 50fdb3d228Smrgusage(void) 51fdb3d228Smrg{ 52fdb3d228Smrg fprintf (stderr, "usage: %s [-options...]\n\n", ProgramName); 53fdb3d228Smrg fprintf (stderr, "where options include:\n"); 54fdb3d228Smrg fprintf (stderr, 55fdb3d228Smrg " -display dpy X server to which to connect\n"); 56fdb3d228Smrg fprintf (stderr, 57fdb3d228Smrg " -format string printf-style format to use\n"); 58fdb3d228Smrg fprintf (stderr, 59fdb3d228Smrg " -range [num]-[num] atom values to list\n"); 60fdb3d228Smrg fprintf (stderr, 61fdb3d228Smrg " -name string name of single atom to print\n"); 62fdb3d228Smrg putc ('\n', stderr); 63fdb3d228Smrg exit (1); 64fdb3d228Smrg} 65fdb3d228Smrg 66fdb3d228Smrgint 67fdb3d228Smrgmain(int argc, char *argv[]) 68fdb3d228Smrg{ 69fdb3d228Smrg char *displayname = NULL; 70fdb3d228Smrg char *format = "%lu\t%s"; 71fdb3d228Smrg int i, doit; 72fdb3d228Smrg int didit = 0; 73f5effb2eSmrg xcb_connection_t *c = NULL; 74fdb3d228Smrg 75fdb3d228Smrg ProgramName = argv[0]; 76fdb3d228Smrg 77fdb3d228Smrg for (doit = 0; doit < 2; doit++) { /* pre-parse to get display */ 78fdb3d228Smrg for (i = 1; i < argc; i++) { 79fdb3d228Smrg char *arg = argv[i]; 80fdb3d228Smrg 81fdb3d228Smrg if (arg[0] == '-') { 82fdb3d228Smrg switch (arg[1]) { 83fdb3d228Smrg case 'd': /* -display dpy */ 84fdb3d228Smrg if (++i >= argc) usage (); 85fdb3d228Smrg if (!doit) displayname = argv[i]; 86fdb3d228Smrg continue; 87fdb3d228Smrg case 'f': /* -format string */ 88fdb3d228Smrg if (++i >= argc) usage (); 89fdb3d228Smrg if (doit) format = argv[i]; 90fdb3d228Smrg continue; 91fdb3d228Smrg case 'r': /* -range num-[num] */ 92fdb3d228Smrg if (++i >= argc) usage (); 93fdb3d228Smrg if (doit) { 94f5effb2eSmrg do_range (c, format, argv[i]); 95fdb3d228Smrg didit = 1; 96fdb3d228Smrg } 97fdb3d228Smrg continue; 98fdb3d228Smrg case 'n': /* -name string */ 99fdb3d228Smrg if (++i >= argc) usage (); 100fdb3d228Smrg if (doit) { 101f5effb2eSmrg do_name (c, format, argv[i]); 102fdb3d228Smrg didit = 1; 103fdb3d228Smrg } 104fdb3d228Smrg continue; 105fdb3d228Smrg } 106fdb3d228Smrg } 107fdb3d228Smrg usage (); 108fdb3d228Smrg } 109fdb3d228Smrg if (!doit) { 110f5effb2eSmrg DisplayString = displayname; 111f5effb2eSmrg if (!DisplayString) 112f5effb2eSmrg DisplayString = getenv("DISPLAY"); 113f5effb2eSmrg if (!DisplayString) 114f5effb2eSmrg DisplayString = ""; 115f5effb2eSmrg c = xcb_connect(displayname, NULL); 116f5effb2eSmrg if (!c || xcb_connection_has_error(c)) { 117fdb3d228Smrg fprintf (stderr, "%s: unable to open display \"%s\"\n", 118f5effb2eSmrg ProgramName, DisplayString); 119fdb3d228Smrg exit (1); 120fdb3d228Smrg } 121fdb3d228Smrg } else 122fdb3d228Smrg if (!didit) /* no options, default is list all */ 123f5effb2eSmrg list_atoms(c, format, 0, 0, 0); 124fdb3d228Smrg } 125fdb3d228Smrg 126f5effb2eSmrg xcb_disconnect(c); 127fdb3d228Smrg exit (0); 128fdb3d228Smrg} 129fdb3d228Smrg 130fdb3d228Smrgstatic void 131f5effb2eSmrgdo_name(xcb_connection_t *c, char *format, char *name) 132fdb3d228Smrg{ 133f5effb2eSmrg xcb_intern_atom_reply_t *a = xcb_intern_atom_reply(c, 134f5effb2eSmrg xcb_intern_atom_unchecked(c, 1, strlen(name), name), NULL); 135fdb3d228Smrg 136f5effb2eSmrg if (a && a->atom != XCB_NONE) { 137f5effb2eSmrg printf (format, (unsigned long) a->atom, name); 138fdb3d228Smrg putchar ('\n'); 139fdb3d228Smrg } else { 140fdb3d228Smrg fprintf (stderr, "%s: no atom named \"%s\" on server \"%s\"\n", 141f5effb2eSmrg ProgramName, name, DisplayString); 142fdb3d228Smrg } 143f5effb2eSmrg 144f5effb2eSmrg if (a) 145f5effb2eSmrg free(a); 146fdb3d228Smrg} 147fdb3d228Smrg 148fdb3d228Smrg 149fdb3d228Smrg#define RangeLow (1 << 0) 150fdb3d228Smrg#define RangeHigh (1 << 1) 151fdb3d228Smrg 152fdb3d228Smrgstatic int 153fdb3d228Smrgparse_range(char *range, long *lowp, long *highp) 154fdb3d228Smrg{ 155fdb3d228Smrg char *dash; 156fdb3d228Smrg int mask = 0; 157fdb3d228Smrg 158fdb3d228Smrg if (!range) { /* NULL means default */ 159fdb3d228Smrg *lowp = 1; 160fdb3d228Smrg return RangeLow; 161fdb3d228Smrg } 162fdb3d228Smrg 163fdb3d228Smrg dash = strchr(range, '-'); 164fdb3d228Smrg if (!dash) dash = strchr(range, ':'); 165fdb3d228Smrg if (dash) { 166fdb3d228Smrg if (dash == range) { /* -high */ 167fdb3d228Smrg *lowp = 1; 168fdb3d228Smrg } else { /* low-[high] */ 169fdb3d228Smrg *dash = '\0'; 170fdb3d228Smrg *lowp = atoi (range); 171fdb3d228Smrg *dash = '-'; 172fdb3d228Smrg } 173fdb3d228Smrg mask |= RangeLow; 174fdb3d228Smrg dash++; 175fdb3d228Smrg if (*dash) { /* [low]-high */ 176fdb3d228Smrg *highp = atoi (dash); 177fdb3d228Smrg mask |= RangeHigh; 178fdb3d228Smrg } 179fdb3d228Smrg } else { /* number (low == high) */ 180fdb3d228Smrg *lowp = *highp = atoi (range); 181fdb3d228Smrg mask |= (RangeLow | RangeHigh); 182fdb3d228Smrg } 183fdb3d228Smrg 184fdb3d228Smrg return mask; 185fdb3d228Smrg} 186fdb3d228Smrg 187fdb3d228Smrgstatic void 188f5effb2eSmrgdo_range(xcb_connection_t *c, char *format, char *range) 189fdb3d228Smrg{ 190fdb3d228Smrg int mask; 191fdb3d228Smrg long low, high; 192fdb3d228Smrg 193fdb3d228Smrg mask = parse_range (range, &low, &high); 194f5effb2eSmrg list_atoms (c, format, mask, low, high); 195fdb3d228Smrg} 196fdb3d228Smrg 197f5effb2eSmrgstatic int 198f5effb2eSmrgsay_batch(xcb_connection_t *c, char *format, xcb_get_atom_name_cookie_t *cookie, long low, long count) 199fdb3d228Smrg{ 200f5effb2eSmrg xcb_generic_error_t *e; 201f5effb2eSmrg char atom_name[1024]; 202f5effb2eSmrg long i; 203f5effb2eSmrg int done = 0; 204f5effb2eSmrg 205f5effb2eSmrg for (i = 0; i < count; i++) 206f5effb2eSmrg cookie[i] = xcb_get_atom_name(c, i + low); 207f5effb2eSmrg 208f5effb2eSmrg for (i = 0; i < count; i++) { 209f5effb2eSmrg xcb_get_atom_name_reply_t *r; 210f5effb2eSmrg r = xcb_get_atom_name_reply(c, cookie[i], &e); 211f5effb2eSmrg if (r) { 212f5effb2eSmrg /* We could just use %.*s in 'format', but we want to be compatible 213f5effb2eSmrg with legacy command line usage */ 214f5effb2eSmrg snprintf(atom_name, sizeof(atom_name), "%.*s", 215f5effb2eSmrg r->name_len, xcb_get_atom_name_name(r)); 216f5effb2eSmrg 217f5effb2eSmrg printf (format, i + low, atom_name); 218f5effb2eSmrg putchar ('\n'); 219f5effb2eSmrg free(r); 220f5effb2eSmrg } 221f5effb2eSmrg if (e) { 222f5effb2eSmrg done = 1; 223f5effb2eSmrg free(e); 224f5effb2eSmrg } 225fdb3d228Smrg } 226f5effb2eSmrg 227f5effb2eSmrg return done; 228fdb3d228Smrg} 229fdb3d228Smrg 230fdb3d228Smrgstatic void 231f5effb2eSmrglist_atoms(xcb_connection_t *c, char *format, int mask, long low, long high) 232fdb3d228Smrg{ 233f5effb2eSmrg xcb_get_atom_name_cookie_t *cookie_jar; 234f5effb2eSmrg int done = 0; 235fdb3d228Smrg 236fdb3d228Smrg switch (mask) { 237fdb3d228Smrg case RangeHigh: 238fdb3d228Smrg low = 1; 239fdb3d228Smrg /* fall through */ 240fdb3d228Smrg case (RangeLow | RangeHigh): 241f5effb2eSmrg cookie_jar = malloc((high - low + 1) * sizeof(xcb_get_atom_name_cookie_t)); 242f5effb2eSmrg if (!cookie_jar) { 243f5effb2eSmrg fprintf(stderr, "Out of memory allocating space for %ld atom requests\n", high - low); 244f5effb2eSmrg return; 245fdb3d228Smrg } 246f5effb2eSmrg 247f5effb2eSmrg say_batch(c, format, cookie_jar, low, high - low + 1); 248f5effb2eSmrg free(cookie_jar); 249fdb3d228Smrg break; 250fdb3d228Smrg 251fdb3d228Smrg default: 252fdb3d228Smrg low = 1; 253fdb3d228Smrg /* fall through */ 254fdb3d228Smrg case RangeLow: 255f5effb2eSmrg cookie_jar = malloc(ATOMS_PER_BATCH * sizeof(xcb_get_atom_name_cookie_t)); 256f5effb2eSmrg if (!cookie_jar) { 257f5effb2eSmrg fprintf(stderr, "Out of memory allocating space for %ld atom requests\n", (long) ATOMS_PER_BATCH); 258f5effb2eSmrg return; 259f5effb2eSmrg } 260f5effb2eSmrg while (!done) { 261f5effb2eSmrg done = say_batch(c, format, cookie_jar, low, ATOMS_PER_BATCH); 262f5effb2eSmrg low += ATOMS_PER_BATCH; 263fdb3d228Smrg } 264f5effb2eSmrg free(cookie_jar); 265fdb3d228Smrg break; 266fdb3d228Smrg } 267fdb3d228Smrg 268fdb3d228Smrg return; 269fdb3d228Smrg} 270