[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, &section, &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,
>> +                             &registry_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