Refactor: output, backend APIs and etc
authorTaekyun Kim <tkq.kim@samsung.com>
Tue, 31 Mar 2015 06:43:12 +0000 (15:43 +0900)
committerTaekyun Kim <tkq.kim@samsung.com>
Fri, 19 Jun 2015 09:06:39 +0000 (18:06 +0900)
Change-Id: I2fdcd700ea541e347c44a60cdd0f3699cd1aa40d

src/compositor.c
src/modules/wayland/pepper-wayland.h
src/modules/wayland/wayland-common.c
src/modules/wayland/wayland-input.c
src/modules/wayland/wayland-internal.h
src/modules/wayland/wayland-output.c
src/output.c
src/pepper-internal.h
src/pepper.h

index 6f9a7b9..f3a73df 100644 (file)
@@ -98,16 +98,3 @@ pepper_compositor_get_display(pepper_compositor_t *compositor)
 {
     return compositor->display;
 }
-
-PEPPER_API void
-pepper_compositor_set_user_data(pepper_compositor_t *compositor, uint32_t key, void *data)
-{
-    PEPPER_TRACE("TODO: %s\n", __FUNCTION__);
-}
-
-PEPPER_API void *
-pepper_compositor_get_user_data(pepper_compositor_t *compositor, uint32_t key)
-{
-    PEPPER_TRACE("TODO: %s\n", __FUNCTION__);
-    return NULL;
-}
index 509da45..5a9e7a1 100644 (file)
@@ -7,18 +7,16 @@
 extern "C" {
 #endif
 
-typedef struct pepper_wayland_output_info   pepper_wayland_output_info_t;
+typedef struct pepper_wayland   pepper_wayland_t;
 
-struct pepper_wayland_output_info
-{
-    const char  *socket_name;
-};
+PEPPER_API pepper_wayland_t *
+pepper_wayland_connect(pepper_compositor_t *compositor, const char *socket_name);
 
-PEPPER_API pepper_bool_t
-pepper_wayland_init(pepper_compositor_t *compositor);
+PEPPER_API void
+pepper_wayland_destroy(pepper_wayland_t *conn);
 
-PEPPER_API const pepper_output_interface_t *
-pepper_wayland_get_output_interface();
+PEPPER_API pepper_bool_t
+pepper_wayland_output_create(pepper_wayland_t *conn, int32_t w, int32_t h);
 
 #ifdef __cplusplus
 }
index 02cad88..571b40b 100644 (file)
@@ -1,12 +1,10 @@
 #include "wayland-internal.h"
 
-#define WAYLAND_DATA_KEY    0x721dfa02
-
 static void
 handle_global(void *data, struct wl_registry *registry,
               uint32_t name, const char *interface, uint32_t version)
 {
-    wayland_connection_t *conn = data;
+    pepper_wayland_t *conn = data;
 
     if (strcmp(interface, "wl_compositor") == 0)
     {
@@ -37,7 +35,7 @@ static const struct wl_registry_listener registry_listener =
 static int
 handle_wayland_event(int fd, uint32_t mask, void *data)
 {
-    wayland_connection_t *conn = data;
+    pepper_wayland_t *conn = data;
     int count = 0;
 
     if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR))
@@ -58,80 +56,66 @@ handle_wayland_event(int fd, uint32_t mask, void *data)
     return count;
 }
 
