[PATCH weston 3/6] ivi-shell: implementation of ivi-shell protocol
Nobuhiko Tanibata
NOBUHIKO_TANIBATA at xddp.denso.co.jp
Tue Sep 3 18:06:54 PDT 2013
Implementing layer management for In-Vehicle Infotainment use cases. The
ivi-shell protocol allows us to manage a Scene which contains screens,
layers, and surfaces. Additionally, it can control attributes of layers
and surfaces, e.g. position, visibility, Opacity, and so on. The concept
of layer management is well overviewed here,
http://projects.genivi.org/ivi-layer-management/node/13
Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp>
---
src/ivi-shell.c | 2948 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 2948 insertions(+), 0 deletions(-)
create mode 100644 src/ivi-shell.c
diff --git a/src/ivi-shell.c b/src/ivi-shell.c
new file mode 100644
index 0000000..2c73401
--- /dev/null
+++ b/src/ivi-shell.c
@@ -0,0 +1,2948 @@
+/*
+ * Copyright (C) 2013 DENSO CORPORATION
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <linux/input.h>
+#include <cairo.h>
+
+#include "compositor.h"
+#include "ivi-shell-server-protocol.h"
+
+enum {
+ PROP_EVENT_OPACITY = 0x00000001,
+ PROP_EVENT_DIMENSION = 0x00000002,
+ PROP_EVENT_POSITION = 0x00000004,
+ PROP_EVENT_SRC_REGION = 0x00000008,
+ PROP_EVENT_DST_REGION = 0x00000010,
+ PROP_EVENT_ORIENTATION = 0x00000020,
+ PROP_EVENT_VISIBILITY = 0x00000040,
+ PROP_EVENT_PIXELFORMAT = 0x00000080,
+ PROP_EVENT_ADD = 0x00000100,
+ PROP_EVENT_ALL = 0xFFFFFFFF
+};
+
+struct ivi_shell;
+
+struct ivi_properties {
+ wl_fixed_t opacity;
+ int32_t src_x;
+ int32_t src_y;
+ int32_t src_width;
+ int32_t src_height;
+ int32_t dest_x;
+ int32_t dest_y;
+ int32_t dest_width;
+ int32_t dest_height;
+ int32_t orientation;
+ uint32_t visibility;
+};
+
+struct ivi_client_layer;
+struct ivi_client_screen;
+
+struct link_layer {
+ struct ivi_client_layer *layer;
+ struct wl_list link;
+};
+
+struct link_screen {
+ struct ivi_client_screen *screen;
+ struct wl_list link;
+};
+
+struct ivi_client_surface {
+ struct wl_list link;
+ struct wl_list list_resource;
+ struct wl_list list_layer;
+ struct wl_client *client;
+ uint32_t id_surface;
+ struct ivi_shell *shell;
+ uint32_t update_count;
+
+ struct weston_surface *surface;
+ struct wl_listener surface_destroy_listener;
+ struct weston_transform surface_rotation;
+ struct weston_transform layer_rotation;
+ struct weston_transform surface_pos;
+ struct weston_transform layer_pos;
+ struct weston_transform scaling;
+ struct ivi_properties prop;
+ int32_t pixelformat;
+ uint32_t event_mask;
+
+ struct {
+ struct ivi_properties prop;
+ struct wl_list link;
+ } pending;
+
+ struct {
+ struct wl_list link;
+ struct wl_list list_layer;
+ } order;
+};
+
+struct ivisurface_resource {
+ struct wl_listener destroy_listener;
+ struct wl_resource *res_surf;
+ struct wl_resource *res_ctrl_surf;
+ struct wl_client *client;
+ struct ivi_client_surface *ivisurf;
+ struct wl_list link;
+};
+
+struct ivi_client_layer {
+ struct wl_list link;
+ struct wl_list list_resource;
+ struct wl_list list_screen;
+ struct ivi_shell *shell;
+ struct weston_layer el;
+ uint32_t id_layer;
+
+ struct ivi_properties prop;
+ uint32_t event_mask;
+
+ struct {
+ struct wl_list list_surface;
+ struct wl_list link;
+ struct ivi_properties prop;
+ } pending;
+
+ struct {
+ struct wl_list list_surface;
+ struct wl_list link;
+ } order;
+};
+
+struct ivilayer_resource {
+ struct wl_listener destroy_listener;
+ struct wl_resource *res_layer;
+ struct wl_resource *res_ctrl_layer;
+ struct wl_client *client;
+ struct ivi_client_layer *ivilayer;
+ struct wl_list link;
+};
+
+struct ivi_client_screen {
+ struct wl_list link;
+ struct ivi_shell *shell;
+ struct wl_list list_resource;
+
+ uint32_t id_screen;
+ struct weston_output *output;
+ struct wl_list list_layer;
+ uint32_t event_mask;
+
+ struct {
+ struct wl_list list_layer;
+ struct wl_list link;
+ } pending;
+
+ struct {
+ struct wl_list list_layer;
+ struct wl_list link;
+ } order;
+};
+
+struct iviscrn_resource {
+ struct wl_listener destroy_listener;
+ struct wl_resource *res_ctrl_scrn;
+ struct wl_client *client;
+ struct ivi_client_screen *iviscrn;
+ struct wl_list link;
+ uint32_t id_output;
+};
+
+struct ivi_client_ctrl {
+ struct wl_resource *resource;
+ uint32_t id;
+ struct wl_client *client;
+ struct wl_list link;
+ struct ivi_shell *shell;
+};
+
+struct link_shell_weston_surface
+{
+ struct wl_resource resource;
+ struct wl_listener destroy_listener;
+ struct weston_surface *surface;
+ struct wl_list link;
+};
+
+struct ping_timer {
+ struct wl_event_source *source;
+ uint32_t serial;
+};
+
+struct shell_surface {
+ struct wl_resource *resource;
+
+ struct weston_surface *surface;
+ struct wl_listener surface_destroy_listener;
+
+ struct ivi_shell *shell;
+ struct ping_timer *ping_timer;
+
+ char *title, *class;
+ int32_t width;
+ int32_t height;
+ pid_t pid;
+ struct wl_list link;
+
+ const struct weston_shell_client *client;
+ struct weston_output *output;
+};
+
+struct ivi_shell {
+ struct wl_resource resource;
+
+ struct wl_listener destroy_listener;
+
+ struct weston_compositor *compositor;
+
+ struct weston_surface *surface;
+
+ struct weston_process process;
+
+ struct weston_seat *seat;
+
+ struct wl_list list_surface;
+ struct wl_list list_layer;
+ struct wl_list list_screen;
+
+ struct wl_list list_weston_surface;
+
+ struct wl_list list_controller_client;
+
+ struct {
+ struct weston_process process;
+ struct wl_client *client;
+ struct wl_resource *desktop_shell;
+
+ unsigned deathcount;
+ uint32_t deathstamp;
+ } child;
+
+ int state;
+ int previous_state;
+};
+
+#ifdef _DEBUG
+static void
+log_list_length_in_ivi_client_surface(struct ivi_client_surface *ivisurf)
+{
+ weston_log(" LENGTH:%03d of list_resource in ivi_client_surface\n",
+ wl_list_length(&ivisurf->list_resource));
+ weston_log(" LENGTH:%03d of list_layer in ivi_client_surface\n",
+ wl_list_length(&ivisurf->list_layer));
+}
+
+static void
+log_list_length_in_ivi_client_layer(struct ivi_client_layer *ivilayer)
+{
+ struct ivi_client_surface *ivisurf;
+ weston_log(" LENGTH:%03d of list_resource in ivi_client_layer\n",
+ wl_list_length(&ivilayer->list_resource));
+ weston_log(" LENGTH:%03d of pending.list_surface in ivi_client_layer\n",
+ wl_list_length(&ivilayer->pending.list_surface));
+ wl_list_for_each(ivisurf, &ivilayer->pending.list_surface, pending.link) {
+ log_list_length_in_ivi_client_surface(ivisurf);
+ }
+ weston_log(" LENGTH:%03d of order.list_surface in ivi_client_layer\n",
+ wl_list_length(&ivilayer->order.list_surface));
+ wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) {
+ log_list_length_in_ivi_client_surface(ivisurf);
+ }
+ weston_log(" LENGTH:%03d of list_screen in ivi_client_layer\n",
+ wl_list_length(&ivilayer->list_screen));
+}
+
+static void
+log_list_length_in_ivi_client_screen(struct ivi_client_screen *iviscrn)
+{
+ struct ivi_client_layer *ivilayer;
+ weston_log(" LENGTH:%03d of list_resource in ivi_client_screen\n",
+ wl_list_length(&iviscrn->list_resource));
+ weston_log(" LENGTH:%03d of list_layer in ivi_client_screen\n",
+ wl_list_length(&iviscrn->list_layer));
+ wl_list_for_each(ivilayer, &iviscrn->list_layer, link) {
+ log_list_length_in_ivi_client_layer(ivilayer);
+ }
+ weston_log(" LENGTH:%03d of pending.list_layer in ivi_client_screen\n",
+ wl_list_length(&iviscrn->pending.list_layer));
+ wl_list_for_each(ivilayer, &iviscrn->pending.list_layer, pending.link) {
+ log_list_length_in_ivi_client_layer(ivilayer);
+ }
+ weston_log(" LENGTH:%03d of order.list_layer in ivi_client_screen\n",
+ wl_list_length(&iviscrn->order.list_layer));
+ wl_list_for_each(ivilayer, &iviscrn->order.list_layer, order.link) {
+ log_list_length_in_ivi_client_layer(ivilayer);
+ }
+}
+
+static void
+log_list_length_in_ivi_shell(struct ivi_shell *shell)
+{
+ struct ivi_client_surface *ivisurf;
+ struct ivi_client_layer *ivilayer;
+ struct ivi_client_screen *clscrn;
+
+ weston_log("\n---- LOG LENGTH OF ALL LISTS ----\n");
+ weston_log("LENGTH:%03d of list_surface in ivi_shell\n",
+ wl_list_length(&shell->list_surface));
+ wl_list_for_each(ivisurf, &shell->list_surface, link) {
+ log_list_length_in_ivi_client_surface(ivisurf);
+ }
+ weston_log("LENGTH:%03d of list_layer in ivi_shell\n",
+ wl_list_length(&shell->list_layer));
+ wl_list_for_each(ivilayer, &shell->list_layer, link) {
+ log_list_length_in_ivi_client_layer(ivilayer);
+ }
+ weston_log("LENGTH:%03d of list_screen in ivi_shell\n",
+ wl_list_length(&shell->list_screen));
+ wl_list_for_each(clscrn, &shell->list_screen, link) {
+ log_list_length_in_ivi_client_screen(clscrn);
+ }
+ weston_log("LENGTH:%03d of list_weston_surface in ivi_shell\n",
+ wl_list_length(&shell->list_weston_surface));
+ weston_log("LENGTH:%03d of list_controller_client in ivi_shell\n",
+ wl_list_length(&shell->list_controller_client));
+ weston_log("\n---- LOG LENGTH OF ALL LISTS ----\n\n");
+}
+#endif
+
+static void
+send_naivesurface(struct wl_resource *resource,
+ struct shell_surface *shsurf,
+ const char *title)
+{
+ struct ivi_shell *shell = shsurf->shell;
+ struct ivi_client_ctrl *controller = NULL;
+ uint32_t id_native = 0;
+ struct weston_buffer_reference *bufref = NULL;
+ int32_t width = 0;
+ int32_t height = 0;
+
+ if (shsurf->surface != NULL) {
+ id_native = (0x000FFFFF & shsurf->surface->resource->object.id) |
+ ((0xFFF00000 & shsurf->pid) << 20);
+ bufref = &shsurf->surface->buffer_ref;
+
+ if (bufref->buffer != NULL) {
+ width = bufref->buffer->width;
+ height = bufref->buffer->height;
+ }
+ }
+
+ wl_list_for_each(controller, &shell->list_controller_client, link) {
+ ivi_controller_send_nativesurface(controller->resource, id_native,
+ shsurf->pid,
+ title, width, height);
+ }
+}
+
+static void
+add_ordersurface_to_layer(struct ivi_client_surface *ivisurf,
+ struct ivi_client_layer *ivilayer)
+{
+ struct link_layer *link_layer = NULL;
+
+ link_layer = malloc(sizeof *link_layer);
+ if (link_layer == NULL) {
+ weston_log("memory insufficient for link_layer\n");
+ return;
+ }
+
+ link_layer->layer = ivilayer;
+ wl_list_init(&link_layer->link);
+ wl_list_insert(&ivisurf->list_layer, &link_layer->link);
+}
+
+static void
+remove_ordersurface_from_layer(struct ivi_client_surface *ivisurf)
+{
+ struct link_layer *link_layer = NULL;
+ struct link_layer *next = NULL;
+
+ wl_list_for_each_safe(link_layer, next, &ivisurf->list_layer, link) {
+ wl_list_remove(&link_layer->link);
+ free(link_layer);
+ }
+ wl_list_init(&ivisurf->list_layer);
+}
+
+static void
+add_orderlayer_to_screen(struct ivi_client_layer *ivilayer,
+ struct ivi_client_screen *iviscreen)
+{
+ struct link_screen *link_scrn = NULL;
+
+ link_scrn = malloc(sizeof *link_scrn);
+ if (link_scrn == NULL) {
+ weston_log("memory insufficient for link_screen\n");
+ return;
+ }
+
+ link_scrn->screen = iviscreen;
+ wl_list_init(&link_scrn->link);
+ wl_list_insert(&ivilayer->list_screen, &link_scrn->link);
+}
+
+static void
+remove_orderlayer_from_screen(struct ivi_client_layer *ivilayer)
+{
+ struct link_screen *link_scrn = NULL;
+ struct link_screen *next = NULL;
+
+ wl_list_for_each_safe(link_scrn, next, &ivilayer->list_screen, link) {
+ wl_list_remove(&link_scrn->link);
+ free(link_scrn);
+ }
+ wl_list_init(&ivilayer->list_screen);
+}
+
+static struct weston_surface*
+get_weston_surface_from_id(struct ivi_shell *shell,
+ struct wl_client *client, uint32_t id_native)
+{
+ struct link_shell_weston_surface *lsurf;
+ struct weston_surface *ret = NULL;
+ struct wl_client *client_es = NULL;
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+ pid_t pid_es;
+ uid_t uid_es;
+ gid_t gid_es;
+ wl_client_get_credentials(client, &pid, &uid, &gid);
+
+ wl_list_for_each(lsurf, &shell->list_weston_surface, link) {
+ client_es = wl_resource_get_client(lsurf->surface->resource);
+ wl_client_get_credentials(client_es, &pid_es, &uid_es, &gid_es);
+
+ if (lsurf->surface->resource->object.id == id_native) {
+ ret = lsurf->surface;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static void
+destroy_ivisurface_resource(struct ivisurface_resource *ivires)
+{
+ if (ivires->res_surf != NULL) {
+ wl_resource_destroy(ivires->res_surf);
+ ivires->res_surf = NULL;
+ }
+ if (ivires->res_ctrl_surf != NULL) {
+ wl_resource_destroy(ivires->res_ctrl_surf);
+ ivires->res_ctrl_surf = NULL;
+ }
+
+ wl_list_remove(&ivires->link);
+ free(ivires);
+}
+
+static void
+destroy_listener_ivisurface_resource(struct wl_listener *listener, void *data)
+{
+ struct ivisurface_resource *ivires =
+ container_of(listener, struct ivisurface_resource, destroy_listener);
+
+ destroy_ivisurface_resource(ivires);
+}
+
+static void
+destroy_ivilayer_resource(struct ivilayer_resource *ivires)
+{
+ if (ivires->res_layer != NULL) {
+ wl_resource_destroy(ivires->res_layer);
+ ivires->res_layer = NULL;
+ }
+ if (ivires->res_ctrl_layer != NULL) {
+ wl_resource_destroy(ivires->res_ctrl_layer);
+ ivires->res_ctrl_layer = NULL;
+ }
+
+ wl_list_remove(&ivires->link);
+ free(ivires);
+}
+
+static void
+destroy_listener_ivilayer_resource(struct wl_listener *listener, void *data)
+{
+ struct ivilayer_resource *ivires =
+ container_of(listener, struct ivilayer_resource, destroy_listener);
+
+ destroy_ivilayer_resource(ivires);
+}
+
+static void
+destroy_listener_iviscreen_resource(struct wl_listener *listener, void *data)
+{
+ struct iviscrn_resource *ivires =
+ container_of(listener, struct iviscrn_resource, destroy_listener);
+
+ wl_list_remove(&ivires->link);
+ free(ivires);
+}
+
+static void
+unbind_resource_controller(struct wl_resource *resource)
+{
+ struct ivi_client_ctrl *controller = resource->data;
+
+ wl_list_remove(&controller->link);
+
+ free(controller);
+}
+
+static struct ivi_client_surface*
+get_surface(struct wl_list *list_surf, uint32_t id_surface)
+{
+ struct ivi_client_surface *ivisurf;
+ wl_list_for_each(ivisurf, list_surf, link) {
+ if (ivisurf->id_surface == id_surface) {
+ return ivisurf;
+ }
+ }
+
+ return NULL;
+}
+
+static struct ivi_client_layer*
+get_layer(struct wl_list *list_layer, uint32_t id_layer)
+{
+ struct ivi_client_layer *ivilayer;
+ wl_list_for_each(ivilayer, list_layer, link) {
+ if (ivilayer->id_layer == id_layer) {
+ return ivilayer;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+init_properties(struct ivi_properties *prop, int32_t width, int32_t height)
+{
+ memset(prop, 0, sizeof *prop);
+ prop->opacity = wl_fixed_from_double(1.0);
+ prop->src_width = width;
+ prop->src_height = height;
+ prop->dest_width = width;
+ prop->dest_height = height;
+}
+
+static const
+struct ivi_surface_interface surface_implementation;
+static const
+struct ivi_controller_surface_interface controller_surface_implementation;
+static const
+struct ivi_controller_layer_interface controller_layer_implementation;
+static const
+struct ivi_controller_screen_interface controller_screen_implementation;
+static const
+struct ivi_controller_interface controller_implementation;
+
+static void
+controller_surface_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivisurface_resource *ivires = resource->data;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_destroy: client=0x%08x, resource=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource);
+#endif
+
+ if (ivires->res_ctrl_surf != NULL) {
+ wl_resource_destroy(ivires->res_ctrl_surf);
+ ivires->res_ctrl_surf = NULL;
+ }
+}
+
+static void
+controller_layer_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivilayer_resource *ivires = resource->data;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_destroy: client=0x%08x, resource=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource);
+#endif
+
+ if (ivires->res_ctrl_layer != NULL) {
+ wl_resource_destroy(ivires->res_ctrl_layer);
+ ivires->res_ctrl_layer = NULL;
+ }
+}
+
+static struct ivisurface_resource*
+create_surfaceresource(struct ivi_client_surface *ivisurf,
+ struct wl_client *client,
+ struct wl_signal *signal_destroy)
+{
+ struct ivisurface_resource *ivires;
+
+ ivires = calloc(1, sizeof *ivires);
+ if (ivires == NULL) {
+ weston_log("no memory to allocate ivisurface_resource\n");
+ return NULL;
+ }
+
+ ivires->client = client;
+ ivires->ivisurf = ivisurf;
+
+ ivires->res_surf =
+ wl_resource_create(client, &ivi_surface_interface, 1, 0);
+ if (ivires->res_surf == NULL) {
+ weston_log("couldn't new surface object");
+ free(ivires);
+ return NULL;
+ }
+ wl_resource_set_implementation(ivires->res_surf,
+ &surface_implementation,
+ ivires, NULL);
+
+ ivires->res_ctrl_surf =
+ wl_resource_create(client, &ivi_controller_surface_interface, 1, 0);
+ if (ivires->res_ctrl_surf == NULL) {
+ weston_log("couldn't new surface controller object");
+ free(ivires);
+ return NULL;
+ }
+ wl_resource_set_implementation(ivires->res_ctrl_surf,
+ &controller_surface_implementation,
+ ivires, NULL);
+
+ wl_list_insert(&ivisurf->list_resource, &ivires->link);
+
+ ivires->destroy_listener.notify = destroy_listener_ivisurface_resource;
+ wl_signal_add(signal_destroy, &ivires->destroy_listener);
+
+ return ivires;
+}
+
+static void
+layer_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivilayer_resource *ivires_client = resource->data;
+ struct ivi_client_layer *ivilayer = ivires_client->ivilayer;
+ struct ivilayer_resource *ivires = NULL;
+ pid_t pid_cl;
+ uid_t uid_cl;
+ gid_t gid_cl;
+ pid_t pid_res;
+ uid_t uid_res;
+ gid_t gid_res;
+
+#ifdef _DEBUG
+ weston_log("layer_destroy: client=0x%08x, resource=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource);
+#endif
+
+ wl_client_get_credentials(client, &pid_cl, &uid_cl, &gid_cl);
+
+ wl_list_for_each(ivires, &ivilayer->list_resource, link) {
+ wl_client_get_credentials(ivires->client,
+ &pid_res, &uid_res, &gid_res);
+
+ //destroy_ivilayer_resource(ivires);
+ if ((pid_cl != pid_res) ||
+ (uid_cl != uid_res) ||
+ (gid_cl != gid_res)) {
+ ivi_layer_send_destroyed(ivires->res_layer);
+ ivi_controller_layer_send_destroyed(ivires->res_ctrl_layer);
+ }
+ }
+
+ wl_list_remove(&ivilayer->link);
+ wl_list_remove(&ivilayer->pending.link);
+ wl_list_remove(&ivilayer->order.link);
+ remove_orderlayer_from_screen(ivilayer);
+
+ free(ivilayer);
+}
+
+static const struct ivi_layer_interface layer_implementation = {
+ layer_destroy
+};
+
+static struct ivilayer_resource*
+create_layerresource(struct ivi_client_layer *ivilayer,
+ struct wl_client *client,
+ struct wl_signal *signal_destroy)
+{
+ struct ivilayer_resource *ivires;
+
+ ivires = calloc(1, sizeof *ivires);
+ if (ivires == NULL) {
+ weston_log("no memory to allocate ivilayer_resource\n");
+ return NULL;
+ }
+
+ ivires->client = client;
+ ivires->ivilayer = ivilayer;
+
+ ivires->res_layer =
+ wl_resource_create(client, &ivi_layer_interface, 1, 0);
+ if (ivires->res_layer == NULL) {
+ weston_log("couldn't new layer object");
+ free(ivires);
+ return NULL;
+ }
+ wl_resource_set_implementation(ivires->res_layer,
+ &layer_implementation,
+ ivires, NULL);
+
+ ivires->res_ctrl_layer =
+ wl_resource_create(client, &ivi_controller_layer_interface, 1, 0);
+ if (ivires->res_ctrl_layer == NULL) {
+ weston_log("couldn't new layer controller object");
+ free(ivires);
+ return NULL;
+ }
+ wl_resource_set_implementation(ivires->res_ctrl_layer,
+ &controller_layer_implementation,
+ ivires, NULL);
+
+ wl_list_insert(&ivilayer->list_resource, &ivires->link);
+
+ ivires->destroy_listener.notify = destroy_listener_ivilayer_resource;
+ wl_signal_add(signal_destroy, &ivires->destroy_listener);
+
+ return ivires;
+}
+
+static struct iviscrn_resource*
+create_screenresource(struct ivi_client_screen *iviscrn,
+ struct wl_client *client,
+ struct wl_signal *signal_destroy, uint32_t id_output)
+{
+ struct iviscrn_resource *ivires;
+
+ ivires = calloc(1, sizeof *ivires);
+ if (ivires == NULL) {
+ weston_log("no memory to allocate iviscrn_resource\n");
+ return NULL;
+ }
+
+ ivires->client = client;
+ ivires->iviscrn = iviscrn;
+ ivires->id_output = id_output;
+
+ ivires->res_ctrl_scrn =
+ wl_resource_create(client, &ivi_controller_screen_interface, 1, 0);
+ if (ivires->res_ctrl_scrn == NULL) {
+ weston_log("couldn't new screen controller object");
+ free(ivires);
+ return NULL;
+ }
+ wl_resource_set_implementation(ivires->res_ctrl_scrn,
+ &controller_screen_implementation,
+ ivires, NULL);
+
+ wl_list_insert(&iviscrn->list_resource, &ivires->link);
+
+ ivires->destroy_listener.notify = destroy_listener_iviscreen_resource;
+ wl_signal_add(signal_destroy,
+ &ivires->destroy_listener);
+
+ return ivires;
+}
+
+static struct wl_resource *
+find_resource_for_client(struct wl_list *list, struct wl_client *client)
+{
+ struct wl_resource *r;
+ wl_list_for_each(r, list, link) {
+ if (r->client == client) {
+ return r;
+ }
+ }
+ return NULL;
+}
+
+static void
+update_opacity(struct ivi_client_layer *ivilayer,
+ struct ivi_client_surface *ivisurf)
+{
+ double layer_alpha = wl_fixed_to_double(ivilayer->prop.opacity);
+ double surf_alpha = wl_fixed_to_double(ivisurf->prop.opacity);
+
+ if ((ivilayer->event_mask & PROP_EVENT_OPACITY) ||
+ (ivisurf->event_mask & PROP_EVENT_OPACITY)) {
+ if (ivisurf->surface == NULL) {
+ return;
+ }
+ ivisurf->surface->alpha = layer_alpha * surf_alpha;
+ }
+}
+
+static void
+shell_surface_configure(struct weston_surface *, int32_t, int32_t, int32_t, int32_t);
+
+static struct shell_surface *
+get_shell_surface(struct weston_surface *surface)
+{
+ if (surface->configure == shell_surface_configure) {
+ return surface->configure_private;
+ } else {
+ return NULL;
+ }
+}
+
+static void
+update_surface_orientation(struct ivi_client_layer *ivilayer,
+ struct ivi_client_surface *ivisurf)
+{
+ float cx = 0.0f;
+ float cy = 0.0f;
+ struct weston_surface *es = ivisurf->surface;
+ float v_sin = 0.0f;
+ float v_cos = 0.0f;
+ float sx = 1.0f;
+ float sy = 1.0f;
+ float width = 0.0f;
+ float height = 0.0f;
+ struct weston_matrix *matrix = &ivisurf->surface_rotation.matrix;
+ struct shell_surface *shsurf = NULL;
+
+ if (es == NULL) {
+ return;
+ }
+
+ shsurf = get_shell_surface(es);
+ if (shsurf == NULL) {
+ return;
+ }
+
+ if ((shsurf->width == 0) || (shsurf->height == 0)) {
+ return;
+ }
+
+ if ((ivilayer->prop.dest_width == 0) ||
+ (ivilayer->prop.dest_height == 0)) {
+ return;
+ }
+ width = (float)ivilayer->prop.dest_width;
+ height = (float)ivilayer->prop.dest_height;
+
+ switch (ivisurf->prop.orientation) {
+ case IVI_SURFACE_ORIENTATION_0_DEGREES:
+ v_sin = 0.0f;
+ v_cos = 1.0f;
+ break;
+ case IVI_SURFACE_ORIENTATION_90_DEGREES:
+ v_sin = 1.0f;
+ v_cos = 0.0f;
+ sx = width / height;
+ sy = height / width;
+ break;
+ case IVI_SURFACE_ORIENTATION_180_DEGREES:
+ v_sin = 0.0f;
+ v_cos = -1.0f;
+ break;
+ case IVI_SURFACE_ORIENTATION_270_DEGREES:
+ default:
+ v_sin = -1.0f;
+ v_cos = 0.0f;
+ sx = width / height;
+ sy = height / width;
+ break;
+ }
+ wl_list_remove(&ivisurf->surface_rotation.link);
+ weston_surface_geometry_dirty(es);
+
+ weston_matrix_init(matrix);
+ cx = 0.5f * width;
+ cy = 0.5f * height;
+ weston_matrix_translate(matrix, -cx, -cy, 0.0f);
+ weston_matrix_rotate_xy(matrix, v_cos, v_sin);
+ weston_matrix_scale(matrix, sx, sy, 1.0);
+ weston_matrix_translate(matrix, cx, cy, 0.0f);
+ wl_list_insert(&es->geometry.transformation_list,
+ &ivisurf->surface_rotation.link);
+
+ weston_surface_set_transform_parent(es, NULL);
+ weston_surface_update_transform(es);
+}
+
+static void
+update_layer_orientation(struct ivi_client_layer *ivilayer,
+ struct ivi_client_surface *ivisurf)
+{
+ float cx = 0.0f;
+ float cy = 0.0f;
+ struct weston_surface *es = ivisurf->surface;
+ struct weston_output *output = NULL;
+ float v_sin = 0.0f;
+ float v_cos = 0.0f;
+ float sx = 1.0f;
+ float sy = 1.0f;
+ float width = 0.0f;
+ float height = 0.0f;
+ struct weston_matrix *matrix = &ivisurf->layer_rotation.matrix;
+ struct shell_surface *shsurf = NULL;
+
+ if (es == NULL) {
+ return;
+ }
+
+ shsurf = get_shell_surface(es);
+ if (shsurf == NULL) {
+ return;
+ }
+
+ if ((shsurf->width == 0) || (shsurf->height == 0)) {
+ return;
+ }
+
+ output = es->output;
+ if (output == NULL) {
+ return;
+ }
+ if ((output->width == 0) || (output->height == 0)) {
+ return;
+ }
+ width = (float)output->width;
+ height = (float)output->height;
+
+ switch (ivilayer->prop.orientation) {
+ case IVI_SURFACE_ORIENTATION_0_DEGREES:
+ v_sin = 0.0f;
+ v_cos = 1.0f;
+ break;
+ case IVI_SURFACE_ORIENTATION_90_DEGREES:
+ v_sin = 1.0f;
+ v_cos = 0.0f;
+ sx = width / height;
+ sy = height / width;
+ break;
+ case IVI_SURFACE_ORIENTATION_180_DEGREES:
+ v_sin = 0.0f;
+ v_cos = -1.0f;
+ break;
+ case IVI_SURFACE_ORIENTATION_270_DEGREES:
+ default:
+ v_sin = -1.0f;
+ v_cos = 0.0f;
+ sx = width / height;
+ sy = height / width;
+ break;
+ }
+ wl_list_remove(&ivisurf->layer_rotation.link);
+ weston_surface_geometry_dirty(es);
+
+ weston_matrix_init(matrix);
+ cx = 0.5f * width;
+ cy = 0.5f * height;
+ weston_matrix_translate(matrix, -cx, -cy, 0.0f);
+ weston_matrix_rotate_xy(matrix, v_cos, v_sin);
+ weston_matrix_scale(matrix, sx, sy, 1.0);
+ weston_matrix_translate(matrix, cx, cy, 0.0f);
+ wl_list_insert(&es->geometry.transformation_list,
+ &ivisurf->layer_rotation.link);
+
+ weston_surface_set_transform_parent(es, NULL);
+ weston_surface_update_transform(es);
+}
+
+static void
+update_surface_position(struct ivi_client_surface *ivisurf)
+{
+ struct weston_surface *es = ivisurf->surface;
+ float tx = (float)ivisurf->prop.dest_x;
+ float ty = (float)ivisurf->prop.dest_y;
+ struct weston_matrix *matrix = &ivisurf->surface_pos.matrix;
+ struct shell_surface *shsurf = NULL;
+
+ if (es == NULL) {
+ return;
+ }
+
+ shsurf = get_shell_surface(es);
+ if (shsurf == NULL) {
+ return;
+ }
+
+ if ((shsurf->width == 0) || (shsurf->height == 0)) {
+ return;
+ }
+
+ wl_list_remove(&ivisurf->surface_pos.link);
+
+ weston_matrix_init(matrix);
+ weston_matrix_translate(matrix, tx, ty, 0.0f);
+ wl_list_insert(&es->geometry.transformation_list,
+ &ivisurf->surface_pos.link);
+
+ weston_surface_set_transform_parent(es, NULL);
+ weston_surface_update_transform(es);
+}
+
+static void
+update_layer_position(struct ivi_client_layer *ivilayer,
+ struct ivi_client_surface *ivisurf)
+{
+ struct weston_surface *es = ivisurf->surface;
+ float tx = (float)ivilayer->prop.dest_x;
+ float ty = (float)ivilayer->prop.dest_y;
+ struct weston_matrix *matrix = &ivisurf->layer_pos.matrix;
+ struct shell_surface *shsurf = NULL;
+
+ if (es == NULL) {
+ return;
+ }
+
+ shsurf = get_shell_surface(es);
+ if (shsurf == NULL) {
+ return;
+ }
+
+ if ((shsurf->width == 0) || (shsurf->height == 0)) {
+ return;
+ }
+
+ wl_list_remove(&ivisurf->layer_pos.link);
+
+ weston_matrix_init(matrix);
+ weston_matrix_translate(matrix, tx, ty, 0.0f);
+ wl_list_insert(
+ &es->geometry.transformation_list,
+ &ivisurf->layer_pos.link);
+
+ weston_surface_set_transform_parent(es, NULL);
+ weston_surface_update_transform(es);
+}
+
+static void
+update_scale(struct ivi_client_layer *ivilayer,
+ struct ivi_client_surface *ivisurf)
+{
+ struct weston_surface *es = ivisurf->surface;
+ float sx = 0.0f;
+ float sy = 0.0f;
+ float lw = 0.0f;
+ float sw = 0.0f;
+ float lh = 0.0f;
+ float sh = 0.0f;
+ struct weston_matrix *matrix = &ivisurf->scaling.matrix;
+ struct shell_surface *shsurf = NULL;
+
+ if (es == NULL) {
+ return;
+ }
+
+ shsurf = get_shell_surface(es);
+ if (shsurf == NULL) {
+ return;
+ }
+
+ if ((shsurf->width == 0) || (shsurf->height == 0)) {
+ return;
+ }
+
+ lw = ((float)ivilayer->prop.dest_width / shsurf->width);
+ sw = ((float)ivisurf->prop.dest_width / shsurf->width);
+ lh = ((float)ivilayer->prop.dest_height / shsurf->height);
+ sh = ((float)ivisurf->prop.dest_height / shsurf->height);
+ sx = sw * lw;
+ sy = sh * lh;
+
+ wl_list_remove(&ivisurf->scaling.link);
+ weston_matrix_init(matrix);
+ weston_matrix_scale(matrix, sx, sy, 1.0f);
+
+ wl_list_insert(&es->geometry.transformation_list,
+ &ivisurf->scaling.link);
+
+ weston_surface_set_transform_parent(es, NULL);
+ weston_surface_update_transform(es);
+}
+
+static void
+update_prop(struct ivi_client_layer *ivilayer,
+ struct ivi_client_surface *ivisurf)
+{
+// if (ivilayer->event_mask | ivisurf->event_mask) {
+ update_opacity(ivilayer, ivisurf);
+ update_layer_orientation(ivilayer, ivisurf);
+ update_layer_position(ivilayer, ivisurf);
+ update_surface_position(ivisurf);
+ update_surface_orientation(ivilayer, ivisurf);
+ update_scale(ivilayer, ivisurf);
+
+ ivisurf->update_count++;
+
+ if (ivisurf->surface == NULL) {
+ return;
+ }
+ weston_surface_geometry_dirty(ivisurf->surface);
+ weston_surface_damage(ivisurf->surface);
+// }
+}
+
+static void
+send_surface_add_event(struct ivi_client_surface *ivisurf,
+ struct wl_resource *resource)
+{
+ struct link_layer* link_layer = NULL;
+ struct ivisurface_resource* res_surf = NULL;
+ struct ivilayer_resource* res_ivilayer = NULL;
+ struct wl_resource *res_ctrl_surf = NULL;
+ struct wl_resource *res_layer = NULL;
+ struct ivi_client_layer *ivilayer = NULL;
+
+ wl_list_for_each(res_surf, &ivisurf->list_resource, link) {
+ if (res_surf->res_ctrl_surf->client == resource->client) {
+ res_ctrl_surf = res_surf->res_ctrl_surf;
+ break;
+ }
+ }
+
+ if (res_ctrl_surf == NULL) {
+ return;
+ }
+
+ wl_list_for_each(link_layer, &ivisurf->list_layer, link) {
+ res_layer = NULL;
+
+ ivilayer = link_layer->layer;
+ wl_list_for_each(res_ivilayer, &ivilayer->list_resource, link) {
+ if (res_ctrl_surf->client == res_ivilayer->res_layer->client) {
+ res_layer = res_ivilayer->res_layer;
+ break;
+ }
+ }
+ ivi_controller_surface_send_layer(res_ctrl_surf, res_layer);
+ }
+}
+
+static void
+send_surface_event(struct ivi_client_surface *ivisurf,
+ struct wl_resource *resource, uint32_t mask)
+{
+ if (mask & PROP_EVENT_OPACITY) {
+ ivi_surface_send_opacity(resource, ivisurf->prop.opacity);
+ }
+ if (mask & PROP_EVENT_DIMENSION) {
+ ivi_surface_send_dimension(resource,
+ ivisurf->prop.dest_width,
+ ivisurf->prop.dest_height);
+ }
+ if (mask & PROP_EVENT_POSITION) {
+ ivi_surface_send_position(resource,
+ ivisurf->prop.dest_x,
+ ivisurf->prop.dest_y);
+ }
+ if (mask & PROP_EVENT_SRC_REGION) {
+ ivi_surface_send_source_rectangle(resource,
+ ivisurf->prop.src_x, ivisurf->prop.src_y,
+ ivisurf->prop.src_width, ivisurf->prop.src_height);
+ }
+ if (mask & PROP_EVENT_DST_REGION) {
+ ivi_surface_send_destination_rectangle(resource,
+ ivisurf->prop.dest_x, ivisurf->prop.dest_y,
+ ivisurf->prop.dest_width, ivisurf->prop.dest_height);
+ }
+ if (mask & PROP_EVENT_ORIENTATION) {
+ ivi_surface_send_orientation(resource, ivisurf->prop.orientation);
+ }
+ if (mask & PROP_EVENT_VISIBILITY) {
+ ivi_surface_send_visibility(resource, ivisurf->prop.visibility);
+ }
+ if (mask & PROP_EVENT_PIXELFORMAT) {
+ ivi_surface_send_pixelformat(resource, ivisurf->pixelformat);
+ }
+ if (mask & PROP_EVENT_ADD) {
+ send_surface_add_event(ivisurf, resource);
+ }
+}
+
+static void
+send_layer_add_event(struct ivi_client_layer *ivilayer,
+ struct wl_resource *resource)
+{
+ struct link_screen *link_scrn = NULL;
+ struct ivilayer_resource* res_layer = NULL;
+ struct wl_resource *res_ctrl_layer = NULL;
+ struct wl_resource *res_out = NULL;
+ struct ivi_client_screen *iviscrn = NULL;
+
+ wl_list_for_each(res_layer, &ivilayer->list_resource, link) {
+ if (res_layer->res_layer->client == resource->client) {
+ res_ctrl_layer = res_layer->res_ctrl_layer;
+ break;
+ }
+ }
+
+ if (res_ctrl_layer == NULL) {
+ return;
+ }
+
+ wl_list_for_each(link_scrn, &ivilayer->list_screen, link) {
+ iviscrn = link_scrn->screen;
+ res_out =
+ find_resource_for_client(&iviscrn->output->resource_list,
+ res_ctrl_layer->client);
+ ivi_controller_layer_send_screen(res_ctrl_layer, res_out);
+ }
+}
+
+static void
+send_layer_event(struct ivi_client_layer *ivilayer,
+ struct wl_resource *resource, uint32_t mask)
+{
+ if (mask & PROP_EVENT_OPACITY) {
+ ivi_layer_send_opacity(resource, ivilayer->prop.opacity);
+ }
+ if (mask & PROP_EVENT_DIMENSION) {
+ ivi_layer_send_dimension(resource,
+ ivilayer->prop.dest_width,
+ ivilayer->prop.dest_height);
+ }
+ if (mask & PROP_EVENT_POSITION) {
+ ivi_layer_send_position(resource,
+ ivilayer->prop.dest_x,
+ ivilayer->prop.dest_y);
+ }
+ if (mask & PROP_EVENT_SRC_REGION) {
+ ivi_layer_send_source_rectangle(resource,
+ ivilayer->prop.src_x,
+ ivilayer->prop.src_y,
+ ivilayer->prop.src_width,
+ ivilayer->prop.src_height);
+ }
+ if (mask & PROP_EVENT_DST_REGION) {
+ ivi_layer_send_destination_rectangle(resource,
+ ivilayer->prop.dest_x,
+ ivilayer->prop.dest_y,
+ ivilayer->prop.dest_width,
+ ivilayer->prop.dest_height);
+ }
+ if (mask & PROP_EVENT_ORIENTATION) {
+ ivi_layer_send_orientation(resource, ivilayer->prop.orientation);
+ }
+ if (mask & PROP_EVENT_VISIBILITY) {
+ ivi_layer_send_visibility(resource, ivilayer->prop.visibility);
+ }
+ if (mask & PROP_EVENT_ADD) {
+ send_layer_add_event(ivilayer, resource);
+ }
+}
+
+static void
+send_surface_prop(struct ivi_client_surface *ivisurf)
+{
+ struct ivisurface_resource *ivires;
+ wl_list_for_each(ivires, &ivisurf->list_resource, link) {
+ send_surface_event(ivisurf, ivires->res_surf, ivisurf->event_mask);
+ }
+ ivisurf->event_mask = 0;
+}
+
+static void
+send_layer_prop(struct ivi_client_layer *ivilayer)
+{
+ struct ivilayer_resource *ivires;
+ wl_list_for_each(ivires, &ivilayer->list_resource, link) {
+ send_layer_event(ivilayer, ivires->res_layer, ivilayer->event_mask);
+ }
+ ivilayer->event_mask = 0;
+}
+
+static void
+commit_changes(struct ivi_shell *shell)
+{
+ struct ivi_client_screen *iviscrn;
+ struct ivi_client_layer *ivilayer;
+ struct ivi_client_surface *ivisurf;
+ wl_list_for_each(iviscrn, &shell->list_screen, link) {
+ wl_list_for_each(ivilayer,
+ &iviscrn->order.list_layer,
+ order.link) {
+ wl_list_for_each(ivisurf,
+ &ivilayer->order.list_surface,
+ order.link) {
+ update_prop(ivilayer, ivisurf);
+ }
+ }
+ }
+}
+
+static void
+send_prop(struct ivi_shell *shell)
+{
+ struct ivi_client_layer *ivilayer;
+ struct ivi_client_surface *ivisurf;
+ wl_list_for_each(ivilayer, &shell->list_layer, link) {
+ send_layer_prop(ivilayer);
+ }
+
+ wl_list_for_each(ivisurf, &shell->list_surface, link) {
+ send_surface_prop(ivisurf);
+ }
+}
+
+static void
+surface_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivisurface_resource *ivires_client = resource->data;
+ struct ivi_client_surface *ivisurf = ivires_client->ivisurf;
+ struct ivisurface_resource *ivires = NULL;
+ pid_t pid_cl;
+ uid_t uid_cl;
+ gid_t gid_cl;
+ pid_t pid_res;
+ uid_t uid_res;
+ gid_t gid_res;
+
+#ifdef _DEBUG
+ weston_log("surface_destroy: client=0x%08x, resource=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource);
+#endif
+
+ wl_client_get_credentials(client, &pid_cl, &uid_cl, &gid_cl);
+
+ wl_list_for_each(ivires, &ivisurf->list_resource, link) {
+ wl_client_get_credentials(ivires->client,
+ &pid_res, &uid_res, &gid_res);
+
+ //destroy_ivisurface_resource(ivires);
+ if ((pid_cl != pid_res) ||
+ (uid_cl != uid_res) ||
+ (gid_cl != gid_res)) {
+ ivi_surface_send_destroyed(ivires->res_surf);
+ ivi_controller_surface_send_destroyed(ivires->res_ctrl_surf);
+ }
+ }
+
+ wl_list_remove(&ivisurf->link);
+ wl_list_remove(&ivisurf->pending.link);
+ wl_list_remove(&ivisurf->order.link);
+ remove_ordersurface_from_layer(ivisurf);
+ wl_list_remove(&ivisurf->surface_destroy_listener.link);
+
+ free(ivisurf);
+}
+
+static void
+surface_set_native(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id_native)
+{
+ struct weston_surface *es = NULL;
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface* ivisurf = ivires->ivisurf;
+
+#ifdef _DEBUG
+ weston_log("surface_set_native: client=0x%08x, resource=0x%08x, \
+ native=%d\n",
+ (uint32_t)client, (uint32_t)resource, id_native);
+#endif
+
+ if (id_native == 0xFFFFFFFF) {
+ ivisurf->surface = NULL;
+ return;
+ }
+
+ es = get_weston_surface_from_id(ivisurf->shell, client, id_native);
+ if (es == NULL) {
+ weston_log("surface_set_native: invalid id_native\n");
+ return;
+ }
+
+ ivisurf->surface = es;
+}
+
+static void
+surface_send_stats(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface* ivisurf = ivires->ivisurf;
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+ wl_client_get_credentials(client, &pid, &uid, &gid);
+
+ ivi_surface_send_stats(resource, 0, 0, ivisurf->update_count, pid);
+}
+
+static const struct ivi_surface_interface surface_implementation = {
+ surface_destroy,
+ surface_set_native,
+ surface_send_stats
+};
+
+static void
+controller_surface_set_opacity(struct wl_client *client,
+ struct wl_resource *resource,
+ wl_fixed_t opacity)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface *ivisurf = ivires->ivisurf;
+ struct ivi_properties *prop = &ivisurf->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_set_opacity: client=0x%08x, \
+ resource=0x%08x, opacity=%lf\n",
+ (uint32_t)client, (uint32_t)resource, wl_fixed_to_double(opacity));
+#endif
+
+ prop->opacity = opacity;
+ ivisurf->event_mask |= PROP_EVENT_OPACITY;
+}
+
+static void
+controller_surface_set_source_rectangle(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface *ivisurf = ivires->ivisurf;
+ struct ivi_properties *prop = &ivisurf->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_set_source_rectangle: client=0x%08x, \
+ resource=0x%08x, x=%d, y=%d, width=%d, height=%d\n",
+ (uint32_t)client, (uint32_t)resource, x, y, width, height);
+#endif
+
+ prop->src_x = x;
+ prop->src_y = y;
+ prop->src_width = width;
+ prop->src_height = height;
+ ivisurf->event_mask |= PROP_EVENT_SRC_REGION;
+}
+
+static void
+controller_surface_set_destination_rectangle(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface *ivisurf = ivires->ivisurf;
+ struct ivi_properties *prop = &ivisurf->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_set_destination_rectangle: client=0x%08x, \
+ resource=0x%08x, x=%d, y=%d, width=%d, height=%d\n",
+ (uint32_t)client, (uint32_t)resource, x, y, width, height);
+#endif
+
+ prop->dest_x = x;
+ prop->dest_y = y;
+ prop->dest_width = width;
+ prop->dest_height = height;
+
+ ivisurf->event_mask |= PROP_EVENT_DST_REGION;
+}
+
+static void
+controller_surface_set_visibility(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t visibility)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface *ivisurf = ivires->ivisurf;
+ struct ivi_properties *prop = &ivisurf->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_set_visiblity: client=0x%08x, \
+ resource=0x%08x, visibility=%d\n",
+ (uint32_t)client, (uint32_t)resource, visibility);
+#endif
+
+ prop->visibility = visibility;
+ ivisurf->event_mask |= PROP_EVENT_VISIBILITY;
+}
+
+static void
+controller_surface_set_dimension(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t width,
+ int32_t height)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface *ivisurf = ivires->ivisurf;
+ struct ivi_properties *prop = &ivisurf->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_set_dimension: client=0x%08x, \
+ resource=0x%08x, width=%d, height=%d\n",
+ (uint32_t)client, (uint32_t)resource, width, height);
+#endif
+
+ prop->dest_width = width;
+ prop->dest_height = height;
+ ivisurf->event_mask |= PROP_EVENT_DIMENSION;
+}
+
+static void
+controller_surface_set_position(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface *ivisurf = ivires->ivisurf;
+ struct ivi_properties *prop = &ivisurf->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_set_position: client=0x%08x, \
+ resource=0x%08x, x=%d, y=%d\n",
+ (uint32_t)client, (uint32_t)resource, x, y);
+#endif
+
+ prop->dest_x = x;
+ prop->dest_y = y;
+ ivisurf->event_mask |= PROP_EVENT_POSITION;
+}
+
+static void
+controller_surface_set_orientation(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t orientation)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface *ivisurf = ivires->ivisurf;
+ struct ivi_properties *prop = &ivisurf->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_set_orientation: client=0x%08x, \
+ resource=0x%08x, orientation=%d\n",
+ (uint32_t)client, (uint32_t)resource, orientation);
+#endif
+
+ prop->orientation = orientation;
+ ivisurf->event_mask |= PROP_EVENT_ORIENTATION;
+}
+
+static void
+controller_surface_screenshot(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *filename)
+{
+ struct ivisurface_resource *ivires = resource->data;
+ struct ivi_client_surface *ivisurf = ivires->ivisurf;
+ struct weston_compositor *compositor = ivisurf->shell->compositor;
+ cairo_surface_t *surface;
+ int32_t width;
+ int32_t height;
+ int32_t stride;
+ uint8_t *pixels;
+
+#ifdef _DEBUG
+ weston_log("controller_surface_screenshot: client=0x%08x, \
+ resource=0x%08x, filename=%s\n",
+ (uint32_t)client, (uint32_t)resource, filename);
+#endif
+
+ width = ivisurf->prop.dest_width;
+ height = ivisurf->prop.dest_height;
+ stride = width *
+ (PIXMAN_FORMAT_BPP(compositor->read_format) / 8);
+ pixels = malloc(stride * height);
+ if (pixels == NULL) {
+ return;
+ }
+
+ compositor->renderer->read_surface_pixels(ivisurf->surface,
+ compositor->read_format, pixels,
+ 0, 0, width, height);
+
+ surface = cairo_image_surface_create_for_data(pixels,
+ CAIRO_FORMAT_ARGB32,
+ width, height, stride);
+ cairo_surface_write_to_png(surface, filename);
+ cairo_surface_destroy(surface);
+ free(pixels);
+}
+
+static const
+struct ivi_controller_surface_interface controller_surface_implementation = {
+ controller_surface_destroy,
+ controller_surface_set_visibility,
+ controller_surface_set_opacity,
+ controller_surface_set_source_rectangle,
+ controller_surface_set_destination_rectangle,
+ controller_surface_set_dimension,
+ controller_surface_set_position,
+ controller_surface_set_orientation,
+ controller_surface_screenshot
+};
+
+static void
+controller_layer_set_source_rectangle(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_properties *prop = &ivilayer->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_set_source_rectangle: client=0x%08x, \
+ resource=0x%08x, x=%d, y=%d, width=%d, height=%d\n",
+ (uint32_t)client, (uint32_t)resource, x, y, width, height);
+#endif
+
+ prop->src_x = x;
+ prop->src_y = y;
+ prop->src_width = width;
+ prop->src_height = height;
+ ivilayer->event_mask |= PROP_EVENT_SRC_REGION;
+}
+
+static void
+controller_layer_set_destination_rectangle(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y,
+ int32_t width,
+ int32_t height)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_properties *prop = &ivilayer->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_set_destination_rectangle: client=0x%08x, \
+ resource=0x%08x, x=%d, y=%d, width=%d, height=%d\n",
+ (uint32_t)client, (uint32_t)resource, x, y, width, height);
+#endif
+
+ prop->dest_x = x;
+ prop->dest_y = y;
+ prop->dest_width = width;
+ prop->dest_height = height;
+ ivilayer->event_mask |= PROP_EVENT_DST_REGION;
+}
+
+static void
+controller_layer_set_visibility(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t visibility)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_properties *prop = &ivilayer->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_set_visibility: client=0x%08x, \
+ resource=0x%08x, visibility=%d\n",
+ (uint32_t)client, (uint32_t)resource, visibility);
+#endif
+
+ prop->visibility = visibility;
+ ivilayer->event_mask |= PROP_EVENT_VISIBILITY;
+}
+
+static void
+controller_layer_set_opacity(struct wl_client *client,
+ struct wl_resource *resource,
+ wl_fixed_t opacity)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_properties *prop = &ivilayer->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_set_opacity: client=0x%08x, \
+ resource=0x%08x, opacity=%lf\n",
+ (uint32_t)client, (uint32_t)resource, wl_fixed_to_double(opacity));
+#endif
+
+ prop->opacity = opacity;
+ ivilayer->event_mask |= PROP_EVENT_OPACITY;
+}
+
+static void
+controller_layer_set_dimension(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t width,
+ int32_t height)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_properties *prop = &ivilayer->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_set_dimension: client=0x%08x, \
+ resource=0x%08x, width=%d, height=%d\n",
+ (uint32_t)client, (uint32_t)resource, width, height);
+#endif
+
+ prop->dest_width = width;
+ prop->dest_height = height;
+ ivilayer->event_mask |= PROP_EVENT_DIMENSION;
+}
+
+static void
+controller_layer_set_position(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_properties *prop = &ivilayer->pending.prop;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_set_position: client=0x%08x, \
+ resource=0x%08x, x=%d, y=%d\n",
+ (uint32_t)client, (uint32_t)resource, x, y);
+#endif
+
+ prop->dest_x = x;
+ prop->dest_y = y;
+ ivilayer->event_mask |= PROP_EVENT_POSITION;
+}
+
+static void
+controller_layer_set_orientation(struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t orientation)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_properties *prop = &ivilayer->pending.prop;
+
+ prop->orientation = orientation;
+ ivilayer->event_mask |= PROP_EVENT_ORIENTATION;
+}
+
+static void
+controller_layer_clear_surfaces(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+
+ wl_list_init(&ivilayer->pending.list_surface);
+
+ ivilayer->event_mask |= PROP_EVENT_ADD;
+}
+
+static int
+is_surface_in_layer(struct ivi_client_surface *ivisurf,
+ struct ivi_client_layer *ivilayer)
+{
+ struct ivi_client_surface *surf = NULL;
+
+ wl_list_for_each(surf, &ivilayer->pending.list_surface, pending.link) {
+ if (surf->id_surface == ivisurf->id_surface) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void
+controller_layer_add_surface(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *surface)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivisurface_resource *addsurf = surface->data;
+ struct ivi_client_surface *ivisurf;
+ int is_surf_in_layer = 0;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_add_surface: client=0x%08x, \
+ resource=0x%08x, surface=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource, (uint32_t)surface);
+#endif
+
+ if (addsurf == NULL) {
+ weston_log("invalid surface in layer_add_surface\n");
+ return;
+ }
+ is_surf_in_layer = is_surface_in_layer(addsurf->ivisurf, ivilayer);
+ if (is_surf_in_layer == 1) {
+ return;
+ }
+
+ wl_list_for_each(ivisurf, &ivilayer->shell->list_surface, link) {
+ if (ivisurf->id_surface == addsurf->ivisurf->id_surface) {
+ wl_list_init(&ivisurf->pending.link);
+ wl_list_insert(&ivilayer->pending.list_surface,
+ &ivisurf->pending.link);
+ break;
+ }
+ }
+
+ ivilayer->event_mask |= PROP_EVENT_ADD;
+}
+
+static void
+controller_layer_remove_surface(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *surface)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_client_surface *remsurf = surface->data;
+ struct ivi_client_surface *ivisurf = NULL;
+ struct ivi_client_surface *next = NULL;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_remove_surface: client=0x%08x, \
+ resource=0x%08x, surface=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource, (uint32_t)surface);
+#endif
+
+ wl_list_for_each_safe(ivisurf, next,
+ &ivilayer->pending.list_surface, link) {
+ if (ivisurf->id_surface == remsurf->id_surface) {
+ wl_list_remove(&ivisurf->link);
+ wl_list_init(&ivisurf->link);
+ break;
+ }
+ }
+}
+
+static void
+controller_layer_screenshot(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *filename)
+{
+}
+
+static void
+controller_layer_set_render_order(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_array *id_surfaces)
+{
+ struct ivilayer_resource *ivires = resource->data;
+ struct ivi_client_layer *ivilayer = ivires->ivilayer;
+ struct ivi_client_surface *ivisurf = NULL;
+ uint32_t *id_surface = NULL;
+
+#ifdef _DEBUG
+ weston_log("controller_layer_renderorder: client=0x%08x, \
+ resource=0x%08x, id_surfaces=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource, (uint32_t)id_surfaces);
+#endif
+
+ wl_list_init(&ivilayer->pending.list_surface);
+ wl_array_for_each(id_surface, id_surfaces) {
+ wl_list_for_each(ivisurf, &ivilayer->shell->list_surface, link) {
+ if (*id_surface != ivisurf->id_surface) {
+ continue;
+ }
+
+ wl_list_init(&ivisurf->pending.link);
+ wl_list_insert(&ivilayer->pending.list_surface,
+ &ivisurf->pending.link);
+ break;
+ }
+ }
+
+ ivilayer->event_mask |= PROP_EVENT_ADD;
+}
+
+static const
+struct ivi_controller_layer_interface controller_layer_implementation = {
+ controller_layer_destroy,
+ controller_layer_set_visibility,
+ controller_layer_set_opacity,
+ controller_layer_set_source_rectangle,
+ controller_layer_set_destination_rectangle,
+ controller_layer_set_dimension,
+ controller_layer_set_position,
+ controller_layer_set_orientation,
+ controller_layer_screenshot,
+ controller_layer_clear_surfaces,
+ controller_layer_add_surface,
+ controller_layer_remove_surface,
+ controller_layer_set_render_order
+};
+
+static void
+controller_screen_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct iviscrn_resource *ivires = resource->data;
+
+#ifdef _DEBUG
+ weston_log("controller_screen_destroy: client=0x%08x, resource=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource);
+#endif
+
+ if (ivires->res_ctrl_scrn != NULL) {
+ wl_resource_destroy(ivires->res_ctrl_scrn);
+ ivires->res_ctrl_scrn = NULL;
+ }
+}
+
+static void
+controller_screen_clear(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct iviscrn_resource *ivires = resource->data;
+ struct ivi_client_screen *iviscrn = ivires->iviscrn;
+
+#ifdef _DEBUG
+ weston_log("controller_screen_clear: client=0x%08x, \
+ resource=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource);
+#endif
+
+ wl_list_init(&iviscrn->pending.list_layer);
+
+ iviscrn->event_mask |= PROP_EVENT_ADD;
+}
+
+static int
+is_layer_in_screen(struct ivi_client_layer *ivilayer,
+ struct ivi_client_screen *iviscrn)
+{
+ struct ivi_client_layer *layer = NULL;
+
+ wl_list_for_each(layer, &iviscrn->pending.list_layer, pending.link) {
+ if (layer->id_layer == ivilayer->id_layer) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void
+controller_screen_add_layer(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *layer)
+{
+ struct iviscrn_resource *ivires = resource->data;
+ struct ivi_client_screen *iviscrn = ivires->iviscrn;
+ struct ivilayer_resource *addlayer = layer->data;
+ struct ivi_client_layer *ivilayer;
+ int is_layer_in_scrn = 0;
+
+#ifdef _DEBUG
+ weston_log("controller_screen_add_layer: client=0x%08x, \
+ resource=0x%08x, layer=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource, (uint32_t)layer);
+#endif
+
+ is_layer_in_scrn = is_layer_in_screen(addlayer->ivilayer, iviscrn);
+ if (is_layer_in_scrn == 1) {
+ return;
+ }
+
+ wl_list_for_each(ivilayer, &iviscrn->shell->list_layer, link) {
+ if (ivilayer->id_layer == addlayer->ivilayer->id_layer) {
+ wl_list_init(&ivilayer->pending.link);
+ wl_list_insert(&iviscrn->pending.list_layer,
+ &ivilayer->pending.link);
+ break;
+ }
+ }
+
+ iviscrn->event_mask |= PROP_EVENT_ADD;
+}
+
+static void
+controller_screen_screenshot(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *filename)
+{
+ struct iviscrn_resource *ivires = resource->data;
+ struct ivi_client_screen *iviscrn = ivires->iviscrn;
+ struct weston_output *output = iviscrn->output;
+ cairo_surface_t *surface = NULL;
+ int i = 0;
+ int32_t width = 0;
+ int32_t height = 0;
+ int32_t stride = 0;
+ uint8_t *readpixs = NULL;
+ uint8_t *writepixs = NULL;
+ uint8_t *d = NULL;
+ uint8_t *s = NULL;
+
+ output->disable_planes--;
+
+ width = output->current->width;
+ height = output->current->height;
+ stride = width *
+ (PIXMAN_FORMAT_BPP(output->compositor->read_format) / 8);
+ readpixs = malloc(stride * height);
+ if (readpixs == NULL) {
+ return;
+ }
+ writepixs = malloc(stride * height);
+ if (writepixs == NULL) {
+ return;
+ }
+
+ output->compositor->renderer->read_pixels(output,
+ output->compositor->read_format, readpixs,
+ 0, 0, width, height);
+
+ s = readpixs;
+ d = writepixs + stride * (height - 1);
+
+ for (i = 0; i < height; i++) {
+ memcpy(d, s, stride);
+ d -= stride;
+ s += stride;
+ }
+
+ surface = cairo_image_surface_create_for_data(writepixs,
+ CAIRO_FORMAT_ARGB32,
+ width, height, stride);
+ cairo_surface_write_to_png(surface, filename);
+ cairo_surface_destroy(surface);
+ free(writepixs);
+ free(readpixs);
+}
+
+static void
+controller_screen_set_render_order(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_array *id_layers)
+{
+ struct iviscrn_resource *ivires = resource->data;
+ struct ivi_client_screen *iviscrn = ivires->iviscrn;
+ uint32_t *id_layer = NULL;
+ struct ivi_client_layer *ivilayer;
+
+#ifdef _DEBUG
+ weston_log("controller_screen_set_render_order: client=0x%08x, \
+ resource=0x%08x, id_layers=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource, (uint32_t)id_layers);
+#endif
+
+ wl_list_init(&iviscrn->pending.list_layer);
+ wl_array_for_each(id_layer, id_layers) {
+ wl_list_for_each(ivilayer, &iviscrn->shell->list_layer, link) {
+ if (*id_layer == ivilayer->id_layer) {
+ continue;
+ }
+
+ wl_list_init(&ivilayer->pending.link);
+ wl_list_insert(&iviscrn->pending.list_layer,
+ &ivilayer->pending.link);
+ break;
+ }
+ }
+
+ iviscrn->event_mask |= PROP_EVENT_ADD;
+}
+
+static const
+struct ivi_controller_screen_interface controller_screen_implementation = {
+ controller_screen_destroy,
+ controller_screen_clear,
+ controller_screen_add_layer,
+ controller_screen_screenshot,
+ controller_screen_set_render_order
+};
+
+static void
+commit_list_surface(struct ivi_shell *shell)
+{
+ struct ivi_client_surface *ivisurf;
+ wl_list_for_each(ivisurf, &shell->list_surface, link) {
+ ivisurf->prop = ivisurf->pending.prop;
+ }
+}
+
+static void
+commit_list_layer(struct ivi_shell *shell)
+{
+ struct ivi_client_layer *ivilayer;
+ struct ivi_client_surface *ivisurf;
+
+#ifdef _DEBUG
+ weston_log("commit_list_layer list_layer length=%d\n",
+ wl_list_length(&shell->list_layer));
+#endif
+
+ wl_list_for_each(ivilayer, &shell->list_layer, link) {
+ ivilayer->prop = ivilayer->pending.prop;
+
+ if (!(ivilayer->event_mask & PROP_EVENT_ADD)) {
+ continue;
+ }
+ wl_list_init(&ivilayer->order.list_surface);
+ wl_list_for_each(ivisurf, &ivilayer->pending.list_surface,
+ pending.link) {
+ wl_list_insert(&ivilayer->order.list_surface,
+ &ivisurf->order.link);
+ add_ordersurface_to_layer(ivisurf, ivilayer);
+ }
+ }
+}
+
+static void
+commit_list_screen(struct ivi_shell *shell)
+{
+ struct weston_compositor *ec = shell->compositor;
+ struct ivi_client_screen *iviscrn;
+ struct ivi_client_layer *ivilayer;
+ struct ivi_client_surface *ivisurf;
+ wl_list_for_each(iviscrn, &shell->list_screen, link) {
+ if (iviscrn->event_mask & PROP_EVENT_ADD) {
+ wl_list_init(&iviscrn->order.list_layer);
+
+ wl_list_for_each(ivilayer, &iviscrn->pending.list_layer,
+ pending.link) {
+ wl_list_insert(&iviscrn->order.list_layer,
+ &ivilayer->order.link);
+ add_orderlayer_to_screen(ivilayer, iviscrn);
+ }
+ iviscrn->event_mask = 0;
+ }
+
+ /* For rendering */
+ wl_list_init(&ec->layer_list);
+ wl_list_for_each(ivilayer, &iviscrn->order.list_layer, order.link) {
+ if (ivilayer->prop.visibility == 0) {
+ continue;
+ }
+
+ wl_list_insert(&ec->layer_list, &ivilayer->el.link);
+ wl_list_init(&ivilayer->el.surface_list);
+
+ wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) {
+ if (ivisurf->prop.visibility == 0) {
+ continue;
+ }
+
+ if (ivisurf->surface == NULL) {
+ continue;
+ }
+ wl_list_insert(&ivilayer->el.surface_list,
+ &ivisurf->surface->layer_link);
+ ivisurf->surface->output = iviscrn->output;
+ }
+ }
+ break;
+ }
+}
+
+static void
+controller_commit_changes(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct ivi_client_ctrl *controller = resource->data;
+#ifdef _DEBUG
+ weston_log("controller_commit_changes: client=0x%08x, resource=0x%08x\n",
+ (uint32_t)client, (uint32_t)resource);
+#endif
+
+ commit_list_surface(controller->shell);
+ commit_list_layer(controller->shell);
+ commit_list_screen(controller->shell);
+
+ commit_changes(controller->shell);
+ send_prop(controller->shell);
+ weston_compositor_schedule_repaint(controller->shell->compositor);
+}
+
+static const struct ivi_controller_interface controller_implementation = {
+ controller_commit_changes
+};
+
+static void
+westonsurface_destroy_from_ivisurface(struct wl_listener *listener, void *data)
+{
+ struct ivi_client_surface *ivisurf = container_of(listener,
+ struct ivi_client_surface,
+ surface_destroy_listener);
+ ivisurf->surface = NULL;
+}
+
+static void
+client_surface_create(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id_surface,
+ uint32_t id_native,
+ int32_t width,
+ int32_t height,
+ uint32_t id)
+{
+ struct ivi_shell *shell = resource->data;
+ struct weston_surface *es = NULL;
+ struct ivi_client_surface *ivisurf = NULL;
+ struct ivi_client_ctrl *controller = NULL;
+ struct ivisurface_resource *ivires = NULL;
+
+#ifdef _DEBUG
+ weston_log("client_surface_create: client=0x%08x, resource=0x%08x, \
+ native=%d, id_surface=%d, width=%d, height=%d, id=%d\n",
+ (uint32_t)client, (uint32_t)resource,
+ id_native, id_surface, width, height, id);
+#endif
+
+ es = get_weston_surface_from_id(shell, client, id_native);
+ if (es == NULL) {
+ weston_log("client_surface_create: invalid id_native\n");
+ }
+
+ ivisurf = get_surface(&shell->list_surface, id_surface);
+ if (ivisurf != NULL)
+ {
+ weston_log("id_surface is already created\n");
+
+ resource = wl_resource_create(client, &ivi_surface_interface, 1, id);
+ ivisurf->surface = es;
+ if (es != NULL) {
+ ivisurf->surface_destroy_listener.notify =
+ westonsurface_destroy_from_ivisurface;
+ wl_signal_add(&es->resource->destroy_signal,
+ &ivisurf->surface_destroy_listener);
+ }
+ send_surface_event(ivisurf, resource, PROP_EVENT_ALL);
+ return;
+ }
+
+ ivisurf = calloc(1, sizeof *ivisurf);
+ if (ivisurf == NULL) {
+ weston_log("no memory to allocate client surface\n");
+ return;
+ }
+
+ init_properties(&ivisurf->prop, width, height);
+ ivisurf->pixelformat = IVI_SURFACE_PIXELFORMAT_RGBA_8888;
+ ivisurf->pending.prop = ivisurf->prop;
+ ivisurf->surface = es;
+ if (es != NULL) {
+ ivisurf->surface_destroy_listener.notify =
+ westonsurface_destroy_from_ivisurface;
+ wl_signal_add(&es->resource->destroy_signal,
+ &ivisurf->surface_destroy_listener);
+ }
+ ivisurf->id_surface = id_surface;
+ ivisurf->shell = shell;
+ ivisurf->event_mask = 0;
+
+ wl_list_init(&ivisurf->surface_rotation.link);
+ wl_list_init(&ivisurf->layer_rotation.link);
+ wl_list_init(&ivisurf->surface_pos.link);
+ wl_list_init(&ivisurf->layer_pos.link);
+ wl_list_init(&ivisurf->scaling.link);
+ wl_list_init(&ivisurf->list_resource);
+
+ wl_list_init(&ivisurf->link);
+ wl_list_init(&ivisurf->pending.link);
+ wl_list_init(&ivisurf->order.link);
+ wl_list_init(&ivisurf->list_layer);
+ wl_list_insert(&shell->list_surface, &ivisurf->link);
+
+ wl_list_for_each(controller, &shell->list_controller_client, link) {
+ ivires =
+ create_surfaceresource(ivisurf,
+ controller->client,
+ &controller->resource->destroy_signal);
+ if (ivires == NULL) {
+ weston_log("no memory to allocate surfaceresource\n");
+ continue;
+ }
+ ivi_controller_send_surface(controller->resource,
+ ivisurf->id_surface,
+ ivires->res_surf,
+ ivires->res_ctrl_surf);
+ send_surface_event(ivisurf, ivires->res_surf, PROP_EVENT_ALL);
+ }
+
+ resource = wl_resource_create(client, &ivi_surface_interface, 1, id);
+ if (resource == NULL) {
+ weston_log("couldn't surface object");
+ return;
+ }
+ wl_resource_set_implementation(resource,
+ &surface_implementation,
+ ivires, NULL);
+
+ send_surface_event(ivisurf, resource, PROP_EVENT_ALL);
+}
+
+static void
+client_layer_create(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id_layer,
+ int32_t width,
+ int32_t height,
+ uint32_t id)
+{
+ struct ivi_shell *shell = resource->data;
+ struct ivi_client_layer *ivilayer = NULL;
+ struct ivi_client_ctrl *controller = NULL;
+ struct ivilayer_resource* ivires = NULL;
+
+#ifdef _DEBUG
+ weston_log("client_layer_create: client=0x%08x, resource=0x%08x \
+ id_layer=%d, width=%d, height=%d, id=%d\n",
+ (uint32_t)client, (uint32_t)resource,
+ id_layer, width, height, id);
+#endif
+
+ ivilayer = get_layer(&shell->list_layer, id_layer);
+ if (ivilayer != NULL)
+ {
+ weston_log("id_layer is already created\n");
+ resource = wl_resource_create(client, &ivi_layer_interface, 1, id);
+
+ send_layer_event(ivilayer, resource, PROP_EVENT_ALL);
+ return;
+ }
+
+ ivilayer = calloc(1, sizeof *ivilayer);
+ if (!ivilayer) {
+ weston_log("no memory to allocate client layer\n");
+ return;
+ }
+
+ init_properties(&ivilayer->prop, width, height);
+ ivilayer->pending.prop = ivilayer->prop;
+ ivilayer->id_layer = id_layer;
+ ivilayer->shell = shell;
+ ivilayer->event_mask = 0;
+ wl_list_init(&ivilayer->list_resource);
+ wl_list_init(&ivilayer->link);
+ wl_list_init(&ivilayer->pending.link);
+ wl_list_init(&ivilayer->order.link);
+ wl_list_init(&ivilayer->list_screen);
+
+ wl_list_init(&ivilayer->pending.list_surface);
+ wl_list_init(&ivilayer->order.list_surface);
+ wl_list_insert(&shell->list_layer, &ivilayer->link);
+
+ wl_list_for_each(controller, &shell->list_controller_client, link) {
+ ivires = create_layerresource(ivilayer,
+ controller->client,
+ &controller->resource->destroy_signal);
+ if (ivires == NULL) {
+ weston_log("no memory to allocate layerresource\n");
+ continue;
+ }
+
+ ivi_controller_send_layer(controller->resource,
+ ivilayer->id_layer,
+ ivires->res_layer,
+ ivires->res_ctrl_layer);
+ send_layer_event(ivilayer, ivires->res_layer, PROP_EVENT_ALL);
+ }
+
+ resource = wl_resource_create(client, &ivi_layer_interface, 1, id);
+ if (resource == NULL) {
+ weston_log("couldn't layer object");
+ return;
+ }
+ wl_resource_set_implementation(resource,
+ &layer_implementation,
+ ivires, NULL);
+
+ send_layer_event(ivilayer, resource, PROP_EVENT_ALL);
+}
+
+static const struct ivi_client_interface client_implementation = {
+ client_surface_create,
+ client_layer_create
+};
+
+static void
+bind_ivi_client(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+ struct ivi_shell *shell = data;
+ struct wl_resource *resource = NULL;
+
+#ifdef _DEBUG
+ weston_log("bind_ivi_client is called: client=0x%08x, data=0x%08x\n, \
+ version=%d, id=%d\n",
+ (uint32_t)client, (uint32_t)data, version, id);
+#endif
+
+ resource = wl_resource_create(client, &ivi_client_interface, 1, id);
+ wl_resource_set_implementation(resource,
+ &client_implementation,
+ shell, NULL);
+}
+
+static void
+add_client_to_resources(struct ivi_shell *shell,
+ struct wl_client *client,
+ struct wl_signal *signal_destroy,
+ struct ivi_client_ctrl *controller)
+{
+ struct ivi_client_surface* ivisurf = NULL;
+ struct ivisurface_resource* ressurf = NULL;
+ struct ivi_client_layer* ivilayer = NULL;
+ struct ivilayer_resource* reslayer = NULL;
+ struct ivi_client_screen* iviscrn = NULL;
+ struct iviscrn_resource* resscrn = NULL;
+ struct wl_resource *resource_output = NULL;
+
+ wl_list_for_each(ivisurf, &shell->list_surface, link) {
+ ressurf = create_surfaceresource(ivisurf, client,
+ signal_destroy);
+ if (ressurf == NULL) {
+ continue;
+ }
+
+ ivi_controller_send_surface(controller->resource,
+ ivisurf->id_surface,
+ ressurf->res_surf,
+ ressurf->res_ctrl_surf);
+ }
+
+ wl_list_for_each(ivilayer, &shell->list_layer, link) {
+ reslayer = create_layerresource(ivilayer, client,
+ signal_destroy);
+ if (reslayer == NULL) {
+ continue;
+ }
+
+ ivi_controller_send_layer(controller->resource,
+ ivilayer->id_layer,
+ reslayer->res_layer,
+ reslayer->res_ctrl_layer);
+ }
+
+ wl_list_for_each(iviscrn, &shell->list_screen, link) {
+ resource_output =
+ find_resource_for_client(&iviscrn->output->resource_list,
+ client);
+ if (resource_output == NULL) {
+ continue;
+ }
+ resscrn = create_screenresource(iviscrn, client,
+ signal_destroy,
+ resource_output->object.id);
+ if (resscrn == NULL) {
+ continue;
+ }
+
+ ivi_controller_send_screen(controller->resource,
+ resource_output->object.id,
+ resscrn->res_ctrl_scrn);
+ }
+
+ wl_list_for_each(ivisurf, &shell->list_surface, link) {
+ wl_list_for_each(ressurf, &ivisurf->list_resource, link) {
+ if (ressurf->client != controller->resource->client) {
+ continue;
+ }
+usleep(1000);
+ send_surface_event(ivisurf, ressurf->res_surf, PROP_EVENT_ALL);
+ }
+ }
+
+ wl_list_for_each(ivilayer, &shell->list_layer, link) {
+ wl_list_for_each(reslayer, &ivilayer->list_resource, link) {
+ if (reslayer->client != controller->resource->client) {
+ continue;
+ }
+ send_layer_event(ivilayer, reslayer->res_layer, PROP_EVENT_ALL);
+ }
+ }
+}
+
+static void
+bind_ivi_controller(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+ struct ivi_shell *shell = data;
+ struct ivi_client_ctrl *controller;
+
+#ifdef _DEBUG
+ weston_log("bind_ivi_controller is called: client=0x%08x, \
+ data=0x%08x\n, version=%d, id=%d\n",
+ (uint32_t)client, (uint32_t)data, version, id);
+#endif
+
+ controller = calloc(1, sizeof *controller);
+ if (controller == NULL) {
+ weston_log("no memory to allocate controller\n");
+ return;
+ }
+
+ controller->resource =
+ wl_resource_create(client, &ivi_controller_interface, 1, id);
+ wl_resource_set_implementation(controller->resource,
+ &controller_implementation,
+ controller, unbind_resource_controller);
+
+ controller->shell = shell;
+ controller->client = client;
+ controller->id = id;
+
+ wl_list_init(&controller->link);
+ wl_list_insert(&shell->list_controller_client, &controller->link);
+
+ add_client_to_resources(shell, client,
+ &controller->resource->destroy_signal,
+ controller);
+}
+
+static struct ivi_client_screen*
+create_screen(struct ivi_shell *shell, struct weston_output *output)
+{
+ struct ivi_client_screen *iviscrn;
+ iviscrn = calloc(1, sizeof *iviscrn);
+ if (iviscrn == NULL) {
+ weston_log("no memory to allocate client screen\n");
+ return NULL;
+ }
+ iviscrn->shell = shell;
+ iviscrn->output = output;
+ iviscrn->event_mask = 0;
+
+ wl_list_init(&iviscrn->link);
+ wl_list_init(&iviscrn->list_layer);
+ wl_list_init(&iviscrn->pending.list_layer);
+ wl_list_init(&iviscrn->order.list_layer);
+ wl_list_init(&iviscrn->list_resource);
+
+ return iviscrn;
+}
+
+static void
+init_ivi_shell(struct weston_compositor *ec, struct ivi_shell *shell)
+{
+ struct weston_output *output = NULL;
+ struct ivi_client_screen *iviscrn = NULL;
+ shell->compositor = ec;
+
+ wl_list_init(&ec->layer_list);
+ wl_list_init(&shell->list_surface);
+ wl_list_init(&shell->list_layer);
+ wl_list_init(&shell->list_screen);
+ wl_list_init(&shell->list_weston_surface);
+ wl_list_init(&shell->list_controller_client);
+
+ wl_list_for_each(output, &ec->output_list, link) {
+ iviscrn = create_screen(shell, output);
+ if (iviscrn != NULL) {
+ wl_list_insert(&shell->list_screen, &iviscrn->link);
+ }
+ wl_list_init(&iviscrn->order.list_layer);
+ }
+}
+
+static void
+shell_destroy(struct wl_listener *listener, void *data)
+{
+ struct ivi_shell *shell =
+ container_of(listener, struct ivi_shell, destroy_listener);
+
+ free(shell);
+}
+
+static void
+ping_timer_destroy(struct shell_surface *shsurf)
+{
+ if (!shsurf || !shsurf->ping_timer) {
+ return;
+ }
+
+ if (shsurf->ping_timer->source) {
+ wl_event_source_remove(shsurf->ping_timer->source);
+ }
+
+ free(shsurf->ping_timer);
+ shsurf->ping_timer = NULL;
+}
+
+static void
+destroy_shell_surface(struct shell_surface *shsurf)
+{
+ wl_list_remove(&shsurf->surface_destroy_listener.link);
+ shsurf->surface->configure = NULL;
+ ping_timer_destroy(shsurf);
+ free(shsurf->title);
+
+ wl_list_remove(&shsurf->link);
+ free(shsurf);
+}
+
+static void
+shell_handle_surface_destroy(struct wl_listener *listener, void *data)
+{
+ struct shell_surface *shsurf = container_of(listener,
+ struct shell_surface,
+ surface_destroy_listener);
+
+ if (shsurf->resource->client) {
+ wl_resource_destroy(shsurf->resource);
+ } else {
+ wl_signal_emit(&shsurf->resource->destroy_signal,
+ shsurf->resource);
+ destroy_shell_surface(shsurf);
+ }
+}
+
+static void
+configure(struct weston_surface *surface,
+ float x, float y, int32_t width, int32_t height)
+{
+ weston_surface_configure(surface, x, y, width, height);
+ if (surface->output) {
+ weston_surface_update_transform(surface);
+ }
+}
+
+static void
+shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
+{
+ float from_x = 0.0f;
+ float from_y = 0.0f;
+ float to_x = 0.0f;
+ float to_y = 0.0f;
+ struct shell_surface *shsurf = get_shell_surface(es);
+
+ if ((width == 0) || (height == 0) || (shsurf == NULL)) {
+ return;
+ }
+
+ if (weston_surface_is_mapped(es) &&
+ (sx != 0 || sy != 0 ||
+ shsurf->width != width ||
+ shsurf->height != height)) {
+
+ shsurf->width = width;
+ shsurf->height = height;
+
+ weston_surface_to_global_float(es, 0, 0, &from_x, &from_y);
+ weston_surface_to_global_float(es, sx, sy, &to_x, &to_y);
+ configure(es,
+ es->geometry.x + to_x - from_x,
+ es->geometry.y + to_y - from_y,
+ width, height);
+
+ send_naivesurface(shsurf->resource,
+ shsurf, shsurf->title);
+
+ commit_changes(shsurf->shell);
+ }
+}
+
+static struct shell_surface *
+create_shell_surface(void *shell, struct weston_surface *surface,
+ const struct weston_shell_client *client)
+{
+ struct shell_surface *shsurf;
+
+ if (surface->configure) {
+ weston_log("surface->configure already set\n");
+ return NULL;
+ }
+
+ shsurf = calloc(1, sizeof *shsurf);
+ if (shsurf == NULL) {
+ weston_log("no memory to allocate shell surface\n");
+ return NULL;
+ }
+
+ surface->configure = shell_surface_configure;
+ surface->configure_private = shsurf;
+
+ shsurf->shell = (struct ivi_shell *)shell;
+ shsurf->surface = surface;
+ shsurf->ping_timer = NULL;
+ shsurf->title = strdup("");
+
+ /* init link so its safe to always remove it in destroy_shell_surface */
+ wl_list_init(&shsurf->link);
+
+ shsurf->client = client;
+
+ return shsurf;
+}
+
+static void
+send_configure(struct weston_surface *surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+ struct shell_surface *shsurf = get_shell_surface(surface);
+
+ wl_shell_surface_send_configure(shsurf->resource,
+ edges, width, height);
+}
+
+static const struct weston_shell_client shell_client = {
+ send_configure
+};
+
+static void
+shell_destroy_shell_surface(struct wl_resource *resource)
+{
+ struct shell_surface *shsurf = resource->data;
+
+ destroy_shell_surface(shsurf);
+}
+
+static void
+shell_surface_pong(struct wl_client *client,
+ struct wl_resource *resource, uint32_t serial)
+{
+ struct shell_surface *shsurf = resource->data;
+
+ if (shsurf->ping_timer == NULL) {
+ return;
+ }
+
+ if (shsurf->ping_timer->serial == serial) {
+ ping_timer_destroy(shsurf);
+ }
+}
+
+static void
+shell_surface_move(struct wl_client *client, struct wl_resource *resource,
+ struct wl_resource *seat_resource, uint32_t serial)
+{
+}
+
+static void
+shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
+ struct wl_resource *seat_resource, uint32_t serial,
+ uint32_t edges)
+{
+}
+
+static void
+shell_surface_set_toplevel(struct wl_client *client,
+ struct wl_resource *resource)
+{
+}
+
+static void
+shell_surface_set_transient(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *parent_resource,
+ int x, int y, uint32_t flags)
+{
+}
+
+static void
+shell_surface_set_fullscreen(struct wl_client *client,
+struct wl_resource *resource,
+uint32_t method,
+uint32_t framerate,
+struct wl_resource *output_resource)
+{
+}
+
+static void
+shell_surface_set_popup(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *seat_resource,
+ uint32_t serial,
+ struct wl_resource *parent_resource,
+ int32_t x, int32_t y, uint32_t flags)
+{
+}
+
+static void
+shell_surface_set_maximized(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *output_resource)
+{
+}
+
+static void
+shell_surface_set_title(struct wl_client *client,
+ struct wl_resource *resource, const char *title)
+{
+ struct shell_surface *shsurf = resource->data;
+
+ free(shsurf->title);
+ if (title != NULL) {
+ shsurf->title = strdup(title);
+ } else {
+ shsurf->title = strdup("");
+ }
+
+ send_naivesurface(resource, shsurf, title);
+}
+
+static void
+shell_surface_set_class(struct wl_client *client,
+ struct wl_resource *resource, const char *class)
+{
+ struct shell_surface *shsurf = resource->data;
+
+ free(shsurf->class);
+ shsurf->class = strdup(class);
+}
+
+static const struct wl_shell_surface_interface shell_surface_implementation = {
+ shell_surface_pong,
+ shell_surface_move,
+ shell_surface_resize,
+ shell_surface_set_toplevel,
+ shell_surface_set_transient,
+ shell_surface_set_fullscreen,
+ shell_surface_set_popup,
+ shell_surface_set_maximized,
+ shell_surface_set_title,
+ shell_surface_set_class
+};
+
+static void
+shell_weston_surface_destroy(struct wl_listener *listener, void *data)
+{
+ struct link_shell_weston_surface *lsurf =
+ container_of(listener,
+ struct link_shell_weston_surface,
+ destroy_listener);
+ wl_list_remove(&lsurf->link);
+ free(lsurf);
+}
+
+
+static void
+shell_get_shell_surface(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id,
+ struct wl_resource *surface_resource)
+{
+ struct weston_surface *surface =
+ wl_resource_get_user_data(surface_resource);
+ struct ivi_shell *shell = wl_resource_get_user_data(resource);
+ struct shell_surface *shsurf;
+ struct link_shell_weston_surface *lsurf;
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+
+ if (get_shell_surface(surface)) {
+ wl_resource_post_error(surface_resource,
+ WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "ivi_shell::get_shell_surface already requested");
+ return;
+ }
+
+ shsurf = create_shell_surface(shell, surface, &shell_client);
+ if (!shsurf) {
+ wl_resource_post_error(surface_resource,
+ WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "surface->configure already set");
+ return;
+ }
+
+ shsurf->resource = wl_resource_create(client,
+ &wl_shell_surface_interface,
+ 1, id);
+ wl_resource_set_implementation(shsurf->resource,
+ &shell_surface_implementation,
+ shsurf, shell_destroy_shell_surface);
+
+ wl_signal_init(&shsurf->resource->destroy_signal);
+ shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
+ wl_signal_add(&surface->resource->destroy_signal,
+ &shsurf->surface_destroy_listener);
+
+ lsurf = (struct link_shell_weston_surface*)malloc(sizeof *lsurf);
+ lsurf->surface = surface;
+ wl_list_init(&lsurf->link);
+ wl_list_insert(&shell->list_weston_surface, &lsurf->link);
+
+ wl_signal_init(&lsurf->resource.destroy_signal);
+ lsurf->destroy_listener.notify = shell_weston_surface_destroy;
+ wl_signal_add(&surface->resource->destroy_signal,
+ &lsurf->destroy_listener);
+
+ wl_client_get_credentials(client, &pid, &uid, &gid);
+ shsurf->pid = pid;
+ send_naivesurface(resource, shsurf, "");
+}
+
+static const struct wl_shell_interface shell_implementation = {
+ shell_get_shell_surface
+};
+
+static void
+bind_shell(struct wl_client *client, void *data,
+ uint32_t version, uint32_t id)
+{
+ struct ivi_shell *shell = data;
+ struct wl_resource *resource = NULL;
+
+ resource = wl_resource_create(client, &wl_shell_interface, 1, id);
+ wl_resource_set_implementation(resource,
+ &shell_implementation,
+ shell, NULL);
+}
+
+WL_EXPORT int
+module_init(struct weston_compositor *ec,
+ int *argc, char *argv[])
+{
+ struct weston_seat *seat;
+ struct ivi_shell *shell;
+
+ shell = malloc(sizeof *shell);
+ if (shell == NULL)
+ return -1;
+
+ memset(shell, 0, sizeof *shell);
+ init_ivi_shell(ec, shell);
+
+ shell->destroy_listener.notify = shell_destroy;
+ wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
+
+ if (wl_global_create(ec->wl_display, &wl_shell_interface, 1,
+ shell, bind_shell) == NULL) {
+ return -1;
+ }
+
+ if (wl_global_create(ec->wl_display, &ivi_client_interface, 1,
+ shell, bind_ivi_client) == NULL)
+ return -1;
+
+ if (wl_global_create(ec->wl_display, &ivi_controller_interface, 1,
+ shell, bind_ivi_controller) == NULL)
+ return -1;
+
+ wl_list_for_each(seat, &ec->seat_list, link) {
+ if (seat) {
+ shell->seat = seat;
+ }
+ }
+
+ return 0;
+}
--
1.7.4.4
More information about the wayland-devel
mailing list