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:
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;