-wayland_connection_t *
-wayland_get_connection(pepper_compositor_t *compositor, const char *socket_name)
+PEPPER_API pepper_wayland_t *
+pepper_wayland_connect(const char *socket_name, pepper_compositor_t *compositor)
 {
-    wayland_data_t          *data;
-    wayland_connection_t    *conn = NULL;
-
-    data = pepper_compositor_get_user_data(compositor, WAYLAND_DATA_KEY);
-    if (!data)
-    {
-        PEPPER_ERROR("Wayland module is not initialized. Call pepper_wayland_init() first.\n");
-        return NULL;
-    }
-
-    if (!wl_list_empty(&data->connections))
-    {
-        wayland_connection_t *c;
-        wl_list_for_each(c, &data->connections, link)
-        {
-            if (strcmp(c->socket_name, socket_name) == 0)
-            {
-                conn = c;
-                break;
-            }
-        }
-    }
+    pepper_wayland_t        *conn;
+    struct wl_display       *compositor_display;
+    struct wl_event_loop    *loop;
 
+    conn = pepper_calloc(1, sizeof(pepper_wayland_t));
     if (!conn)
-    {
-        struct wl_display       *display;
-        struct wl_event_loop    *loop;
-
-        conn = (wayland_connection_t *)pepper_calloc(1, sizeof(wayland_connection_t));
-        if (!conn)
-            return NULL;
+        return NULL;
 
-        conn->data = data;
-        conn->display = wl_display_connect(socket_name);
-        conn->fd = wl_display_get_fd(conn->display);
-        conn->socket_name = pepper_string_copy(socket_name);
+    conn->compositor = compositor;
 
-        display = pepper_compositor_get_display(compositor);
-        loop = wl_display_get_event_loop(display);
+    conn->socket_name = pepper_string_copy(socket_name);
+    conn->display = wl_display_connect(socket_name);
+    conn->fd = wl_display_get_fd(conn->display);
 
-        conn->event_source = wl_event_loop_add_fd(loop, conn->fd, WL_EVENT_READABLE,
-                                                  handle_wayland_event, conn);
+    compositor_display = pepper_compositor_get_display(compositor);
+    loop = wl_display_get_event_loop(compositor_display);
+    conn->event_source = wl_event_loop_add_fd(loop, conn->fd, WL_EVENT_READABLE,
+                                              handle_wayland_event, conn);
 
-        conn->registry = wl_display_get_registry(conn->display);
-        wl_registry_add_listener(conn->registry, &registry_listener, conn);
-        wl_display_roundtrip(conn->display);
+    wl_signal_init(&conn->destroy_signal);
 
-        wl_list_insert(&data->connections, &conn->link);
-    }
+    conn->registry = wl_display_get_registry(conn->display);
+    wl_registry_add_listener(conn->registry, &registry_listener, conn);
+    wl_display_roundtrip(conn->display);
 
     return conn;
 }
 
-PEPPER_API pepper_bool_t
-pepper_wayland_init(pepper_compositor_t *compositor)
+PEPPER_API void
+pepper_wayland_destroy(pepper_wayland_t *conn)
 {
-    wayland_data_t *data = pepper_compositor_get_user_data(compositor, WAYLAND_DATA_KEY);
+    wl_signal_emit(&conn->destroy_signal);
 
-    if (data)
-    {
-        PEPPER_ERROR("Wayland key is already used by another module.\n");
-        return PEPPER_FALSE;
-    }
+    if (conn->socket_name)
+        pepper_string_free(conn->socket_name);
+
+    if (conn->event_source)
+        wl_event_source_remove(conn->event_source);
+
+    if (conn->registry)
+        wl_registry_destroy(conn->registry);
+
+    if (conn->compositor)
+        wl_compositor_destroy(conn->compositor);
+
+    if (conn->seat)
+        wl_seat_destroy(conn->seat);
+
+    if (conn->pointer)
+        wl_pointer_destroy(conn->pointer);
 
-    data = (wayland_data_t *)pepper_calloc(1, sizeof(wayland_data_t));
-    if (!data)
-        return PEPPER_FALSE;
+    if (conn->keyboard)
+        wl_keyboard_destroy(conn->keyboard);
 
-    data->compositor = compositor;
-    wl_list_init(&data->connections);
-    pepper_compositor_set_user_data(compositor, WAYLAND_DATA_KEY, data);
+    if (conn->touch)
+        wl_touch_destroy(conn->touch);
 
-    return PEPPER_TRUE;
+    if (conn->shell)
+        wl_shell_destroy(conn->shell);
 }
