diff options
author | Julien Danjou <julien@danjou.info> | 2008-09-16 14:03:12 +0200 |
---|---|---|
committer | Julien Danjou <julien@danjou.info> | 2008-09-16 14:07:39 +0200 |
commit | 24b521fea8606cda064e5662562b44b14f0922b5 (patch) | |
tree | 78add5cf428133c31f512703918146a49240d2fa | |
parent | 078a8bd31fcff7624b22fb6466000059aa4324c3 (diff) |
property: rewrite property handler interface
Signed-off-by: Julien Danjou <julien@danjou.info>
-rw-r--r-- | property/Makefile.am | 3 | ||||
-rw-r--r-- | property/prop.c | 149 | ||||
-rw-r--r-- | property/property.c | 147 | ||||
-rw-r--r-- | property/xcb_property.h | 139 | ||||
-rw-r--r-- | wm/xcbwm-test.c | 10 |
5 files changed, 279 insertions, 169 deletions
diff --git a/property/Makefile.am b/property/Makefile.am index 6cdbba1..3fb56de 100644 --- a/property/Makefile.am +++ b/property/Makefile.am @@ -7,9 +7,10 @@ xcbinclude_HEADERS = xcb_property.h AM_CFLAGS = $(CWARNFLAGS) -libxcb_property_la_SOURCES = prop.c +libxcb_property_la_SOURCES = property.c libxcb_property_la_CPPFLAGS = $(XCB_CFLAGS) $(XCB_EVENT_CFLAGS) libxcb_property_la_LIBADD = $(XCB_LIBS) $(XCB_EVENT_LIBS) +libxcb_property_la_LDFLAGS = -version-info 1:0:0 pkgconfig_DATA = xcb-property.pc diff --git a/property/prop.c b/property/prop.c deleted file mode 100644 index 751afdf..0000000 --- a/property/prop.c +++ /dev/null @@ -1,149 +0,0 @@ -#include <stdlib.h> -#include <assert.h> -#include <xcb/xcb.h> -#include "xcb_property.h" - -typedef struct { - uint32_t long_len; - xcb_generic_property_handler_t handler; - void *data; -} prop_handler_t; - -typedef struct node node; -struct node { - node *next; - xcb_atom_t name; - prop_handler_t h; -}; - -struct xcb_property_handlers { - node *head; - prop_handler_t *def; - xcb_event_handlers_t *evenths; -}; - -xcb_get_property_cookie_t xcb_get_any_property(xcb_connection_t *c, uint8_t del, xcb_window_t window, xcb_atom_t name, uint32_t long_len) -{ - static const xcb_atom_t type = XCB_GET_PROPERTY_TYPE_ANY; - - return xcb_get_property(c, del, window, name, type, 0, long_len); -} - -xcb_get_property_cookie_t xcb_get_any_property_unchecked(xcb_connection_t *c, - uint8_t del, - xcb_window_t window, - xcb_atom_t name, - uint32_t long_len) -{ - static const xcb_atom_t type = XCB_GET_PROPERTY_TYPE_ANY; - - return xcb_get_property_unchecked(c, del, window, name, type, 0, - long_len); -} - -static int call_handler(xcb_connection_t *c, uint8_t state, xcb_window_t window, xcb_atom_t atom, prop_handler_t *h) -{ - xcb_get_property_reply_t *propr = 0; - int ret; - - if(state != XCB_PROPERTY_DELETE) - { - xcb_get_property_cookie_t cookie = xcb_get_any_property(c, 0, window, atom, h->long_len); - propr = xcb_get_property_reply(c, cookie, 0); - } - ret = h->handler(h->data, c, state, window, atom, propr); - free(propr); - return ret; -} - -int xcb_property_changed(xcb_property_handlers_t *prophs, uint8_t state, xcb_window_t window, xcb_atom_t atom) -{ - xcb_connection_t *c = xcb_get_xcb_connection(xcb_get_property_event_handlers(prophs)); - node *cur; - - for(cur = prophs->head; cur; cur = cur->next) - if(cur->name == atom) - return call_handler(c, state, window, atom, &cur->h); - if(prophs->def) - return call_handler(c, state, window, atom, prophs->def); - return 0; -} - -static int handle_property_notify_event(void *data, xcb_connection_t *c, xcb_property_notify_event_t *e) -{ - xcb_property_handlers_t *prophs = data; - uint8_t state = e->state; - xcb_window_t window = e->window; - xcb_atom_t atom = e->atom; - - return xcb_property_changed(prophs, state, window, atom); -} - -xcb_property_handlers_t *xcb_alloc_property_handlers(xcb_event_handlers_t *evenths) -{ - xcb_property_handlers_t *prophs = malloc(sizeof(xcb_property_handlers_t)); - - if(prophs) - { - prophs->head = 0; - prophs->def = 0; - prophs->evenths = evenths; - set_property_notify_event_handler(evenths, handle_property_notify_event, prophs); - } - return prophs; -} - -void xcb_free_property_handlers(xcb_property_handlers_t *prophs) -{ - free(prophs); -} - -xcb_event_handlers_t *xcb_get_property_event_handlers(xcb_property_handlers_t *prophs) -{ - return prophs->evenths; -} - -static inline void set_prop_handler(prop_handler_t *cur, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) -{ - cur->long_len = long_len; - cur->handler = handler; - cur->data = data; -} - -int xcb_set_property_handler(xcb_property_handlers_t *prophs, xcb_atom_t name, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) -{ - node *cur = malloc(sizeof(node)); - if(!cur) - return 0; - cur->next = prophs->head; - cur->name = name; - set_prop_handler(&cur->h, long_len, handler, data); - prophs->head = cur; - return 1; -} - -int xcb_set_default_property_handler(xcb_property_handlers_t *prophs, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) -{ - assert(!prophs->def); - prophs->def = malloc(sizeof(prop_handler_t)); - if(!prophs->def) - return 0; - set_prop_handler(prophs->def, long_len, handler, data); - return 1; -} - -int root_of_screen(xcb_connection_t *c, int screen, xcb_window_t *root) -{ - xcb_screen_iterator_t i = xcb_setup_roots_iterator(xcb_get_setup(c)); - if(screen >= i.rem) - return 0; - for(; screen && i.rem; --screen, xcb_screen_next(&i)) - /* empty */; - *root = i.data->root; - return 1; -} - -xcb_void_cookie_t send_to_window(xcb_connection_t *c, xcb_window_t root, const xcb_client_message_event_t *ev) -{ - return xcb_send_event(c, /* propagate */ 0, root, XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) ev); -} diff --git a/property/property.c b/property/property.c new file mode 100644 index 0000000..defac17 --- /dev/null +++ b/property/property.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2008 Julien Danjou <julien@danjou.info> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include <stdlib.h> +#include <string.h> + +#include "xcb_property.h" + +xcb_get_property_cookie_t +xcb_get_any_property(xcb_connection_t *c, uint8_t del, xcb_window_t window, xcb_atom_t name, uint32_t long_len) +{ + static const xcb_atom_t type = XCB_GET_PROPERTY_TYPE_ANY; + + return xcb_get_property(c, del, window, name, type, 0, long_len); +} + +xcb_get_property_cookie_t +xcb_get_any_property_unchecked(xcb_connection_t *c, + uint8_t del, + xcb_window_t window, + xcb_atom_t name, + uint32_t long_len) +{ + return xcb_get_property_unchecked(c, del, window, name, XCB_GET_PROPERTY_TYPE_ANY, 0, long_len); +} + +static int +call_handler(xcb_connection_t *c, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_property_handler_t *h) +{ + xcb_get_property_reply_t *propr = 0; + int ret; + + if(state != XCB_PROPERTY_DELETE) + { + xcb_get_property_cookie_t cookie = xcb_get_any_property(c, 0, window, atom, h->long_len); + propr = xcb_get_property_reply(c, cookie, 0); + } + ret = h->handler(h->data, c, state, window, atom, propr); + free(propr); + return ret; +} + +int +xcb_property_changed(xcb_property_handlers_t *prophs, uint8_t state, xcb_window_t window, xcb_atom_t atom) +{ + xcb_connection_t *c = xcb_get_xcb_connection(xcb_property_get_event_handlers(prophs)); + xcb_property_handler_node_t *cur; + + for(cur = prophs->head; cur; cur = cur->next) + if(cur->name == atom) + return call_handler(c, state, window, atom, &cur->h); + + if(prophs->def.handler) + return call_handler(c, state, window, atom, &prophs->def); + + return 0; +} + +static int +handle_property_notify_event(void *data, xcb_connection_t *c, xcb_property_notify_event_t *e) +{ + xcb_property_handlers_t *prophs = data; + uint8_t state = e->state; + xcb_window_t window = e->window; + xcb_atom_t atom = e->atom; + + return xcb_property_changed(prophs, state, window, atom); +} + +void +xcb_property_handlers_init(xcb_property_handlers_t *prophs, xcb_event_handlers_t *evenths) +{ + memset(prophs, 0, sizeof(prophs)); + prophs->evenths = evenths; + set_property_notify_event_handler(evenths, handle_property_notify_event, prophs); +} + +void +xcb_property_handlers_wipe(xcb_property_handlers_t *prophs) +{ + xcb_property_handler_node_t *node, *next; + + for(node = prophs->head; node; node = next) + { + next = node->next; + free(node); + } +} + +xcb_event_handlers_t * +xcb_property_get_event_handlers(xcb_property_handlers_t *prophs) +{ + return prophs->evenths; +} + +static inline void +set_prop_handler(xcb_property_handler_t *cur, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) +{ + cur->long_len = long_len; + cur->handler = handler; + cur->data = data; +} + +uint8_t +xcb_property_set_handler(xcb_property_handlers_t *prophs, xcb_atom_t name, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) +{ + xcb_property_handler_node_t *cur = malloc(sizeof(xcb_property_handler_node_t)); + if(!cur) + return 0; + cur->next = prophs->head; + cur->name = name; + set_prop_handler(&cur->h, long_len, handler, data); + prophs->head = cur; + return 1; +} + +uint8_t +xcb_property_set_default_handler(xcb_property_handlers_t *prophs, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) +{ + set_prop_handler(&prophs->def, long_len, handler, data); + return 1; +} diff --git a/property/xcb_property.h b/property/xcb_property.h index 2a7b4e7..ea2962c 100644 --- a/property/xcb_property.h +++ b/property/xcb_property.h @@ -1,38 +1,149 @@ -#ifndef __XCB_PROP_H__ -#define __XCB_PROP_H__ +/* + * Copyright (C) 2008 Julien Danjou <julien@danjou.info> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ -#include "xcb_event.h" +#ifndef __XCB_PROPERTY_H__ +#define __XCB_PROPERTY_H__ +#include "xcb_event.h" #ifdef __cplusplus extern "C" { #endif +typedef struct xcb_property_handlers xcb_property_handlers_t; +typedef int (*xcb_generic_property_handler_t)(void *data, xcb_connection_t *c, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *property); + +typedef struct { + uint32_t long_len; + xcb_generic_property_handler_t handler; + void *data; +} xcb_property_handler_t; + +typedef struct xcb_property_handler_node xcb_property_handler_node_t; +struct xcb_property_handler_node { + xcb_property_handler_node_t *next; + xcb_atom_t name; + xcb_property_handler_t h; +}; -xcb_get_property_cookie_t xcb_get_any_property(xcb_connection_t *c, uint8_t del, xcb_window_t window, xcb_atom_t name, uint32_t long_len); +struct xcb_property_handlers { + xcb_property_handler_node_t *head; + xcb_property_handler_t def; + xcb_event_handlers_t *evenths; +}; + +/** + * @brief Get any property from a window, from any format. + * @param c The connection to the X server. + * @param del The XCB_PROP_MODE value. + * @param window The window to get property from. + * @param name The property atom name. + * @param long_len The maximum length of the property. + * @return A cookie. + */ +xcb_get_property_cookie_t xcb_get_any_property(xcb_connection_t *c, + uint8_t del, + xcb_window_t window, + xcb_atom_t name, + uint32_t long_len); + +/** + * @see xcb_get_any_property + */ xcb_get_property_cookie_t xcb_get_any_property_unchecked(xcb_connection_t *c, uint8_t del, xcb_window_t window, xcb_atom_t name, uint32_t long_len); +/** + * @brief Initialize a property handlers structure. + * @param prophs The property handlers data structure pointer. + * @param evenths The event handlers. + */ +void xcb_property_handlers_init(xcb_property_handlers_t *prophs, xcb_event_handlers_t *evenths); -typedef struct xcb_property_handlers xcb_property_handlers_t; +/** + * @brief Wipe a property handler structure. + * @param prophs The property handlers data structure pointer. + */ +void xcb_property_handlers_wipe(xcb_property_handlers_t *prophs); -xcb_property_handlers_t *xcb_alloc_property_handlers(xcb_event_handlers_t *evenths); -void xcb_free_property_handlers(xcb_property_handlers_t *prophs); -xcb_event_handlers_t *xcb_get_property_event_handlers(xcb_property_handlers_t *prophs); +/** + * @brief Get a event handlers from a property handlers data structure. + * @param prophs The property handlers. + * @return The event handlers data structure which was set if any, NULL + * otherwise. + */ +xcb_event_handlers_t *xcb_property_get_event_handlers(xcb_property_handlers_t *prophs); -typedef int (*xcb_generic_property_handler_t)(void *data, xcb_connection_t *c, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *property); +/** + * @brief Set a property handler for an event. + * @param prophs The property handlers. + * @param name The property atom name. + * @param long_len The maximum length of the property value that will be + * handled. + * @param handler The handler callback function. + * @param data Optional data that will be passed as argument of the handler + * callback function. Can be NULL safely if you do not need it. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_property_set_handler(xcb_property_handlers_t *prophs, + xcb_atom_t name, + uint32_t long_len, + xcb_generic_property_handler_t handler, + void *data); -int xcb_set_property_handler(xcb_property_handlers_t *prophs, xcb_atom_t name, uint32_t long_len, xcb_generic_property_handler_t handler, void *data); -int xcb_set_default_property_handler(xcb_property_handlers_t *prophs, uint32_t long_len, xcb_generic_property_handler_t handler, void *data); +/** + * @brief Set the default property handler. + * If a property does not have its own handler function, this one will be + * used. + * @param prophs The property handlers. + * @param name The property atom name. + * @param long_len The maximum length of the property value that will be + * handled. + * @param handler The handler callback function. + * @param data Optional data that will be passed as argument of the handler + * callback function. Can be NULL safely if you do not need it. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_property_set_default_handler(xcb_property_handlers_t *prophs, uint32_t long_len, xcb_generic_property_handler_t handler, void *data); +/** + * @brief Notify that a property has changed and call handler function callback as needed. + * @param prophs The property handlers. + * @param state The property state. + * @param window The window. + * @param atom The property atom name. + */ int xcb_property_changed(xcb_property_handlers_t *prophs, uint8_t state, xcb_window_t window, xcb_atom_t atom); - #ifdef __cplusplus } #endif - -#endif /* __XCB_PROP_H__ */ +#endif /* __XCB_PROPERTY_H__ */ diff --git a/wm/xcbwm-test.c b/wm/xcbwm-test.c index c928d7a..10c2e1b 100644 --- a/wm/xcbwm-test.c +++ b/wm/xcbwm-test.c @@ -177,7 +177,7 @@ int main(int argc, char **argv) { xcb_connection_t *c; xcb_event_handlers_t *evenths; - xcb_property_handlers_t *prophs; + xcb_property_handlers_t prophs; xcb_window_t root; pthread_t event_thread; int screen_nbr; @@ -199,9 +199,9 @@ int main(int argc, char **argv) set_unmap_notify_event_handler(evenths, handle_unmap_notify_event, 0); set_expose_event_handler(evenths, handleExposeEvent, 0); - prophs = xcb_alloc_property_handlers(evenths); - set_map_notify_event_handler(evenths, handle_map_notify_event, prophs); - xcb_watch_wm_name(prophs, 40, handleWMNameChange, 0); + xcb_property_handlers_init(&prophs, evenths); + set_map_notify_event_handler(evenths, handle_map_notify_event, &prophs); + xcb_watch_wm_name(&prophs, 40, handleWMNameChange, 0); if(TEST_THREADS) { @@ -217,7 +217,7 @@ int main(int argc, char **argv) } xcb_flush(c); - manage_existing_windows(c, prophs, root); + manage_existing_windows(c, &prophs, root); /* Terminate only when the event loop terminates */ if(TEST_THREADS) |