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