index 8b71590..7f5aefc 100644 (file)
@@ -145,7 +145,7 @@ static const struct wl_touch_listener touch_listener =
 static void
 seat_handle_caps(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
 {
-    wayland_connection_t *conn = data;
+    pepper_wayland_t *conn = data;
 
     if ((caps & WL_SEAT_CAPABILITY_POINTER) && (!conn->pointer))
     {
@@ -200,38 +200,9 @@ static const struct wl_seat_listener seat_listener =
 };
 
 void
-wayland_handle_global_seat(wayland_connection_t *conn, struct wl_registry *registry,
+wayland_handle_global_seat(pepper_wayland_t *conn, struct wl_registry *registry,
                            uint32_t name, uint32_t version)
 {
     conn->seat = wl_registry_bind(registry, name, &wl_seat_interface, 1);
     wl_seat_add_listener(conn->seat, &seat_listener, conn);
 }
-
-#if 0
-PEPPER_API pepper_seat_t *
-pepper_compositor_add_wayland_seat(pepper_compositor_t *compositor,
-                                   const char *socket_name)
-{
-    wayland_connection_t    *conn;
-    pepper_seat_t           *seat;
-
-    conn = wayland_get_connection(compositor, socket_name);
-    if (!conn)
-        return NULL;
-
-    seat = pepper_seat_create(compositor);
-
-    if (conn->pointer)
-        wl_pointer_add_listener(conn->pointer, &pointer_listener, seat);
-
-    if (conn->keyboard)
-        wl_pointer_add_listener(conn->keyboard, &keyboard_listener, seat);
-
-    if (conn->touch)
-        wl_pointer_add_listener(conn->touch, &touch_listener, seat);
-
-    conn->seat = seat;
-
-    return seat;
-}
-#endif
index 6e2a66d..8a9be6c 100644 (file)
@@ -2,53 +2,45 @@
 #include <wayland-client.h>
 #include <common.h>
 
-typedef struct wayland_connection   wayland_connection_t;
-typedef struct wayland_data         wayland_data_t;
 typedef struct wayland_output       wayland_output_t;
 
-struct wayland_connection
+struct pepper_wayland
 {
-    wayland_data_t          *data;
+    pepper_compositor_t    *compositor;
 
-    char                    *socket_name;
-    struct wl_display       *display;
+    char                   *socket_name;
+    struct wl_display      *display;
     int                     fd;
 
-    struct wl_event_source  *event_source;
+    struct wl_event_source *event_source;
 
-    struct wl_registry      *registry;
-    struct wl_compositor    *compositor;
-    struct wl_seat          *seat;
-    struct wl_pointer       *pointer;
-    struct wl_keyboard      *keyboard;
-    struct wl_touch         *touch;
-    struct wl_shell         *shell;
+    struct wl_registry     *registry;
+    struct wl_compositor   *compositor;
+    struct wl_seat         *seat;
+    struct wl_pointer      *pointer;
+    struct wl_keyboard     *keyboard;
+    struct wl_touch        *touch;
+    struct wl_shell        *shell;
 
-    struct wl_list          link;
-};
-
-struct wayland_data
-{
-    pepper_compositor_t *compositor;
-    struct wl_list      connections;
+    struct wl_signal        destroy_signal;
 };
 
 struct wayland_output
 {
-    wayland_connection_t    *connection;
-    pepper_output_t         *base;
+    pepper_wayland_t           *conn;
 
-    int32_t                 w, h;
-    int32_t                 subpixel;
-    int32_t                 scale;
+    struct wl_signal            destroy_signal;
+    struct wl_signal            mode_change_signal;
 
-    struct wl_surface       *surface;
-    struct wl_shell_surface *shell_surface;
-};
+    struct wl_listener          conn_destroy_listener;
+
+    int32_t                     w, h;
+    int32_t                     subpixel;
 
-wayland_connection_t *
-wayland_get_connection(pepper_compositor_t *compositor, const char *socket_name);
+    struct wl_surface          *surface;
+    struct wl_shell_surface    *shell_surface;
+};
 
 void
-wayland_handle_global_seat(wayland_connection_t *conn, struct wl_registry *registry,
+wayland_handle_global_seat(pepper_wayland_t *conn, struct wl_registry *registry,
                            uint32_t name, uint32_t version);
index 721c14b..0b42caa 100644 (file)
@@ -11,17 +11,17 @@ shell_surface_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t
 
 static void
 shell_surface_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t edges,
-                        int32_t width, int32_t height)
+                        int32_t w, int32_t h)
 {
     wayland_output_t *output = data;
 
     PEPPER_IGNORE(shell_surface);
     PEPPER_IGNORE(edges);
 
-    output->w = width;
-    output->h = height;
+    output->w = w;
+    output->h = h;
 
-    pepper_output_update_mode(output->base);
+    wl_signal_emit(&output->mode_change_signal, NULL);
 }
 
 static void
@@ -36,48 +36,33 @@ static const struct wl_shell_surface_listener shell_surface_listener =
     shell_surface_popup_done,
 };
 
