property.c revision 4bc7f083
1/* 2 * Copyright © 2008 Julien Danjou <julien@danjou.info> 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * Except as contained in this notice, the names of the authors or 24 * their institutions shall not be used in advertising or otherwise to 25 * promote the sale, use or other dealings in this Software without 26 * prior written authorization from the authors. 27 */ 28 29#include <stdlib.h> 30#include <string.h> 31 32#include "xcb_property.h" 33 34xcb_get_property_cookie_t 35xcb_get_any_property(xcb_connection_t *c, uint8_t del, xcb_window_t window, xcb_atom_t name, uint32_t long_len) 36{ 37 static const xcb_atom_t type = XCB_GET_PROPERTY_TYPE_ANY; 38 39 return xcb_get_property(c, del, window, name, type, 0, long_len); 40} 41 42xcb_get_property_cookie_t 43xcb_get_any_property_unchecked(xcb_connection_t *c, 44 uint8_t del, 45 xcb_window_t window, 46 xcb_atom_t name, 47 uint32_t long_len) 48{ 49 return xcb_get_property_unchecked(c, del, window, name, XCB_GET_PROPERTY_TYPE_ANY, 0, long_len); 50} 51 52static int 53call_handler(xcb_connection_t *c, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_property_handler_t *h) 54{ 55 xcb_get_property_reply_t *propr = 0; 56 int ret; 57 58 if(state != XCB_PROPERTY_DELETE) 59 { 60 xcb_get_property_cookie_t cookie = xcb_get_any_property(c, 0, window, atom, h->long_len); 61 propr = xcb_get_property_reply(c, cookie, 0); 62 } 63 ret = h->handler(h->data, c, state, window, atom, propr); 64 free(propr); 65 return ret; 66} 67 68int 69xcb_property_changed(xcb_property_handlers_t *prophs, uint8_t state, xcb_window_t window, xcb_atom_t atom) 70{ 71 xcb_connection_t *c = xcb_event_get_xcb_connection(xcb_property_get_event_handlers(prophs)); 72 xcb_property_handler_node_t *cur; 73 74 for(cur = prophs->head; cur; cur = cur->next) 75 if(cur->name == atom) 76 return call_handler(c, state, window, atom, &cur->h); 77 78 if(prophs->def.handler) 79 return call_handler(c, state, window, atom, &prophs->def); 80 81 return 0; 82} 83 84static int 85handle_property_notify_event(void *data, xcb_connection_t *c, xcb_property_notify_event_t *e) 86{ 87 xcb_property_handlers_t *prophs = data; 88 uint8_t state = e->state; 89 xcb_window_t window = e->window; 90 xcb_atom_t atom = e->atom; 91 92 return xcb_property_changed(prophs, state, window, atom); 93} 94 95void 96xcb_property_handlers_init(xcb_property_handlers_t *prophs, xcb_event_handlers_t *evenths) 97{ 98 memset(prophs, 0, sizeof(*prophs)); 99 prophs->evenths = evenths; 100 xcb_event_set_property_notify_handler(evenths, handle_property_notify_event, prophs); 101} 102 103void 104xcb_property_handlers_wipe(xcb_property_handlers_t *prophs) 105{ 106 xcb_property_handler_node_t *node, *next; 107 108 for(node = prophs->head; node; node = next) 109 { 110 next = node->next; 111 free(node); 112 } 113} 114 115xcb_event_handlers_t * 116xcb_property_get_event_handlers(xcb_property_handlers_t *prophs) 117{ 118 return prophs->evenths; 119} 120 121static inline void 122set_prop_handler(xcb_property_handler_t *cur, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) 123{ 124 cur->long_len = long_len; 125 cur->handler = handler; 126 cur->data = data; 127} 128 129uint8_t 130xcb_property_set_handler(xcb_property_handlers_t *prophs, xcb_atom_t name, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) 131{ 132 xcb_property_handler_node_t *cur = malloc(sizeof(xcb_property_handler_node_t)); 133 if(!cur) 134 return 0; 135 cur->next = prophs->head; 136 cur->name = name; 137 set_prop_handler(&cur->h, long_len, handler, data); 138 prophs->head = cur; 139 return 1; 140} 141 142uint8_t 143xcb_property_set_default_handler(xcb_property_handlers_t *prophs, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) 144{ 145 set_prop_handler(&prophs->def, long_len, handler, data); 146 return 1; 147} 148