swc

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

commit 5b1678fb06b19d8465846d93e07db74f813335ad
parent 28f049f8c0e24edffdd6d08750e900f3111d8feb
Author: Michael Forney <mforney@mforney.org>
Date:   Sat, 16 Aug 2014 12:40:25 -0700

view: Use a view_handler structure instead of swc_event

Diffstat:
Mlibswc/compositor.c | 52+++++++++++++++++++++++-----------------------------
Mlibswc/panel.c | 34+++++++++++++++-------------------
Mlibswc/surface.c | 120++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mlibswc/surface.h | 4+++-
Mlibswc/view.c | 36+++++++++++++++++++++---------------
Mlibswc/view.h | 59++++++++++++++++++++---------------------------------------
6 files changed, 140 insertions(+), 165 deletions(-)

diff --git a/libswc/compositor.c b/libswc/compositor.c @@ -57,7 +57,7 @@ struct target struct wld_surface * surface; struct wld_buffer * next_buffer, * current_buffer; struct view * view; - struct wl_listener view_listener; + struct view_handler view_handler; uint32_t mask; struct wl_listener screen_destroy_listener; @@ -112,40 +112,34 @@ static struct target * target_get(struct screen * screen) : NULL; } -static void handle_screen_view_event(struct wl_listener * listener, void * data) +static void handle_screen_frame(struct view_handler * handler, uint32_t time) { - struct swc_event * event = data; - struct view_event_data * event_data = event->data; - struct target * target = wl_container_of(listener, target, view_listener); - - switch (event->type) - { - case VIEW_EVENT_FRAME: - { - struct compositor_view * view; + struct target * target = wl_container_of(handler, target, view_handler); + struct compositor_view * view; - compositor.pending_flips &= ~target->mask; + compositor.pending_flips &= ~target->mask; - wl_list_for_each(view, &compositor.views, link) - { - if (view->base.screens & target->mask) - view_frame(&view->base, event_data->frame.time); - } + wl_list_for_each(view, &compositor.views, link) + { + if (view->base.screens & target->mask) + view_frame(&view->base, time); + } - if (target->current_buffer) - wld_surface_release(target->surface, target->current_buffer); + if (target->current_buffer) + wld_surface_release(target->surface, target->current_buffer); - target->current_buffer = target->next_buffer; + target->current_buffer = target->next_buffer; - /* If we had scheduled updates that couldn't run because we were - * waiting on a page flip, run them now. */ - if (compositor.scheduled_updates && !compositor.updating) - perform_update(NULL); - break; - } - } + /* If we had scheduled updates that couldn't run because we were + * waiting on a page flip, run them now. */ + if (compositor.scheduled_updates && !compositor.updating) + perform_update(NULL); } +static const struct view_handler_impl screen_view_handler = { + .frame = &handle_screen_frame, +}; + static int target_swap_buffers(struct target * target) { target->next_buffer = wld_surface_take(target->surface); @@ -169,8 +163,8 @@ static struct target * target_new(struct screen * screen) goto error1; target->view = &screen->planes.framebuffer.view; - target->view_listener.notify = &handle_screen_view_event; - wl_signal_add(&target->view->event_signal, &target->view_listener); + target->view_handler.impl = &screen_view_handler; + wl_list_insert(&target->view->handlers, &target->view_handler.link); target->current_buffer = NULL; target->mask = screen_mask(screen); target_swap_buffers(target); diff --git a/libswc/panel.c b/libswc/panel.c @@ -23,7 +23,6 @@ #include "panel.h" #include "compositor.h" -#include "event.h" #include "internal.h" #include "keyboard.h" #include "output.h" @@ -44,7 +43,7 @@ struct panel struct swc_surface * surface; struct wl_listener surface_destroy_listener; struct compositor_view * view; - struct wl_listener view_listener; + struct view_handler view_handler; struct screen * screen; struct screen_modifier modifier; uint32_t edge; @@ -107,7 +106,7 @@ static void dock(struct wl_client * client, struct wl_resource * resource, } if (panel->docked) - wl_list_remove(&panel->view_listener.link); + wl_list_remove(&panel->view_handler.link); if (panel->screen && screen_changed) { @@ -128,7 +127,7 @@ static void dock(struct wl_client * client, struct wl_resource * resource, update_position(panel); compositor_view_show(panel->view); - wl_signal_add(&panel->view->base.event_signal, &panel->view_listener); + wl_list_insert(&panel->view->base.handlers, &panel->view_handler.link); wl_list_insert(&screen->modifiers, &panel->modifier.link); if (focus) @@ -165,6 +164,17 @@ static const struct swc_panel_interface panel_implementation = { .set_strut = &set_strut }; +static void handle_resize(struct view_handler * handler) +{ + struct panel * panel = wl_container_of(handler, panel, view_handler); + + update_position(panel); +} + +static const struct view_handler_impl view_handler_impl = { + .resize = &handle_resize, +}; + static void modify(struct screen_modifier * modifier, const struct swc_rectangle * geometry, pixman_region32_t * usable) @@ -211,7 +221,6 @@ static void destroy_panel(struct wl_resource * resource) if (panel->docked) { - wl_list_remove(&panel->view_listener.link); wl_list_remove(&panel->modifier.link); screen_update_usable_geometry(panel->screen); compositor_view_destroy(panel->view); @@ -220,19 +229,6 @@ static void destroy_panel(struct wl_resource * resource) free(panel); } -static void handle_view_event(struct wl_listener * listener, void * data) -{ - struct panel * panel = wl_container_of(listener, panel, view_listener); - struct swc_event * event = data; - - switch (event->type) - { - case VIEW_EVENT_RESIZED: - update_position(panel); - break; - } -} - static void handle_surface_destroy(struct wl_listener * listener, void * data) { struct panel * panel @@ -261,7 +257,7 @@ struct panel * panel_new(struct wl_client * client, uint32_t id, panel->surface = surface; panel->surface_destroy_listener.notify = &handle_surface_destroy; - panel->view_listener.notify = &handle_view_event; + panel->view_handler.impl = &view_handler_impl; panel->modifier.modify = &modify; panel->screen = NULL; panel->offset = 0; diff --git a/libswc/surface.c b/libswc/surface.c @@ -107,6 +107,60 @@ static void state_set_buffer(struct swc_surface_state * state, state->buffer_resource = resource; } +static void handle_frame(struct view_handler * handler, uint32_t time) +{ + struct swc_surface * surface + = wl_container_of(handler, surface, view_handler); + struct wl_resource * resource, * tmp; + + wl_list_for_each_safe(resource, tmp, + &surface->state.frame_callbacks, link) + { + wl_callback_send_done(resource, time); + wl_resource_destroy(resource); + } + + wl_list_init(&surface->state.frame_callbacks); +} + +static void handle_screens(struct view_handler * handler, + uint32_t entered, uint32_t left) +{ + struct swc_surface * surface + = wl_container_of(handler, surface, view_handler); + struct screen * screen; + struct swc_output * output; + struct wl_client * client; + struct wl_resource * resource; + + client = wl_resource_get_client(surface->resource); + + wl_list_for_each(screen, &swc.screens, link) + { + if (!((entered | left) & screen_mask(screen))) + continue; + + wl_list_for_each(output, &screen->outputs, link) + { + resource = wl_resource_find_for_client + (&output->resources, client); + + if (resource) + { + if (entered & screen_mask(screen)) + wl_surface_send_enter(surface->resource, resource); + else if (left & screen_mask(screen)) + wl_surface_send_leave(surface->resource, resource); + } + } + } +} + +static const struct view_handler_impl view_handler_impl = { + .frame = &handle_frame, + .screens = &handle_screens, +}; + static void destroy(struct wl_client * client, struct wl_resource * resource) { wl_resource_destroy(resource); @@ -291,69 +345,11 @@ static void surface_destroy(struct wl_resource * resource) state_finalize(&surface->pending.state); if (surface->view) - wl_list_remove(&surface->view_listener.link); + wl_list_remove(&surface->view_handler.link); free(surface); } -static void handle_view_event(struct wl_listener * listener, void * data) -{ - struct swc_surface * surface - = wl_container_of(listener, surface, view_listener); - struct swc_event * event = data; - struct view_event_data * event_data = event->data; - - switch (event->type) - { - case VIEW_EVENT_FRAME: - { - struct wl_resource * resource, * tmp; - - wl_list_for_each_safe(resource, tmp, - &surface->state.frame_callbacks, link) - { - wl_callback_send_done(resource, event_data->frame.time); - wl_resource_destroy(resource); - } - - wl_list_init(&surface->state.frame_callbacks); - break; - } - case VIEW_EVENT_SCREENS_CHANGED: - { - struct screen * screen; - struct swc_output * output; - struct wl_client * client; - struct wl_resource * resource; - uint32_t entered = event_data->screens_changed.entered, - left = event_data->screens_changed.left; - - client = wl_resource_get_client(surface->resource); - - wl_list_for_each(screen, &swc.screens, link) - { - if (!((entered | left) & screen_mask(screen))) - continue; - - wl_list_for_each(output, &screen->outputs, link) - { - resource = wl_resource_find_for_client - (&output->resources, client); - - if (resource) - { - if (entered & screen_mask(screen)) - wl_surface_send_enter(surface->resource, resource); - else if (left & screen_mask(screen)) - wl_surface_send_leave(surface->resource, resource); - } - } - } - break; - } - } -} - /** * Construct a new surface, adding it to the given client as id. * @@ -374,7 +370,7 @@ struct swc_surface * swc_surface_new(struct wl_client * client, /* Initialize the surface. */ surface->pending.commit = 0; surface->view = NULL; - surface->view_listener.notify = &handle_view_event; + surface->view_handler.impl = &view_handler_impl; state_initialize(&surface->state); state_initialize(&surface->pending.state); @@ -394,13 +390,13 @@ void swc_surface_set_view(struct swc_surface * surface, struct view * view) return; if (surface->view) - wl_list_remove(&surface->view_listener.link); + wl_list_remove(&surface->view_handler.link); surface->view = view; if (view) { - wl_signal_add(&view->event_signal, &surface->view_listener); + wl_list_insert(&view->handlers, &surface->view_handler.link); view_attach(view, surface->state.buffer); view_update(view); } diff --git a/libswc/surface.h b/libswc/surface.h @@ -24,6 +24,8 @@ #ifndef SWC_SURFACE_H #define SWC_SURFACE_H +#include "view.h" + #include <stdbool.h> #include <wayland-server.h> #include <pixman.h> @@ -69,7 +71,7 @@ struct swc_surface } pending; struct view * view; - struct wl_listener view_listener; + struct view_handler view_handler; }; struct swc_surface * swc_surface_new(struct wl_client * client, diff --git a/libswc/view.c b/libswc/view.c @@ -29,6 +29,16 @@ #include <wld/wld.h> +#define HANDLE(view, handler, method, ...) \ + do \ + { \ + wl_list_for_each(handler, &view->handlers, link) \ + { \ + if (handler->impl->method) \ + handler->impl->method(handler, ## __VA_ARGS__); \ + } \ + } while (0) + void view_initialize(struct view * view, const struct view_impl * impl) { view->impl = impl; @@ -38,7 +48,7 @@ void view_initialize(struct view * view, const struct view_impl * impl) view->geometry.height = 0; view->buffer = NULL; view->screens = 0; - wl_signal_init(&view->event_signal); + wl_list_init(&view->handlers); } void view_finalize(struct view * view) @@ -77,28 +87,28 @@ bool view_move(struct view * view, int32_t x, int32_t y) bool view_set_position(struct view * view, int32_t x, int32_t y) { - struct view_event_data data = { .view = view }; + struct view_handler * handler; if (x == view->geometry.x && y == view->geometry.y) return false; view->geometry.x = x; view->geometry.y = y; - swc_send_event(&view->event_signal, VIEW_EVENT_MOVED, &data); + HANDLE(view, handler, move); return true; } bool view_set_size(struct view * view, uint32_t width, uint32_t height) { - struct view_event_data data = { .view = view }; + struct view_handler * handler; if (view->geometry.width == width && view->geometry.height == height) return false; view->geometry.width = width; view->geometry.height = height; - swc_send_event(&view->event_signal, VIEW_EVENT_RESIZED, &data); + HANDLE(view, handler, resize); return true; } @@ -114,16 +124,12 @@ void view_set_screens(struct view * view, uint32_t screens) if (view->screens == screens) return; - struct view_event_data data = { - .view = view, - .screens_changed = { - .entered = screens & ~view->screens, - .left = view->screens & ~screens - } - }; + uint32_t entered = screens & ~view->screens, + left = view->screens & ~screens; + struct view_handler * handler; view->screens = screens; - swc_send_event(&view->event_signal, VIEW_EVENT_SCREENS_CHANGED, &data); + HANDLE(view, handler, screens, entered, left); } void view_update_screens(struct view * view) @@ -142,8 +148,8 @@ void view_update_screens(struct view * view) void view_frame(struct view * view, uint32_t time) { - struct view_event_data data = { .view = view, .frame = { time } }; + struct view_handler * handler; - swc_send_event(&view->event_signal, VIEW_EVENT_FRAME, &data); + HANDLE(view, handler, frame, time); } diff --git a/libswc/view.h b/libswc/view.h @@ -26,44 +26,6 @@ #include "swc.h" -enum -{ - /* Sent when the view has displayed the next frame. */ - VIEW_EVENT_FRAME, - - /* Sent when the origin of the view has moved. */ - VIEW_EVENT_MOVED, - - /* Sent when the view's size changes. */ - VIEW_EVENT_RESIZED, - - /* Sent when the set of screens the view is visible on changes. */ - VIEW_EVENT_SCREENS_CHANGED -}; - -/** - * This structure contains data sent along with a view's events. - * - * Extra data correspending to the particular event is stored in the - * corresponding struct inside the union. - */ -struct view_event_data -{ - struct view * view; - union - { - struct - { - uint32_t time; - } frame; - - struct - { - uint32_t left, entered; - } screens_changed; - }; -}; - /** * A view represents a component that can display buffers to the user. * @@ -79,14 +41,20 @@ struct view_event_data struct view { const struct view_impl * impl; + struct wl_list handlers; - struct wl_signal event_signal; struct swc_rectangle geometry; uint32_t screens; struct wld_buffer * buffer; }; +struct view_handler +{ + const struct view_handler_impl * impl; + struct wl_list link; +}; + /** * Every view must have an implementation containing these functions. * @@ -99,6 +67,19 @@ struct view_impl bool (* move)(struct view * view, int32_t x, int32_t y); }; +struct view_handler_impl +{ + /* Called when the view has displayed the next frame. */ + void (* frame)(struct view_handler * handler, uint32_t time); + /* Called after the view's position changes. */ + void (* move)(struct view_handler * handler); + /* Called after the view's size changes. */ + void (* resize)(struct view_handler * handler); + /* Called when the set of screens the view is visible on changes. */ + void (* screens)(struct view_handler * handler, + uint32_t left, uint32_t entered); +}; + /** * Attach a new buffer to the view. *