[PATCH weston-ivi-shell v5 6/9] clients: a reference implementation of UI client how to use ivi-hmi-controller.
Manuel Bachmann
manuel.bachmann at open.eurogiciel.org
Wed Jun 25 02:41:47 PDT 2014
Hello Tanibata-San,
I am currently testing your patches against the latest Weston 1.5 release.
For this particular patch, I had to modify this section in order to compile
:
nodist_weston_ivi_shell_user_interface_SOURCES = \
protocol/ivi-hmi-controller-client-protocol.h \
protocol/ivi-hmi-controller-protocol.c \
protocol/ivi-application-protocol.c
Notice the "protocol/ivi-application-protocol.c" line at the end. WIthout
it, the build process failed when linking the binary.
2014-05-20 6:30 GMT+02:00 Nobuhiko Tanibata <
NOBUHIKO_TANIBATA at xddp.denso.co.jp>:
> This is launched from hmi-controller by launch_hmi_client_process and
> invoke a
> client process.
>
> The basic flow is as followed,
> 1/ process invoked
> 2/ read configuration from weston.ini.
> 3/ draw png file to surface according to configuration of weston.ini
> 4/ all parts of UI are ready. request "UI_ready" to draw UI.
> 5/ Enter event loop
> 6/ If a surface receives touch/pointer event, followings are invoked
> according
> to type of event and surface
> 6-1/ If a surface to launch ivi_application receive touch up, it execs
> ivi-application configured in weston.ini.
> 6-2/ If a surface to switch layout mode receive touch up, it sends a
> request,
> ivi_hmi_controller_switch_mode, to hmi-controller.
> 6-3/ If a surface to show workspace having launchers, it sends a request,
> ivi_hmi_controller_home, to hmi-controller.
> 6-4/ If touch down events happens in workspace,
> ivi_hmi_controller_workspace_control is sent to slide workspace.
> When control finished, event: ivi_hmi_controller_workspace_end_control
> is received.
>
> Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA at xddp.denso.co.jp>
> ---
>
> Changes for v2:
> - squash Makefile to this patch
>
> Changes for v3 and v4
> - nothing. Version number aligned to the first patch
>
> Changes for v5:
> - rebase weston v1.5 branch
> - apply review comments from mailing list
>
> Makefile.am | 10 +-
> clients/ivi-shell-user-interface.c | 1332
> ++++++++++++++++++++++++++++++++++++
> ivi-shell/hmi-controller.c | 42 +-
> 3 files changed, 1380 insertions(+), 4 deletions(-)
> create mode 100644 clients/ivi-shell-user-interface.c
>
> diff --git a/Makefile.am b/Makefile.am
> index 1f75cc3..46c5e3d 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -359,7 +359,8 @@ libexec_PROGRAMS += \
> weston-desktop-shell \
> weston-screenshooter \
> weston-keyboard \
> - weston-simple-im
> + weston-simple-im \
> + weston-ivi-shell-user-interface
>
> demo_clients = \
> weston-flower \
> @@ -570,6 +571,13 @@ nodist_weston_desktop_shell_SOURCES =
> \
> weston_desktop_shell_LDADD = libtoytoolkit.la
> weston_desktop_shell_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
>
> +weston_ivi_shell_user_interface_SOURCES =
> clients/ivi-shell-user-interface.c
> +nodist_weston_ivi_shell_user_interface_SOURCES = \
> + protocol/ivi-hmi-controller-client-protocol.h \
> + protocol/ivi-hmi-controller-protocol.c
> +weston_ivi_shell_user_interface_LDADD = libtoytoolkit.la
> +weston_ivi_shell_user_interface_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
> +
> if BUILD_FULL_GL_CLIENTS
> demo_clients += weston-gears
> weston_gears_SOURCES = clients/gears.c
> diff --git a/clients/ivi-shell-user-interface.c
> b/clients/ivi-shell-user-interface.c
> new file mode 100644
> index 0000000..70b854b
> --- /dev/null
> +++ b/clients/ivi-shell-user-interface.c
> @@ -0,0 +1,1332 @@
> +/*
> + * 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 <assert.h>
> +#include <fcntl.h>
> +#include <signal.h>
> +#include <sys/mman.h>
> +#include <getopt.h>
> +#include <pthread.h>
> +#include <wayland-cursor.h>
> +#include "../shared/cairo-util.h"
> +#include "../shared/config-parser.h"
> +#include "ivi-application-client-protocol.h"
> +#include "ivi-hmi-controller-client-protocol.h"
> +
> +/**
> + * A reference implementation how to use ivi-hmi-controller interface to
> interact
> + * with hmi-controller. This is launched from hmi-controller by using
> + * hmi_client_start and create a pthread.
> + *
> + * The basic flow is as followed,
> + * 1/ create pthread
> + * 2/ read configuration from weston.ini.
> + * 3/ draw png file to surface according to configuration of weston.ini
> + * 4/ set up UI by using ivi-hmi-controller protocol
> + * 5/ Enter event loop
> + * 6/ If a surface receives touch/pointer event, followings are invoked
> according
> + * to type of event and surface
> + * 6-1/ If a surface to launch ivi_application receive touch up, it execs
> + * ivi-application configured in weston.ini.
> + * 6-2/ If a surface to switch layout mode receive touch up, it sends a
> request,
> + * ivi_hmi_controller_switch_mode, to hmi-controller.
> + * 6-3/ If a surface to show workspace having launchers, it sends a
> request,
> + * ivi_hmi_controller_home, to hmi-controller.
> + * 6-4/ If touch down events happens in workspace,
> + * ivi_hmi_controller_workspace_control is sent to slide workspace.
> + * When control finished, event:
> ivi_hmi_controller_workspace_end_control
> + * is received.
> + */
> +
>
> +/*****************************************************************************
> + * structure, globals
> +
> ****************************************************************************/
> +enum cursor_type {
> + CURSOR_BOTTOM_LEFT,
> + CURSOR_BOTTOM_RIGHT,
> + CURSOR_BOTTOM,
> + CURSOR_DRAGGING,
> + CURSOR_LEFT_PTR,
> + CURSOR_LEFT,
> + CURSOR_RIGHT,
> + CURSOR_TOP_LEFT,
> + CURSOR_TOP_RIGHT,
> + CURSOR_TOP,
> + CURSOR_IBEAM,
> + CURSOR_HAND1,
> + CURSOR_WATCH,
> +
> + CURSOR_BLANK
> +};
> +struct wlContextCommon {
> + struct wl_display *wlDisplay;
> + struct wl_registry *wlRegistry;
> + struct wl_compositor *wlCompositor;
> + struct wl_shm *wlShm;
> + struct wl_seat *wlSeat;
> + struct wl_pointer *wlPointer;
> + struct wl_touch *wlTouch;
> + struct ivi_application *iviApplication;
> + struct ivi_hmi_controller *hmiCtrl;
> + struct hmi_homescreen_setting *hmi_setting;
> + struct wl_list *list_wlContextStruct;
> + struct wl_surface *enterSurface;
> + int32_t is_home_on;
> + struct wl_cursor_theme *cursor_theme;
> + struct wl_cursor **cursors;
> + struct wl_surface *pointer_surface;
> + enum cursor_type current_cursor;
> + uint32_t enter_serial;
> +};
> +
> +struct wlContextStruct {
> + struct wlContextCommon cmm;
> + struct wl_surface *wlSurface;
> + struct wl_buffer *wlBuffer;
> + uint32_t formats;
> + cairo_surface_t *ctx_image;
> + void *data;
> + uint32_t id_surface;
> + struct wl_list link;
> +};
> +
> +struct
> +hmi_homescreen_srf {
> + uint32_t id;
> + char *filePath;
> + uint32_t color;
> +};
> +
> +struct
> +hmi_homescreen_workspace {
> + struct wl_array launcher_id_array;
> + struct wl_list link;
> +};
> +
> +struct
> +hmi_homescreen_launcher {
> + uint32_t icon_surface_id;
> + uint32_t workspace_id;
> + char* icon;
> + char* path;
> + struct wl_list link;
> +};
> +
> +struct
> +hmi_homescreen_setting {
> + struct hmi_homescreen_srf background;
> + struct hmi_homescreen_srf panel;
> + struct hmi_homescreen_srf tiling;
> + struct hmi_homescreen_srf sidebyside;
> + struct hmi_homescreen_srf fullscreen;
> + struct hmi_homescreen_srf random;
> + struct hmi_homescreen_srf home;
> + struct hmi_homescreen_srf workspace_background;
> +
> + struct wl_list workspace_list;
> + struct wl_list launcher_list;
> +
> + char *cursor_theme;
> + int32_t cursor_size;
> +};
> +
> +volatile int gRun = 0;
> +
> +static void *
> +fail_on_null(void *p, size_t size, char* file, int32_t line)
> +{
> + if (size && !p) {
> + fprintf(stderr, "%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__)
> +#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
> +
>
> +/*****************************************************************************
> + * Event Handler
> +
> ****************************************************************************/
> +
> +static void
> +shm_format(void* data, struct wl_shm* pWlShm, uint32_t format)
> +{
> + struct wlContextStruct* pDsp = data;
> + pDsp->formats |= (1 << format);
> +}
> +
> +static struct wl_shm_listener shm_listenter = {
> + shm_format
> +};
> +
> +static int32_t
> +getIdOfWlSurface(struct wlContextCommon *pCtx, struct wl_surface
> *wlSurface)
> +{
> + if (NULL == pCtx ||
> + NULL == wlSurface ) {
> + return 0;
> + }
> +
> + struct wlContextStruct* pWlCtxSt = NULL;
> + wl_list_for_each(pWlCtxSt, pCtx->list_wlContextStruct, link) {
> + if (pWlCtxSt->wlSurface == wlSurface) {
> + return pWlCtxSt->id_surface;
> + }
> + continue;
> + }
> + return -1;
> +}
> +
> +static void
> +set_pointer_image(struct wlContextCommon *pCtx, uint32_t index)
> +{
> + if (!pCtx->wlPointer ||
> + !pCtx->cursors) {
> + return;
> + }
> +
> + if (CURSOR_BLANK == pCtx->current_cursor) {
> + wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial,
> + NULL, 0, 0);
> + return;
> + }
> +
> + struct wl_cursor *cursor = pCtx->cursors[pCtx->current_cursor];
> + if (!cursor) {
> + return;
> + }
> +
> + if (cursor->image_count <= index) {
> + fprintf(stderr, "cursor index out of range\n");
> + return;
> + }
> +
> + struct wl_cursor_image *image = cursor->images[index];
> + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
> +
> + if (!buffer) {
> + return;
> + }
> +
> + wl_pointer_set_cursor(pCtx->wlPointer, pCtx->enter_serial,
> + pCtx->pointer_surface,
> + image->hotspot_x, image->hotspot_y);
> +
> + wl_surface_attach(pCtx->pointer_surface, buffer, 0, 0);
> +
> + wl_surface_damage(pCtx->pointer_surface, 0, 0,
> + image->width, image->height);
> +
> + wl_surface_commit(pCtx->pointer_surface);
> +}
> +
> +static void
> +PointerHandleEnter(void* data, struct wl_pointer* wlPointer, uint32_t
> serial,
> + struct wl_surface* wlSurface, wl_fixed_t sx,
> wl_fixed_t sy)
> +{
> + (void)wlPointer;
> + (void)serial;
> +
> + struct wlContextCommon *pCtx = data;
> + pCtx->enter_serial = serial;
> + pCtx->enterSurface = wlSurface;
> + set_pointer_image(pCtx, 0);
> +#ifdef _DEBUG
> + printf("ENTER PointerHandleEnter: x(%d), y(%d)\n", sx, sy);
> +#endif
> +}
> +
> +static void
> +PointerHandleLeave(void* data, struct wl_pointer* wlPointer, uint32_t
> serial,
> + struct wl_surface* wlSurface)
> +{
> + (void)wlPointer;
> + (void)wlSurface;
> +
> + struct wlContextCommon *pCtx = data;
> + pCtx->enterSurface = NULL;
> +
> +#ifdef _DEBUG
> + printf("ENTER PointerHandleLeave: serial(%d)\n", serial);
> +#endif
> +}
> +
> +static void
> +PointerHandleMotion(void* data, struct wl_pointer* wlPointer, uint32_t
> time,
> + wl_fixed_t sx, wl_fixed_t sy)
> +{
> + (void)data;
> + (void)wlPointer;
> + (void)time;
> +
> +#ifdef _DEBUG
> + printf("ENTER PointerHandleMotion: x(%d), y(%d)\n", gPointerX,
> gPointerY);
> +#endif
> +}
> +
> +/**
> + * if a surface assigned as launcher receives touch-off event, invoking
> + * ivi-application which configured in weston.ini with path to binary.
> + */
> +extern char **environ; /*defied by libc */
> +
> +static pid_t execute_process(char* path, char *argv[])
> +{
> + pid_t pid = fork();
> + if (pid < 0) {
> + fprintf(stderr, "Failed to fork\n");
> + }
> +
> + if (pid) {
> + return pid;
> + }
> +
> + if (-1 == execve(path, argv, environ)) {
> + fprintf(stderr, "Failed to execve %s\n", path);
> + exit(1);
> + }
> +
> + return pid;
> +}
> +
> +static int32_t
> +launcher_button(uint32_t surfaceId, struct wl_list *launcher_list)
> +{
> + struct hmi_homescreen_launcher *launcher = NULL;
> +
> + wl_list_for_each(launcher, launcher_list, link) {
> + if (surfaceId != launcher->icon_surface_id) {
> + continue;
> + }
> +
> + char *argv[] = {NULL};
> + execute_process(launcher->path, argv);
> +
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * is-method to identify a surface set as launcher in workspace or
> workspace
> + * itself. This is-method is used to decide whether request;
> + * ivi_hmi_controller_workspace_control is sent or not.
> + */
> +static int32_t
> +isWorkspaceSurface(uint32_t id, struct hmi_homescreen_setting
> *hmi_setting)
> +{
> + if (id == hmi_setting->workspace_background.id) {
> + return 1;
> + }
> +
> + struct hmi_homescreen_launcher *launcher = NULL;
> + wl_list_for_each(launcher, &hmi_setting->launcher_list, link) {
> + if (id == launcher->icon_surface_id) {
> + return 1;
> + }
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * Decide which request is sent to hmi-controller
> + */
> +static void
> +touch_up(struct ivi_hmi_controller *hmi_ctrl, uint32_t id_surface,
> + int32_t *is_home_on, struct hmi_homescreen_setting* hmi_setting)
> +{
> + if (launcher_button(id_surface, &hmi_setting->launcher_list)) {
> + *is_home_on = 0;
> + ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF);
> + } else if (id_surface == hmi_setting->tiling.id) {
> + ivi_hmi_controller_switch_mode(
> + hmi_ctrl, IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING);
> + } else if (id_surface == hmi_setting->sidebyside.id) {
> + ivi_hmi_controller_switch_mode(
> + hmi_ctrl,
> IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE);
> + } else if (id_surface == hmi_setting->fullscreen.id) {
> + ivi_hmi_controller_switch_mode(
> + hmi_ctrl, IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN);
> + } else if (id_surface == hmi_setting->random.id) {
> + ivi_hmi_controller_switch_mode(
> + hmi_ctrl, IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM);
> + } else if (id_surface == hmi_setting->home.id) {
> + *is_home_on = !(*is_home_on);
> + if (*is_home_on) {
> + ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_ON);
> + } else {
> + ivi_hmi_controller_home(hmi_ctrl,
> IVI_HMI_CONTROLLER_HOME_OFF);
> + }
> + }
> +}
> +
> +/**
> + * Even handler of Pointer event. IVI system is usually manipulated by
> touch
> + * screen. However, some systems also have pointer device.
> + * Release is the same behavior as touch off
> + * Pressed is the same behavior as touch on
> + */
> +static void
> +PointerHandleButton(void* data, struct wl_pointer* wlPointer, uint32_t
> serial,
> + uint32_t time, uint32_t button, uint32_t state)
> +{
> + (void)wlPointer;
> + (void)serial;
> + (void)time;
> + struct wlContextCommon *pCtx = data;
> + struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
> +
> + if (BTN_RIGHT == button) {
> + return;
> + }
> +
> + const uint32_t id_surface = getIdOfWlSurface(pCtx,
> pCtx->enterSurface);
> +
> + switch (state) {
> + case WL_POINTER_BUTTON_STATE_RELEASED:
> + touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on,
> pCtx->hmi_setting);
> + break;
> +
> + case WL_POINTER_BUTTON_STATE_PRESSED:
> +
> + if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) {
> + ivi_hmi_controller_workspace_control(hmi_ctrl, pCtx->wlSeat,
> serial);
> + }
> +
> + break;
> + }
> +#ifdef _DEBUG
> + printf("ENTER PointerHandleButton: button(%d), state(%d)\n", button,
> state);
> +#endif
> +}
> +
> +static void
> +PointerHandleAxis(void* data, struct wl_pointer* wlPointer, uint32_t time,
> + uint32_t axis, wl_fixed_t value)
> +{
> + (void)data;
> + (void)wlPointer;
> + (void)time;
> +#ifdef _DEBUG
> + printf("ENTER PointerHandleAxis: axis(%d), value(%d)\n", axis, value);
> +#endif
> +}
> +
> +static struct wl_pointer_listener pointer_listener = {
> + PointerHandleEnter,
> + PointerHandleLeave,
> + PointerHandleMotion,
> + PointerHandleButton,
> + PointerHandleAxis
> +};
> +
> +/**
> + * Even handler of touch event
> + */
> +static void
> +TouchHandleDown(void *data, struct wl_touch *wlTouch, uint32_t serial,
> uint32_t time,
> + struct wl_surface *surface, int32_t id, wl_fixed_t x_w,
> wl_fixed_t y_w)
> +{
> + struct wlContextCommon *pCtx = data;
> + struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
> +
> + if (0 == id){
> + pCtx->enterSurface = surface;
> + }
> +
> + const uint32_t id_surface = getIdOfWlSurface(pCtx,
> pCtx->enterSurface);
> +
> + /**
> + * When touch down happens on surfaces of workspace, ask
> hmi-controller to start
> + * control workspace to select page of workspace.
> + * After sending seat to hmi-controller by
> ivi_hmi_controller_workspace_control,
> + * hmi-controller-homescreen doesn't receive any event till
> hmi-controller sends
> + * back it.
> + */
> + if (isWorkspaceSurface(id_surface, pCtx->hmi_setting)) {
> + ivi_hmi_controller_workspace_control(hmi_ctrl, pCtx->wlSeat,
> serial);
> + }
> +}
> +
> +static void
> +TouchHandleUp(void *data, struct wl_touch *wlTouch, uint32_t serial,
> uint32_t time,
> + int32_t id)
> +{
> + (void)serial;
> + (void)time;
> + struct wlContextCommon *pCtx = data;
> + struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
> +
> + const uint32_t id_surface = getIdOfWlSurface(pCtx,
> pCtx->enterSurface);
> +
> + /**
> + * triggering event according to touch-up happening on which surface.
> + */
> + if (id == 0){
> + touch_up(hmi_ctrl, id_surface, &pCtx->is_home_on,
> pCtx->hmi_setting);
> + }
> +}
> +
> +static void
> +TouchHandleMotion(void *data, struct wl_touch *wlTouch, uint32_t time,
> + int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
> +{
> +}
> +
> +static void
> +TouchHandleFrame(void *data, struct wl_touch *wlTouch)
> +{
> +}
> +
> +static void
> +TouchHandleCancel(void *data, struct wl_touch *wlTouch)
> +{
> +}
> +
> +static struct wl_touch_listener touch_listener = {
> + TouchHandleDown,
> + TouchHandleUp,
> + TouchHandleMotion,
> + TouchHandleFrame,
> + TouchHandleCancel,
> +};
> +
> +/**
> + * Handler of capabilities
> + */
> +static void
> +seat_handle_capabilities(void* data, struct wl_seat* seat, uint32_t caps)
> +{
> + (void)seat;
> + struct wlContextCommon* p_wlCtx = (struct wlContextCommon*)data;
> + struct wl_seat* wlSeat = p_wlCtx->wlSeat;
> + struct wl_pointer* wlPointer = p_wlCtx->wlPointer;
> + struct wl_touch* wlTouch = p_wlCtx->wlTouch;
> +
> + if (p_wlCtx->hmi_setting->cursor_theme) {
> + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlPointer){
> + wlPointer = wl_seat_get_pointer(wlSeat);
> + wl_pointer_set_user_data(wlPointer, data);
> + wl_pointer_add_listener(wlPointer, &pointer_listener, data);
> + } else
> + if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlPointer){
> + wl_pointer_destroy(wlPointer);
> + wlPointer = NULL;
> + }
> + p_wlCtx->wlPointer = wlPointer;
> + }
> +
> + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !wlTouch){
> + wlTouch = wl_seat_get_touch(wlSeat);
> + wl_touch_set_user_data(wlTouch, data);
> + wl_touch_add_listener(wlTouch, &touch_listener, data);
> + } else
> + if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && wlTouch){
> + wl_touch_destroy(wlTouch);
> + wlTouch = NULL;
> + }
> + p_wlCtx->wlTouch = wlTouch;
> +}
> +
> +static struct wl_seat_listener seat_Listener = {
> + seat_handle_capabilities,
> +};
> +
> +/**
> + * Registration of event
> + * This event is received when hmi-controller server finished controlling
> + * workspace.
> + */
> +static void
> +ivi_hmi_controller_workspace_end_control(void *data,
> + struct ivi_hmi_controller *hmi_ctrl,
> + int32_t is_controlled)
> +{
> + if (is_controlled) {
> + return;
> + }
> +
> + struct wlContextCommon *pCtx = data;
> + const uint32_t id_surface = getIdOfWlSurface(pCtx,
> pCtx->enterSurface);
> +
> + /**
> + * During being controlled by hmi-controller, any input event is not
> + * notified. So when control ends with touch up, it invokes launcher
> + * if up event happens on a launcher surface.
> + *
> + */
> + if (launcher_button(id_surface, &pCtx->hmi_setting->launcher_list)) {
> + pCtx->is_home_on = 0;
> + ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF);
> + }
> +}
> +
> +static const struct ivi_hmi_controller_listener hmi_controller_listener =
> {
> + ivi_hmi_controller_workspace_end_control
> +};
> +
> +/**
> + * Registration of interfaces
> + */
> +static void
> +registry_handle_global(void* data, struct wl_registry* registry, uint32_t
> name,
> + const char *interface, uint32_t version)
> +{
> + (void)version;
> + struct wlContextCommon* p_wlCtx = (struct wlContextCommon*)data;
> +
> + do {
> + if (!strcmp(interface, "wl_compositor")) {
> + p_wlCtx->wlCompositor = wl_registry_bind(registry, name,
> &wl_compositor_interface, 1);
> + break;
> + }
> + if (!strcmp(interface, "wl_shm")) {
> + p_wlCtx->wlShm = wl_registry_bind(registry, name,
> &wl_shm_interface, 1);
> + wl_shm_add_listener(p_wlCtx->wlShm, &shm_listenter, p_wlCtx);
> + break;
> + }
> + if (!strcmp(interface, "wl_seat")) {
> + p_wlCtx->wlSeat = wl_registry_bind(registry, name,
> &wl_seat_interface, 1);
> + wl_seat_add_listener(p_wlCtx->wlSeat, &seat_Listener, data);
> + break;
> + }
> + if (!strcmp(interface, "ivi_application")) {
> + p_wlCtx->iviApplication = wl_registry_bind(registry, name,
> &ivi_application_interface, 1);
> + break;
> + }
> + if (!strcmp(interface, "ivi_hmi_controller")) {
> + p_wlCtx->hmiCtrl = wl_registry_bind(registry, name,
> &ivi_hmi_controller_interface, 1);
> +
> + if (p_wlCtx->hmiCtrl) {
> + ivi_hmi_controller_add_listener(p_wlCtx->hmiCtrl,
> &hmi_controller_listener, p_wlCtx);
> + }
> + break;
> + }
> +
> + } while(0);
> +}
> +
> +static const struct wl_registry_listener registry_listener = {
> + registry_handle_global,
> + NULL
> +};
> +
> +static void
> +frame_listener_func(void *data, struct wl_callback *callback, uint32_t
> time)
> +{
> + if (callback) {
> + wl_callback_destroy(callback);
> + }
> +}
> +
> +static const struct wl_callback_listener frame_listener = {
> + frame_listener_func
> +};
> +
> +/*
> + * The following correspondences between file names and cursors was copied
> + * from: https://bugs.kde.org/attachment.cgi?id=67313
> + */
> +static const char *bottom_left_corners[] = {
> + "bottom_left_corner",
> + "sw-resize",
> + "size_bdiag"
> +};
> +
> +static const char *bottom_right_corners[] = {
> + "bottom_right_corner",
> + "se-resize",
> + "size_fdiag"
> +};
> +
> +static const char *bottom_sides[] = {
> + "bottom_side",
> + "s-resize",
> + "size_ver"
> +};
> +
> +static const char *grabbings[] = {
> + "grabbing",
> + "closedhand",
> + "208530c400c041818281048008011002"
> +};
> +
> +static const char *left_ptrs[] = {
> + "left_ptr",
> + "default",
> + "top_left_arrow",
> + "left-arrow"
> +};
> +
> +static const char *left_sides[] = {
> + "left_side",
> + "w-resize",
> + "size_hor"
> +};
> +
> +static const char *right_sides[] = {
> + "right_side",
> + "e-resize",
> + "size_hor"
> +};
> +
> +static const char *top_left_corners[] = {
> + "top_left_corner",
> + "nw-resize",
> + "size_fdiag"
> +};
> +
> +static const char *top_right_corners[] = {
> + "top_right_corner",
> + "ne-resize",
> + "size_bdiag"
> +};
> +
> +static const char *top_sides[] = {
> + "top_side",
> + "n-resize",
> + "size_ver"
> +};
> +
> +static const char *xterms[] = {
> + "xterm",
> + "ibeam",
> + "text"
> +};
> +
> +static const char *hand1s[] = {
> + "hand1",
> + "pointer",
> + "pointing_hand",
> + "e29285e634086352946a0e7090d73106"
> +};
> +
> +static const char *watches[] = {
> + "watch",
> + "wait",
> + "0426c94ea35c87780ff01dc239897213"
> +};
> +
> +struct cursor_alternatives {
> + const char **names;
> + size_t count;
> +};
> +
> +static const struct cursor_alternatives cursors[] = {
> + {bottom_left_corners, ARRAY_LENGTH(bottom_left_corners)},
> + {bottom_right_corners, ARRAY_LENGTH(bottom_right_corners)},
> + {bottom_sides, ARRAY_LENGTH(bottom_sides)},
> + {grabbings, ARRAY_LENGTH(grabbings)},
> + {left_ptrs, ARRAY_LENGTH(left_ptrs)},
> + {left_sides, ARRAY_LENGTH(left_sides)},
> + {right_sides, ARRAY_LENGTH(right_sides)},
> + {top_left_corners, ARRAY_LENGTH(top_left_corners)},
> + {top_right_corners, ARRAY_LENGTH(top_right_corners)},
> + {top_sides, ARRAY_LENGTH(top_sides)},
> + {xterms, ARRAY_LENGTH(xterms)},
> + {hand1s, ARRAY_LENGTH(hand1s)},
> + {watches, ARRAY_LENGTH(watches)},
> +};
> +
> +static void
> +create_cursors(struct wlContextCommon *cmm)
> +{
> + uint32_t i = 0;
> + uint32_t j = 0;
> + struct wl_cursor *cursor = NULL;
> + char* cursor_theme = cmm->hmi_setting->cursor_theme;
> + int32_t cursor_size = cmm->hmi_setting->cursor_size;
> +
> + cmm->cursor_theme = wl_cursor_theme_load(cursor_theme, cursor_size,
> cmm->wlShm);
> +
> + cmm->cursors = MEM_ALLOC(ARRAY_LENGTH(cursors) *
> sizeof(cmm->cursors[0]));
> +
> + for (i = 0; i < ARRAY_LENGTH(cursors); i++) {
> + cursor = NULL;
> +
> + for (j = 0; !cursor && j < cursors[i].count; ++j) {
> + cursor = wl_cursor_theme_get_cursor(
> + cmm->cursor_theme, cursors[i].names[j]);
> + }
> +
> + if (!cursor) {
> + fprintf(stderr, "could not load cursor '%s'\n",
> + cursors[i].names[0]);
> + }
> +
> + cmm->cursors[i] = cursor;
> + }
> +}
> +
> +static void
> +destroy_cursors(struct wlContextCommon *cmm)
> +{
> + if (cmm->cursor_theme) {
> + wl_cursor_theme_destroy(cmm->cursor_theme);
> + }
> +
> + free(cmm->cursors);
> +}
> +
> +/**
> + * Internal method to prepare parts of UI
> + */
> +static void
> +createShmBuffer(struct wlContextStruct *p_wlCtx)
> +{
> + struct wl_shm_pool *pool;
> +
> + char filename[] = "/tmp/wayland-shm-XXXXXX";
> + int fd = -1;
> + int size = 0;
> + int width = 0;
> + int height = 0;
> + int stride = 0;
> +
> + fd = mkstemp(filename);
> + if (fd < 0) {
> + fprintf(stderr, "open %s failed: %m\n", filename);
> + return;
> + }
> +
> + width = cairo_image_surface_get_width(p_wlCtx->ctx_image);
> + height = cairo_image_surface_get_height(p_wlCtx->ctx_image);
> + stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image);
> +
> + size = stride * height;
> + if (ftruncate(fd, size) < 0) {
> + fprintf(stderr, "ftruncate failed: %m\n");
> + close(fd);
> + return;
> + }
> +
> + p_wlCtx->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
> fd, 0);
> +
> + if (MAP_FAILED == p_wlCtx->data) {
> + fprintf(stderr, "mmap failed: %m\n");
> + close(fd);
> + return;
> + }
> +
> + pool = wl_shm_create_pool(p_wlCtx->cmm.wlShm, fd, size);
> + p_wlCtx->wlBuffer = wl_shm_pool_create_buffer(pool, 0,
> + width,
> + height,
> + stride,
> + WL_SHM_FORMAT_ARGB8888);
> +
> + if (NULL == p_wlCtx->wlBuffer) {
> + fprintf(stderr, "wl_shm_create_buffer failed: %m\n");
> + close(fd);
> + return;
> + }
> + wl_shm_pool_destroy(pool);
> + close(fd);
> +
> + return;
> +}
> +
> +static void
> +destroyWLContextCommon(struct wlContextCommon *p_wlCtx)
> +{
> + destroy_cursors(p_wlCtx);
> +
> + if (p_wlCtx->pointer_surface) {
> + wl_surface_destroy(p_wlCtx->pointer_surface);
> + }
> +
> + if (p_wlCtx->wlCompositor) {
> + wl_compositor_destroy(p_wlCtx->wlCompositor);
> + }
> +}
> +
> +static void
> +destroyWLContextStruct(struct wlContextStruct *p_wlCtx)
> +{
> + if (p_wlCtx->wlSurface) {
> + wl_surface_destroy(p_wlCtx->wlSurface);
> + }
> +
> + if (p_wlCtx->ctx_image) {
> + cairo_surface_destroy(p_wlCtx->ctx_image);
> + p_wlCtx->ctx_image = NULL;
> + }
> +}
> +
> +static int
> +createWLContext(struct wlContextStruct *p_wlCtx)
> +{
> + wl_display_roundtrip(p_wlCtx->cmm.wlDisplay);
> +
> + p_wlCtx->wlSurface =
> wl_compositor_create_surface(p_wlCtx->cmm.wlCompositor);
> + if (NULL == p_wlCtx->wlSurface) {
> + printf("Error: wl_compositor_create_surface failed.\n");
> + destroyWLContextCommon(&p_wlCtx->cmm);
> + abort();
> + }
> +
> +
> + createShmBuffer(p_wlCtx);
> +
> + wl_display_flush(p_wlCtx->cmm.wlDisplay);
> + wl_display_roundtrip(p_wlCtx->cmm.wlDisplay);
> +
> + return 0;
> +}
> +
> +static void
> +drawImage(struct wlContextStruct *p_wlCtx)
> +{
> + struct wl_callback *callback;
> +
> + int width = 0;
> + int height = 0;
> + int stride = 0;
> + void *data = NULL;
> +
> + width = cairo_image_surface_get_width(p_wlCtx->ctx_image);
> + height = cairo_image_surface_get_height(p_wlCtx->ctx_image);
> + stride = cairo_image_surface_get_stride(p_wlCtx->ctx_image);
> + data = cairo_image_surface_get_data(p_wlCtx->ctx_image);
> +
> + memcpy(p_wlCtx->data, data, stride * height);
> +
> + wl_surface_attach(p_wlCtx->wlSurface, p_wlCtx->wlBuffer, 0, 0);
> + wl_surface_damage(p_wlCtx->wlSurface, 0, 0, width, height);
> +
> + callback = wl_surface_frame(p_wlCtx->wlSurface);
> + wl_callback_add_listener(callback, &frame_listener, NULL);
> +
> + wl_surface_commit(p_wlCtx->wlSurface);
> +
> + wl_display_flush(p_wlCtx->cmm.wlDisplay);
> + wl_display_roundtrip(p_wlCtx->cmm.wlDisplay);
> +}
> +
> +static void
> +create_ivisurface(struct wlContextStruct *p_wlCtx,
> + uint32_t id_surface,
> + cairo_surface_t* surface)
> +{
> + struct ivi_surface *ivisurf = NULL;
> +
> + p_wlCtx->ctx_image = surface;
> +
> + p_wlCtx->id_surface = id_surface;
> + wl_list_init(&p_wlCtx->link);
> + wl_list_insert(p_wlCtx->cmm.list_wlContextStruct, &p_wlCtx->link);
> +
> + createWLContext(p_wlCtx);
> +
> + ivisurf = ivi_application_surface_create(p_wlCtx->cmm.iviApplication,
> + id_surface,
> p_wlCtx->wlSurface);
> + if (ivisurf == NULL) {
> + fprintf(stderr, "Failed to create ivi_client_surface\n");
> + return;
> + }
> +
> + drawImage(p_wlCtx);
> +
> + wl_display_roundtrip(p_wlCtx->cmm.wlDisplay);
> +}
> +
> +static void
> +create_ivisurfaceFromFile(struct wlContextStruct *p_wlCtx,
> + uint32_t id_surface,
> + const char* imageFile)
> +{
> + cairo_surface_t* surface = load_cairo_surface(imageFile);
> +
> + if (NULL == surface) {
> + fprintf(stderr, "Failed to load_cairo_surface %s\n", imageFile);
> + return;
> + }
> +
> + create_ivisurface(p_wlCtx, id_surface, surface);
> +}
> +
> +static void
> +set_hex_color(cairo_t *cr, uint32_t color)
> +{
> + cairo_set_source_rgba(cr,
> + ((color >> 16) & 0xff) / 255.0,
> + ((color >> 8) & 0xff) / 255.0,
> + ((color >> 0) & 0xff) / 255.0,
> + ((color >> 24) & 0xff) / 255.0);
> +}
> +
> +static void
> +create_ivisurfaceFromColor(struct wlContextStruct *p_wlCtx,
> + uint32_t id_surface,
> + uint32_t width, uint32_t height,
> + uint32_t color)
> +{
> + cairo_surface_t *surface = NULL;
> + cairo_t *cr = NULL;
> +
> + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width,
> height);
> +
> + cr = cairo_create(surface);
> + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
> + cairo_rectangle(cr, 0, 0, width, height);
> + set_hex_color(cr, color);
> + cairo_fill(cr);
> + cairo_destroy(cr);
> +
> + create_ivisurface(p_wlCtx, id_surface, surface);
> +}
> +
> +static void
> +UI_ready(struct ivi_hmi_controller *controller)
> +{
> + ivi_hmi_controller_UI_ready(controller);
> +}
> +
> +/**
> + * Internal method to set up UI by using ivi-hmi-controller
> + */
> +static void
> +create_background(struct wlContextStruct *p_wlCtx, const uint32_t
> id_surface,
> + const char* imageFile)
> +{
> + create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
> +}
> +
> +static void
> +create_panel(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
> + const char* imageFile)
> +{
> + create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
> +}
> +
> +static void
> +create_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
> + const char* imageFile, uint32_t number)
> +{
> + create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
> +}
> +
> +static void
> +create_home_button(struct wlContextStruct *p_wlCtx, const uint32_t
> id_surface,
> + const char* imageFile)
> +{
> + create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
> +}
> +
> +static void
> +create_workspace_background(
> + struct wlContextStruct *p_wlCtx, struct hmi_homescreen_srf *srf)
> +{
> + create_ivisurfaceFromColor(p_wlCtx, srf->id, 1, 1, srf->color);
> +}
> +
> +static void
> +create_launchers(struct wlContextCommon *cmm, struct wl_list
> *launcher_list)
> +{
> + int launcher_count = wl_list_length(launcher_list);
> +
> + if (0 == launcher_count) {
> + return;
> + }
> +
> + struct hmi_homescreen_launcher** launchers;
> + launchers = MEM_ALLOC(launcher_count * sizeof(*launchers));
> +
> + int ii = 0;
> + struct hmi_homescreen_launcher *launcher = NULL;
> +
> + wl_list_for_each(launcher, launcher_list, link) {
> + launchers[ii] = launcher;
> + ii++;
> + }
> +
> + int start = 0;
> +
> + for (ii = 0; ii < launcher_count; ii++) {
> +
> + if (ii != launcher_count -1 &&
> + launchers[ii]->workspace_id == launchers[ii +
> 1]->workspace_id) {
> + continue;
> + }
> +
> + int jj = 0;
> + for (jj = start; jj <= ii; jj++) {
> + struct wlContextStruct *p_wlCtx = MEM_ALLOC(sizeof(*p_wlCtx));
> + p_wlCtx->cmm = *cmm;
> +
> create_ivisurfaceFromFile(p_wlCtx,launchers[jj]->icon_surface_id,
> launchers[jj]->icon);
> + }
> +
> + start = ii + 1;
> + }
> +
> + free(launchers);
> +}
> +
> +static void sigFunc(int signum)
> +{
> + gRun = 0;
> +}
> +
> +/**
> + * Internal method to read out weston.ini to get configuration
> + */
> +static struct hmi_homescreen_setting*
> +hmi_homescreen_setting_create(void)
> +{
> + struct hmi_homescreen_setting* setting = MEM_ALLOC(sizeof(*setting));
> +
> + wl_list_init(&setting->workspace_list);
> + wl_list_init(&setting->launcher_list);
> +
> + struct weston_config *config = NULL;
> + config = weston_config_parse("weston.ini");
> +
> + struct weston_config_section *shellSection = NULL;
> + shellSection = weston_config_get_section(config, "ivi-shell", NULL,
> NULL);
> +
> + weston_config_section_get_string(
> + shellSection, "cursor-theme", &setting->cursor_theme, NULL);
> +
> + weston_config_section_get_int(shellSection, "cursor-size",
> &setting->cursor_size, 32);
> +
> + uint32_t workspace_layer_id;
> + weston_config_section_get_uint(
> + shellSection, "workspace-layer-id", &workspace_layer_id, 3000);
> +
> + weston_config_section_get_string(
> + shellSection, "background-image", &setting->background.filePath,
> + DATADIR "/weston/background.png");
> +
> + weston_config_section_get_uint(
> + shellSection, "background-id", &setting->background.id, 1001);
> +
> + weston_config_section_get_string(
> + shellSection, "panel-image", &setting->panel.filePath,
> + DATADIR "/weston/panel.png");
> +
> + weston_config_section_get_uint(
> + shellSection, "panel-id", &setting->panel.id, 1002);
> +
> + weston_config_section_get_string(
> + shellSection, "tiling-image", &setting->tiling.filePath,
> + DATADIR "/weston/tiling.png");
> +
> + weston_config_section_get_uint(
> + shellSection, "tiling-id", &setting->tiling.id, 1003);
> +
> + weston_config_section_get_string(
> + shellSection, "sidebyside-image", &setting->sidebyside.filePath,
> + DATADIR "/weston/sidebyside.png");
> +
> + weston_config_section_get_uint(
> + shellSection, "sidebyside-id", &setting->sidebyside.id, 1004);
> +
> + weston_config_section_get_string(
> + shellSection, "fullscreen-image", &setting->fullscreen.filePath,
> + DATADIR "/weston/fullscreen.png");
> +
> + weston_config_section_get_uint(
> + shellSection, "fullscreen-id", &setting->fullscreen.id, 1005);
> +
> + weston_config_section_get_string(
> + shellSection, "random-image", &setting->random.filePath,
> + DATADIR "/weston/random.png");
> +
> + weston_config_section_get_uint(
> + shellSection, "random-id", &setting->random.id, 1006);
> +
> + weston_config_section_get_string(
> + shellSection, "home-image", &setting->home.filePath,
> + DATADIR "/weston/home.png");
> +
> + weston_config_section_get_uint(
> + shellSection, "home-id", &setting->home.id, 1007);
> +
> + weston_config_section_get_uint(
> + shellSection, "workspace-background-color",
> + &setting->workspace_background.color, 0x99000000);
> +
> + weston_config_section_get_uint(
> + shellSection, "workspace-background-id",
> + &setting->workspace_background.id, 2001);
> +
> + struct weston_config_section *section = NULL;
> + const char *name = NULL;
> +
> + uint32_t icon_surface_id = workspace_layer_id + 1;
> +
> + while (weston_config_next_section(config, §ion, &name)) {
> +
> + if (0 == strcmp(name, "ivi-launcher")) {
> +
> + struct hmi_homescreen_launcher *launcher = NULL;
> + launcher = MEM_ALLOC(sizeof(*launcher));
> + wl_list_init(&launcher->link);
> +
> + weston_config_section_get_string(section, "icon",
> &launcher->icon, NULL);
> + weston_config_section_get_string(section, "path",
> &launcher->path, NULL);
> + weston_config_section_get_uint(section, "workspace-id",
> &launcher->workspace_id, 0);
> + weston_config_section_get_uint(section, "icon-id",
> &launcher->icon_surface_id, icon_surface_id);
> + icon_surface_id++;
> +
> + wl_list_insert(setting->launcher_list.prev, &launcher->link);
> + }
> + }
> +
> + weston_config_destroy(config);
> + return setting;
> +}
> +
> +/**
> + * Main thread
> + *
> + * The basic flow are as followed,
> + * 1/ read configuration from weston.ini by hmi_homescreen_setting_create
> + * 2/ draw png file to surface according to configuration of weston.ini
> and
> + * set up UI by using ivi-hmi-controller protocol by each create_*
> method
> + */
> +int main(int argc, char **argv)
> +{
> + struct wlContextCommon wlCtxCommon;
> + struct wlContextStruct wlCtx_BackGround;
> + struct wlContextStruct wlCtx_Panel;
> + struct wlContextStruct wlCtx_Button_1;
> + struct wlContextStruct wlCtx_Button_2;
> + struct wlContextStruct wlCtx_Button_3;
> + struct wlContextStruct wlCtx_Button_4;
> + struct wlContextStruct wlCtx_HomeButton;
> + struct wlContextStruct wlCtx_WorkSpaceBackGround;
> + struct wl_list launcher_wlCtxList;
> +
> + memset(&wlCtxCommon, 0x00, sizeof(wlCtxCommon));
> + memset(&wlCtx_BackGround, 0x00, sizeof(wlCtx_BackGround));
> + memset(&wlCtx_Panel, 0x00, sizeof(wlCtx_Panel));
> + memset(&wlCtx_Button_1, 0x00, sizeof(wlCtx_Button_1));
> + memset(&wlCtx_Button_2, 0x00, sizeof(wlCtx_Button_2));
> + memset(&wlCtx_Button_3, 0x00, sizeof(wlCtx_Button_3));
> + memset(&wlCtx_Button_4, 0x00, sizeof(wlCtx_Button_4));
> + memset(&wlCtx_HomeButton, 0x00, sizeof(wlCtx_HomeButton));
> + memset(&wlCtx_WorkSpaceBackGround, 0x00,
> sizeof(wlCtx_WorkSpaceBackGround));
> + wl_list_init(&launcher_wlCtxList);
> + wlCtxCommon.list_wlContextStruct = MEM_ALLOC(sizeof(struct wl_list));
> + assert(wlCtxCommon.list_wlContextStruct);
> + wl_list_init(wlCtxCommon.list_wlContextStruct);
> +
> + struct hmi_homescreen_setting *hmi_setting =
> hmi_homescreen_setting_create();
> + wlCtxCommon.hmi_setting = hmi_setting;
> +
> + gRun = 1;
> +
> + wlCtxCommon.wlDisplay = wl_display_connect(NULL);
> + if (NULL == wlCtxCommon.wlDisplay) {
> + printf("Error: wl_display_connect failed.\n");
> + return -1;
> + }
> +
> + /* get wl_registry */
> + wlCtxCommon.wlRegistry =
> wl_display_get_registry(wlCtxCommon.wlDisplay);
> + wl_registry_add_listener(wlCtxCommon.wlRegistry,
> + ®istry_listener, &wlCtxCommon);
> + wl_display_dispatch(wlCtxCommon.wlDisplay);
> + wl_display_roundtrip(wlCtxCommon.wlDisplay);
> +
> + if (wlCtxCommon.hmi_setting->cursor_theme) {
> + create_cursors(&wlCtxCommon);
> +
> + wlCtxCommon.pointer_surface =
> + wl_compositor_create_surface(wlCtxCommon.wlCompositor);
> +
> + wlCtxCommon.current_cursor = CURSOR_LEFT_PTR;
> + }
> +
> + wlCtx_BackGround.cmm = wlCtxCommon;
> + wlCtx_Panel.cmm = wlCtxCommon;
> + wlCtx_Button_1.cmm = wlCtxCommon;
> + wlCtx_Button_2.cmm = wlCtxCommon;
> + wlCtx_Button_3.cmm = wlCtxCommon;
> + wlCtx_Button_4.cmm = wlCtxCommon;
> + wlCtx_HomeButton.cmm = wlCtxCommon;
> + wlCtx_WorkSpaceBackGround.cmm = wlCtxCommon;
> +
> + /* create desktop widgets */
> + create_background(&wlCtx_BackGround, hmi_setting->background.id,
> + hmi_setting->background.filePath);
> +
> + create_panel(&wlCtx_Panel, hmi_setting->panel.id,
> + hmi_setting->panel.filePath);
> +
> + create_button(&wlCtx_Button_1, hmi_setting->tiling.id,
> + hmi_setting->tiling.filePath, 0);
> +
> + create_button(&wlCtx_Button_2, hmi_setting->sidebyside.id,
> + hmi_setting->sidebyside.filePath, 1);
> +
> + create_button(&wlCtx_Button_3, hmi_setting->fullscreen.id,
> + hmi_setting->fullscreen.filePath, 2);
> +
> + create_button(&wlCtx_Button_4, hmi_setting->random.id,
> + hmi_setting->random.filePath, 3);
> +
> + create_workspace_background(&wlCtx_WorkSpaceBackGround,
> + &hmi_setting->workspace_background);
> +
> + create_launchers(&wlCtxCommon, &hmi_setting->launcher_list);
> +
> + create_home_button(&wlCtx_HomeButton, hmi_setting->home.id,
> + hmi_setting->home.filePath);
> +
> + UI_ready(wlCtxCommon.hmiCtrl);
> +
> + /* signal handling */
> + signal(SIGINT, sigFunc);
> + signal(SIGKILL, sigFunc);
> +
> + while(gRun) {
> + wl_display_dispatch(wlCtxCommon.wlDisplay);
> + }
> +
> + struct wlContextStruct* pWlCtxSt = NULL;
> + wl_list_for_each(pWlCtxSt, wlCtxCommon.list_wlContextStruct, link) {
> + destroyWLContextStruct(pWlCtxSt);
> + }
> +
> + destroyWLContextCommon(&wlCtxCommon);
> + free(wlCtxCommon.list_wlContextStruct);
> +
> + return 0;
> +}
> diff --git a/ivi-shell/hmi-controller.c b/ivi-shell/hmi-controller.c
> index 4e4e7c0..86db700 100644
> --- a/ivi-shell/hmi-controller.c
> +++ b/ivi-shell/hmi-controller.c
> @@ -134,6 +134,7 @@ hmi_server_setting {
> uint32_t workspace_background_layer_id;
> uint32_t workspace_layer_id;
> uint32_t panel_height;
> + char *ivi_homescreen;
> };
>
> struct hmi_controller
> @@ -151,6 +152,10 @@ struct hmi_controller
> int32_t workspace_count;
> struct wl_array ui_widgets;
> int32_t is_initialized;
> +
> + struct weston_compositor *compositor;
> + struct weston_process process;
> + struct wl_listener destroy_listener;
> };
>
> struct launcher_info
> @@ -830,6 +835,9 @@ hmi_server_setting_create(void)
>
> setting->panel_height = 70;
>
> + weston_config_section_get_string(
> + shellSection, "ivi-shell-user-interface",
> &setting->ivi_homescreen, NULL);
> +
> weston_config_destroy(config);
>
> return setting;
> @@ -1896,9 +1904,36 @@ bind_hmi_controller(struct wl_client *client,
> }
>
> static void
> -launch_hmi_client(void *data)
> +handle_hmi_client_process_sigchld(struct weston_process *proc, int status)
> +{
> + proc->pid = 0;
> +}
> +
> +static void
> +hmi_client_destroy(struct wl_listener *listener, void *data)
> +{
> + struct hmi_controller *hmi_ctrl =
> + container_of(listener, struct hmi_controller, destroy_listener);
> +
> + kill(hmi_ctrl->process.pid, SIGTERM);
> + hmi_ctrl->process.pid = 0;
> +}
> +
> +static void
> +launch_hmi_client_process(void *data)
> {
> - /*Nothing to do here*/
> + struct hmi_controller *hmi_ctrl =
> + (struct hmi_controller *)data;
> +
> + weston_client_launch(hmi_ctrl->compositor,
> + &hmi_ctrl->process,
> + hmi_ctrl->hmi_setting->ivi_homescreen,
> + handle_hmi_client_process_sigchld);
> +
> + hmi_ctrl->destroy_listener.notify = hmi_client_destroy;
> + wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
> &hmi_ctrl->destroy_listener);
> +
> + free(hmi_ctrl->hmi_setting->ivi_homescreen);
> }
>
>
> /*****************************************************************************
> @@ -1910,6 +1945,7 @@ module_init(struct weston_compositor *ec,
> int *argc, char *argv[])
> {
> struct hmi_controller *hmi_ctrl = hmi_controller_create(ec);
> + hmi_ctrl->compositor = ec;
>
> if (wl_global_create(ec->wl_display,
> &ivi_hmi_controller_interface, 1,
> @@ -1918,7 +1954,7 @@ module_init(struct weston_compositor *ec,
> }
>
> struct wl_event_loop *loop =
> wl_display_get_event_loop(ec->wl_display);
> - wl_event_loop_add_idle(loop, launch_hmi_client, ec);
> + wl_event_loop_add_idle(loop, launch_hmi_client_process, hmi_ctrl);
>
> return 0;
> }
> --
> 1.8.3.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
--
Regards,
*Manuel BACHMANN Tizen Project VANNES-FR*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20140625/9cd2f37f/attachment-0001.html>
More information about the wayland-devel
mailing list