atoms.gperf.m4 revision ecce36be
1%{ 2 3/* Rely on vasprintf (GNU extension) instead of vsnprintf if 4 possible... */ 5#ifdef HAVE_VASPRINTF 6#define _GNU_SOURCE 7#include <stdio.h> 8#endif 9 10#include <xcb/xcb.h> 11#include <stdlib.h> 12#include <stdarg.h> 13#include "xcb_atom.h" 14 15define(`COUNT', 0)dnl 16define(`DO', `const xcb_atom_t $1 = define(`COUNT', incr(COUNT))COUNT;')dnl 17include(atomlist.m4)`'dnl 18%} 19 20%readonly-tables 21%pic 22%null-strings 23%enum 24%includes 25%compare-strncmp 26 27%struct-type 28struct atom_map { int name; xcb_atom_t value; }; 29%% 30define(`COUNT', 0)dnl 31define(`DO', `$1,define(`COUNT', incr(COUNT))COUNT')dnl 32include(atomlist.m4)`'dnl 33%% 34 35static const char atom_names[] = 36define(`DO', ` "$1\0"')dnl 37include(atomlist.m4); 38 39static const uint16_t atom_name_offsets[] = { 40define(`OFFSET', 0)dnl 41define(`DO', ` OFFSET,define(`OFFSET', eval(OFFSET+1+len($1)))')dnl 42include(atomlist.m4)`'dnl 43}; 44 45xcb_atom_t xcb_atom_get(xcb_connection_t *connection, const char *atom_name) 46{ 47 if(atom_name == NULL) 48 return XCB_NONE; 49 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, 50 xcb_intern_atom(connection, 0, strlen(atom_name), atom_name), NULL); 51 if(!reply) 52 return XCB_NONE; 53 xcb_atom_t atom = reply->atom; 54 free(reply); 55 return atom; 56} 57 58xcb_atom_t xcb_atom_get_predefined(uint16_t name_len, const char *name) 59{ 60 const struct atom_map *value = in_word_set(name, name_len); 61 xcb_atom_t ret = XCB_NONE; 62 if(value) 63 ret = value->value; 64 return ret; 65} 66 67xcb_atom_fast_cookie_t xcb_atom_get_fast(xcb_connection_t *c, uint8_t only_if_exists, uint16_t name_len, const char *name) 68{ 69 xcb_atom_fast_cookie_t cookie; 70 71 if((cookie.u.atom = xcb_atom_get_predefined(name_len, name)) != XCB_NONE) 72 { 73 cookie.tag = TAG_VALUE; 74 return cookie; 75 } 76 77 cookie.tag = TAG_COOKIE; 78 cookie.u.cookie = xcb_intern_atom(c, only_if_exists, name_len, name); 79 return cookie; 80} 81 82xcb_atom_t xcb_atom_get_fast_reply(xcb_connection_t *c, xcb_atom_fast_cookie_t cookie, xcb_generic_error_t **e) 83{ 84 switch(cookie.tag) 85 { 86 xcb_intern_atom_reply_t *reply; 87 case TAG_VALUE: 88 if(e) 89 *e = 0; 90 break; 91 case TAG_COOKIE: 92 reply = xcb_intern_atom_reply(c, cookie.u.cookie, e); 93 if(reply) 94 { 95 cookie.u.atom = reply->atom; 96 free(reply); 97 } 98 else 99 cookie.u.atom = XCB_NONE; 100 break; 101 } 102 return cookie.u.atom; 103} 104 105const char *xcb_atom_get_name_predefined(xcb_atom_t atom) 106{ 107 if(atom <= 0 || atom > (sizeof(atom_name_offsets) / sizeof(*atom_name_offsets))) 108 return 0; 109 return atom_names + atom_name_offsets[atom - 1]; 110} 111 112int xcb_atom_get_name(xcb_connection_t *c, xcb_atom_t atom, const char **namep, int *lengthp) 113{ 114 static char buf[100]; 115 const char *name = xcb_atom_get_name_predefined(atom); 116 int namelen; 117 xcb_get_atom_name_cookie_t atomc; 118 xcb_get_atom_name_reply_t *atomr; 119 if(name) 120 { 121 *namep = name; 122 *lengthp = strlen(name); 123 return 1; 124 } 125 atomc = xcb_get_atom_name(c, atom); 126 atomr = xcb_get_atom_name_reply(c, atomc, 0); 127 if(!atomr) 128 return 0; 129 namelen = xcb_get_atom_name_name_length(atomr); 130 if(namelen > sizeof(buf)) 131 namelen = sizeof(buf); 132 *lengthp = namelen; 133 memcpy(buf, xcb_get_atom_name_name(atomr), namelen); 134 *namep = buf; 135 free(atomr); 136 return 1; 137} 138 139static char *makename(const char *fmt, ...) 140{ 141 char *ret; 142 int n; 143 va_list ap; 144 145#ifndef HAVE_VASPRINTF 146 char *np; 147 int size = 64; 148 149 /* First allocate 'size' bytes, should be enough usually */ 150 if((ret = malloc(size)) == NULL) 151 return NULL; 152 153 while(1) 154 { 155 va_start(ap, fmt); 156 n = vsnprintf(ret, size, fmt, ap); 157 va_end(ap); 158 159 if(n < 0) 160 return NULL; 161 162 if(n < size) 163 return ret; 164 165 size = n + 1; 166 if((np = realloc(ret, size)) == NULL) 167 { 168 free(ret); 169 return NULL; 170 } 171 172 ret = np; 173 } 174#else 175 va_start(ap, fmt); 176 n = vasprintf(&ret, fmt, ap); 177 va_end(ap); 178 179 if(n < 0) 180 return NULL; 181 182 return ret; 183#endif 184} 185 186char *xcb_atom_name_by_screen(const char *base, uint8_t screen) 187{ 188 return makename("%s_S%u", base, screen); 189} 190 191char *xcb_atom_name_by_resource(const char *base, uint32_t resource) 192{ 193 return makename("%s_R%08X", base, resource); 194} 195 196char *xcb_atom_name_unique(const char *base, uint32_t id) 197{ 198 if(base) 199 return makename("%s_U%lu", base, id); 200 else 201 return makename("U%lu", id); 202} 203