diff options
-rw-r--r-- | event/Makefile.am | 3 | ||||
-rw-r--r-- | event/event.c | 117 | ||||
-rw-r--r-- | event/events.c | 99 | ||||
-rw-r--r-- | event/xcb_event.h | 187 | ||||
-rw-r--r-- | property/property.c | 4 | ||||
-rw-r--r-- | wm/xcbwm-test.c | 26 |
6 files changed, 268 insertions, 168 deletions
diff --git a/event/Makefile.am b/event/Makefile.am index cc085bb..5a7d819 100644 --- a/event/Makefile.am +++ b/event/Makefile.am @@ -7,9 +7,10 @@ xcbinclude_HEADERS = xcb_event.h AM_CFLAGS = $(CWARNFLAGS) -libxcb_event_la_SOURCES = events.c +libxcb_event_la_SOURCES = event.c libxcb_event_la_CPPFLAGS = $(XCB_CFLAGS) libxcb_event_la_LIBADD = $(XCB_LIBS) +libxcb_event_la_LDFLAGS = -version-info 1:0:0 pkgconfig_DATA = xcb-event.pc diff --git a/event/event.c b/event/event.c new file mode 100644 index 0000000..e19a077 --- /dev/null +++ b/event/event.c @@ -0,0 +1,117 @@ +/* + * 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 <assert.h> +#include <stdlib.h> + +#include "xcb_event.h" + +void +xcb_event_handlers_init(xcb_connection_t *c, xcb_event_handlers_t *evenths) +{ + evenths->c = c; +} + +xcb_connection_t * +xcb_event_get_xcb_connection(xcb_event_handlers_t *evenths) +{ + return evenths->c; +} + +static xcb_event_handler_t * +get_event_handler(xcb_event_handlers_t *evenths, int event) +{ + assert(event < 256); + event &= 0x7f; + assert(event >= 2); + return &evenths->event[event - 2]; +} + +static xcb_event_handler_t * +get_error_handler(xcb_event_handlers_t *evenths, int error) +{ + assert(error >= 0 && error < 256); + return &evenths->error[error]; +} + +int +xcb_event_handle(xcb_event_handlers_t *evenths, xcb_generic_event_t *event) +{ + xcb_event_handler_t *eventh = 0; + assert(event->response_type != 1); + + if(event->response_type == 0) + eventh = get_error_handler(evenths, ((xcb_generic_error_t *) event)->error_code); + else + eventh = get_event_handler(evenths, event->response_type); + + if(eventh->handler) + return eventh->handler(eventh->data, evenths->c, event); + return 0; +} + +void +xcb_event_wait_for_event_loop(xcb_event_handlers_t *evenths) +{ + xcb_generic_event_t *event; + while((event = xcb_wait_for_event(evenths->c))) + { + xcb_event_handle(evenths, event); + free(event); + } +} + +void +xcb_event_poll_for_event_loop(xcb_event_handlers_t *evenths) +{ + xcb_generic_event_t *event; + while ((event = xcb_poll_for_event(evenths->c))) + { + xcb_event_handle(evenths, event); + free(event); + } +} + +static void +set_handler(xcb_generic_event_handler_t handler, void *data, xcb_event_handler_t *place) +{ + xcb_event_handler_t eventh = { handler, data }; + *place = eventh; +} + +void +xcb_event_set_handler(xcb_event_handlers_t *evenths, int event, xcb_generic_event_handler_t handler, void *data) +{ + set_handler(handler, data, get_event_handler(evenths, event)); +} + +void +xcb_event_set_error_handler(xcb_event_handlers_t *evenths, int error, xcb_generic_error_handler_t handler, void *data) +{ + set_handler((xcb_generic_event_handler_t) handler, data, get_error_handler(evenths, error)); +} diff --git a/event/events.c b/event/events.c deleted file mode 100644 index 4f5ea89..0000000 --- a/event/events.c +++ /dev/null @@ -1,99 +0,0 @@ -#include <assert.h> -#include <stdlib.h> - -#include "xcb_event.h" - -typedef struct xcb_event_handler_t xcb_event_handler_t; -struct xcb_event_handler_t { - xcb_generic_event_handler_t handler; - void *data; -}; - -struct xcb_event_handlers_t { - xcb_event_handler_t event[126]; - xcb_event_handler_t error[256]; - xcb_connection_t *c; -}; - -xcb_event_handlers_t *xcb_alloc_event_handlers(xcb_connection_t *c) -{ - xcb_event_handlers_t *ret = calloc(1, sizeof(xcb_event_handlers_t)); - if(ret) - ret->c = c; - return ret; -} - -void xcb_free_event_handlers(xcb_event_handlers_t *evenths) -{ - free(evenths); -} - -xcb_connection_t *xcb_get_xcb_connection(xcb_event_handlers_t *evenths) -{ - return evenths->c; -} - -static xcb_event_handler_t *get_event_handler(xcb_event_handlers_t *evenths, int event) -{ - assert(event < 256); - event &= 0x7f; - assert(event >= 2); - return &evenths->event[event - 2]; -} - -static xcb_event_handler_t *get_error_handler(xcb_event_handlers_t *evenths, int error) -{ - assert(error >= 0 && error < 256); - return &evenths->error[error]; -} - -int xcb_handle_event(xcb_event_handlers_t *evenths, xcb_generic_event_t *event) -{ - xcb_event_handler_t *eventh = 0; - assert(event->response_type != 1); - - if(event->response_type == 0) - eventh = get_error_handler(evenths, ((xcb_generic_error_t *) event)->error_code); - else - eventh = get_event_handler(evenths, event->response_type); - - if(eventh->handler) - return eventh->handler(eventh->data, evenths->c, event); - return 0; -} - -void xcb_wait_for_event_loop(xcb_event_handlers_t *evenths) -{ - xcb_generic_event_t *event; - while((event = xcb_wait_for_event(evenths->c))) - { - xcb_handle_event(evenths, event); - free(event); - } -} - -void xcb_poll_for_event_loop(xcb_event_handlers_t *evenths) -{ - xcb_generic_event_t *event; - while ((event = xcb_poll_for_event(evenths->c))) - { - xcb_handle_event(evenths, event); - free(event); - } -} - -static void set_handler(xcb_generic_event_handler_t handler, void *data, xcb_event_handler_t *place) -{ - xcb_event_handler_t eventh = { handler, data }; - *place = eventh; -} - -void xcb_set_event_handler(xcb_event_handlers_t *evenths, int event, xcb_generic_event_handler_t handler, void *data) -{ - set_handler(handler, data, get_event_handler(evenths, event)); -} - -void xcb_set_error_handler(xcb_event_handlers_t *evenths, int error, xcb_generic_error_handler_t handler, void *data) -{ - set_handler((xcb_generic_event_handler_t) handler, data, get_error_handler(evenths, error)); -} diff --git a/event/xcb_event.h b/event/xcb_event.h index e35ceb1..19dd492 100644 --- a/event/xcb_event.h +++ b/event/xcb_event.h @@ -1,73 +1,154 @@ -#ifndef __XCB_EVENTS_H__ -#define __XCB_EVENTS_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/xcb.h> +#ifndef __XCB_EVENT_H__ +#define __XCB_EVENT_H__ +#include <xcb/xcb.h> #ifdef __cplusplus extern "C" { #endif +typedef int (*xcb_generic_event_handler_t)(void *data, xcb_connection_t *c, xcb_generic_event_t *event); +typedef int (*xcb_generic_error_handler_t)(void *data, xcb_connection_t *c, xcb_generic_error_t *error); -typedef struct xcb_event_handlers_t xcb_event_handlers_t; -xcb_event_handlers_t *xcb_alloc_event_handlers(xcb_connection_t *c); -void xcb_free_event_handlers(xcb_event_handlers_t *evenths); -xcb_connection_t *xcb_get_xcb_connection(xcb_event_handlers_t *evenths); +typedef struct xcb_event_handler xcb_event_handler_t; +struct xcb_event_handler +{ + xcb_generic_event_handler_t handler; + void *data; +}; -void xcb_wait_for_event_loop(xcb_event_handlers_t *evenths); -void xcb_poll_for_event_loop(xcb_event_handlers_t *evenths); -int xcb_handle_event(xcb_event_handlers_t *evenths, xcb_generic_event_t *event); +typedef struct xcb_event_handlers xcb_event_handlers_t; +struct xcb_event_handlers +{ + xcb_event_handler_t event[126]; + xcb_event_handler_t error[256]; + xcb_connection_t *c; +}; -typedef int (*xcb_generic_event_handler_t)(void *data, xcb_connection_t *c, xcb_generic_event_t *event); -typedef int (*xcb_generic_error_handler_t)(void *data, xcb_connection_t *c, xcb_generic_error_t *error); +/** + * @brief Initialize event handlers data structure. + * @param c The connection to the X server. + * @param evenths A pointer to the event handler data structure to initialize. + */ +void xcb_event_handlers_init(xcb_connection_t *c, xcb_event_handlers_t *evenths); + +/** + * @brief Get X connection used in event handlers. + * @param evenths The event handlers. + * @return The connection to the X server. + */ +xcb_connection_t *xcb_event_get_xcb_connection(xcb_event_handlers_t *evenths); -void xcb_set_event_handler(xcb_event_handlers_t *evenths, int event, xcb_generic_event_handler_t handler, void *data); -void xcb_set_error_handler(xcb_event_handlers_t *evenths, int error, xcb_generic_error_handler_t handler, void *data); +/** + * @brief Wait for event and handle it with event handler. + * @param evenths The event handlers. + */ +void xcb_event_wait_for_event_loop(xcb_event_handlers_t *evenths); -#define MAKE_HANDLER(cls,lkind, ukind) \ -static inline void set_##lkind##_##cls##_handler(xcb_event_handlers_t *evenths, int (*handler)(void *, xcb_connection_t *, xcb_##lkind##_##cls##_t *), void *data) \ +/** + * @brief Poll for event and handle it with event handler. + * @param evenths The event handlers. + */ +void xcb_event_poll_for_event_loop(xcb_event_handlers_t *evenths); + +/** + * @brief Handle an event using event handlers from event handlers data + * structure. + * @param evenths The event handlers. + * @param event The event to handle. + * @return The return value of the handler, or 0 if no handler exists for this + * event. + */ +int xcb_event_handle(xcb_event_handlers_t *evenths, xcb_generic_event_t *event); + +/** + * @brief Set an event handler for an event type. + * @param evenths The event handlers data structure. + * @param event The event type. + * @param handler The callback function to call for this event type. + * @param data Optional data pointer to pass to handler callback function. + */ +void xcb_event_set_handler(xcb_event_handlers_t *evenths, int event, xcb_generic_event_handler_t handler, void *data); + +/** + * @brief Set an error handler for an error type. + * @param evenths The error handlers data structure. + * @param error The error type. + * @param handler The callback function to call for this error type. + * @param data Optional data pointer to pass to handler callback function. + */ +void xcb_event_set_error_handler(xcb_event_handlers_t *evenths, int error, xcb_generic_error_handler_t handler, void *data); + +#define XCB_EVENT_MAKE_EVENT_HANDLER(lkind, ukind) \ +static inline void xcb_event_set_##lkind##_handler(xcb_event_handlers_t *evenths, int (*handler)(void *, xcb_connection_t *, xcb_##lkind##_event_t *), void *data) \ { \ - xcb_set_##cls##_handler(evenths, XCB_##ukind, (xcb_generic_event_handler_t) handler, data); \ + xcb_event_set_handler(evenths, XCB_##ukind, (xcb_generic_event_handler_t) handler, data); \ } -MAKE_HANDLER(event, key_press, KEY_PRESS) -MAKE_HANDLER(event, key_release, KEY_RELEASE) -MAKE_HANDLER(event, button_press, BUTTON_PRESS) -MAKE_HANDLER(event, button_release, BUTTON_RELEASE) -MAKE_HANDLER(event, motion_notify, MOTION_NOTIFY) -MAKE_HANDLER(event, enter_notify, ENTER_NOTIFY) -MAKE_HANDLER(event, leave_notify, LEAVE_NOTIFY) -MAKE_HANDLER(event, focus_in, FOCUS_IN) -MAKE_HANDLER(event, focus_out, FOCUS_OUT) -MAKE_HANDLER(event, keymap_notify, KEYMAP_NOTIFY) -MAKE_HANDLER(event, expose, EXPOSE) -MAKE_HANDLER(event, graphics_exposure, GRAPHICS_EXPOSURE) -MAKE_HANDLER(event, no_exposure, NO_EXPOSURE) -MAKE_HANDLER(event, visibility_notify, VISIBILITY_NOTIFY) -MAKE_HANDLER(event, create_notify, CREATE_NOTIFY) -MAKE_HANDLER(event, destroy_notify, DESTROY_NOTIFY) -MAKE_HANDLER(event, unmap_notify, UNMAP_NOTIFY) -MAKE_HANDLER(event, map_notify, MAP_NOTIFY) -MAKE_HANDLER(event, map_request, MAP_REQUEST) -MAKE_HANDLER(event, reparent_notify, REPARENT_NOTIFY) -MAKE_HANDLER(event, configure_notify, CONFIGURE_NOTIFY) -MAKE_HANDLER(event, configure_request, CONFIGURE_REQUEST) -MAKE_HANDLER(event, gravity_notify, GRAVITY_NOTIFY) -MAKE_HANDLER(event, resize_request, RESIZE_REQUEST) -MAKE_HANDLER(event, circulate_notify, CIRCULATE_NOTIFY) -MAKE_HANDLER(event, circulate_request, CIRCULATE_REQUEST) -MAKE_HANDLER(event, property_notify, PROPERTY_NOTIFY) -MAKE_HANDLER(event, selection_clear, SELECTION_CLEAR) -MAKE_HANDLER(event, selection_request, SELECTION_REQUEST) -MAKE_HANDLER(event, selection_notify, SELECTION_NOTIFY) -MAKE_HANDLER(event, colormap_notify, COLORMAP_NOTIFY) -MAKE_HANDLER(event, client_message, CLIENT_MESSAGE) -MAKE_HANDLER(event, mapping_notify, MAPPING_NOTIFY) - +XCB_EVENT_MAKE_EVENT_HANDLER(key_press, KEY_PRESS) +XCB_EVENT_MAKE_EVENT_HANDLER(key_release, KEY_RELEASE) +XCB_EVENT_MAKE_EVENT_HANDLER(button_press, BUTTON_PRESS) +XCB_EVENT_MAKE_EVENT_HANDLER(button_release, BUTTON_RELEASE) +XCB_EVENT_MAKE_EVENT_HANDLER(motion_notify, MOTION_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(enter_notify, ENTER_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(leave_notify, LEAVE_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(focus_in, FOCUS_IN) +XCB_EVENT_MAKE_EVENT_HANDLER(focus_out, FOCUS_OUT) +XCB_EVENT_MAKE_EVENT_HANDLER(keymap_notify, KEYMAP_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(expose, EXPOSE) +XCB_EVENT_MAKE_EVENT_HANDLER(graphics_exposure, GRAPHICS_EXPOSURE) +XCB_EVENT_MAKE_EVENT_HANDLER(no_exposure, NO_EXPOSURE) +XCB_EVENT_MAKE_EVENT_HANDLER(visibility_notify, VISIBILITY_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(create_notify, CREATE_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(destroy_notify, DESTROY_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(unmap_notify, UNMAP_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(map_notify, MAP_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(map_request, MAP_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(reparent_notify, REPARENT_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(configure_notify, CONFIGURE_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(configure_request, CONFIGURE_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(gravity_notify, GRAVITY_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(resize_request, RESIZE_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(circulate_notify, CIRCULATE_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(circulate_request, CIRCULATE_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(property_notify, PROPERTY_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(selection_clear, SELECTION_CLEAR) +XCB_EVENT_MAKE_EVENT_HANDLER(selection_request, SELECTION_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(selection_notify, SELECTION_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(colormap_notify, COLORMAP_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(client_message, CLIENT_MESSAGE) +XCB_EVENT_MAKE_EVENT_HANDLER(mapping_notify, MAPPING_NOTIFY) #ifdef __cplusplus } #endif - -#endif /* __XCB_EVENTS_H__ */ +#endif /* __XCB_EVENT_H__ */ diff --git a/property/property.c b/property/property.c index defac17..498c612 100644 --- a/property/property.c +++ b/property/property.c @@ -68,7 +68,7 @@ call_handler(xcb_connection_t *c, uint8_t state, xcb_window_t window, xcb_atom_t 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_connection_t *c = xcb_event_get_xcb_connection(xcb_property_get_event_handlers(prophs)); xcb_property_handler_node_t *cur; for(cur = prophs->head; cur; cur = cur->next) @@ -97,7 +97,7 @@ xcb_property_handlers_init(xcb_property_handlers_t *prophs, xcb_event_handlers_t { memset(prophs, 0, sizeof(prophs)); prophs->evenths = evenths; - set_property_notify_event_handler(evenths, handle_property_notify_event, prophs); + xcb_event_set_property_notify_handler(evenths, handle_property_notify_event, prophs); } void diff --git a/wm/xcbwm-test.c b/wm/xcbwm-test.c index 10c2e1b..67ca26f 100644 --- a/wm/xcbwm-test.c +++ b/wm/xcbwm-test.c @@ -176,7 +176,7 @@ static int handleWMNameChange(void *data, xcb_connection_t *c, uint8_t state, xc int main(int argc, char **argv) { xcb_connection_t *c; - xcb_event_handlers_t *evenths; + xcb_event_handlers_t evenths; xcb_property_handlers_t prophs; xcb_window_t root; pthread_t event_thread; @@ -188,24 +188,24 @@ int main(int argc, char **argv) c = xcb_connect(NULL, &screen_nbr); - evenths = xcb_alloc_event_handlers(c); + xcb_event_handlers_init(c, &evenths); for(i = 2; i < 128; ++i) - xcb_set_event_handler(evenths, i, handleEvent, 0); + xcb_event_set_handler(&evenths, i, handleEvent, 0); for(i = 0; i < 256; ++i) - xcb_set_error_handler(evenths, i, (xcb_generic_error_handler_t) handleEvent, 0); - set_button_press_event_handler(evenths, handleButtonPressEvent, 0); - set_button_release_event_handler(evenths, handleButtonReleaseEvent, 0); - set_unmap_notify_event_handler(evenths, handle_unmap_notify_event, 0); - set_expose_event_handler(evenths, handleExposeEvent, 0); - - xcb_property_handlers_init(&prophs, evenths); - set_map_notify_event_handler(evenths, handle_map_notify_event, &prophs); + xcb_event_set_error_handler(&evenths, i, (xcb_generic_error_handler_t) handleEvent, 0); + xcb_event_set_button_press_handler(&evenths, handleButtonPressEvent, 0); + xcb_event_set_button_release_handler(&evenths, handleButtonReleaseEvent, 0); + xcb_event_set_unmap_notify_handler(&evenths, handle_unmap_notify_event, 0); + xcb_event_set_expose_handler(&evenths, handleExposeEvent, 0); + + xcb_property_handlers_init(&prophs, &evenths); + xcb_event_set_map_notify_handler(&evenths, handle_map_notify_event, &prophs); xcb_watch_wm_name(&prophs, 40, handleWMNameChange, 0); if(TEST_THREADS) { - pthread_create(&event_thread, 0, (void *(*)(void *))xcb_wait_for_event_loop, evenths); + pthread_create(&event_thread, 0, (void *(*)(void *))xcb_event_wait_for_event_loop, &evenths); } root = xcb_aux_get_screen(c, screen_nbr)->root; @@ -223,7 +223,7 @@ int main(int argc, char **argv) if(TEST_THREADS) pthread_join(event_thread, 0); else - xcb_wait_for_event_loop(evenths); + xcb_event_wait_for_event_loop(&evenths); exit(0); /*NOTREACHED*/ |