Redesign the compositor / server interface.
This lets the compositor directly provide the implementation of the RMI
objects for the surface object and a new compositor object. We avoid the
manual forwarding of requests into the compositor and the clumsy compositor
interface struct.
diff --git a/egl-compositor.c b/egl-compositor.c
index e5fe679..2cf9ec1 100644
--- a/egl-compositor.c
+++ b/egl-compositor.c
@@ -89,10 +89,11 @@
};
struct egl_surface {
+ struct wl_surface base;
+ struct egl_compositor *compositor;
GLuint texture;
struct wl_map map;
EGLSurface surface;
- struct wl_surface *wl_surface;
int width, height;
struct wl_list link;
};
@@ -102,6 +103,10 @@
struct egl_compositor *ec;
};
+struct screenshooter_interface {
+ void (*shoot)(struct wl_client *client, struct screenshooter *shooter);
+};
+
static void
screenshooter_shoot(struct wl_client *client, struct screenshooter *shooter)
{
@@ -120,7 +125,7 @@
}
static const struct wl_method screenshooter_methods[] = {
- { "shoot", screenshooter_shoot, "", NULL }
+ { "shoot", "", NULL }
};
static const struct wl_interface screenshooter_interface = {
@@ -129,6 +134,10 @@
screenshooter_methods,
};
+struct screenshooter_interface screenshooter_implementation = {
+ screenshooter_shoot
+};
+
static struct screenshooter *
screenshooter_create(struct egl_compositor *ec)
{
@@ -139,6 +148,7 @@
return NULL;
shooter->base.interface = &screenshooter_interface;
+ shooter->base.implementation = (void(**)(void)) &screenshooter_implementation;
shooter->ec = ec;
return shooter;
@@ -498,7 +508,8 @@
clock_gettime(CLOCK_MONOTONIC, &ts);
msecs = ts.tv_sec * 1000 + ts.tv_nsec / (1000 * 1000);
- wl_display_post_frame(ec->wl_display, ec->current_frame, msecs);
+ wl_display_post_frame(ec->wl_display, &ec->base,
+ ec->current_frame, msecs);
ec->current_frame++;
wl_event_source_timer_update(ec->timer_source, 10);
@@ -518,36 +529,13 @@
wl_event_loop_add_idle(loop, repaint, ec);
}
}
-
-static void
-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);
- if (es == NULL)
- return;
-
- es->surface = EGL_NO_SURFACE;
- es->wl_surface = surface;
- wl_surface_set_data(surface, es);
- wl_list_insert(ec->surface_list.prev, &es->link);
-
- glGenTextures(1, &es->texture);
-}
static void
-notify_surface_destroy(struct wl_compositor *compositor,
- struct wl_surface *surface)
+surface_destroy(struct wl_client *client,
+ struct wl_surface *surface)
{
- struct egl_compositor *ec = (struct egl_compositor *) compositor;
- struct egl_surface *es;
-
- es = wl_surface_get_data(surface);
- if (es == NULL)
- return;
+ struct egl_surface *es = (struct egl_surface *) surface;
+ struct egl_compositor *ec = es->compositor;
wl_list_remove(&es->link);
egl_surface_destroy(es, ec);
@@ -556,16 +544,12 @@
}
static void
-notify_surface_attach(struct wl_compositor *compositor,
- struct wl_surface *surface, uint32_t name,
- uint32_t width, uint32_t height, uint32_t stride)
+surface_attach(struct wl_client *client,
+ struct wl_surface *surface, uint32_t name,
+ uint32_t width, uint32_t height, uint32_t stride)
{
- struct egl_compositor *ec = (struct egl_compositor *) compositor;
- struct egl_surface *es;
-
- es = wl_surface_get_data(surface);
- if (es == NULL)
- return;
+ struct egl_surface *es = (struct egl_surface *) surface;
+ struct egl_compositor *ec = es->compositor;
if (es->surface != EGL_NO_SURFACE)
eglDestroySurface(ec->display, es->surface);
@@ -584,30 +568,28 @@
}
static void
-notify_surface_map(struct wl_compositor *compositor,
- struct wl_surface *surface, struct wl_map *map)
+surface_map(struct wl_client *client,
+ struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
{
- struct egl_surface *es;
+ struct egl_surface *es = (struct egl_surface *) surface;
- es = wl_surface_get_data(surface);
- if (es == NULL)
- return;
-
- es->map = *map;
+ es->map.x = x;
+ es->map.y = y;
+ es->map.width = width;
+ es->map.height = height;
}
static void
-notify_surface_copy(struct wl_compositor *compositor,
- struct wl_surface *surface,
- int32_t dst_x, int32_t dst_y,
- uint32_t name, uint32_t stride,
- int32_t x, int32_t y, int32_t width, int32_t height)
+surface_copy(struct wl_client *client,
+ struct wl_surface *surface,
+ int32_t dst_x, int32_t dst_y,
+ uint32_t name, uint32_t stride,
+ int32_t x, int32_t y, int32_t width, int32_t height)
{
- struct egl_compositor *ec = (struct egl_compositor *) compositor;
+ struct egl_surface *es = (struct egl_surface *) surface;
+ struct egl_compositor *ec = es->compositor;
EGLSurface src;
- struct egl_surface *es;
-
- es = wl_surface_get_data(surface);
/* FIXME: glCopyPixels should work, but then we'll have to
* call eglMakeCurrent to set up the src and dest surfaces
@@ -623,23 +605,56 @@
}
static void
-notify_surface_damage(struct wl_compositor *compositor,
- struct wl_surface *surface,
- int32_t x, int32_t y, int32_t width, int32_t height)
+surface_damage(struct wl_client *client,
+ struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t width, int32_t height)
{
/* FIXME: This need to take a damage region, of course. */
}
-static uint32_t
-notify_commit(struct wl_compositor *compositor)
+const static struct wl_surface_interface surface_interface = {
+ surface_destroy,
+ surface_attach,
+ surface_map,
+ surface_copy,
+ surface_damage
+};
+
+static void
+compositor_create_surface(struct wl_client *client,
+ struct wl_compositor *compositor, uint32_t id)
+{
+ struct egl_compositor *ec = (struct egl_compositor *) compositor;
+ struct egl_surface *es;
+
+ es = malloc(sizeof *es);
+ if (es == NULL)
+ /* FIXME: Send OOM event. */
+ return;
+
+ es->compositor = ec;
+ es->surface = EGL_NO_SURFACE;
+ wl_list_insert(ec->surface_list.prev, &es->link);
+ glGenTextures(1, &es->texture);
+ wl_client_add_surface(client, &es->base,
+ &surface_interface, id);
+}
+
+static void
+compositor_commit(struct wl_client *client,
+ struct wl_compositor *compositor, uint32_t key)
{
struct egl_compositor *ec = (struct egl_compositor *) compositor;
schedule_repaint(ec);
-
- return ec->current_frame;
+ wl_client_send_acknowledge(client, compositor, key, ec->current_frame);
}
+const static struct wl_compositor_interface compositor_interface = {
+ compositor_create_surface,
+ compositor_commit
+};
+
static struct egl_surface *
pick_surface(struct egl_input_device *device)
{
@@ -677,7 +692,7 @@
if (es) {
sx = (x - es->map.x) * es->width / es->map.width;
sy = (y - es->map.y) * es->height / es->map.height;
- wl_surface_post_event(es->wl_surface, &device->base,
+ wl_surface_post_event(&es->base, &device->base,
WL_INPUT_MOTION, x, y, sx, sy);
}
@@ -715,7 +730,7 @@
sy = (device->y - es->map.y) * es->height / es->map.height;
/* FIXME: Swallow click on raise? */
- wl_surface_post_event(es->wl_surface, &device->base,
+ wl_surface_post_event(&es->base, &device->base,
WL_INPUT_BUTTON, button, state,
device->x, device->y, sx, sy);
@@ -737,29 +752,16 @@
schedule_repaint(ec);
} else if (!wl_list_empty(&ec->surface_list)) {
if (device->focus_surface != NULL)
- wl_surface_post_event(device->focus_surface->wl_surface,
+ wl_surface_post_event(&device->focus_surface->base,
&device->base,
WL_INPUT_KEY, key, state);
}
}
-static const struct wl_compositor_interface interface = {
- notify_surface_create,
- notify_surface_destroy,
- notify_surface_attach,
- notify_surface_map,
- notify_surface_copy,
- notify_surface_damage,
- notify_commit,
-};
-
struct evdev_input_device *
evdev_input_device_create(struct egl_input_device *device,
struct wl_display *display, const char *path);
-void
-egl_device_get_position(struct egl_input_device *device, int32_t *x, int32_t *y);
-
static void
create_input_device(struct egl_compositor *ec, const char *glob)
{
@@ -984,7 +986,6 @@
if (ec == NULL)
return NULL;
- ec->base.interface = &interface;
ec->wl_display = display;
ec->display = eglCreateDisplayNative(gem_device, "i965");
@@ -1027,6 +1028,8 @@
glOrtho(0, ec->width, ec->height, 0, 0, 1000.0);
glMatrixMode(GL_MODELVIEW);
+ wl_display_set_compositor(display, &ec->base, &compositor_interface);
+
wl_list_init(&ec->input_device_list);
for (i = 0; option_input_devices[i]; i++)
create_input_device(ec, option_input_devices[i]);
@@ -1086,8 +1089,6 @@
exit(EXIT_FAILURE);
}
- wl_display_set_compositor(display, &ec->base);
-
if (wl_display_add_socket(display, socket_name, sizeof socket_name)) {
fprintf(stderr, "failed to add socket: %m\n");
exit(EXIT_FAILURE);