1 From c89c2d63db3cbe83fb1ddd983e4b0ffe87fab296 Mon Sep 17 00:00:00 2001
2 From: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
3 Date: Fri, 1 Jul 2016 00:28:50 -0400
4 Subject: [PATCH 8/8] ivi-shell: Add simple IVI shell layout controller
6 Simple IVI shell layout controller.
7 Assign only one application to primary display.
8 Second and rest application will go to secondary display if it's
11 Signed-off-by: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
12 Signed-off-by: Karthik Ramanan <a0393906@ti.com>
15 ivi-shell/ivi-layout-controller-ti.c | 532 +++++++++++++++++++++++++++++++++++
16 2 files changed, 543 insertions(+), 1 deletion(-)
17 create mode 100644 ivi-shell/ivi-layout-controller-ti.c
19 diff --git a/Makefile.am b/Makefile.am
20 index 55aed6d..a9fe3c8 100644
23 @@ -868,7 +868,8 @@ if ENABLE_IVI_SHELL
25 module_LTLIBRARIES += \
29 + $(layout_controller)
31 ivi_shell = ivi-shell.la
32 ivi_shell_la_LDFLAGS = -module -avoid-version
33 @@ -903,6 +904,15 @@ nodist_hmi_controller_la_SOURCES = \
35 BUILT_SOURCES += $(nodist_hmi_controller_la_SOURCES)
37 +layout_controller = layout-controller.la
38 +layout_controller_la_LDFLAGS = -module -avoid-version
39 +layout_controller_la_LIBADD = $(COMPOSITOR_LIBS) libshared.la
40 +layout_controller_la_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS)
41 +layout_controller_la_SOURCES = \
42 + ivi-shell/ivi-layout-export.h \
43 + ivi-shell/ivi-layout-controller-ti.c \
49 diff --git a/ivi-shell/ivi-layout-controller-ti.c b/ivi-shell/ivi-layout-controller-ti.c
51 index 0000000..b7cf436
53 +++ b/ivi-shell/ivi-layout-controller-ti.c
56 + * Copyright (C) 2016 GlobalLogic Inc
58 + * Permission is hereby granted, free of charge, to any person obtaining
59 + * a copy of this software and associated documentation files (the
60 + * "Software"), to deal in the Software without restriction, including
61 + * without limitation the rights to use, copy, modify, merge, publish,
62 + * distribute, sublicense, and/or sell copies of the Software, and to
63 + * permit persons to whom the Software is furnished to do so, subject to
64 + * the following conditions:
66 + * The above copyright notice and this permission notice (including the
67 + * next paragraph) shall be included in all copies or substantial
68 + * portions of the Software.
70 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
71 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
72 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
73 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
74 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
75 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
76 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
84 +#include "ivi-layout-export.h"
87 +#define container_of(ptr, type, member) ({ \
88 + const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
89 + (type *)( (char *)__mptr - offsetof(type,member) );})
93 +#define BIT(bit) (1 << (bit))
96 +#define __MODULE__ "layout-controller"
97 +#define DL_ERR BIT(0)
98 +#define DL_WRN BIT(1)
99 +#define DL_DBG BIT(2)
102 +static unsigned debug_level = DL_ALL;
104 +#define __print_log(__dl__, ... ) \
105 +if (__dl__ & debug_level) \
106 + fprintf(__dl__ == DL_ERR ? stderr : stdout," ["__MODULE__"]:" __VA_ARGS__);
108 +#define pr_err(...) __print_log(DL_ERR, "E: " __VA_ARGS__)
109 +#define pr_dbg(...) __print_log(DL_DBG, "D: " __VA_ARGS__)
110 +#define pr_wrn(...) __print_log(DL_WRN, "W: " __VA_ARGS__)
111 +#define TRACE() __print_log(DL_DBG, "TR: %s - %d\n", __func__, __LINE__)
114 +#define WINDOWS_TITLE_HEIGHT 30
115 +#define DEFAULT_SURFACE_ID_FOR_WL_SHELL_APP 0x80000000
117 +/*****************************************************************************
118 + * structure, globals
119 + ****************************************************************************/
120 +struct hmi_controller_layer {
121 + struct ivi_layout_layer *ivilayer;
127 + int32_t num_surfaces;
129 + struct wl_list link;
130 + struct wl_list screen_link;
131 + struct wl_list surfaces_list;
134 +struct hmi_controller_surface {
137 + struct wl_list link;
138 + struct wl_listener destroy_listener;
141 +struct hmi_controller_screen {
142 + struct ivi_layout_screen *iviscrn;
143 + struct wl_list layers_list;
146 +struct hmi_server_setting {
147 + uint32_t base_layer_id;
148 + int32_t panel_height;
149 + char *ivi_homescreen;
152 +struct hmi_controller {
153 + int32_t current_layer;
154 + int32_t current_screen;
155 + int32_t screens_count;
156 + int32_t workspace_count;
158 + struct hmi_server_setting *hmi_setting;
159 + struct hmi_controller_screen screens[4];
160 + struct hmi_controller_layer application_layer;
161 + struct weston_compositor *compositor;
162 + struct wl_listener destroy_listener;
163 + struct wl_client *user_interface;
164 + struct wl_list layers_list;
167 +const struct ivi_controller_interface *ivi_controller_interface;
170 +hmi_ctrl_surface_destroy(struct wl_listener *listener, void *data);
173 +controller_module_init(struct weston_compositor *ec,
174 + int *argc, char *argv[],
175 + const struct ivi_controller_interface *interface,
176 + size_t interface_version);
178 +/*****************************************************************************
180 + ****************************************************************************/
182 +fail_on_null(void *p, size_t size, char *file, int32_t line)
185 + weston_log("%s(%d) %zd: out of memory\n", file, line, size);
186 + exit(EXIT_FAILURE);
193 +mem_alloc(size_t size, char *file, int32_t line)
195 + return fail_on_null(calloc(1, size), size, file, line);
198 +#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
201 + * Internal method to create ivi_layer with hmi_controller_layer and
202 + * add to a ivi_screen
205 +create_layer(struct ivi_layout_screen *iviscrn,
206 + struct hmi_controller_layer *layer)
211 + ivi_controller_interface->layer_create_with_dimension(layer->id_layer,
214 + assert(layer->ivilayer != NULL);
216 + ret = ivi_controller_interface->screen_add_layer(iviscrn, layer->ivilayer);
220 + ret = ivi_controller_interface->layer_set_destination_rectangle(layer->ivilayer,
221 + layer->x, layer->y,
226 + ret = ivi_controller_interface->layer_set_visibility(layer->ivilayer, true);
230 + ivi_controller_interface->commit_changes();
234 +static struct hmi_controller_layer
235 +*get_layer_for_surface(struct hmi_controller *hmi_ctrl
236 + , struct ivi_layout_surface *ivisurf
239 + struct hmi_controller_layer *layer;
240 + struct weston_surface *surface;
242 + struct wl_client *client;
243 + struct ivi_layout_screen *iviscrn = NULL;
244 + struct weston_output *output = NULL;
249 + surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
254 + client = wl_resource_get_client(surface->resource);
256 + wl_client_get_credentials(client, &pid, &uid, &gid);
258 + wl_list_for_each(layer, &hmi_ctrl->layers_list, link) {
259 + if (layer->pid == pid) {
260 + pr_dbg("Existed layer for PID=%d was found\n", pid);
265 + if (!(create && hmi_ctrl->screens_count))
268 + pr_dbg("Existed layer for PID=%d was not found. Creating new\n", pid);
271 + if (wl_list_empty(&hmi_ctrl->screens[i].layers_list) ||
272 + (i == (hmi_ctrl->screens_count - 1)))
276 + iviscrn = hmi_ctrl->screens[i].iviscrn;
278 + layer = calloc(1, sizeof *layer);
280 + output = ivi_controller_interface->screen_get_output(iviscrn);
282 + wl_list_init(&layer->link);
283 + wl_list_init(&layer->screen_link);
284 + wl_list_init(&layer->surfaces_list);
286 + layer->width = output->width;
287 + layer->height = output->height + WINDOWS_TITLE_HEIGHT;
288 + layer->id_layer = hmi_ctrl->hmi_setting->base_layer_id++;
291 + create_layer(iviscrn, layer);
293 + wl_list_insert(&hmi_ctrl->layers_list, &layer->link);
294 + wl_list_insert(&hmi_ctrl->screens[i].layers_list, &layer->screen_link);
303 +set_notification_create_surface(struct ivi_layout_surface *ivisurf,
306 + struct hmi_controller *hmi_ctrl = userdata;
307 + struct hmi_controller_layer *hmi_ctrl_layer = NULL;
308 + struct hmi_controller_surface *hmi_ctrl_surf = NULL;
309 + struct ivi_layout_layer *dest_layer;
310 + struct weston_surface *surface;
312 + wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
313 + wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
314 + if (hmi_ctrl_surf->ivisurf == ivisurf) {
315 + pr_dbg("Surface was already configured. Skip add to list\n");
321 + pr_dbg("Surface create: add to list and get the layer\n");
323 + hmi_ctrl_layer = get_layer_for_surface(hmi_ctrl, ivisurf, true);
324 + dest_layer = hmi_ctrl_layer->ivilayer;
326 + ivi_controller_interface->layer_add_surface(dest_layer, ivisurf);
328 + hmi_ctrl_surf = calloc(1, sizeof(*hmi_ctrl_surf));
329 + hmi_ctrl_surf->ivisurf = ivisurf;
330 + wl_list_init(&hmi_ctrl_surf->link);
331 + wl_list_insert(&hmi_ctrl_layer->surfaces_list, &hmi_ctrl_surf->link);
335 + * Set destroy signal for surface
336 + * HACK: We trying to track surfaces were created by wl_shell_emulator
338 + if (ivi_controller_interface->get_id_of_surface(ivisurf) >=
339 + DEFAULT_SURFACE_ID_FOR_WL_SHELL_APP) {
340 + surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
341 + hmi_ctrl_surf->destroy_listener.notify = hmi_ctrl_surface_destroy;
342 + wl_signal_add(&surface->destroy_signal, &hmi_ctrl_surf->destroy_listener);
343 + hmi_ctrl_surf->controller = userdata;
348 +set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
351 + struct hmi_controller *hmi_ctrl = userdata;
352 + struct hmi_controller_layer *hmi_ctrl_layer = NULL;
353 + struct hmi_controller_surface *surf = NULL;
354 + struct ivi_layout_layer *dest_layer;
356 + wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
357 + wl_list_for_each(surf, &hmi_ctrl_layer->surfaces_list, link) {
358 + if (surf->ivisurf == ivisurf) {
359 + pr_dbg("Surface remove: surface was found\n");
368 + dest_layer = hmi_ctrl_layer->ivilayer;
370 + wl_list_remove(&surf->link);
372 + ivi_controller_interface->layer_remove_surface(dest_layer, ivisurf);
374 + if (wl_list_empty(&hmi_ctrl_layer->surfaces_list)) {
375 + wl_list_remove(&hmi_ctrl_layer->link);
376 + wl_list_remove(&hmi_ctrl_layer->screen_link);
377 + ivi_controller_interface->layer_destroy(dest_layer);
378 + free(hmi_ctrl_layer);
384 + ivi_controller_interface->commit_changes();
388 +hmi_ctrl_surface_destroy(struct wl_listener *listener, void *data)
390 + struct hmi_controller_surface *hmi_ctrl_surface =
391 + container_of(listener, struct hmi_controller_surface,
394 + pr_dbg("Try to remove surface by direct notification\n");
396 + ivi_controller_interface->surface_destroy(hmi_ctrl_surface->ivisurf);
400 +set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
403 + struct hmi_controller *hmi_ctrl = userdata;
404 + struct hmi_controller_layer *hmi_ctrl_layer = NULL;
405 + struct weston_surface *surface;
406 + struct hmi_controller_surface *hmi_ctrl_surf = NULL;
408 + wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
409 + wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
410 + if (hmi_ctrl_surf->ivisurf == ivisurf) {
411 + pr_dbg("Surface was already configured. Skip add to list\n");
417 + hmi_ctrl_layer = NULL;
419 + surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
423 + ivi_controller_interface->surface_set_source_rectangle(
424 + ivisurf, 0, WINDOWS_TITLE_HEIGHT, surface->width,
428 + ivi_controller_interface->surface_set_destination_rectangle(
429 + ivisurf, 0, 0, surface->width, surface->height);
431 + if (hmi_ctrl_layer) {
432 + ivi_controller_interface->surface_set_destination_rectangle(
433 + ivisurf, 0, 0, hmi_ctrl_layer->width, hmi_ctrl_layer->height);
435 + ivi_controller_interface->surface_set_destination_rectangle(
436 + ivisurf, 0, 0, surface->width, surface->height);
439 + ivi_controller_interface->surface_set_visibility(ivisurf, true);
440 + ivi_controller_interface->commit_changes();
444 +static struct hmi_server_setting *
445 +hmi_server_setting_create(struct weston_compositor *ec)
447 + struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
448 + struct weston_config *config = ec->config;
449 + struct weston_config_section *shell_section = NULL;
451 + shell_section = weston_config_get_section(config, "ivi-shell",
454 + weston_config_section_get_uint(shell_section, "base-layer-id",
455 + &setting->base_layer_id, 1000);
457 + setting->panel_height = 30;
463 +hmi_controller_destroy(struct wl_listener *listener, void *data)
465 + struct hmi_controller *hmi_ctrl =
466 + container_of(listener, struct hmi_controller, destroy_listener);
468 + free(hmi_ctrl->hmi_setting);
472 +static struct hmi_controller *
473 +hmi_controller_create(struct weston_compositor *ec)
475 + struct ivi_layout_screen **pp_screen = NULL;
476 + struct ivi_layout_screen *iviscrn = NULL;
477 + int32_t screen_length = 0;
478 + struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
481 + hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
482 + hmi_ctrl->compositor = ec;
484 + ivi_controller_interface->get_screens(&screen_length, &pp_screen);
486 + for (i = screen_length; i-- ; j++) {
488 + iviscrn = pp_screen[i];
489 + hmi_ctrl->screens[j].iviscrn = iviscrn;
490 + wl_list_init(&hmi_ctrl->screens[i].layers_list);
492 + hmi_ctrl->screens_count++;
495 + ivi_controller_interface->add_notification_create_surface(
496 + set_notification_create_surface, hmi_ctrl);
497 + ivi_controller_interface->add_notification_remove_surface(
498 + set_notification_remove_surface, hmi_ctrl);
499 + ivi_controller_interface->add_notification_configure_surface(
500 + set_notification_configure_surface, hmi_ctrl);
502 + hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
503 + wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
504 + &hmi_ctrl->destroy_listener);
506 + wl_list_init(&hmi_ctrl->layers_list);
514 +WL_EXPORT const struct wl_interface ivi_hmi_controller_interface = {
515 + "ivi_layout_controller", 1,
521 +bind_hmi_controller(struct wl_client *client,
522 + void *data, uint32_t version, uint32_t id)
524 + struct hmi_controller *hmi_ctrl = data;
526 + if (hmi_ctrl->user_interface != client) {
527 + struct wl_resource *res = wl_client_get_object(client, 1);
528 + wl_resource_post_error(res,
529 + WL_DISPLAY_ERROR_INVALID_OBJECT,
530 + "hmi-controller failed: permission denied");
534 + wl_resource_create(client, &ivi_hmi_controller_interface, 1, id);
538 +initialize(struct hmi_controller *hmi_ctrl)
540 + struct config_command {
545 + struct weston_config *config = hmi_ctrl->compositor->config;
547 + weston_config_get_section(config, "ivi-shell", NULL, NULL);
552 +/*****************************************************************************
553 + * exported functions
554 + ****************************************************************************/
556 +controller_module_init(struct weston_compositor *ec,
557 + int *argc, char *argv[],
558 + const struct ivi_controller_interface *interface,
559 + size_t interface_version)
561 + struct hmi_controller *hmi_ctrl = NULL;
564 + if (interface_version < sizeof(struct ivi_controller_interface)) {
565 + weston_log("ivi-layout-controller-ti: version mismatch of controller interface");
569 + ivi_controller_interface = interface;
571 + hmi_ctrl = hmi_controller_create(ec);
573 + if (!initialize(hmi_ctrl)) {
577 + if (wl_global_create(ec->wl_display,
578 + &ivi_hmi_controller_interface, 1,
579 + hmi_ctrl, bind_hmi_controller) == NULL) {
583 + weston_log("ivi-layout-controller-ti: Successfully started.");