buffer.c \
renderer.c \
pixman-renderer.c \
- data-device.c
+ data-device.c \
+ view.c \
+ layer.c
# gl renderer
if ENABLE_GL_RENDERER
goto error;
}
+ wl_list_init(&compositor->layers);
return compositor;
error:
--- /dev/null
+#include "pepper-internal.h"
+
+PEPPER_API pepper_layer_t *
+pepper_layer_create(pepper_compositor_t *compositor)
+{
+ pepper_layer_t *layer;
+ PEPPER_ASSERT(compositor != NULL);
+
+ layer = pepper_calloc(1, sizeof(pepper_layer_t));
+ if (!layer)
+ return NULL;
+
+ layer->compositor = compositor;
+ wl_list_init(&layer->views);
+
+ return layer;
+}
+
+PEPPER_API pepper_compositor_t *
+pepper_layer_get_compositor(pepper_layer_t *layer)
+{
+ return layer->compositor;
+}
+
+PEPPER_API void
+pepper_compositor_stack_layer(pepper_compositor_t *compositor, pepper_layer_t *layer,
+ pepper_layer_t *below)
+{
+ PEPPER_ASSERT(compositor != NULL);
+ PEPPER_ASSERT(!below || (layer->compositor == below->compositor));
+
+ if ((!below && (layer->link.prev == &compositor->layers)) ||
+ ( below && (layer->link.prev == &below->link)))
+ return;
+
+ if (!wl_list_empty(&layer->link))
+ {
+ wl_list_remove(&layer->link);
+
+ /* TODO: Handle layer removal. */
+ }
+
+ if (below)
+ wl_list_insert(&below->link, &layer->link);
+ else
+ wl_list_insert(&compositor->layers, &layer->link);
+
+ /* TODO: Handle layer insert. */
+}
+
+PEPPER_API pepper_layer_t *
+pepper_compositor_get_top_layer(pepper_compositor_t *compositor)
+{
+ pepper_layer_t *layer;
+
+ if (wl_list_empty(&compositor->layers))
+ return NULL;
+
+ layer = wl_container_of(compositor->layers.prev, layer, link);
+ return layer;
+}
+
+PEPPER_API pepper_layer_t *
+pepper_compositor_get_bottom_layer(pepper_compositor_t *compositor)
+{
+ pepper_layer_t *layer;
+
+ if (wl_list_empty(&compositor->layers))
+ return NULL;
+
+ layer = wl_container_of(compositor->layers.next, layer, link);
+ return layer;
+}
+
+PEPPER_API pepper_layer_t *
+pepper_layer_get_above(pepper_layer_t *layer)
+{
+ pepper_layer_t *above;
+
+ if (wl_list_empty(&layer->link))
+ return NULL;
+
+ if (layer->link.next == &layer->compositor->layers)
+ return NULL;
+
+ above = wl_container_of(layer->link.next, layer, link);
+ return above;
+}
+
+PEPPER_API pepper_layer_t *
+pepper_layer_get_below(pepper_layer_t *layer)
+{
+ pepper_layer_t *below;
+
+ if (wl_list_empty(&layer->link))
+ return NULL;
+
+ if (layer->link.prev == &layer->compositor->layers)
+ return NULL;
+
+ below = wl_container_of(layer->link.prev, layer, link);
+ return below;
+}
+
+PEPPER_API void
+pepper_layer_stack_view(pepper_layer_t *layer, pepper_view_t *view, pepper_view_t *below)
+{
+ PEPPER_ASSERT(layer != NULL);
+ PEPPER_ASSERT(!below || (below->compositor == view->compositor));
+
+ if ((!below && (view->layer_link.prev == &layer->views)) ||
+ ( below && (view->layer_link.prev == &below->layer_link)))
+ return;
+
+ if (view->layer)
+ {
+ wl_list_remove(&view->layer_link);
+
+ /* TODO: Handle view removal. */
+ }
+
+ if (below)
+ wl_list_insert(&below->layer_link, &view->layer_link);
+ else
+ wl_list_insert(&layer->views, &view->layer_link);
+
+ /* TODO: Handle view insert. */
+}
+
+PEPPER_API pepper_view_t *
+pepper_layer_get_top_view(pepper_layer_t *layer)
+{
+ pepper_view_t *view;
+
+ if (wl_list_empty(&layer->views))
+ return NULL;
+
+ view = wl_container_of(layer->views.prev, view, layer_link);
+ return view;
+}
+
+PEPPER_API pepper_view_t *
+pepper_layer_get_bottom_view(pepper_layer_t *layer)
+{
+ pepper_view_t *view;
+
+ if (wl_list_empty(&layer->views))
+ return NULL;
+
+ view = wl_container_of(layer->views.next, view, layer_link);
+ return view;
+}
struct wl_list surfaces;
struct wl_list regions;
struct wl_list seat_list;
+ struct wl_list layers;
};
struct pepper_output
pepper_bool_t
pepper_data_device_manager_init(struct wl_display *display);
+struct pepper_view
+{
+ pepper_compositor_t *compositor;
+ struct wl_signal destroy_signal;
+
+ pepper_surface_t *surface;
+ pepper_bool_t mapped;
+ float alpha;
+
+ pepper_view_t *parent;
+ struct wl_list parent_link;
+ struct wl_listener parent_destroy_listener;
+ struct wl_list childs;
+
+ struct {
+ pepper_bool_t dirty;
+
+ float x, y;
+ pepper_matrix_t transform;
+ } geometry;
+
+ pepper_layer_t *layer;
+ struct wl_list layer_link;
+};
+
+struct pepper_layer
+{
+ pepper_compositor_t *compositor;
+ struct wl_list link;
+ struct wl_list views;
+};
+
#endif /* PEPPER_INTERNAL_H */
typedef struct pepper_renderer pepper_renderer_t;
typedef struct pepper_surface pepper_surface_t;
+typedef struct pepper_view pepper_view_t;
+typedef struct pepper_layer pepper_layer_t;
+
+typedef struct pepper_matrix pepper_matrix_t;
#define PEPPER_FORMAT(type, bpp, a, r, g, b) \
((((type) & 0xff) << 24) | \
PEPPER_FORMAT_ALPHA = PEPPER_FORMAT(PEPPER_FORMAT_TYPE_ARGB, 8, 8, 0, 0, 0),
} pepper_format_t;
+#define PEPPER_MATRIX_IS_IDENTITY 1
+
+struct pepper_matrix
+{
+ float m[16];
+ uint32_t flags;
+};
+
+static inline void
+pepper_matrix_load_identity(pepper_matrix_t *matrix)
+{
+ matrix->m[ 0] = 1.0f;
+ matrix->m[ 1] = 0.0f;
+ matrix->m[ 2] = 0.0f;
+ matrix->m[ 3] = 0.0f;
+
+ matrix->m[ 4] = 0.0f;
+ matrix->m[ 5] = 1.0f;
+ matrix->m[ 6] = 0.0f;
+ matrix->m[ 7] = 0.0f;
+
+ matrix->m[ 8] = 0.0f;
+ matrix->m[ 9] = 0.0f;
+ matrix->m[10] = 1.0f;
+ matrix->m[11] = 0.0f;
+
+ matrix->m[12] = 0.0f;
+ matrix->m[13] = 0.0f;
+ matrix->m[14] = 0.0f;
+ matrix->m[15] = 1.0f;
+
+ matrix->flags = PEPPER_MATRIX_IS_IDENTITY;
+}
+
+static inline pepper_bool_t
+pepper_matrix_equal(const pepper_matrix_t *a, const pepper_matrix_t *b)
+{
+ return a->m[ 0] == b->m[ 0] && a->m[ 1] == b->m[ 1] &&
+ a->m[ 2] == b->m[ 2] && a->m[ 3] && b->m[ 3] &&
+ a->m[ 4] == b->m[ 4] && a->m[ 5] && b->m[ 5] &&
+ a->m[ 6] == b->m[ 6] && a->m[ 7] && b->m[ 7] &&
+ a->m[ 8] == b->m[ 8] && a->m[ 9] && b->m[ 9] &&
+ a->m[10] == b->m[10] && a->m[11] && b->m[11] &&
+ a->m[12] == b->m[12] && a->m[13] && b->m[13] &&
+ a->m[14] == b->m[14] && a->m[15] && b->m[15];
+}
+
+/* TODO: Other matrix utility functions. */
+
struct pepper_output_geometry
{
int32_t x;
PEPPER_API pepper_bool_t
pepper_surface_set_role(pepper_surface_t *surface, const char *role);
+/* View. */
+PEPPER_API pepper_view_t *
+pepper_view_create(pepper_compositor_t *compositor, pepper_surface_t *surface);
+
+PEPPER_API pepper_compositor_t *
+pepper_view_get_compositor(pepper_view_t *view);
+
+PEPPER_API pepper_surface_t *
+pepper_view_get_surface(pepper_view_t *view);
+
+PEPPER_API void
+pepper_view_destroy(pepper_view_t *view);
+
+PEPPER_API void
+pepper_view_add_destroy_listener(pepper_view_t *view, struct wl_listener *listener);
+
+PEPPER_API void
+pepper_view_set_transform(pepper_view_t *view, const pepper_matrix_t *matrix);
+
+PEPPER_API const pepper_matrix_t *
+pepper_view_get_transform(pepper_view_t *view);
+
+PEPPER_API void
+pepper_view_set_position(pepper_view_t *view, float x, float y);
+
+PEPPER_API void
+pepper_view_get_position(pepper_view_t *view, float *x, float *y);
+
+PEPPER_API void
+pepper_view_set_parent(pepper_view_t *view, pepper_view_t *parent);
+
+PEPPER_API pepper_view_t *
+pepper_view_get_parent(pepper_view_t *view);
+
+PEPPER_API void
+pepper_view_map(pepper_view_t *view);
+
+PEPPER_API void
+pepper_view_unmap(pepper_view_t *view);
+
+PEPPER_API pepper_bool_t
+pepper_view_is_mapped(pepper_view_t *view);
+
+PEPPER_API void
+pepper_view_set_alpha(pepper_view_t *view, float alpha);
+
+PEPPER_API float
+pepper_view_get_alpha(pepper_view_t *view);
+
+PEPPER_API pepper_view_t *
+pepper_view_get_above(pepper_view_t *view);
+
+PEPPER_API pepper_view_t *
+pepper_view_get_below(pepper_view_t *view);
+
+/* Layer. */
+PEPPER_API pepper_layer_t *
+pepper_layer_create(pepper_compositor_t *compositor);
+
+PEPPER_API pepper_compositor_t *
+pepper_layer_get_compositor(pepper_layer_t *layer);
+
+PEPPER_API void
+pepper_compositor_stack_layer(pepper_compositor_t *compositor, pepper_layer_t *layer,
+ pepper_layer_t *below);
+
+PEPPER_API pepper_layer_t *
+pepper_compositor_get_top_layer(pepper_compositor_t *compositor);
+
+PEPPER_API pepper_layer_t *
+pepper_compositor_get_bottom_layer(pepper_compositor_t *compositor);
+
+PEPPER_API pepper_layer_t *
+pepper_layer_get_above(pepper_layer_t *layer);
+
+PEPPER_API pepper_layer_t *
+pepper_layer_get_below(pepper_layer_t *layer);
+
+PEPPER_API void
+pepper_layer_stack_view(pepper_layer_t *layer, pepper_view_t *view, pepper_view_t *below);
+
+PEPPER_API pepper_view_t *
+pepper_layer_get_top_view(pepper_layer_t *layer);
+
+PEPPER_API pepper_view_t *
+pepper_layer_get_bottom_view(pepper_layer_t *layer);
+
#ifdef __cplusplus
}
#endif
--- /dev/null
+#include "pepper-internal.h"
+#include <string.h>
+
+void
+view_geometry_dirty(pepper_view_t *view)
+{
+ pepper_view_t *child;
+
+ if (view->geometry.dirty)
+ return;
+
+ view->geometry.dirty = PEPPER_TRUE;
+
+ wl_list_for_each(child, &view->childs, parent_link)
+ view_geometry_dirty(child);
+}
+
+static void
+handle_parent_destroy(struct wl_listener *listener, void *data)
+{
+ pepper_view_t *view = wl_container_of(listener, view, parent_destroy_listener);
+
+ PEPPER_ASSERT(view->parent == data);
+ pepper_view_set_parent(view, NULL);
+}
+
+PEPPER_API pepper_view_t *
+pepper_view_create(pepper_compositor_t *compositor, pepper_surface_t *surface)
+{
+ pepper_view_t *view;
+
+ if (!compositor)
+ {
+ PEPPER_ERROR("Compositor must be given.\n");
+ return NULL;
+ }
+
+ if (surface && surface->compositor != compositor)
+ {
+ PEPPER_ERROR("Unable to create a view for a surface from different compositor.\n");
+ return NULL;
+ }
+
+ view = pepper_calloc(1, sizeof(pepper_view_t));
+ if (!view)
+ return NULL;
+
+ view->compositor = compositor;
+ wl_signal_init(&view->destroy_signal);
+
+ view->surface = surface;
+ view->alpha = 1.0f;
+
+ view->parent_destroy_listener.notify = handle_parent_destroy;
+ wl_list_init(&view->childs);
+
+ /* Initialize geometry properties. */
+ view->geometry.dirty = PEPPER_TRUE;
+ view->geometry.x = 0.0f;
+ view->geometry.y = 0.0f;
+ pepper_matrix_load_identity(&view->geometry.transform);
+
+ return view;
+}
+
+PEPPER_API pepper_compositor_t *
+pepper_view_get_compositor(pepper_view_t *view)
+{
+ return view->compositor;
+}
+
+PEPPER_API pepper_surface_t *
+pepper_view_get_surface(pepper_view_t *view)
+{
+ return view->surface;
+}
+
+PEPPER_API void
+pepper_view_destroy(pepper_view_t *view)
+{
+ wl_signal_emit(&view->destroy_signal, view);
+ PEPPER_ASSERT(wl_list_empty(&view->childs));
+
+ if (view->parent)
+ {
+ wl_list_remove(&view->parent_link);
+ wl_list_remove(&view->parent_destroy_listener.link);
+ }
+
+ pepper_free(view);
+}
+
+PEPPER_API void
+pepper_view_add_destroy_listener(pepper_view_t *view, struct wl_listener *listener)
+{
+ wl_signal_add(&view->destroy_signal, listener);
+}
+
+PEPPER_API void
+pepper_view_set_position(pepper_view_t *view, float x, float y)
+{
+ view->geometry.x = x;
+ view->geometry.y = y;
+}
+
+PEPPER_API void
+pepper_view_get_position(pepper_view_t *view, float *x, float *y)
+{
+ if (x)
+ *x = view->geometry.x;
+
+ if (y)
+ *y = view->geometry.y;
+}
+
+PEPPER_API void
+pepper_view_set_transform(pepper_view_t *view, const pepper_matrix_t *matrix)
+{
+ memcpy(&view->geometry.transform, matrix, sizeof(pepper_matrix_t));
+ view_geometry_dirty(view);
+}
+
+PEPPER_API const pepper_matrix_t *
+pepper_view_get_transform(pepper_view_t *view)
+{
+ return &view->geometry.transform;
+}
+
+PEPPER_API void
+pepper_view_set_parent(pepper_view_t *view, pepper_view_t *parent)
+{
+ if (view->parent == parent)
+ return;
+
+ if (view->parent)
+ {
+ wl_list_remove(&view->parent_link);
+ wl_list_remove(&view->parent_destroy_listener.link);
+ }
+
+ view->parent = parent;
+
+ if (parent)
+ {
+ wl_list_insert(&parent->childs, &view->parent_link);
+ pepper_view_add_destroy_listener(parent, &view->parent_destroy_listener);
+ }
+
+ view_geometry_dirty(view);
+}
+
+PEPPER_API pepper_view_t *
+pepper_view_get_parent(pepper_view_t *view)
+{
+ return view->parent;
+}
+
+PEPPER_API void
+pepper_view_map(pepper_view_t *view)
+{
+ if (view->mapped)
+ return;
+
+ view->mapped = PEPPER_TRUE;
+}
+
+PEPPER_API void
+pepper_view_unmap(pepper_view_t *view)
+{
+ if (!view->mapped)
+ return;
+
+ view->mapped = PEPPER_FALSE;
+}
+
+PEPPER_API pepper_bool_t
+pepper_view_is_mapped(pepper_view_t *view)
+{
+ return view->mapped;
+}
+
+PEPPER_API void
+pepper_view_set_alpha(pepper_view_t *view, float alpha)
+{
+ if (view->alpha == alpha)
+ return;
+
+ view->alpha = alpha;
+}
+
+PEPPER_API float
+pepper_view_get_alpha(pepper_view_t *view)
+{
+ return view->alpha;
+}
+
+PEPPER_API pepper_view_t *
+pepper_view_get_above(pepper_view_t *view)
+{
+ pepper_view_t *above;
+
+ if (!view->layer)
+ return NULL;
+
+ if (view->layer_link.next == &view->layer->views)
+ return NULL;
+
+ above = wl_container_of(view->layer_link.next, view, layer_link);
+ return above;
+}
+
+PEPPER_API pepper_view_t *
+pepper_view_get_below(pepper_view_t *view)
+{
+ pepper_view_t *below;
+
+ if (!view->layer)
+ return NULL;
+
+ if (view->layer_link.prev == &view->layer->views)
+ return NULL;
+
+ below = wl_container_of(view->layer_link.prev, view, layer_link);
+ return below;
+}