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