-static void *
-wayland_output_create(pepper_compositor_t *compositor, int32_t w, int32_t h, void *data)
+static void
+wayland_output_destroy(void *o)
 {
-    pepper_wayland_output_info_t    *info = data;
-    wayland_connection_t            *conn;
-    wayland_output_t                *output;
-
-    conn = wayland_get_connection(compositor, info->socket_name);
-    if (!conn)
-        return NULL;
-
-    output = pepper_calloc(1, sizeof(wayland_output_t));
-    if (!output)
-        return NULL;
-
-    output->connection = conn;
-
-    output->w = w;
-    output->h = h;
+    wayland_output_t *output = o;
 
-    /* Hard-Coded: subpixel order to horizontal RGB. */
-    output->subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
+    wl_signal_emit(&output->destroy_signal, output);
 
-    /* Hard-Coded: scale value to 1. */
-    output->scale = 1;
+    wl_list_remove(&conn_destroy_listener.link);
 
-    output->surface = wl_compositor_create_surface(conn->compositor);
-    output->shell_surface = wl_shell_get_shell_surface(conn->shell, output->surface);
-    wl_shell_surface_add_listener(output->shell_surface, &shell_surface_listener, output);
+    wl_surface_destroy(output->surface);
+    wl_shell_surface_destroy(output->shell_surface);
 
-    return output;
+    pepper_free(output);
 }
 
 static void
-wayland_output_destroy(void *o)
+wayland_output_add_destroy_listener(void *o, struct wl_listener *listener)
 {
     wayland_output_t *output = o;
+    wl_signal_add(&output->destroy_signal, listener);
+}
 
-    wl_surface_destroy(output->surface);
-    wl_shell_surface_destroy(output->shell_surface);
-
-    pepper_free(output);
+static void
+wayland_output_add_mode_change_listener(void *o, struct wl_listener *listener)
+{
+    wayland_output_t *output = o;
+    wl_signal_add(&output->mode_change_signal, listener);
 }
 
 static int32_t
@@ -101,13 +86,6 @@ wayland_output_get_model_name(void *o)
     return model_name;
 }
 
-static int32_t
-wayland_output_get_scale(void *o)
-{
-    wayland_output_t *output = o;
-    return output->scale;
-}
-
 static int
 wayland_output_get_mode_count(void *o)
 {
@@ -126,25 +104,78 @@ wayland_output_get_mode(void *o, int index, pepper_output_mode_t *mode)
         return;
 
     mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
-    mode->width = output->w;
-    mode->height = output->h;
+    mode->w = output->w;
+    mode->h = output->h;
     mode->refresh = 60000;
 }
 
+static pepper_bool_t
+wayland_output_set_mode(void *o, const pepper_output_mode_t *mode)
+{
+    wayland_output_t *output = o;
+
+    if (mode->w <= 0 || mode->h <= 0)
+        return PEPPER_FALSE;
+
+    if (mode->refresh != 60000)
+        return PEPPER_FALSE;
+
+    if (output->w != w || output->h != h)
+    {
+        output->w = w;
+        output->h = h;
+
+        /* TODO: Handle resize here. */
+
+        wl_signal_emit(&output->mode_change_signal, output);
+    }
+
+    return PEPPER_TRUE;
+}
+
 static const pepper_output_interface_t wayland_output_interface =
 {
-    wayland_output_create,
     wayland_output_destroy,
+    wayland_output_add_destroy_listener,
+    wayland_output_add_mode_change_listener,
+
     wayland_output_get_subpixel_order,
     wayland_output_get_maker_name,
     wayland_output_get_model_name,
-    wayland_output_get_scale,
+
     wayland_output_get_mode_count,
     wayland_output_get_mode,
+    wayland_output_set_mode,
 };
 
