6c71aaeec5
We have the Weston command line option '--no-config' which is meant to prevent loading weston.ini at all. It works for Weston itself, but it does not work for any clients that also want to read weston.ini. To fix that, introduce a new environment variable WESTON_CONFIG_FILE. Weston will set it to the absolute path of the config file it loads. Clients will load the config file pointed to by WESTON_CONFIG_FILE. If the environment variable is set but empty, no config file will be loaded. If the variable is unset, things fall back to the default "weston.ini". Note, that Weston will only set WESTON_CONFIG_FILE, it never reads it. The ability to specify a custom config file to load will be another patch. All programs that loaded "weston.ini" are modified to honour WESTON_CONFIG_FILE. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Jonny Lamb <jonny.lamb@collabora.co.uk> Reviewed-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
1313 lines
34 KiB
C
1313 lines
34 KiB
C
/*
|
|
* 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 <wayland-cursor.h>
|
|
#include "../shared/cairo-util.h"
|
|
#include "../shared/config-parser.h"
|
|
#include "../shared/os-compatibility.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/ read configuration from weston.ini.
|
|
* 2/ draw png file to surface according to configuration of weston.ini
|
|
* 3/ set up UI by using ivi-hmi-controller protocol
|
|
* 4/ Enter event loop
|
|
* 5/ If a surface receives touch/pointer event, followings are invoked
|
|
* according to type of event and surface
|
|
* 5-1/ If a surface to launch ivi_application receive touch up, it execs
|
|
* ivi-application configured in weston.ini.
|
|
* 5-2/ If a surface to switch layout mode receive touch up, it sends a request,
|
|
* ivi_hmi_controller_switch_mode, to hmi-controller.
|
|
* 5-3/ If a surface to show workspace having launchers, it sends a request,
|
|
* ivi_hmi_controller_home, to hmi-controller.
|
|
* 5-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;
|
|
uint32_t formats;
|
|
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;
|
|
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;
|
|
uint32_t transition_duration;
|
|
};
|
|
|
|
static void *
|
|
fail_on_null(void *p, size_t size, char *file, int32_t line)
|
|
{
|
|
if (size && !p) {
|
|
fprintf(stderr, "%s(%d) %zd: out of memory\n",
|
|
file, line, size);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
static void *
|
|
mem_alloc(size_t size, char *file, int32_t line)
|
|
{
|
|
return fail_on_null(calloc(1, size), size, file, line);
|
|
}
|
|
|
|
#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
|
|
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
|
|
|
/*****************************************************************************
|
|
* Event Handler
|
|
****************************************************************************/
|
|
|
|
static void
|
|
shm_format(void *data, struct wl_shm *pWlShm, uint32_t format)
|
|
{
|
|
struct wlContextCommon *pCtx = data;
|
|
|
|
pCtx->formats |= (1 << format);
|
|
}
|
|
|
|
static struct wl_shm_listener shm_listenter = {
|
|
shm_format
|
|
};
|
|
|
|
static int32_t
|
|
getIdOfWlSurface(struct wlContextCommon *pCtx, struct wl_surface *wlSurface)
|
|
{
|
|
struct wlContextStruct *pWlCtxSt = NULL;
|
|
|
|
if (NULL == pCtx || NULL == wlSurface )
|
|
return 0;
|
|
|
|
wl_list_for_each(pWlCtxSt, &pCtx->list_wlContextStruct, link) {
|
|
if (pWlCtxSt->wlSurface == wlSurface)
|
|
return pWlCtxSt->id_surface;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static void
|
|
set_pointer_image(struct wlContextCommon *pCtx, uint32_t index)
|
|
{
|
|
struct wl_cursor *cursor = NULL;
|
|
struct wl_cursor_image *image = NULL;
|
|
struct wl_buffer *buffer = NULL;
|
|
|
|
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;
|
|
}
|
|
|
|
cursor = pCtx->cursors[pCtx->current_cursor];
|
|
if (!cursor)
|
|
return;
|
|
|
|
if (cursor->image_count <= index) {
|
|
fprintf(stderr, "cursor index out of range\n");
|
|
return;
|
|
}
|
|
|
|
image = cursor->images[index];
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
#ifdef _DEBUG
|
|
printf("ENTER PointerHandleMotion: x(%d), y(%d)\n", sx, sy);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* if a surface assigned as launcher receives touch-off event, invoking
|
|
* ivi-application which configured in weston.ini with path to binary.
|
|
*/
|
|
extern char **environ; /*defied by libc */
|
|
|
|
static pid_t
|
|
execute_process(char *path, char *argv[])
|
|
{
|
|
pid_t pid = fork();
|
|
if (pid < 0)
|
|
fprintf(stderr, "Failed to fork\n");
|
|
|
|
if (pid)
|
|
return pid;
|
|
|
|
if (-1 == execve(path, argv, environ)) {
|
|
fprintf(stderr, "Failed to execve %s\n", path);
|
|
exit(1);
|
|
}
|
|
|
|
return pid;
|
|
}
|
|
|
|
static int32_t
|
|
launcher_button(uint32_t surfaceId, struct wl_list *launcher_list)
|
|
{
|
|
struct hmi_homescreen_launcher *launcher = NULL;
|
|
|
|
wl_list_for_each(launcher, launcher_list, link) {
|
|
char *argv[] = { NULL };
|
|
|
|
if (surfaceId != launcher->icon_surface_id)
|
|
continue;
|
|
|
|
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)
|
|
{
|
|
struct hmi_homescreen_launcher *launcher = NULL;
|
|
|
|
if (id == hmi_setting->workspace_background.id)
|
|
return 1;
|
|
|
|
wl_list_for_each(launcher, &hmi_setting->launcher_list, link) {
|
|
if (id == launcher->icon_surface_id)
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Decide which request is sent to hmi-controller
|
|
*/
|
|
static void
|
|
touch_up(struct ivi_hmi_controller *hmi_ctrl, uint32_t id_surface,
|
|
int32_t *is_home_on, struct hmi_homescreen_setting *hmi_setting)
|
|
{
|
|
if (launcher_button(id_surface, &hmi_setting->launcher_list)) {
|
|
*is_home_on = 0;
|
|
ivi_hmi_controller_home(hmi_ctrl, IVI_HMI_CONTROLLER_HOME_OFF);
|
|
} else if (id_surface == hmi_setting->tiling.id) {
|
|
ivi_hmi_controller_switch_mode(hmi_ctrl,
|
|
IVI_HMI_CONTROLLER_LAYOUT_MODE_TILING);
|
|
} else if (id_surface == hmi_setting->sidebyside.id) {
|
|
ivi_hmi_controller_switch_mode(hmi_ctrl,
|
|
IVI_HMI_CONTROLLER_LAYOUT_MODE_SIDE_BY_SIDE);
|
|
} else if (id_surface == hmi_setting->fullscreen.id) {
|
|
ivi_hmi_controller_switch_mode(hmi_ctrl,
|
|
IVI_HMI_CONTROLLER_LAYOUT_MODE_FULL_SCREEN);
|
|
} else if (id_surface == hmi_setting->random.id) {
|
|
ivi_hmi_controller_switch_mode(hmi_ctrl,
|
|
IVI_HMI_CONTROLLER_LAYOUT_MODE_RANDOM);
|
|
} else if (id_surface == hmi_setting->home.id) {
|
|
*is_home_on = !(*is_home_on);
|
|
if (*is_home_on) {
|
|
ivi_hmi_controller_home(hmi_ctrl,
|
|
IVI_HMI_CONTROLLER_HOME_ON);
|
|
} else {
|
|
ivi_hmi_controller_home(hmi_ctrl,
|
|
IVI_HMI_CONTROLLER_HOME_OFF);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Even handler of Pointer event. IVI system is usually manipulated by touch
|
|
* screen. However, some systems also have pointer device.
|
|
* Release is the same behavior as touch off
|
|
* Pressed is the same behavior as touch on
|
|
*/
|
|
static void
|
|
PointerHandleButton(void *data, struct wl_pointer *wlPointer, uint32_t serial,
|
|
uint32_t time, uint32_t button, uint32_t state)
|
|
{
|
|
struct wlContextCommon *pCtx = data;
|
|
struct ivi_hmi_controller *hmi_ctrl = pCtx->hmiCtrl;
|
|
const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
|
|
|
|
if (BTN_RIGHT == button)
|
|
return;
|
|
|
|
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)
|
|
{
|
|
#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;
|
|
uint32_t id_surface = 0;
|
|
|
|
if (0 == id)
|
|
pCtx->enterSurface = surface;
|
|
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
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_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_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)
|
|
{
|
|
struct wlContextCommon *pCtx = data;
|
|
const uint32_t id_surface = getIdOfWlSurface(pCtx, pCtx->enterSurface);
|
|
|
|
if (is_controlled)
|
|
return;
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
struct wlContextCommon *p_wlCtx = (struct wlContextCommon*)data;
|
|
|
|
if (!strcmp(interface, "wl_compositor")) {
|
|
p_wlCtx->wlCompositor =
|
|
wl_registry_bind(registry, name,
|
|
&wl_compositor_interface, 1);
|
|
} else 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);
|
|
} else 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);
|
|
} else if (!strcmp(interface, "ivi_application")) {
|
|
p_wlCtx->iviApplication =
|
|
wl_registry_bind(registry, name,
|
|
&ivi_application_interface, 1);
|
|
} else if (!strcmp(interface, "ivi_hmi_controller")) {
|
|
p_wlCtx->hmiCtrl =
|
|
wl_registry_bind(registry, name,
|
|
&ivi_hmi_controller_interface, 1);
|
|
|
|
ivi_hmi_controller_add_listener(p_wlCtx->hmiCtrl,
|
|
&hmi_controller_listener, p_wlCtx);
|
|
}
|
|
}
|
|
|
|
static void
|
|
registry_handle_global_remove(void *data, struct wl_registry *registry,
|
|
uint32_t name)
|
|
{
|
|
}
|
|
|
|
static const struct wl_registry_listener registry_listener = {
|
|
registry_handle_global,
|
|
registry_handle_global_remove
|
|
};
|
|
|
|
static void
|
|
frame_listener_func(void *data, struct wl_callback *callback, uint32_t time)
|
|
{
|
|
if (callback)
|
|
wl_callback_destroy(callback);
|
|
}
|
|
|
|
static const struct wl_callback_listener frame_listener = {
|
|
frame_listener_func
|
|
};
|
|
|
|
/*
|
|
* The following correspondences between file names and cursors was copied
|
|
* from: https://bugs.kde.org/attachment.cgi?id=67313
|
|
*/
|
|
static const char *bottom_left_corners[] = {
|
|
"bottom_left_corner",
|
|
"sw-resize",
|
|
"size_bdiag"
|
|
};
|
|
|
|
static const char *bottom_right_corners[] = {
|
|
"bottom_right_corner",
|
|
"se-resize",
|
|
"size_fdiag"
|
|
};
|
|
|
|
static const char *bottom_sides[] = {
|
|
"bottom_side",
|
|
"s-resize",
|
|
"size_ver"
|
|
};
|
|
|
|
static const char *grabbings[] = {
|
|
"grabbing",
|
|
"closedhand",
|
|
"208530c400c041818281048008011002"
|
|
};
|
|
|
|
static const char *left_ptrs[] = {
|
|
"left_ptr",
|
|
"default",
|
|
"top_left_arrow",
|
|
"left-arrow"
|
|
};
|
|
|
|
static const char *left_sides[] = {
|
|
"left_side",
|
|
"w-resize",
|
|
"size_hor"
|
|
};
|
|
|
|
static const char *right_sides[] = {
|
|
"right_side",
|
|
"e-resize",
|
|
"size_hor"
|
|
};
|
|
|
|
static const char *top_left_corners[] = {
|
|
"top_left_corner",
|
|
"nw-resize",
|
|
"size_fdiag"
|
|
};
|
|
|
|
static const char *top_right_corners[] = {
|
|
"top_right_corner",
|
|
"ne-resize",
|
|
"size_bdiag"
|
|
};
|
|
|
|
static const char *top_sides[] = {
|
|
"top_side",
|
|
"n-resize",
|
|
"size_ver"
|
|
};
|
|
|
|
static const char *xterms[] = {
|
|
"xterm",
|
|
"ibeam",
|
|
"text"
|
|
};
|
|
|
|
static const char *hand1s[] = {
|
|
"hand1",
|
|
"pointer",
|
|
"pointing_hand",
|
|
"e29285e634086352946a0e7090d73106"
|
|
};
|
|
|
|
static const char *watches[] = {
|
|
"watch",
|
|
"wait",
|
|
"0426c94ea35c87780ff01dc239897213"
|
|
};
|
|
|
|
struct cursor_alternatives {
|
|
const char **names;
|
|
size_t count;
|
|
};
|
|
|
|
static const struct cursor_alternatives cursors[] = {
|
|
{ bottom_left_corners, ARRAY_LENGTH(bottom_left_corners) },
|
|
{ bottom_right_corners, ARRAY_LENGTH(bottom_right_corners) },
|
|
{ bottom_sides, ARRAY_LENGTH(bottom_sides) },
|
|
{ grabbings, ARRAY_LENGTH(grabbings) },
|
|
{ left_ptrs, ARRAY_LENGTH(left_ptrs) },
|
|
{ left_sides, ARRAY_LENGTH(left_sides) },
|
|
{ right_sides, ARRAY_LENGTH(right_sides) },
|
|
{ top_left_corners, ARRAY_LENGTH(top_left_corners) },
|
|
{ top_right_corners, ARRAY_LENGTH(top_right_corners) },
|
|
{ top_sides, ARRAY_LENGTH(top_sides) },
|
|
{ xterms, ARRAY_LENGTH(xterms) },
|
|
{ hand1s, ARRAY_LENGTH(hand1s) },
|
|
{ watches, ARRAY_LENGTH(watches) },
|
|
};
|
|
|
|
static void
|
|
create_cursors(struct wlContextCommon *cmm)
|
|
{
|
|
uint32_t i = 0;
|
|
uint32_t j = 0;
|
|
struct wl_cursor *cursor = NULL;
|
|
char *cursor_theme = cmm->hmi_setting->cursor_theme;
|
|
int32_t cursor_size = cmm->hmi_setting->cursor_size;
|
|
|
|
cmm->cursor_theme = wl_cursor_theme_load(cursor_theme, cursor_size,
|
|
cmm->wlShm);
|
|
|
|
cmm->cursors =
|
|
MEM_ALLOC(ARRAY_LENGTH(cursors) * sizeof(cmm->cursors[0]));
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(cursors); i++) {
|
|
cursor = NULL;
|
|
|
|
for (j = 0; !cursor && j < cursors[i].count; ++j) {
|
|
cursor = wl_cursor_theme_get_cursor(
|
|
cmm->cursor_theme, cursors[i].names[j]);
|
|
}
|
|
|
|
if (!cursor) {
|
|
fprintf(stderr, "could not load cursor '%s'\n",
|
|
cursors[i].names[0]);
|
|
}
|
|
|
|
cmm->cursors[i] = cursor;
|
|
}
|
|
}
|
|
|
|
static void
|
|
destroy_cursors(struct wlContextCommon *cmm)
|
|
{
|
|
if (cmm->cursor_theme)
|
|
wl_cursor_theme_destroy(cmm->cursor_theme);
|
|
|
|
free(cmm->cursors);
|
|
}
|
|
|
|
/**
|
|
* Internal method to prepare parts of UI
|
|
*/
|
|
static void
|
|
createShmBuffer(struct wlContextStruct *p_wlCtx)
|
|
{
|
|
struct wl_shm_pool *pool;
|
|
|
|
int fd = -1;
|
|
int size = 0;
|
|
int width = 0;
|
|
int height = 0;
|
|
int stride = 0;
|
|
|
|
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;
|
|
|
|
fd = os_create_anonymous_file(size);
|
|
if (fd < 0) {
|
|
fprintf(stderr, "creating a buffer file for %d B failed: %m\n",
|
|
size);
|
|
return ;
|
|
}
|
|
|
|
p_wlCtx->data =
|
|
mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
|
|
if (MAP_FAILED == p_wlCtx->data) {
|
|
fprintf(stderr, "mmap failed: %m\n");
|
|
close(fd);
|
|
return;
|
|
}
|
|
|
|
pool = wl_shm_create_pool(p_wlCtx->cmm->wlShm, fd, size);
|
|
p_wlCtx->wlBuffer = wl_shm_pool_create_buffer(pool, 0,
|
|
width,
|
|
height,
|
|
stride,
|
|
WL_SHM_FORMAT_ARGB8888);
|
|
|
|
if (NULL == p_wlCtx->wlBuffer) {
|
|
fprintf(stderr, "wl_shm_create_buffer failed: %m\n");
|
|
close(fd);
|
|
return;
|
|
}
|
|
|
|
wl_shm_pool_destroy(pool);
|
|
close(fd);
|
|
}
|
|
|
|
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
|
|
createSurface(struct wlContextStruct *p_wlCtx)
|
|
{
|
|
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();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
|
|
createSurface(p_wlCtx);
|
|
createShmBuffer(p_wlCtx);
|
|
|
|
ivisurf = ivi_application_surface_create(p_wlCtx->cmm->iviApplication,
|
|
id_surface,
|
|
p_wlCtx->wlSurface);
|
|
if (ivisurf == NULL) {
|
|
fprintf(stderr, "Failed to create ivi_client_surface\n");
|
|
return;
|
|
}
|
|
|
|
drawImage(p_wlCtx);
|
|
}
|
|
|
|
static void
|
|
create_ivisurfaceFromFile(struct wlContextStruct *p_wlCtx,
|
|
uint32_t id_surface,
|
|
const char *imageFile)
|
|
{
|
|
cairo_surface_t *surface = load_cairo_surface(imageFile);
|
|
|
|
if (NULL == surface) {
|
|
fprintf(stderr, "Failed to load_cairo_surface %s\n", imageFile);
|
|
return;
|
|
}
|
|
|
|
create_ivisurface(p_wlCtx, id_surface, surface);
|
|
}
|
|
|
|
static void
|
|
set_hex_color(cairo_t *cr, uint32_t color)
|
|
{
|
|
cairo_set_source_rgba(cr,
|
|
((color >> 16) & 0xff) / 255.0,
|
|
((color >> 8) & 0xff) / 255.0,
|
|
((color >> 0) & 0xff) / 255.0,
|
|
((color >> 24) & 0xff) / 255.0);
|
|
}
|
|
|
|
static void
|
|
create_ivisurfaceFromColor(struct wlContextStruct *p_wlCtx,
|
|
uint32_t id_surface,
|
|
uint32_t width, uint32_t height,
|
|
uint32_t color)
|
|
{
|
|
cairo_surface_t *surface = NULL;
|
|
cairo_t *cr = NULL;
|
|
|
|
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
|
|
width, height);
|
|
|
|
cr = cairo_create(surface);
|
|
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
|
cairo_rectangle(cr, 0, 0, width, height);
|
|
set_hex_color(cr, color);
|
|
cairo_fill(cr);
|
|
cairo_destroy(cr);
|
|
|
|
create_ivisurface(p_wlCtx, id_surface, surface);
|
|
}
|
|
|
|
static void
|
|
UI_ready(struct ivi_hmi_controller *controller)
|
|
{
|
|
ivi_hmi_controller_UI_ready(controller);
|
|
}
|
|
|
|
/**
|
|
* Internal method to set up UI by using ivi-hmi-controller
|
|
*/
|
|
static void
|
|
create_background(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
|
|
const char *imageFile)
|
|
{
|
|
create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
|
|
}
|
|
|
|
static void
|
|
create_panel(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
|
|
const char *imageFile)
|
|
{
|
|
create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
|
|
}
|
|
|
|
static void
|
|
create_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
|
|
const char *imageFile, uint32_t number)
|
|
{
|
|
create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
|
|
}
|
|
|
|
static void
|
|
create_home_button(struct wlContextStruct *p_wlCtx, const uint32_t id_surface,
|
|
const char *imageFile)
|
|
{
|
|
create_ivisurfaceFromFile(p_wlCtx, id_surface, imageFile);
|
|
}
|
|
|
|
static void
|
|
create_workspace_background(struct wlContextStruct *p_wlCtx,
|
|
struct hmi_homescreen_srf *srf)
|
|
{
|
|
create_ivisurfaceFromColor(p_wlCtx, srf->id, 1, 1, srf->color);
|
|
}
|
|
|
|
static void
|
|
create_launchers(struct wlContextCommon *cmm, struct wl_list *launcher_list)
|
|
{
|
|
struct hmi_homescreen_launcher **launchers;
|
|
struct hmi_homescreen_launcher *launcher = NULL;
|
|
|
|
int launcher_count = wl_list_length(launcher_list);
|
|
int ii = 0;
|
|
int start = 0;
|
|
|
|
if (0 == launcher_count)
|
|
return;
|
|
|
|
launchers = MEM_ALLOC(launcher_count * sizeof(*launchers));
|
|
|
|
wl_list_for_each(launcher, launcher_list, link) {
|
|
launchers[ii] = launcher;
|
|
ii++;
|
|
}
|
|
|
|
for (ii = 0; ii < launcher_count; ii++) {
|
|
int jj = 0;
|
|
|
|
if (ii != launcher_count - 1 &&
|
|
launchers[ii]->workspace_id ==
|
|
launchers[ii + 1]->workspace_id)
|
|
continue;
|
|
|
|
for (jj = start; jj <= ii; jj++) {
|
|
struct wlContextStruct *p_wlCtx;
|
|
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* Internal method to read out weston.ini to get configuration
|
|
*/
|
|
static struct hmi_homescreen_setting *
|
|
hmi_homescreen_setting_create(void)
|
|
{
|
|
const char *config_file;
|
|
struct weston_config *config = NULL;
|
|
struct weston_config_section *shellSection = NULL;
|
|
struct hmi_homescreen_setting *setting = MEM_ALLOC(sizeof(*setting));
|
|
struct weston_config_section *section = NULL;
|
|
const char *name = NULL;
|
|
uint32_t workspace_layer_id;
|
|
uint32_t icon_surface_id = 0;
|
|
|
|
wl_list_init(&setting->workspace_list);
|
|
wl_list_init(&setting->launcher_list);
|
|
|
|
config_file = weston_config_get_name_from_env();
|
|
config = weston_config_parse(config_file);
|
|
|
|
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);
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "workspace-layer-id", &workspace_layer_id, 3000);
|
|
|
|
weston_config_section_get_string(
|
|
shellSection, "background-image", &setting->background.filePath,
|
|
DATADIR "/weston/background.png");
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "background-id", &setting->background.id, 1001);
|
|
|
|
weston_config_section_get_string(
|
|
shellSection, "panel-image", &setting->panel.filePath,
|
|
DATADIR "/weston/panel.png");
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "panel-id", &setting->panel.id, 1002);
|
|
|
|
weston_config_section_get_string(
|
|
shellSection, "tiling-image", &setting->tiling.filePath,
|
|
DATADIR "/weston/tiling.png");
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "tiling-id", &setting->tiling.id, 1003);
|
|
|
|
weston_config_section_get_string(
|
|
shellSection, "sidebyside-image", &setting->sidebyside.filePath,
|
|
DATADIR "/weston/sidebyside.png");
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "sidebyside-id", &setting->sidebyside.id, 1004);
|
|
|
|
weston_config_section_get_string(
|
|
shellSection, "fullscreen-image", &setting->fullscreen.filePath,
|
|
DATADIR "/weston/fullscreen.png");
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "fullscreen-id", &setting->fullscreen.id, 1005);
|
|
|
|
weston_config_section_get_string(
|
|
shellSection, "random-image", &setting->random.filePath,
|
|
DATADIR "/weston/random.png");
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "random-id", &setting->random.id, 1006);
|
|
|
|
weston_config_section_get_string(
|
|
shellSection, "home-image", &setting->home.filePath,
|
|
DATADIR "/weston/home.png");
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "home-id", &setting->home.id, 1007);
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "workspace-background-color",
|
|
&setting->workspace_background.color, 0x99000000);
|
|
|
|
weston_config_section_get_uint(
|
|
shellSection, "workspace-background-id",
|
|
&setting->workspace_background.id, 2001);
|
|
|
|
icon_surface_id = workspace_layer_id + 1;
|
|
|
|
while (weston_config_next_section(config, §ion, &name)) {
|
|
struct hmi_homescreen_launcher *launcher;
|
|
|
|
if (strcmp(name, "ivi-launcher") != 0)
|
|
continue;
|
|
|
|
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;
|
|
int ret = 0;
|
|
struct hmi_homescreen_setting *hmi_setting;
|
|
struct wlContextStruct *pWlCtxSt = NULL;
|
|
|
|
hmi_setting = hmi_homescreen_setting_create();
|
|
|
|
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);
|
|
wl_list_init(&wlCtxCommon.list_wlContextStruct);
|
|
|
|
wlCtxCommon.hmi_setting = hmi_setting;
|
|
|
|
wlCtxCommon.wlDisplay = wl_display_connect(NULL);
|
|
if (NULL == wlCtxCommon.wlDisplay) {
|
|
printf("Error: wl_display_connect failed.\n");
|
|
return -1;
|
|
}
|
|
|
|
/* get wl_registry */
|
|
wlCtxCommon.formats = 0;
|
|
wlCtxCommon.wlRegistry = wl_display_get_registry(wlCtxCommon.wlDisplay);
|
|
wl_registry_add_listener(wlCtxCommon.wlRegistry,
|
|
®istry_listener, &wlCtxCommon);
|
|
wl_display_roundtrip(wlCtxCommon.wlDisplay);
|
|
|
|
if (wlCtxCommon.wlShm == NULL) {
|
|
fprintf(stderr, "No wl_shm global\n");
|
|
exit(1);
|
|
}
|
|
|
|
wl_display_roundtrip(wlCtxCommon.wlDisplay);
|
|
|
|
if (!(wlCtxCommon.formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
|
|
fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (wlCtxCommon.hmi_setting->cursor_theme) {
|
|
create_cursors(&wlCtxCommon);
|
|
|
|
wlCtxCommon.pointer_surface =
|
|
wl_compositor_create_surface(wlCtxCommon.wlCompositor);
|
|
|
|
wlCtxCommon.current_cursor = CURSOR_LEFT_PTR;
|
|
}
|
|
|
|
wlCtx_BackGround.cmm = &wlCtxCommon;
|
|
wlCtx_Panel.cmm = &wlCtxCommon;
|
|
wlCtx_Button_1.cmm = &wlCtxCommon;
|
|
wlCtx_Button_2.cmm = &wlCtxCommon;
|
|
wlCtx_Button_3.cmm = &wlCtxCommon;
|
|
wlCtx_Button_4.cmm = &wlCtxCommon;
|
|
wlCtx_HomeButton.cmm = &wlCtxCommon;
|
|
wlCtx_WorkSpaceBackGround.cmm = &wlCtxCommon;
|
|
|
|
/* create desktop widgets */
|
|
create_background(&wlCtx_BackGround, hmi_setting->background.id,
|
|
hmi_setting->background.filePath);
|
|
|
|
create_panel(&wlCtx_Panel, hmi_setting->panel.id,
|
|
hmi_setting->panel.filePath);
|
|
|
|
create_button(&wlCtx_Button_1, hmi_setting->tiling.id,
|
|
hmi_setting->tiling.filePath, 0);
|
|
|
|
create_button(&wlCtx_Button_2, hmi_setting->sidebyside.id,
|
|
hmi_setting->sidebyside.filePath, 1);
|
|
|
|
create_button(&wlCtx_Button_3, hmi_setting->fullscreen.id,
|
|
hmi_setting->fullscreen.filePath, 2);
|
|
|
|
create_button(&wlCtx_Button_4, hmi_setting->random.id,
|
|
hmi_setting->random.filePath, 3);
|
|
|
|
create_workspace_background(&wlCtx_WorkSpaceBackGround,
|
|
&hmi_setting->workspace_background);
|
|
|
|
create_launchers(&wlCtxCommon, &hmi_setting->launcher_list);
|
|
|
|
create_home_button(&wlCtx_HomeButton, hmi_setting->home.id,
|
|
hmi_setting->home.filePath);
|
|
|
|
UI_ready(wlCtxCommon.hmiCtrl);
|
|
|
|
while(ret != -1)
|
|
ret = wl_display_dispatch(wlCtxCommon.wlDisplay);
|
|
|
|
wl_list_for_each(pWlCtxSt, &wlCtxCommon.list_wlContextStruct, link) {
|
|
destroyWLContextStruct(pWlCtxSt);
|
|
}
|
|
|
|
destroyWLContextCommon(&wlCtxCommon);
|
|
|
|
return 0;
|
|
}
|