summaryrefslogtreecommitdiffstats
path: root/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch')
-rw-r--r--meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch589
1 files changed, 589 insertions, 0 deletions
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch
new file mode 100644
index 000000000..4e63c7a0b
--- /dev/null
+++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch
@@ -0,0 +1,589 @@
+From c89c2d63db3cbe83fb1ddd983e4b0ffe87fab296 Mon Sep 17 00:00:00 2001
+From: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Date: Fri, 1 Jul 2016 00:28:50 -0400
+Subject: [PATCH 8/8] ivi-shell: Add simple IVI shell layout controller
+
+Simple IVI shell layout controller.
+Assign only one application to primary display.
+Second and rest application will go to secondary display if it's
+present.
+
+Signed-off-by: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Signed-off-by: Karthik Ramanan <a0393906@ti.com>
+---
+ Makefile.am | 12 +-
+ ivi-shell/ivi-layout-controller-ti.c | 532 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 543 insertions(+), 1 deletion(-)
+ create mode 100644 ivi-shell/ivi-layout-controller-ti.c
+
+diff --git a/Makefile.am b/Makefile.am
+index 55aed6d..a9fe3c8 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -868,7 +868,8 @@ if ENABLE_IVI_SHELL
+
+ module_LTLIBRARIES += \
+ $(ivi_shell) \
+- $(hmi_controller)
++ $(hmi_controller) \
++ $(layout_controller)
+
+ ivi_shell = ivi-shell.la
+ ivi_shell_la_LDFLAGS = -module -avoid-version
+@@ -903,6 +904,15 @@ nodist_hmi_controller_la_SOURCES = \
+
+ BUILT_SOURCES += $(nodist_hmi_controller_la_SOURCES)
+
++layout_controller = layout-controller.la
++layout_controller_la_LDFLAGS = -module -avoid-version
++layout_controller_la_LIBADD = $(COMPOSITOR_LIBS) libshared.la
++layout_controller_la_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS)
++layout_controller_la_SOURCES = \
++ ivi-shell/ivi-layout-export.h \
++ ivi-shell/ivi-layout-controller-ti.c \
++ shared/helpers.h
++
+ endif
+
+
+diff --git a/ivi-shell/ivi-layout-controller-ti.c b/ivi-shell/ivi-layout-controller-ti.c
+new file mode 100644
+index 0000000..b7cf436
+--- /dev/null
++++ b/ivi-shell/ivi-layout-controller-ti.c
+@@ -0,0 +1,532 @@
++/*
++ * Copyright (C) 2016 GlobalLogic Inc
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ */
++
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++
++#include "ivi-layout-export.h"
++
++#ifndef container_of
++#define container_of(ptr, type, member) ({ \
++ const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
++ (type *)( (char *)__mptr - offsetof(type,member) );})
++#endif
++
++#ifndef BIT
++#define BIT(bit) (1 << (bit))
++#endif
++
++#define __MODULE__ "layout-controller"
++#define DL_ERR BIT(0)
++#define DL_WRN BIT(1)
++#define DL_DBG BIT(2)
++#define DL_ALL (~0)
++
++static unsigned debug_level = DL_ALL;
++
++#define __print_log(__dl__, ... ) \
++if (__dl__ & debug_level) \
++ fprintf(__dl__ == DL_ERR ? stderr : stdout," ["__MODULE__"]:" __VA_ARGS__);
++
++#define pr_err(...) __print_log(DL_ERR, "E: " __VA_ARGS__)
++#define pr_dbg(...) __print_log(DL_DBG, "D: " __VA_ARGS__)
++#define pr_wrn(...) __print_log(DL_WRN, "W: " __VA_ARGS__)
++#define TRACE() __print_log(DL_DBG, "TR: %s - %d\n", __func__, __LINE__)
++
++
++#define WINDOWS_TITLE_HEIGHT 30
++#define DEFAULT_SURFACE_ID_FOR_WL_SHELL_APP 0x80000000
++
++/*****************************************************************************
++ * structure, globals
++ ****************************************************************************/
++struct hmi_controller_layer {
++ struct ivi_layout_layer *ivilayer;
++ uint32_t id_layer;
++ int32_t x;
++ int32_t y;
++ int32_t width;
++ int32_t height;
++ int32_t num_surfaces;
++ pid_t pid;
++ struct wl_list link;
++ struct wl_list screen_link;
++ struct wl_list surfaces_list;
++};
++
++struct hmi_controller_surface {
++ void *controller;
++ void *ivisurf;
++ struct wl_list link;
++ struct wl_listener destroy_listener;
++};
++
++struct hmi_controller_screen {
++ struct ivi_layout_screen *iviscrn;
++ struct wl_list layers_list;
++};
++
++struct hmi_server_setting {
++ uint32_t base_layer_id;
++ int32_t panel_height;
++ char *ivi_homescreen;
++};
++
++struct hmi_controller {
++ int32_t current_layer;
++ int32_t current_screen;
++ int32_t screens_count;
++ int32_t workspace_count;
++
++ struct hmi_server_setting *hmi_setting;
++ struct hmi_controller_screen screens[4];
++ struct hmi_controller_layer application_layer;
++ struct weston_compositor *compositor;
++ struct wl_listener destroy_listener;
++ struct wl_client *user_interface;
++ struct wl_list layers_list;
++};
++
++const struct ivi_controller_interface *ivi_controller_interface;
++
++static void
++hmi_ctrl_surface_destroy(struct wl_listener *listener, void *data);
++
++int
++controller_module_init(struct weston_compositor *ec,
++ int *argc, char *argv[],
++ const struct ivi_controller_interface *interface,
++ size_t interface_version);
++
++/*****************************************************************************
++ * local functions
++ ****************************************************************************/
++static void *
++fail_on_null(void *p, size_t size, char *file, int32_t line)
++{
++ if (size && !p) {
++ weston_log("%s(%d) %zd: out of memory\n", file, line, size);
++ exit(EXIT_FAILURE);
++ }
++
++ return p;
++}
++
++static void *
++mem_alloc(size_t size, char *file, int32_t line)
++{
++ return fail_on_null(calloc(1, size), size, file, line);
++}
++
++#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
++
++/**
++ * Internal method to create ivi_layer with hmi_controller_layer and
++ * add to a ivi_screen
++ */
++static void
++create_layer(struct ivi_layout_screen *iviscrn,
++ struct hmi_controller_layer *layer)
++{
++ int32_t ret = 0;
++
++ layer->ivilayer =
++ ivi_controller_interface->layer_create_with_dimension(layer->id_layer,
++ layer->width,
++ layer->height);
++ assert(layer->ivilayer != NULL);
++
++ ret = ivi_controller_interface->screen_add_layer(iviscrn, layer->ivilayer);
++
++ assert(!ret);
++
++ ret = ivi_controller_interface->layer_set_destination_rectangle(layer->ivilayer,
++ layer->x, layer->y,
++ layer->width,
++ layer->height);
++ assert(!ret);
++
++ ret = ivi_controller_interface->layer_set_visibility(layer->ivilayer, true);
++
++ assert(!ret);
++
++ ivi_controller_interface->commit_changes();
++
++}
++
++static struct hmi_controller_layer
++*get_layer_for_surface(struct hmi_controller *hmi_ctrl
++ , struct ivi_layout_surface *ivisurf
++ , bool create)
++{
++ struct hmi_controller_layer *layer;
++ struct weston_surface *surface;
++ int32_t i = 0;
++ struct wl_client *client;
++ struct ivi_layout_screen *iviscrn = NULL;
++ struct weston_output *output = NULL;
++ pid_t pid;
++ uid_t uid;
++ gid_t gid;
++
++ surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
++
++ if (!surface)
++ goto exit;
++
++ client = wl_resource_get_client(surface->resource);
++
++ wl_client_get_credentials(client, &pid, &uid, &gid);
++
++ wl_list_for_each(layer, &hmi_ctrl->layers_list, link) {
++ if (layer->pid == pid) {
++ pr_dbg("Existed layer for PID=%d was found\n", pid);
++ return layer;
++ }
++ }
++
++ if (!(create && hmi_ctrl->screens_count))
++ goto exit;
++
++ pr_dbg("Existed layer for PID=%d was not found. Creating new\n", pid);
++
++ for(;; i++) {
++ if (wl_list_empty(&hmi_ctrl->screens[i].layers_list) ||
++ (i == (hmi_ctrl->screens_count - 1)))
++ break;
++ };
++
++ iviscrn = hmi_ctrl->screens[i].iviscrn;
++
++ layer = calloc(1, sizeof *layer);
++
++ output = ivi_controller_interface->screen_get_output(iviscrn);
++
++ wl_list_init(&layer->link);
++ wl_list_init(&layer->screen_link);
++ wl_list_init(&layer->surfaces_list);
++
++ layer->width = output->width;
++ layer->height = output->height + WINDOWS_TITLE_HEIGHT;
++ layer->id_layer = hmi_ctrl->hmi_setting->base_layer_id++;
++ layer->pid = pid;
++
++ create_layer(iviscrn, layer);
++
++ wl_list_insert(&hmi_ctrl->layers_list, &layer->link);
++ wl_list_insert(&hmi_ctrl->screens[i].layers_list, &layer->screen_link);
++
++ return layer;
++
++exit:
++ return NULL;
++}
++
++static void
++set_notification_create_surface(struct ivi_layout_surface *ivisurf,
++ void *userdata)
++{
++ struct hmi_controller *hmi_ctrl = userdata;
++ struct hmi_controller_layer *hmi_ctrl_layer = NULL;
++ struct hmi_controller_surface *hmi_ctrl_surf = NULL;
++ struct ivi_layout_layer *dest_layer;
++ struct weston_surface *surface;
++
++ wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
++ wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
++ if (hmi_ctrl_surf->ivisurf == ivisurf) {
++ pr_dbg("Surface was already configured. Skip add to list\n");
++ return;
++ }
++ }
++ }
++
++ pr_dbg("Surface create: add to list and get the layer\n");
++
++ hmi_ctrl_layer = get_layer_for_surface(hmi_ctrl, ivisurf, true);
++ dest_layer = hmi_ctrl_layer->ivilayer;
++
++ ivi_controller_interface->layer_add_surface(dest_layer, ivisurf);
++
++ hmi_ctrl_surf = calloc(1, sizeof(*hmi_ctrl_surf));
++ hmi_ctrl_surf->ivisurf = ivisurf;
++ wl_list_init(&hmi_ctrl_surf->link);
++ wl_list_insert(&hmi_ctrl_layer->surfaces_list, &hmi_ctrl_surf->link);
++
++
++ /*
++ * Set destroy signal for surface
++ * HACK: We trying to track surfaces were created by wl_shell_emulator
++ */
++ if (ivi_controller_interface->get_id_of_surface(ivisurf) >=
++ DEFAULT_SURFACE_ID_FOR_WL_SHELL_APP) {
++ surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
++ hmi_ctrl_surf->destroy_listener.notify = hmi_ctrl_surface_destroy;
++ wl_signal_add(&surface->destroy_signal, &hmi_ctrl_surf->destroy_listener);
++ hmi_ctrl_surf->controller = userdata;
++ }
++}
++
++static void
++set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
++ void *userdata)
++{
++ struct hmi_controller *hmi_ctrl = userdata;
++ struct hmi_controller_layer *hmi_ctrl_layer = NULL;
++ struct hmi_controller_surface *surf = NULL;
++ struct ivi_layout_layer *dest_layer;
++
++ wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
++ wl_list_for_each(surf, &hmi_ctrl_layer->surfaces_list, link) {
++ if (surf->ivisurf == ivisurf) {
++ pr_dbg("Surface remove: surface was found\n");
++ goto remove;
++ }
++ }
++ }
++
++ goto exit;
++
++remove:
++ dest_layer = hmi_ctrl_layer->ivilayer;
++
++ wl_list_remove(&surf->link);
++
++ ivi_controller_interface->layer_remove_surface(dest_layer, ivisurf);
++
++ if (wl_list_empty(&hmi_ctrl_layer->surfaces_list)) {
++ wl_list_remove(&hmi_ctrl_layer->link);
++ wl_list_remove(&hmi_ctrl_layer->screen_link);
++ ivi_controller_interface->layer_destroy(dest_layer);
++ free(hmi_ctrl_layer);
++ }
++
++ free(surf);
++
++exit:
++ ivi_controller_interface->commit_changes();
++}
++
++static void
++hmi_ctrl_surface_destroy(struct wl_listener *listener, void *data)
++{
++ struct hmi_controller_surface *hmi_ctrl_surface =
++ container_of(listener, struct hmi_controller_surface,
++ destroy_listener);
++
++ pr_dbg("Try to remove surface by direct notification\n");
++
++ ivi_controller_interface->surface_destroy(hmi_ctrl_surface->ivisurf);
++}
++
++static void
++set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
++ void *userdata)
++{
++ struct hmi_controller *hmi_ctrl = userdata;
++ struct hmi_controller_layer *hmi_ctrl_layer = NULL;
++ struct weston_surface *surface;
++ struct hmi_controller_surface *hmi_ctrl_surf = NULL;
++
++ wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
++ wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
++ if (hmi_ctrl_surf->ivisurf == ivisurf) {
++ pr_dbg("Surface was already configured. Skip add to list\n");
++ goto found;
++ }
++ }
++ }
++
++ hmi_ctrl_layer = NULL;
++found:
++ surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
++
++ if (surface) {
++
++ ivi_controller_interface->surface_set_source_rectangle(
++ ivisurf, 0, WINDOWS_TITLE_HEIGHT, surface->width,
++ surface->height);
++
++#if 0
++ ivi_controller_interface->surface_set_destination_rectangle(
++ ivisurf, 0, 0, surface->width, surface->height);
++#else
++ if (hmi_ctrl_layer) {
++ ivi_controller_interface->surface_set_destination_rectangle(
++ ivisurf, 0, 0, hmi_ctrl_layer->width, hmi_ctrl_layer->height);
++ } else {
++ ivi_controller_interface->surface_set_destination_rectangle(
++ ivisurf, 0, 0, surface->width, surface->height);
++ }
++#endif
++ ivi_controller_interface->surface_set_visibility(ivisurf, true);
++ ivi_controller_interface->commit_changes();
++ }
++}
++
++static struct hmi_server_setting *
++hmi_server_setting_create(struct weston_compositor *ec)
++{
++ struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
++ struct weston_config *config = ec->config;
++ struct weston_config_section *shell_section = NULL;
++
++ shell_section = weston_config_get_section(config, "ivi-shell",
++ NULL, NULL);
++
++ weston_config_section_get_uint(shell_section, "base-layer-id",
++ &setting->base_layer_id, 1000);
++
++ setting->panel_height = 30;
++
++ return setting;
++}
++
++static void
++hmi_controller_destroy(struct wl_listener *listener, void *data)
++{
++ struct hmi_controller *hmi_ctrl =
++ container_of(listener, struct hmi_controller, destroy_listener);
++
++ free(hmi_ctrl->hmi_setting);
++ free(hmi_ctrl);
++}
++
++static struct hmi_controller *
++hmi_controller_create(struct weston_compositor *ec)
++{
++ struct ivi_layout_screen **pp_screen = NULL;
++ struct ivi_layout_screen *iviscrn = NULL;
++ int32_t screen_length = 0;
++ struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
++ int i, j = 0;
++
++ hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
++ hmi_ctrl->compositor = ec;
++
++ ivi_controller_interface->get_screens(&screen_length, &pp_screen);
++
++ for (i = screen_length; i-- ; j++) {
++
++ iviscrn = pp_screen[i];
++ hmi_ctrl->screens[j].iviscrn = iviscrn;
++ wl_list_init(&hmi_ctrl->screens[i].layers_list);
++
++ hmi_ctrl->screens_count++;
++ }
++
++ ivi_controller_interface->add_notification_create_surface(
++ set_notification_create_surface, hmi_ctrl);
++ ivi_controller_interface->add_notification_remove_surface(
++ set_notification_remove_surface, hmi_ctrl);
++ ivi_controller_interface->add_notification_configure_surface(
++ set_notification_configure_surface, hmi_ctrl);
++
++ hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
++ wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
++ &hmi_ctrl->destroy_listener);
++
++ wl_list_init(&hmi_ctrl->layers_list);
++
++ free(pp_screen);
++ pp_screen = NULL;
++
++ return hmi_ctrl;
++}
++
++WL_EXPORT const struct wl_interface ivi_hmi_controller_interface = {
++ "ivi_layout_controller", 1,
++ 0, NULL,
++ 0, NULL,
++};
++
++static void
++bind_hmi_controller(struct wl_client *client,
++ void *data, uint32_t version, uint32_t id)
++{
++ struct hmi_controller *hmi_ctrl = data;
++
++ if (hmi_ctrl->user_interface != client) {
++ struct wl_resource *res = wl_client_get_object(client, 1);
++ wl_resource_post_error(res,
++ WL_DISPLAY_ERROR_INVALID_OBJECT,
++ "hmi-controller failed: permission denied");
++ return;
++ }
++
++ wl_resource_create(client, &ivi_hmi_controller_interface, 1, id);
++}
++
++static int32_t
++initialize(struct hmi_controller *hmi_ctrl)
++{
++ struct config_command {
++ char *key;
++ uint32_t *dest;
++ };
++
++ struct weston_config *config = hmi_ctrl->compositor->config;
++
++ weston_config_get_section(config, "ivi-shell", NULL, NULL);
++
++ return 1;
++}
++
++/*****************************************************************************
++ * exported functions
++ ****************************************************************************/
++WL_EXPORT int
++controller_module_init(struct weston_compositor *ec,
++ int *argc, char *argv[],
++ const struct ivi_controller_interface *interface,
++ size_t interface_version)
++{
++ struct hmi_controller *hmi_ctrl = NULL;
++
++
++ if (interface_version < sizeof(struct ivi_controller_interface)) {
++ weston_log("ivi-layout-controller-ti: version mismatch of controller interface");
++ return -1;
++ }
++
++ ivi_controller_interface = interface;
++
++ hmi_ctrl = hmi_controller_create(ec);
++
++ if (!initialize(hmi_ctrl)) {
++ return -1;
++ }
++
++ if (wl_global_create(ec->wl_display,
++ &ivi_hmi_controller_interface, 1,
++ hmi_ctrl, bind_hmi_controller) == NULL) {
++ return -1;
++ }
++
++ weston_log("ivi-layout-controller-ti: Successfully started.");
++
++ return 0;
++}
+--
+2.4.5
+