summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Danjou <julien@danjou.info>2008-09-16 14:03:12 +0200
committerJulien Danjou <julien@danjou.info>2008-09-16 14:07:39 +0200
commit24b521fea8606cda064e5662562b44b14f0922b5 (patch)
tree78add5cf428133c31f512703918146a49240d2fa
parent078a8bd31fcff7624b22fb6466000059aa4324c3 (diff)
property: rewrite property handler interface
Signed-off-by: Julien Danjou <julien@danjou.info>
-rw-r--r--property/Makefile.am3
-rw-r--r--property/prop.c149
-rw-r--r--property/property.c147
-rw-r--r--property/xcb_property.h139
-rw-r--r--wm/xcbwm-test.c10
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)