commit 6797a556a742c59e837a53510d6eca1e26b6dffc
parent b7805fb9334c8725467c13573aa630cc751af1bc
Author: Michael Forney <mforney@mforney.org>
Date: Thu, 16 Jan 2014 15:15:28 -0800
view: Add event signal and frame events
Diffstat:
5 files changed, 73 insertions(+), 29 deletions(-)
diff --git a/libswc/compositor.c b/libswc/compositor.c
@@ -646,7 +646,7 @@ static void handle_drm_event(struct wl_listener * listener, void * data)
if (compositor->pending_flips == 0)
{
wl_list_for_each(surface, &compositor->surfaces, link)
- swc_surface_send_frame_callbacks(surface, event_data->time);
+ swc_view_frame(surface->view, event_data->time);
}
/* If we had scheduled updates that couldn't run because we were
diff --git a/libswc/surface.c b/libswc/surface.c
@@ -339,6 +339,32 @@ static void surface_destroy(struct wl_resource * resource)
free(surface);
}
+static void handle_view_event(struct wl_listener * listener, void * data)
+{
+ struct swc_surface * surface
+ = CONTAINER_OF(listener, typeof(*surface), view_listener);
+ struct swc_event * event = data;
+ struct swc_view_event_data * event_data = event->data;
+
+ switch (event->type)
+ {
+ case SWC_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;
+ }
+ }
+}
+
/**
* Construct a new surface, adding it to the given client as id.
*
@@ -365,6 +391,7 @@ struct swc_surface * swc_surface_new(struct wl_client * client,
surface->pending.commit = 0;
surface->window = NULL;
surface->view = NULL;
+ surface->view_listener.notify = &handle_view_event;
surface->view_state = NULL;
state_initialize(&surface->state, true);
@@ -381,33 +408,23 @@ struct swc_surface * swc_surface_new(struct wl_client * client,
return surface;
}
-void swc_surface_send_frame_callbacks(struct swc_surface * surface,
- uint32_t time)
-{
- 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);
-}
-
-void swc_surface_set_view(struct swc_surface * surface,
- const struct swc_view * view)
+void swc_surface_set_view(struct swc_surface * surface, struct swc_view * view)
{
if (surface->view == view)
return;
- if (surface->view && surface->view->impl->remove)
- surface->view->impl->remove(surface);
+ if (surface->view)
+ {
+ if (surface->view->impl->remove)
+ surface->view->impl->remove(surface);
+ wl_list_remove(&surface->view_listener.link);
+ }
surface->view = view;
- if (surface->view)
+ if (view)
{
+ wl_signal_add(&view->event_signal, &surface->view_listener);
surface->view->impl->attach(surface, surface->state.buffer);
surface->view->impl->update(surface);
}
diff --git a/libswc/surface.h b/libswc/surface.h
@@ -85,7 +85,8 @@ struct swc_surface
} pending;
struct swc_window * window;
- const struct swc_view * view;
+ struct swc_view * view;
+ struct wl_listener view_listener;
void * view_state;
uint32_t outputs;
@@ -98,10 +99,7 @@ struct swc_surface
struct swc_surface * swc_surface_new(struct wl_client * client,
uint32_t version, uint32_t id);
-void swc_surface_send_frame_callbacks(struct swc_surface * surface,
- uint32_t time);
-void swc_surface_set_view(struct swc_surface * surface,
- const struct swc_view * view);
+void swc_surface_set_view(struct swc_surface * surface, struct swc_view * view);
void swc_surface_update(struct swc_surface * surface);
diff --git a/libswc/view.c b/libswc/view.c
@@ -22,14 +22,23 @@
*/
#include "view.h"
+#include "event.h"
void swc_view_initialize(struct swc_view * view,
const struct swc_view_impl * impl)
{
view->impl = impl;
+ wl_signal_init(&view->event_signal);
}
void swc_view_finalize(struct swc_view * view)
{
}
+void swc_view_frame(struct swc_view * view, uint32_t time)
+{
+ struct swc_view_event_data data = { .view = view, .frame = { time } };
+
+ swc_send_event(&view->event_signal, SWC_VIEW_EVENT_FRAME, &data);
+}
+
diff --git a/libswc/view.h b/libswc/view.h
@@ -24,16 +24,34 @@
#ifndef SWC_VIEW_H
#define SWC_VIEW_H
-#include <stdbool.h>
-#include <stdint.h>
+#include "swc.h"
-struct swc_buffer;
struct swc_surface;
-struct wl_resource;
+struct swc_buffer;
+
+enum swc_view_event
+{
+ /* Sent when the view has displayed the next frame. */
+ SWC_VIEW_EVENT_FRAME,
+};
+
+struct swc_view_event_data
+{
+ struct swc_view * view;
+ union
+ {
+ struct
+ {
+ uint32_t time;
+ } frame;
+ };
+};
struct swc_view
{
const struct swc_view_impl * impl;
+
+ struct wl_signal event_signal;
};
/**
@@ -61,5 +79,7 @@ void swc_view_initialize(struct swc_view * view,
void swc_view_finalize(struct swc_view * view);
+void swc_view_frame(struct swc_view * view, uint32_t time);
+
#endif