[PATCH weston-ivi-shell v5 6/9] clients: a reference implementation of UI client how to use ivi-hmi-controller.
Nobuhiko Tanibata
nobuhiko_tanibata at xddp.denso.co.jp
Wed Jun 25 04:36:41 PDT 2014
Hi Manuel,
Thank you!
I will resend my patches.
BR,
Nobuhiko
2014-06-25 18:41 に Manuel Bachmann さんは書きました:
> 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 [1]
>> 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 [1]
>> +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 memoryn", 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 rangen");
>> + 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 forkn");
>> + }
>> +
>> + if (pid) {
>> + return pid;
>> + }
>> +
>> + if (-1 == execve(path, argv, environ)) {
>> + fprintf(stderr, "Failed to execve %sn", 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 [2]) {
>> + 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 [3]) {
>> + ivi_hmi_controller_switch_mode(
>> + hmi_ctrl,
>> IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING);
>> + } else if (id_surface == hmi_setting->sidebyside.id [4]) {
>> + ivi_hmi_controller_switch_mode(
>> + hmi_ctrl,
>> IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE);
>> + } else if (id_surface == hmi_setting->fullscreen.id [5]) {
>> + ivi_hmi_controller_switch_mode(
>> + hmi_ctrl,
>> IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN);
>> + } else if (id_surface == hmi_setting->random.id [6]) {
>> + ivi_hmi_controller_switch_mode(
>> + hmi_ctrl,
>> IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM);
>> + } else if (id_surface == hmi_setting->home.id [7]) {
>> + *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 [8]
>> + */
>> +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: %mn", 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: %mn");
>> + 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: %mn");
>> + 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: %mn");
>> + 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_surfacen");
>> + 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 %sn",
>> 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
>> [9], 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 [10],
>> 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 [3],
>> 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
>> [4], 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
>> [5], 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 [6],
>> 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 [7], 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 [2], 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 [9],
>> +
>> hmi_setting->background.filePath);
>> +
>> + create_panel(&wlCtx_Panel, hmi_setting->panel.id [10],
>> + hmi_setting->panel.filePath);
>> +
>> + create_button(&wlCtx_Button_1, hmi_setting->tiling.id [3],
>> + hmi_setting->tiling.filePath, 0);
>> +
>> + create_button(&wlCtx_Button_2, hmi_setting->sidebyside.id
>> [4],
>> + hmi_setting->sidebyside.filePath, 1);
>> +
>> + create_button(&wlCtx_Button_3, hmi_setting->fullscreen.id
>> [5],
>> + hmi_setting->fullscreen.filePath, 2);
>> +
>> + create_button(&wlCtx_Button_4, hmi_setting->random.id [6],
>> + 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
>> [7],
>> + 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 [11]
>
> --
>
> Regards,
>
> MANUEL BACHMANN
> Tizen Project
> VANNES-FR
>
>
> Links:
> ------
> [1] http://libtoytoolkit.la
> [2] http://workspace_background.id
> [3] http://tiling.id
> [4] http://sidebyside.id
> [5] http://fullscreen.id
> [6] http://random.id
> [7] http://home.id
> [8] https://bugs.kde.org/attachment.cgi?id=67313
> [9] http://background.id
> [10] http://panel.id
> [11] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list