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