-PEPPER_API const pepper_output_interface_t *
-pepper_wayland_get_output_interface()
+PEPPER_API pepper_bool_t
+pepper_wayland_output_create(pepper_wayland_t *conn, int32_t w, int32_t h)
 {
-    return &wayland_output_interface;
+    wayland_output_t *output;
+
+    output = pepper_calloc(1, sizeof(wayland_output_t));
+    if (!output)
+        return PEPPER_FALSE;
+
+    output->conn = conn;
+
+    output->w = w;
+    output->h = h;
+
+    /* Hard-Coded: subpixel order to horizontal RGB. */
+    output->subpixel = WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
+
+    /* Create wayland resources. */
+    output->surface = wl_compositor_create_surface(conn->compositor);
+    output->shell_surface = wl_shell_get_shell_surface(conn->shell, output->surface);
+    wl_shell_surface_add_listener(output->shell_surface, &shell_surface_listener, output);
+
+    /* Add compositor base class output object for this output. */
+    if (!pepper_compositor_add_output(conn->compositor, &wayland_output_interface, output))
+    {
+        wayland_output_destroy(output);
+        return PEPPER_FALSE;
+    }
+
+    return PEPPER_TRUE;
 }
index 781e6aa..44ffbfa 100644 (file)
@@ -1,6 +1,49 @@
 #include "pepper-internal.h"
 
 static void
+output_update_mode(pepper_output_t *output)
+{
+    int                 i;
+    struct wl_resource  *resource;
+
+    output->current_mode = NULL;
+
+    if (output->modes)
+        pepper_free(output->modes);
+
+    output->mode_count = output->interface->get_mode_count(output->data);
+    PEPPER_ASSERT(output->mode_count > 0);
+
+    output->modes = pepper_calloc(output->mode_count, sizeof(pepper_output_mode_t));
+    if (!output->modes)
+    {
+        pepper_output_destroy(output);
+        return;
+    }
+
+    for (i = 0; i < output->mode_count; i++)
+    {
+        output->interface->get_mode(output->data, i, &output->modes[i]);
+
+        if (output->modes[i].flags & WL_OUTPUT_MODE_CURRENT)
+            output->current_mode = &output->modes[i];
+
+    }
+
+    wl_resource_for_each(resource, &output->resources)
+    {
+        for (i = 0; i < output->mode_count; i++)
+        {
+            wl_output_send_mode(resource, output->modes[i].flags,
+                                output->modes[i].w, output->modes[i].h,
+                                output->modes[i].refresh);
+        }
+
+        wl_output_send_done(resource);
+    }
+}
+
+static void
 output_send_geometry(pepper_output_t *output)
 {
     struct wl_resource *resource;
@@ -52,23 +95,38 @@ output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
     for (i = 0; i < output->mode_count; i++)
     {
         wl_output_send_mode(resource, output->modes[i].flags,
-                            output->modes[i].width, output->modes[i].height,
+                            output->modes[i].w, output->modes[i].h,
                             output->modes[i].refresh);
     }
 
     wl_output_send_done(resource);
 }
 
