swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit 28f049f8c0e24edffdd6d08750e900f3111d8feb
parent 210f52401f19affa3ea9562cf047cffcbdb5427f
Author: Michael Forney <mforney@mforney.org>
Date:   Wed, 13 Aug 2014 22:16:21 -0700

Replace window and screen event signals with handler structures

Diffstat:
Mexample/wm.c | 97++++++++++++++++++++++++++++++++++---------------------------------------------
Mlibswc/compositor.c | 27++++++++++++---------------
Mlibswc/cursor_plane.c | 1+
Mlibswc/event.h | 23+++++++++++++++++++++++
Mlibswc/framebuffer_plane.c | 1+
Mlibswc/panel.c | 1+
Mlibswc/screen.c | 24++++++++++++++++++++----
Mlibswc/screen.h | 3+++
Mlibswc/swc.h | 102+++++++++++++++++++++++++++++++------------------------------------------------
Mlibswc/window.c | 34++++++++++++++++++++++++++++------
Mlibswc/window.h | 2++
11 files changed, 173 insertions(+), 142 deletions(-)

diff --git a/example/wm.c b/example/wm.c @@ -30,7 +30,6 @@ struct screen { struct swc_screen * swc; - struct wl_listener event_listener; struct wl_list windows; unsigned num_windows; }; @@ -38,7 +37,6 @@ struct screen struct window { struct swc_window * swc; - struct wl_listener event_listener; struct screen * screen; struct wl_list link; }; @@ -129,61 +127,57 @@ static void focus(struct window * window) focused_window = window; } -static void window_event(struct wl_listener * listener, void * data) +static void screen_usable_geometry_changed(void * data) { - struct swc_event * event = data; - struct window * window = NULL, * next_focus; + struct screen * screen = data; - window = wl_container_of(listener, window, event_listener); + /* If the usable geometry of the screen changes, for example when a panel is + * docked to the edge of the screen, we need to rearrange the windows to + * ensure they are all within the new usable geometry. */ + arrange(screen); +} + +static const struct swc_screen_handler screen_handler = { + .usable_geometry_changed = &screen_usable_geometry_changed, +}; + +static void window_destroy(void * data) +{ + struct window * window = data, * next_focus; - switch (event->type) + if (focused_window == window) { - case SWC_WINDOW_DESTROYED: - if (focused_window == window) - { - /* Try to find a new focus nearby the old one. */ - next_focus = wl_container_of(window->link.next, window, link); - - if (&next_focus->link == &window->screen->windows) - { - next_focus = wl_container_of(window->link.prev, - window, link); - - if (&next_focus->link == &window->screen->windows) - next_focus = NULL; - } - - focus(next_focus); - } - - screen_remove_window(window->screen, window); - free(window); - break; - case SWC_WINDOW_ENTERED: - focus(window); - break; + /* Try to find a new focus nearby the old one. */ + next_focus = wl_container_of(window->link.next, window, link); + + if (&next_focus->link == &window->screen->windows) + { + next_focus = wl_container_of(window->link.prev, + window, link); + + if (&next_focus->link == &window->screen->windows) + next_focus = NULL; + } + + focus(next_focus); } + + screen_remove_window(window->screen, window); + free(window); } -static void screen_event(struct wl_listener * listener, void * data) +static void window_entered(void * data) { - struct swc_event * event = data; - struct screen * screen = NULL; - - screen = wl_container_of(listener, screen, event_listener); + struct window * window = data; - switch (event->type) - { - case SWC_SCREEN_USABLE_GEOMETRY_CHANGED: - /* If the usable geometry of the screen changes, for example when a - * panel is docked to the edge of the screen, we need to rearrange - * the windows to ensure they are all within the new usable - * geometry. */ - arrange(screen); - break; - } + focus(window); } +static const struct swc_window_handler window_handler = { + .destroy = &window_destroy, + .entered = &window_entered, +}; + static void new_screen(struct swc_screen * swc) { struct screen * screen; @@ -194,12 +188,9 @@ static void new_screen(struct swc_screen * swc) return; screen->swc = swc; - screen->event_listener.notify = &screen_event; screen->num_windows = 0; wl_list_init(&screen->windows); - - /* Register a listener for the screen's event signal. */ - wl_signal_add(&swc->event_signal, &screen->event_listener); + swc_screen_set_handler(swc, &screen_handler, screen); active_screen = screen; } @@ -213,12 +204,8 @@ static void new_window(struct swc_window * swc) return; window->swc = swc; - window->event_listener.notify = &window_event; window->screen = NULL; - - /* Register a listener for the window's event signal. */ - wl_signal_add(&swc->event_signal, &window->event_listener); - + swc_window_set_handler(swc, &window_handler, window); screen_add_window(active_screen, window); focus(window); } diff --git a/libswc/compositor.c b/libswc/compositor.c @@ -31,6 +31,7 @@ #include "compositor.h" #include "data_device_manager.h" #include "drm.h" +#include "event.h" #include "internal.h" #include "launch.h" #include "output.h" @@ -59,7 +60,7 @@ struct target struct wl_listener view_listener; uint32_t mask; - struct wl_listener screen_listener; + struct wl_listener screen_destroy_listener; }; static bool handle_motion(struct pointer_handler * handler, uint32_t time, @@ -92,27 +93,23 @@ struct swc_compositor swc_compositor = { .pointer_handler = &pointer_handler }; -static void handle_screen_event(struct wl_listener * listener, void * data) +static void handle_screen_destroy(struct wl_listener * listener, void * data) { - struct swc_event * event = data; - - if (event->type == SWC_SCREEN_DESTROYED) - { - struct target * target - = wl_container_of(listener, target, screen_listener); + struct target * target + = wl_container_of(listener, target, screen_destroy_listener); - wld_destroy_surface(target->surface); - free(target); - } + wld_destroy_surface(target->surface); + free(target); } static struct target * target_get(struct screen * screen) { struct wl_listener * listener - = wl_signal_get(&screen->base.event_signal, &handle_screen_event); + = wl_signal_get(&screen->destroy_signal, &handle_screen_destroy); struct target * target; - return listener ? wl_container_of(listener, target, screen_listener) : NULL; + return listener ? wl_container_of(listener, target, screen_destroy_listener) + : NULL; } static void handle_screen_view_event(struct wl_listener * listener, void * data) @@ -178,8 +175,8 @@ static struct target * target_new(struct screen * screen) target->mask = screen_mask(screen); target_swap_buffers(target); - target->screen_listener.notify = &handle_screen_event; - wl_signal_add(&screen->base.event_signal, &target->screen_listener); + target->screen_destroy_listener.notify = &handle_screen_destroy; + wl_signal_add(&screen->destroy_signal, &target->screen_destroy_listener); return target; diff --git a/libswc/cursor_plane.c b/libswc/cursor_plane.c @@ -23,6 +23,7 @@ #include "cursor_plane.h" #include "drm.h" +#include "event.h" #include "internal.h" #include "launch.h" #include "screen.h" diff --git a/libswc/event.h b/libswc/event.h @@ -6,6 +6,29 @@ #include <stdint.h> #include <wayland-server.h> +/** + * An event is the data passed to the listeners of the event_signals of various + * objects. + */ +struct swc_event +{ + /** + * The type of event that was sent. + * + * The meaning of this field depends on the type of object containing the + * event_signal that passed this event. + */ + uint32_t type; + + /** + * Data specific to the event type. + * + * Unless explicitly stated in the description of the event type, this + * value is undefined. + */ + void * data; +}; + static inline void swc_send_event(struct wl_signal * signal, uint32_t type, void * event_data) { diff --git a/libswc/framebuffer_plane.c b/libswc/framebuffer_plane.c @@ -23,6 +23,7 @@ #include "framebuffer_plane.h" #include "drm.h" +#include "event.h" #include "internal.h" #include "launch.h" #include "util.h" diff --git a/libswc/panel.c b/libswc/panel.c @@ -23,6 +23,7 @@ #include "panel.h" #include "compositor.h" +#include "event.h" #include "internal.h" #include "keyboard.h" #include "output.h" diff --git a/libswc/screen.c b/libswc/screen.c @@ -35,6 +35,19 @@ #define INTERNAL(s) ((struct screen *) (s)) +static const struct swc_screen_handler null_handler; + +EXPORT +void swc_screen_set_handler(struct swc_screen * base, + const struct swc_screen_handler * handler, + void * data) +{ + struct screen * screen = INTERNAL(base); + + screen->handler = handler; + screen->handler_data = data; +} + bool screens_initialize() { wl_list_init(&swc.screens); @@ -114,7 +127,8 @@ struct screen * screen_new(uint32_t crtc, struct swc_output * output) goto error3; } - wl_signal_init(&screen->base.event_signal); + screen->handler = &null_handler; + wl_signal_init(&screen->destroy_signal); wl_list_init(&screen->resources); wl_list_init(&screen->outputs); wl_list_insert(&screen->outputs, &output->link); @@ -142,7 +156,9 @@ void screen_destroy(struct screen * screen) { struct swc_output * output, * next; - swc_send_event(&screen->base.event_signal, SWC_SCREEN_DESTROYED, NULL); + if (screen->handler->destroy) + screen->handler->destroy(screen->handler_data); + wl_signal_emit(&screen->destroy_signal, NULL); wl_list_for_each_safe(output, next, &screen->outputs, link) swc_output_destroy(output); framebuffer_plane_finalize(&screen->planes.framebuffer); @@ -182,8 +198,8 @@ void screen_update_usable_geometry(struct screen * screen) screen->base.usable_geometry.width = extents->x2 - extents->x1; screen->base.usable_geometry.height = extents->y2 - extents->y1; - swc_send_event(&screen->base.event_signal, - SWC_SCREEN_USABLE_GEOMETRY_CHANGED, NULL); + if (screen->handler->usable_geometry_changed) + screen->handler->usable_geometry_changed(screen->handler_data); } } diff --git a/libswc/screen.h b/libswc/screen.h @@ -49,7 +49,10 @@ struct screen_modifier struct screen { struct swc_screen base; + const struct swc_screen_handler * handler; + void * handler_data; + struct wl_signal destroy_signal; uint8_t id; struct diff --git a/libswc/swc.h b/libswc/swc.h @@ -40,34 +40,32 @@ struct swc_rectangle /* Screens {{{ */ -enum +struct swc_screen_handler { /** - * Sent when the screen is about to be destroyed. + * Called when the screen is about to be destroyed. * - * After this event is sent, the screen is not longer valid. + * After this is called, the screen is no longer valid. */ - SWC_SCREEN_DESTROYED, + void (* destroy)(void * data); /** - * Sent when the total area of the screen is changed. + * Called when the total area of the screen has changed. */ - SWC_SCREEN_GEOMETRY_CHANGED, + void (* geometry_changed)(void * data); /** - * Sent when the geometry of the screen available for laying out windows is - * changed. + * Called when the geometry of the screen available for laying out windows + * has changed. * - * Display servers should respond to this event by making sure all visible - * windows are within this area. + * A window manager should respond by making sure all visible windows are + * within this area. */ - SWC_SCREEN_USABLE_GEOMETRY_CHANGED + void (* usable_geometry_changed)(void * data); }; struct swc_screen { - struct wl_signal event_signal; - /** * The total area of the screen. */ @@ -79,52 +77,52 @@ struct swc_screen struct swc_rectangle usable_geometry; }; +/** + * Set the handler associated with this screen. + */ +void swc_screen_set_handler(struct swc_screen * screen, + const struct swc_screen_handler * handler, + void * data); + /* }}} */ /* Windows {{{ */ -enum +struct swc_window_handler { /** - * Sent when the window is about to be destroyed. + * Called when the window is about to be destroyed. * - * After this event is sent, the window is not longer valid. + * After this is called, the window is no longer valid. */ - SWC_WINDOW_DESTROYED, + void (* destroy)(void * data); /** - * Sent when the window's title changes. + * Called when the window's title changes. */ - SWC_WINDOW_TITLE_CHANGED, + void (* title_changed)(void * data); /** - * Sent when the window's class changes. + * Called when the window's class changes. */ - SWC_WINDOW_CLASS_CHANGED, + void (* class_changed)(void * data); /** - * Sent when the pointer enters the window. - */ - SWC_WINDOW_ENTERED, - - /** - * Sent when the window's size has changed. + * Called when the window's parent changes. + * + * This can occur when the window becomes a transient for another window, or + * becomes a toplevel window. */ - SWC_WINDOW_RESIZED, + void (* parent_changed)(void * data); /** - * Sent when the window's parent changes. - * - * This can occur when the window becomes a transient for another window, - * or becomes a toplevel window. + * Called when the pointer enters the window. */ - SWC_WINDOW_PARENT_CHANGED + void (* entered)(void * data); }; struct swc_window { - struct wl_signal event_signal; - char * title; char * class; @@ -132,6 +130,13 @@ struct swc_window }; /** + * Set the handler associated with this window. + */ +void swc_window_set_handler(struct swc_window * window, + const struct swc_window_handler * handler, + void * data); + +/** * Request that the specified window close. */ void swc_window_close(struct swc_window * window); @@ -250,33 +255,6 @@ int swc_add_binding(enum swc_binding_type type, /* }}} */ -/* Events {{{ */ - -/** - * An event is the data passed to the listeners of the event_signals of various - * objects. - */ -struct swc_event -{ - /** - * The type of event that was sent. - * - * The meaning of this field depends on the type of object containing the - * event_signal that passed this event. - */ - uint32_t type; - - /** - * Data specific to the event type. - * - * Unless explicitly stated in the description of the event type, this - * value is undefined. - */ - void * data; -}; - -/* }}} */ - /** * This is a user-provided structure that swc will use to notify the display * server of new windows and screens. diff --git a/libswc/window.c b/libswc/window.c @@ -36,6 +36,8 @@ #define INTERNAL(w) ((struct window *) (w)) +static const struct swc_window_handler null_handler; + static void handle_window_enter(struct wl_listener * listener, void * data) { struct swc_event * event = data; @@ -48,7 +50,8 @@ static void handle_window_enter(struct wl_listener * listener, void * data) if (!event_data->new || !(window = event_data->new->window)) return; - swc_send_event(&window->base.event_signal, SWC_WINDOW_ENTERED, NULL); + if (window->handler->entered) + window->handler->entered(window->handler_data); } struct wl_listener window_enter_listener = { @@ -56,6 +59,17 @@ struct wl_listener window_enter_listener = { }; EXPORT +void swc_window_set_handler(struct swc_window * base, + const struct swc_window_handler * handler, + void * data) +{ + struct window * window = INTERNAL(base); + + window->handler = handler; + window->handler_data = data; +} + +EXPORT void swc_window_close(struct swc_window * base) { struct window * window = INTERNAL(base); @@ -256,12 +270,12 @@ bool window_initialize(struct window * window, const struct window_impl * impl, window->base.title = NULL; window->base.class = NULL; window->base.parent = NULL; - wl_signal_init(&window->base.event_signal); if (!(window->view = swc_compositor_create_view(surface))) return false; window->impl = impl; + window->handler = &null_handler; window->view->window = window; window->managed = false; window->move.interaction.handler = (struct pointer_handler) { @@ -301,7 +315,9 @@ void window_unmanage(struct window * window) if (!window->managed) return; - swc_send_event(&window->base.event_signal, SWC_WINDOW_DESTROYED, NULL); + if (window->handler->destroy) + window->handler->destroy(window->handler_data); + window->handler = &null_handler; window->managed = false; } @@ -309,14 +325,18 @@ void window_set_title(struct window * window, const char * title, size_t length) { free(window->base.title); window->base.title = strndup(title, length); - swc_send_event(&window->base.event_signal, SWC_WINDOW_TITLE_CHANGED, NULL); + + if (window->handler->title_changed) + window->handler->title_changed(window->handler_data); } void window_set_class(struct window * window, const char * class) { free(window->base.class); window->base.class = strdup(class); - swc_send_event(&window->base.event_signal, SWC_WINDOW_CLASS_CHANGED, NULL); + + if (window->handler->class_changed) + window->handler->class_changed(window->handler_data); } void window_set_parent(struct window * window, struct window * parent) @@ -326,6 +346,8 @@ void window_set_parent(struct window * window, struct window * parent) compositor_view_set_parent(window->view, parent->view); window->base.parent = &parent->base; - swc_send_event(&window->base.event_signal, SWC_WINDOW_PARENT_CHANGED, NULL); + + if (window->handler->parent_changed) + window->handler->parent_changed(window->handler_data); } diff --git a/libswc/window.h b/libswc/window.h @@ -39,6 +39,8 @@ struct window { struct swc_window base; const struct window_impl * impl; + const struct swc_window_handler * handler; + void * handler_data; struct compositor_view * view; bool managed;