Drop surface iterator API, just track surfaces in the compositor.
diff --git a/egl-compositor.c b/egl-compositor.c
index 4f10cb9..c70b2de 100644
--- a/egl-compositor.c
+++ b/egl-compositor.c
@@ -63,6 +63,8 @@
struct egl_surface *overlay;
double overlay_y, overlay_target, overlay_previous;
+ struct wl_list surface_list;
+
/* Repaint state. */
struct wl_event_source *timer_source;
int repaint_needed;
@@ -75,6 +77,8 @@
GLuint texture;
struct wl_map map;
EGLSurface surface;
+
+ struct wl_list link;
};
static void
@@ -550,8 +554,6 @@
repaint(void *data)
{
struct egl_compositor *ec = data;
- struct wl_surface_iterator *iterator;
- struct wl_surface *surface;
struct egl_surface *es;
struct timespec ts;
uint32_t msecs;
@@ -563,15 +565,14 @@
draw_surface(ec->background);
- iterator = wl_surface_iterator_create(ec->wl_display, 0);
- while (wl_surface_iterator_next(iterator, &surface)) {
- es = wl_surface_get_data(surface);
- if (es == NULL)
- continue;
-
+ es = container_of(ec->surface_list.next,
+ struct egl_surface, link);
+ while (&es->link != &ec->surface_list) {
draw_surface(es);
+
+ es = container_of(es->link.next,
+ struct egl_surface, link);
}
- wl_surface_iterator_destroy(iterator);
draw_surface(ec->overlay);
@@ -607,6 +608,7 @@
notify_surface_create(struct wl_compositor *compositor,
struct wl_surface *surface)
{
+ struct egl_compositor *ec = (struct egl_compositor *) compositor;
struct egl_surface *es;
es = malloc(sizeof *es);
@@ -615,6 +617,7 @@
es->surface = EGL_NO_SURFACE;
wl_surface_set_data(surface, es);
+ wl_list_insert(ec->surface_list.prev, &es->link);
glGenTextures(1, &es->texture);
}
@@ -630,6 +633,7 @@
if (es == NULL)
return;
+ wl_list_remove(&es->link);
egl_surface_destroy(es, ec);
schedule_repaint(ec);
@@ -730,6 +734,25 @@
schedule_repaint(ec);
}
+static struct egl_surface *
+pick_surface(struct egl_compositor *ec, int32_t x, int32_t y)
+{
+ struct egl_surface *es;
+
+ es = container_of(ec->surface_list.prev,
+ struct egl_surface, link);
+ while (&es->link != &ec->surface_list) {
+ if (es->map.x <= x && x < es->map.x + es->map.width &&
+ es->map.y <= y && y < es->map.y + es->map.height)
+ return es;
+
+ es = container_of(es->link.prev,
+ struct egl_surface, link);
+ }
+
+ return NULL;
+}
+
static void
notify_pointer_button(struct wl_compositor *compositor,
struct wl_object *source,
@@ -737,29 +760,19 @@
{
struct egl_compositor *ec = (struct egl_compositor *) compositor;
struct egl_surface *es;
- struct wl_surface_iterator *iterator;
- struct wl_surface *surface, *target;
const int hotspot_x = 16, hotspot_y = 16;
int x, y;
x = ec->pointer->map.x + hotspot_x;
y = ec->pointer->map.y + hotspot_y;
- target = NULL;
- iterator = wl_surface_iterator_create(ec->wl_display, 0);
- while (wl_surface_iterator_next(iterator, &surface)) {
- es = wl_surface_get_data(surface);
- if (es == NULL)
- continue;
-
- if (es->map.x <= x && x < es->map.x + es->map.width &&
- es->map.y <= y && y < es->map.y + es->map.height)
- target = surface;
+ es = pick_surface(ec, x, y);
+ if (es) {
+ wl_list_remove(&es->link);
+ wl_list_insert(ec->surface_list.prev, &es->link);
}
- wl_surface_iterator_destroy(iterator);
- if (target)
- wl_display_raise_surface(ec->wl_display, target);
+ schedule_repaint(ec);
}
static void
@@ -1026,6 +1039,7 @@
create_input_devices(display);
+ wl_list_init(&ec->surface_list);
filename = getenv("WAYLAND_BACKGROUND");
if (filename == NULL)
filename = "background.jpg";