-PEPPER_API pepper_output_t *
-pepper_output_create(pepper_compositor_t *compositor,
-                     int32_t x, int32_t y, int32_t w, int32_t h, int32_t transform, int32_t scale,
-                     const pepper_output_interface_t *interface, void *data)
+static void
+handle_output_data_destroy(struct wl_listener *listener, void *data)
+{
+    pepper_output_t *output = wl_container_of(listener, output, data_destroy_listener);
+    output->data = NULL;
+    output->interface = NULL;
+    pepper_output_destroy(output);
+}
+
+static void
+handle_mode_change(struct wl_listener *listener, void *data)
+{
+    pepper_output_t *output = wl_container_of(listener, output, data_destroy_listener);
+    output_update_mode(output);
+}
+
+PEPPER_API pepper_bool_t
+pepper_compositor_add_output(pepper_compositor_t *compositor,
+                             pepper_output_interface_t *interface, void *data)
 {
     pepper_output_t     *output;
 
     output = pepper_calloc(1, sizeof(pepper_output_t));
     if (!output)
-        return NULL;
+        return PEPPER_FALSE;
 
     wl_list_init(&output->resources);
     output->compositor = compositor;
@@ -77,27 +135,40 @@ pepper_output_create(pepper_compositor_t *compositor,
     output->global = wl_global_create(compositor->display, &wl_output_interface, 2, output,
                                       output_bind);
 
-    /* Create backend-side object. */
-    output->interface = *interface;
-    output->data = interface->create(compositor, w, h, data);
-
-    /* Initialize output geometry. */
-    output->geometry.x = x;
-    output->geometry.y = y;
-    output->geometry.w = w;
-    output->geometry.h = h;
-    output->geometry.transform;
-    output->geometry.subpixel = interface->get_subpixel_order(output->data);
-    output->geometry.maker = interface->get_maker_name(output->data);
-    output->geometry.model = interface->get_model_name(output->data);
+    if (!output->global)
+    {
+        pepper_free(output);
+        return PEPPER_FALSE;
+    }
 
-    /* Initialize output scale. */
-    output->scale = interface->get_scale(output->data);
+    /* Create backend-side object. */
+    output->interface = interface;
+    output->data = data;
 
     /* Initialize output modes. */
-    pepper_output_update_mode(output);
+    output_update_mode(output);
+
+    /* TODO: Set scale value according to the config or something. */
+    output->scale = 1;
 
-    return output;
+    /* Initialize geometry. TODO: Calculate position and size of the output. */
+    output->geometry.transform;
+    output->geometry.subpixel = interface->get_subpixel_order(data);
+    output->geometry.maker = interface->get_maker_name(data);
+    output->geometry.model = interface->get_model_name(data);
+    output->geometry.x = 0;
+    output->geometry.y = 0;
+    output->geometry.w = output->current_mode->w;
+    output->geometry.h = output->current_mode->h;
+
+    /* Install listeners. */
+    output->data_destroy_listener.notify = handle_output_data_destroy;
+    interface->add_destroy_listener(data, &output->data_destroy_listener);
+
+    output->mode_change_listener.notify = handle_mode_change;
+    interface->add_mode_change_listener(data, &output->mode_change_listener);
+
+    return PEPPER_TRUE;
 }
 
 PEPPER_API pepper_compositor_t *
@@ -109,7 +180,15 @@ pepper_output_get_compositor(pepper_output_t *output)
 PEPPER_API void
 pepper_output_destroy(pepper_output_t *output)
 {
-    output->interface.destroy(output->data);
+    if (output->interface && output->data)
+        output->interface->destroy(output->data);
+
+    wl_global_destroy(output->global);
+    wl_list_remove(&output->data_destroy_listener.link);
+    wl_list_remove(&output->mode_change_listener.link);
+
+    /* TODO: Handle removal of this output. e.g. Re-position outputs. */
+
     pepper_free(output);
 }
 
@@ -157,49 +236,5 @@ pepper_output_get_mode(pepper_output_t *output, int index)
 PEPPER_API pepper_bool_t
 pepper_output_set_mode(pepper_output_t *output, const pepper_output_mode_t *mode)
 {
-    PEPPER_TRACE("TODO: %s\n", __FUNCTION__);
-    return PEPPER_FALSE;
-}
-
-PEPPER_API void
-pepper_output_update_mode(pepper_output_t *output)
-{
-    int                 i;
-    struct wl_resource  *resource;
-
-    output->current_mode = NULL;
-
-    if (output->modes)
-        pepper_free(output->modes);
-
-    output->mode_count = output->interface.get_mode_count(output->data);
-    PEPPER_ASSERT(output->mode_count > 0);
-
-    output->modes = pepper_calloc(output->mode_count, sizeof(pepper_output_mode_t));
-    if (!output->modes)
-    {
-        pepper_output_destroy(output);
-        return;
-    }
-
-    for (i = 0; i < output->mode_count; i++)
-    {
-        output->interface.get_mode(output->data, i, &output->modes[i]);
-
-        if (output->modes[i].flags & WL_OUTPUT_MODE_CURRENT)
-            output->current_mode = &output->modes[i];
-
-    }
-
-    wl_resource_for_each(resource, &output->resources)
-    {
-        for (i = 0; i < output->mode_count; i++)
-        {
-            wl_output_send_mode(resource, output->modes[i].flags,
-                                output->modes[i].width, output->modes[i].height,
-                                output->modes[i].refresh);
-        }
-
-        wl_output_send_done(resource);
-    }
+    return output->interface->set_mode(output->data, mode);
 }
index ead9751..67f59a7 100644 (file)
@@ -35,8 +35,12 @@ struct pepper_output
     pepper_output_mode_t       *current_mode;
 
     /* Backend-specific variables. */
-    pepper_output_interface_t   interface;
+    pepper_output_interface_t  *interface;
     void                       *data;
+
+    /* Listeners for backend-side events. */
+    struct wl_listener          data_destroy_listener;
+    struct wl_listener          mode_change_listener;
 };
 
 struct pepper_buffer
