atomx.c (2490B)
1 /* See LICENSE file for copyright and license details. */ 2 3 #include <err.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <xcb/xcb.h> 8 #include <xcb/xcb_aux.h> 9 10 #include "util.h" 11 #include "arg.h" 12 13 #define MAXLEN 512 14 15 static xcb_connection_t *conn; 16 17 void 18 usage(char *name) 19 { 20 fprintf(stderr, "%s [-d] atom[=value] wid\n", name); 21 } 22 23 xcb_atom_t 24 add_atom(xcb_atom_t type, char *name, size_t len) 25 { 26 xcb_atom_t atom; 27 xcb_intern_atom_cookie_t c; 28 xcb_intern_atom_reply_t *r; 29 30 c = xcb_intern_atom(conn, 0, len, name); 31 r = xcb_intern_atom_reply(conn, c, NULL); 32 if (!r) 33 return 0; 34 35 atom = r->atom; 36 free(r); 37 38 return atom; 39 } 40 41 int 42 set_atom(xcb_window_t wid, xcb_atom_t atom, xcb_atom_t type, size_t len, void *data) 43 { 44 int errcode; 45 xcb_void_cookie_t c; 46 xcb_generic_error_t *e; 47 48 c = xcb_change_property_checked(conn, XCB_PROP_MODE_REPLACE, 49 wid, atom, type, 8, len, data); 50 e = xcb_request_check(conn, c); 51 if (!e) 52 return 0; 53 54 errcode = e->error_code; 55 free(e); 56 57 return errcode; 58 } 59 60 int 61 get_atom(xcb_window_t wid, xcb_atom_t atom, char *data, xcb_atom_t *type) 62 { 63 size_t n; 64 xcb_get_property_cookie_t c; 65 xcb_get_property_reply_t *r; 66 67 c = xcb_get_property(conn, 0, wid, atom, XCB_ATOM_ANY, 0, MAXLEN); 68 r = xcb_get_property_reply(conn, c, NULL); 69 if (!r) 70 return -1; 71 72 if (!(n = xcb_get_property_value_length(r))) { 73 free(r); 74 return -1; 75 } 76 77 strncpy(data, xcb_get_property_value(r), n); 78 data[n] = 0; 79 80 *type = r->type; 81 82 free(r); 83 84 return 0; 85 } 86 87 88 int 89 main(int argc, char **argv) 90 { 91 int i, dflag = 0; 92 char *key, *val, *argv0; 93 char data[MAXLEN]; 94 xcb_window_t wid; 95 xcb_atom_t atom; 96 97 ARGBEGIN { 98 case 'd': 99 dflag = 1; 100 break; 101 default: 102 usage(argv0); 103 return -1; 104 } ARGEND; 105 106 if (argc < 1) 107 return -1; 108 109 key = strtok(argv[0], "="); 110 val = strtok(NULL, "="); 111 112 init_xcb(&conn); 113 114 for (i = 0; i < argc - 1; i++) { 115 wid = strtoul(argv[i+1], NULL, 16); 116 117 /* retrieve atom ID from server */ 118 atom = add_atom(XCB_ATOM_STRING, key, strlen(key)); 119 if (!atom) 120 return -1; 121 122 /* set property on window (must be a string) */ 123 if (val) 124 set_atom(wid, atom, XCB_ATOM_STRING, strlen(val), val); 125 126 /* remove property from window */ 127 if (dflag) 128 xcb_delete_property(conn, wid, atom); 129 130 /* retrieve and print atom value to stdout */ 131 xcb_atom_t type; 132 if (!get_atom(wid, atom, data, &type)) 133 switch (type) { 134 case XCB_ATOM_INTEGER: 135 printf("%d\n", *data); 136 break; 137 default: 138 printf("%s\n", data); 139 } 140 } 141 142 kill_xcb(&conn); 143 144 return 0; 145 }