index dca417f..6ddbecc 100644 (file)
@@ -25,23 +25,13 @@ typedef struct pepper_output_mode       pepper_output_mode_t;
 typedef struct pepper_output            pepper_output_t;
 typedef struct pepper_output_interface  pepper_output_interface_t;
 
-/* Compositor functions. */
-PEPPER_API pepper_compositor_t *
-pepper_compositor_create(const char *socket_name);
-
-PEPPER_API void
-pepper_compositor_destroy(pepper_compositor_t *compositor);
-
-PEPPER_API struct wl_display *
-pepper_compositor_get_display(pepper_compositor_t *compositor);
-
-PEPPER_API void
-pepper_compositor_set_user_data(pepper_compositor_t *compositor, uint32_t key, void *data);
-
-PEPPER_API void *
-pepper_compositor_get_user_data(pepper_compositor_t *compositor, uint32_t key);
+typedef enum
+{
+    PEPPER_RENDER_METHOD_NONE,
+    PEPPER_RENDER_METHOD_PIXMAN,
+    PEPPER_RENDER_METHOD_NATIVE,
+} pepper_render_method_t;
 
-/* Output. */
 struct pepper_output_geometry
 {
     int32_t     x;
@@ -57,28 +47,40 @@ struct pepper_output_geometry
 struct pepper_output_mode
 {
     uint32_t    flags;
-    int32_t     width;
-    int32_t     height;
+    int32_t     w, h;
     int32_t     refresh;
 };
 
 struct pepper_output_interface
 {
-    void *          (*create)(pepper_compositor_t *compositor, int32_t w, int32_t h, void *data);
     void            (*destroy)(void *output);
 
+    void            (*add_destroy_listener)(void *output, struct wl_listener *listener);
+    void            (*add_mode_change_listener)(void *output, struct wl_listener *listener);
+
     int32_t         (*get_subpixel_order)(void *output);
     const char *    (*get_maker_name)(void *output);
     const char *    (*get_model_name)(void *output);
-    int32_t         (*get_scale)(void *output);
+
     int             (*get_mode_count)(void *output);
     void            (*get_mode)(void *output, int index, pepper_output_mode_t *mode);
+    pepper_bool_t   (*set_mode)(void *output, const pepper_output_mode_t *mode);
 };
 
-PEPPER_API pepper_output_t *
-pepper_output_create(pepper_compositor_t *compositor,
-                     int32_t x, int32_t y, int32_t w, int32_t h, int32_t transform, int32_t scale,
-                     const pepper_output_interface_t *interface, void *data);
+/* Compositor functions. */
+PEPPER_API pepper_compositor_t *
+pepper_compositor_create(const char *socket_name);
+
+PEPPER_API void
+pepper_compositor_destroy(pepper_compositor_t *compositor);
+
+PEPPER_API struct wl_display *
+pepper_compositor_get_display(pepper_compositor_t *compositor);
+
+PEPPER_API pepper_bool_t
+pepper_compositor_add_output(pepper_compositor_t *compositor,
+                             pepper_output_interface_t *interface,
+                             void *data);
 
 PEPPER_API pepper_compositor_t *
 pepper_output_get_compositor(pepper_output_t *output);
@@ -104,9 +106,6 @@ pepper_output_get_mode(pepper_output_t *output, int index);
 PEPPER_API pepper_bool_t
 pepper_output_set_mode(pepper_output_t *output, const pepper_output_mode_t *mode);
 
-PEPPER_API void
-pepper_output_update_mode(pepper_output_t *output);
-
 /* Input. */
 
 #ifdef __cplusplus