summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Friedrich <efriedrich@de.adit-jv.com>2017-08-31 17:35:03 +0200
committerEugen Friedrich <efriedrich@de.adit-jv.com>2017-08-31 17:35:03 +0200
commit521be17d32dcae0f2e05884e3e6b49a96b4568ed (patch)
treec7ff397e9e97fbfb28207152904cddceea5a21a7
parent8ac50edecf0b79093385a2fe25107178086af1fe (diff)
parentf42d5b0dc5a3d03e5e940c360f67b5e8c4bb7cc3 (diff)
downloadwayland-ivi-extension-521be17d32dcae0f2e05884e3e6b49a96b4568ed.tar.gz
Merge remote-tracking branch 'upstream/pull/54'
* upstream/pull/54 ivi-controller: update view transform for bkgnd surface ivi-controller: added bkgnd layer support examples:added client for bkgnd layer and mouse pointer Tested-by: Eugen Friedrich <efriedrich@de.adit-jv.com>
-rw-r--r--ivi-layermanagement-examples/CMakeLists.txt1
-rw-r--r--ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt55
-rw-r--r--ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c491
-rw-r--r--weston-ivi-shell/src/ivi-controller.c213
-rw-r--r--weston-ivi-shell/src/ivi-controller.h11
5 files changed, 759 insertions, 12 deletions
diff --git a/ivi-layermanagement-examples/CMakeLists.txt b/ivi-layermanagement-examples/CMakeLists.txt
index 416b00c..59f4394 100644
--- a/ivi-layermanagement-examples/CMakeLists.txt
+++ b/ivi-layermanagement-examples/CMakeLists.txt
@@ -29,3 +29,4 @@ add_subdirectory(EGLWLInputEventExample)
add_subdirectory(layer-add-surfaces)
add_subdirectory(multi-touch-viewer)
add_subdirectory(simple-ivi-share)
+add_subdirectory(simple-weston-client)
diff --git a/ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt b/ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt
new file mode 100644
index 0000000..022ac44
--- /dev/null
+++ b/ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt
@@ -0,0 +1,55 @@
+############################################################################
+#
+# Copyright 2012 BMW Car IT GmbH
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+############################################################################
+
+project (simple-weston-client)
+
+find_package(PkgConfig)
+pkg_check_modules(WAYLAND_CLIENT wayland-client REQUIRED)
+pkg_check_modules(WAYLAND_CURSOR wayland-cursor REQUIRED)
+
+GET_TARGET_PROPERTY(IVI_EXTENSION_PROTOCOL_DIRS ivi-extension-protocol INCLUDE_DIRECTORIES)
+
+include_directories(
+ ${IVI_EXTENSION_PROTOCOL_DIRS}
+ ${WAYLAND_CLIENT_INCLUDE_DIR}
+ ${WAYLAND_CURSOR_INCLUDE_DIR}
+)
+
+link_directories(
+ ${WAYLAND_CLIENT_LIBRARY_DIRS}
+ ${WAYLAND_CURSOR_LIBRARY_DIRS}
+)
+
+SET(LIBS
+ ivi-application
+ ${WAYLAND_CLIENT_LIBRARIES}
+ ${WAYLAND_CURSOR_LIBRARIES}
+)
+
+SET(SRC_FILES
+ src/simple-weston-client.c
+)
+
+add_executable(${PROJECT_NAME} ${SRC_FILES})
+
+add_dependencies(${PROJECT_NAME} ${LIBS})
+
+target_link_libraries(${PROJECT_NAME} ${LIBS})
+
+install (TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c b/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c
new file mode 100644
index 0000000..167b457
--- /dev/null
+++ b/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2015 Advanced Driver Information Technology Joint Venture GmbH
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include <wayland-cursor.h>
+#include <ivi-application-client-protocol.h>
+
+typedef struct _BkGndSettings
+{
+ uint32_t surface_id;
+ uint32_t surface_width;
+ uint32_t surface_height;
+ uint32_t surface_stride;
+}BkGndSettingsStruct;
+
+typedef struct _WaylandContext {
+ struct wl_display *wl_display;
+ struct wl_registry *wl_registry;
+ struct wl_compositor *wl_compositor;
+ struct wl_shm *wl_shm;
+ struct wl_seat *wl_seat;
+ struct wl_pointer *wl_pointer;
+ struct wl_surface *wl_pointer_surface;
+ struct ivi_application *ivi_application;
+ BkGndSettingsStruct *bkgnd_settings;
+ struct wl_surface *wlBkgndSurface;
+ struct wl_buffer *wlBkgndBuffer;
+ struct wl_cursor_theme *cursor_theme;
+ struct wl_cursor *cursor;
+ void *bkgnddata;
+ uint32_t formats;
+}WaylandContextStruct;
+
+static const char *left_ptrs[] = {
+ "left_ptr",
+ "default",
+ "top_left_arrow",
+ "left-arrow"
+};
+
+static BkGndSettingsStruct*
+get_bkgnd_settings(void)
+{
+ BkGndSettingsStruct* bkgnd_settings;
+ char *option;
+ char *end;
+ int len;
+
+ bkgnd_settings =
+ (BkGndSettingsStruct*)calloc(1, sizeof(BkGndSettingsStruct));
+
+ option = getenv("IVI_CLIENT_SURFACE_ID");
+ if(option)
+ bkgnd_settings->surface_id = strtol(option, &end, 0);
+ else
+ bkgnd_settings->surface_id = 10;
+
+ bkgnd_settings->surface_width = 1;
+ bkgnd_settings->surface_height = 1;
+ bkgnd_settings->surface_stride = bkgnd_settings->surface_width * 4;
+
+ return bkgnd_settings;
+}
+
+static void
+shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
+{
+ WaylandContextStruct* wlcontext = data;
+
+ wlcontext->formats |= (1 << format);
+}
+
+static struct wl_shm_listener shm_listenter = {
+ shm_format
+};
+
+static int create_cursors(WaylandContextStruct* wlcontext) {
+ int size = 32;
+ unsigned int j;
+
+ wlcontext->cursor_theme = wl_cursor_theme_load(NULL, size, wlcontext->wl_shm);
+ if (!wlcontext->cursor_theme) {
+ fprintf(stderr, "could not load default theme\n");
+ return -1;
+ }
+
+ wlcontext->cursor = NULL;
+
+ for (j = 0; !wlcontext->cursor && j < 4; ++j)
+ wlcontext->cursor = wl_cursor_theme_get_cursor(wlcontext->cursor_theme, left_ptrs[j]);
+
+ if (!wlcontext->cursor)
+ {
+ fprintf(stderr, "could not load cursor '%s'\n", left_ptrs[j]);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int set_pointer_image(WaylandContextStruct* wlcontext)
+{
+ struct wl_cursor *cursor = NULL;
+ struct wl_cursor_image *image = NULL;
+ struct wl_buffer *buffer = NULL;
+
+ if (!wlcontext->wl_pointer || !wlcontext->cursor) {
+ fprintf(stderr, "no wl_pointer or no wl_cursor\n");
+ return -1;
+ }
+
+ cursor = wlcontext->cursor;
+ image = cursor->images[0];
+ buffer = wl_cursor_image_get_buffer(image);
+ if (!buffer) {
+ fprintf(stderr, "buffer for cursor not available\n");
+ return -1;
+ }
+
+ wl_pointer_set_cursor(wlcontext->wl_pointer, 0,
+ wlcontext->wl_pointer_surface,
+ image->hotspot_x, image->hotspot_y);
+ wl_surface_attach(wlcontext->wl_pointer_surface, buffer, 0, 0);
+ wl_surface_damage(wlcontext->wl_pointer_surface, 0, 0,
+ image->width, image->height);
+ wl_surface_commit(wlcontext->wl_pointer_surface);
+
+ return 0;
+}
+
+static void
+PointerHandleEnter(void *data, struct wl_pointer *wlPointer, uint32_t serial,
+ struct wl_surface *wlSurface, wl_fixed_t sx, wl_fixed_t sy)
+{
+ WaylandContextStruct *wlcontext = (WaylandContextStruct*)data;
+
+ set_pointer_image(wlcontext);
+
+ printf("ENTER EGLWLINPUT PointerHandleEnter: x(%d), y(%d)\n",
+ wl_fixed_to_int(sx), wl_fixed_to_int(sy));
+}
+
+static void
+PointerHandleLeave(void *data, struct wl_pointer *wlPointer, uint32_t serial,
+ struct wl_surface *wlSurface)
+{
+
+}
+
+static void
+PointerHandleMotion(void *data, struct wl_pointer *wlPointer, uint32_t time,
+ wl_fixed_t sx, wl_fixed_t sy)
+{
+
+}
+
+static void
+PointerHandleAxis(void *data, struct wl_pointer *wlPointer, uint32_t time,
+ uint32_t axis, wl_fixed_t value)
+{
+
+}
+
+static void
+PointerHandleButton(void *data, struct wl_pointer *wlPointer, uint32_t serial,
+ uint32_t time, uint32_t button, uint32_t state)
+{
+
+}
+
+static struct wl_pointer_listener pointer_listener = {
+ PointerHandleEnter,
+ PointerHandleLeave,
+ PointerHandleMotion,
+ PointerHandleButton,
+ PointerHandleAxis
+};
+
+static void
+seat_handle_capabilities(void *data, struct wl_seat *seat, uint32_t caps)
+{
+ WaylandContextStruct *wlcontext = (WaylandContextStruct*)data;
+ struct wl_seat *wl_seat = wlcontext->wl_seat;
+
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlcontext->wl_pointer) {
+ wlcontext->wl_pointer = wl_seat_get_pointer(wl_seat);
+ wl_pointer_add_listener(wlcontext->wl_pointer,
+ &pointer_listener, data);
+ /*create cursors*/
+ create_cursors(wlcontext);
+ wlcontext->wl_pointer_surface =
+ wl_compositor_create_surface(wlcontext->wl_compositor);
+ } else
+ if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlcontext->wl_pointer) {
+ wl_pointer_destroy(wlcontext->wl_pointer);
+ wlcontext->wl_pointer = NULL;
+
+ if (wlcontext->wl_pointer_surface) {
+ wl_surface_destroy(wlcontext->wl_pointer_surface);
+ wlcontext->wl_pointer_surface = NULL;
+ }
+
+ if (wlcontext->cursor_theme)
+ wl_cursor_theme_destroy(wlcontext->cursor_theme);
+ }
+}
+
+static struct wl_seat_listener seat_Listener = {
+ seat_handle_capabilities,
+};
+
+static void
+registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
+ const char *interface, uint32_t version)
+{
+ WaylandContextStruct* wlcontext = (WaylandContextStruct*)data;
+
+ if (!strcmp(interface, "wl_compositor")) {
+ wlcontext->wl_compositor =
+ wl_registry_bind(registry, name,
+ &wl_compositor_interface, 1);
+ }
+ else if (!strcmp(interface, "wl_shm")) {
+ wlcontext->wl_shm =
+ wl_registry_bind(registry, name, &wl_shm_interface, 1);
+ wl_shm_add_listener(wlcontext->wl_shm, &shm_listenter, wlcontext);
+ }
+ else if (!strcmp(interface, "ivi_application")) {
+ wlcontext->ivi_application =
+ wl_registry_bind(registry, name,
+ &ivi_application_interface, 1);
+ }
+ else if (!strcmp(interface, "wl_seat")) {
+ wlcontext->wl_seat =
+ wl_registry_bind(registry, name, &wl_seat_interface, 1);
+ wl_seat_add_listener(wlcontext->wl_seat, &seat_Listener, data);
+ }
+}
+
+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
+};
+
+int init_wayland_context(WaylandContextStruct* wlcontext)
+{
+ wlcontext->wl_display = wl_display_connect(NULL);
+ if (NULL == wlcontext->wl_display) {
+ printf("Error: wl_display_connect failed\n");
+ return -1;
+ }
+
+ wlcontext->wl_registry = wl_display_get_registry(wlcontext->wl_display);
+ wl_registry_add_listener(wlcontext->wl_registry,
+ &registry_listener, wlcontext);
+ wl_display_roundtrip(wlcontext->wl_display);
+
+ if (wlcontext->wl_shm == NULL) {
+ fprintf(stderr, "No wl_shm global\n");
+ return -1;
+ }
+
+ wl_display_roundtrip(wlcontext->wl_display);
+
+ if (!(wlcontext->formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
+ fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+void destroy_wayland_context(WaylandContextStruct* wlcontext)
+{
+ if(wlcontext->wl_compositor)
+ wl_compositor_destroy(wlcontext->wl_compositor);
+
+ if(wlcontext->wl_display)
+ wl_display_disconnect(wlcontext->wl_display);
+}
+
+int
+create_file(int size)
+{
+ static const char template[] = "/weston-shared-XXXXXX";
+ const char *path;
+ char *name;
+ int fd;
+ int ret;
+ long flags;
+
+ path = getenv("XDG_RUNTIME_DIR");
+ if (!path) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ name = malloc(strlen(path) + sizeof(template));
+ if (!name)
+ return -1;
+
+ strcpy(name, path);
+ strcat(name, template);
+
+ fd = mkstemp(name);
+ if (fd >= 0) {
+ flags = fcntl(fd, F_GETFD);
+ fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+ unlink(name);
+ }
+
+ free(name);
+
+ if (fd < 0)
+ return -1;
+
+ ret = ftruncate(fd, size);
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+static int
+create_shm_buffer(WaylandContextStruct* wlcontext)
+{
+ struct wl_shm_pool *pool;
+ BkGndSettingsStruct* bkgnd_settings = wlcontext->bkgnd_settings;
+
+ int fd = -1;
+ int size = 0;
+ int stride = 0;
+
+ stride = bkgnd_settings->surface_stride;
+ size = stride * bkgnd_settings->surface_height;
+ fd = create_file(size);
+ if (fd < 0) {
+ fprintf(stderr, "creating a buffer file for %d B failed: %m\n",
+ size);
+ return -1;
+ }
+
+ wlcontext->bkgnddata =
+ mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ if (MAP_FAILED == wlcontext->bkgnddata) {
+ fprintf(stderr, "mmap failed: %m\n");
+ close(fd);
+ return -1;
+ }
+
+ pool = wl_shm_create_pool(wlcontext->wl_shm, fd, size);
+ wlcontext->wlBkgndBuffer = wl_shm_pool_create_buffer(pool, 0,
+ bkgnd_settings->surface_width,
+ bkgnd_settings->surface_height,
+ stride,
+ WL_SHM_FORMAT_ARGB8888);
+ if (NULL == wlcontext->wlBkgndBuffer) {
+ fprintf(stderr, "wl_shm_create_buffer failed: %m\n");
+ close(fd);
+ return -1;
+ }
+
+ wl_shm_pool_destroy(pool);
+ close(fd);
+
+ return 0;
+}
+
+int draw_bkgnd_surface(WaylandContextStruct* wlcontext)
+{
+ struct ivi_surface *ivisurf = NULL;
+ BkGndSettingsStruct *bkgnd_settings = wlcontext->bkgnd_settings;
+ uint32_t* pixels;
+
+ pixels = (uint32_t*)wlcontext->bkgnddata;
+ *pixels = 0x0;
+
+ wl_surface_attach(wlcontext->wlBkgndSurface, wlcontext->wlBkgndBuffer, 0, 0);
+ wl_surface_damage(wlcontext->wlBkgndSurface, 0, 0,
+ bkgnd_settings->surface_width, bkgnd_settings->surface_height);
+ wl_surface_commit(wlcontext->wlBkgndSurface);
+
+ return 0;
+}
+
+int create_bkgnd_surface(WaylandContextStruct* wlcontext)
+{
+ struct ivi_surface *ivisurf = NULL;
+ BkGndSettingsStruct *bkgnd_settings = wlcontext->bkgnd_settings;
+
+ wlcontext->wlBkgndSurface =
+ wl_compositor_create_surface(wlcontext->wl_compositor);
+ if (NULL == wlcontext->wlBkgndSurface) {
+ printf("Error: wl_compositor_create_surface failed.\n");
+ return -1;
+ }
+
+ if (create_shm_buffer(wlcontext)) {
+ printf("Error: shm buffer creation failed.\n");
+ return -1;
+ }
+
+ ivisurf = ivi_application_surface_create(wlcontext->ivi_application,
+ bkgnd_settings->surface_id,
+ wlcontext->wlBkgndSurface);
+
+ return 0;
+}
+
+void destroy_bkgnd_surface(WaylandContextStruct* wlcontext)
+{
+ if (wlcontext->wlBkgndSurface)
+ wl_surface_destroy(wlcontext->wlBkgndSurface);
+}
+
+int main (int argc, const char * argv[])
+{
+ WaylandContextStruct* wlcontext;
+ BkGndSettingsStruct* bkgnd_settings;
+ int offset = 0;
+ int ret;
+
+ /*get bkgnd settings and create shm-surface*/
+ bkgnd_settings = get_bkgnd_settings();
+
+ /*init wayland context*/
+ wlcontext = (WaylandContextStruct*)calloc(1, sizeof(WaylandContextStruct));
+ wlcontext->bkgnd_settings = bkgnd_settings;
+ if (init_wayland_context(wlcontext)) {
+ fprintf(stderr, "init_wayland_context failed\n");
+ return -1;
+ }
+
+ if (create_bkgnd_surface(wlcontext)) {
+ fprintf(stderr, "create_bkgnd_surface failed\n");
+ goto Error;
+ }
+
+ wl_display_roundtrip(wlcontext->wl_display);
+
+ /*draw the bkgnd display*/
+ draw_bkgnd_surface(wlcontext);
+
+ while (ret != -1)
+ ret = wl_display_dispatch(wlcontext->wl_display);
+
+Error:
+ destroy_bkgnd_surface(wlcontext);
+ destroy_wayland_context(wlcontext);
+
+ free(bkgnd_settings);
+ free(wlcontext);
+
+ return 0;
+}
diff --git a/weston-ivi-shell/src/ivi-controller.c b/weston-ivi-shell/src/ivi-controller.c
index ee694ba..6d95c88 100644
--- a/weston-ivi-shell/src/ivi-controller.c
+++ b/weston-ivi-shell/src/ivi-controller.c
@@ -44,6 +44,8 @@
# include "ivi-share.h"
#endif
+#define IVI_CLIENT_SURFACE_ID_ENV_NAME "IVI_CLIENT_SURFACE_ID"
+
struct ivilayer;
struct iviscreen;
@@ -825,6 +827,95 @@ controller_layer_clear(struct wl_client *client,
}
static void
+calc_trans_matrix(struct weston_geometry *source_rect,
+ struct weston_geometry *dest_rect,
+ struct weston_matrix *m)
+{
+ float source_center_x;
+ float source_center_y;
+ float scale_x;
+ float scale_y;
+ float translate_x;
+ float translate_y;
+
+ source_center_x = source_rect->x + source_rect->width * 0.5f;
+ source_center_y = source_rect->y + source_rect->height * 0.5f;
+ weston_matrix_translate(m, -source_center_x, -source_center_y, 0.0f);
+
+ scale_x = ((float)dest_rect->width) / source_rect->width;
+ scale_y = ((float)dest_rect->height) / source_rect->height;
+
+ weston_matrix_scale(m, scale_x, scale_y, 1.0f);
+
+ translate_x = dest_rect->width * 0.5f + dest_rect->x;
+ translate_y = dest_rect->height * 0.5f + dest_rect->y;
+ weston_matrix_translate(m, translate_x, translate_y, 0.0f);
+}
+
+void
+set_bkgnd_surface_prop(struct ivishell *shell)
+{
+ struct weston_view *view;
+ struct weston_compositor *compositor;
+ struct weston_output *output;
+ const struct ivi_layout_interface *lyt = shell->interface;
+ struct weston_surface *w_surface;
+ struct weston_geometry source_rect = {0};
+ struct weston_geometry dest_rect = {0};
+ uint32_t src_width = 0;
+ uint32_t src_height = 0;
+ uint32_t dest_width = 0;
+ uint32_t dest_height = 0;
+ uint32_t count = 0;
+ uint32_t x = 0;
+ uint32_t y = 0;
+ float scale_x;
+ float scale_y;
+
+ view = shell->bkgnd_view;
+ compositor = shell->compositor;
+
+ wl_list_remove(&shell->bkgnd_transform.link);
+ weston_matrix_init(&shell->bkgnd_transform.matrix);
+
+ /*find the available screen's resolution*/
+ wl_list_for_each(output, &compositor->output_list, link) {
+ if (!count)
+ {
+ x = output->x;
+ y = output->y;
+ count++;
+ }
+ dest_width = output->x + output->width;
+ if (output->height > dest_height)
+ dest_height = output->height;
+ weston_log("set_bkgnd_surface_prop: o_name:%s x:%d y:%d o_width:%d o_height:%d\n",
+ output->name, output->x, output->y, output->width, output->height);
+ }
+
+ w_surface = view->surface;
+ src_width = w_surface->width;
+ src_height = w_surface->height;
+
+ source_rect.width = src_width;
+ source_rect.height = src_height;
+ dest_rect.width = dest_width;
+ dest_rect.height = dest_height;
+
+ calc_trans_matrix(&source_rect, &dest_rect,
+ &shell->bkgnd_transform.matrix);
+ weston_matrix_translate(&shell->bkgnd_transform.matrix, x, y, 0.0f);
+
+ weston_log("set_bkgnd_surface_prop: x:%d y:%d s_width:%d s_height:%d d_width:%d d_height:%d\n",
+ x, y, src_width, src_height, dest_width, dest_height);
+
+ wl_list_insert(&view->geometry.transformation_list,
+ &shell->bkgnd_transform.link);
+ weston_view_update_transform(view);
+ weston_surface_schedule_repaint(w_surface);
+}
+
+static void
controller_layer_add_surface(struct wl_client *client,
struct wl_resource *resource,
uint32_t layer_id,
@@ -1483,6 +1574,20 @@ output_destroyed_event(struct wl_listener *listener, void *data)
if (iviscrn->output == destroyed_output)
destroy_screen(iviscrn);
}
+
+ if (shell->bkgnd_view)
+ set_bkgnd_surface_prop(shell);
+ else
+ weston_compositor_schedule_repaint(shell->compositor);
+}
+
+static void
+output_resized_event(struct wl_listener *listener, void *data)
+{
+ struct ivishell *shell = wl_container_of(listener, shell, output_destroyed);
+
+ if (shell->bkgnd_view)
+ set_bkgnd_surface_prop(shell);
}
static void
@@ -1493,6 +1598,11 @@ output_created_event(struct wl_listener *listener, void *data)
struct weston_output *created_output = (struct weston_output*)data;
iviscrn = create_screen(shell, created_output);
+
+ if (shell->bkgnd_view)
+ set_bkgnd_surface_prop(shell);
+ else
+ weston_compositor_schedule_repaint(shell->compositor);
}
static struct ivilayer*
@@ -1555,20 +1665,26 @@ create_surface(struct ivishell *shell,
ivisurf->shell = shell;
ivisurf->layout_surface = layout_surface;
ivisurf->prop = lyt->get_properties_of_surface(layout_surface);
- wl_list_insert(&shell->list_surface, &ivisurf->link);
wl_list_init(&ivisurf->notification_list);
ivisurf->committed.notify = surface_committed;
surface = lyt->surface_get_weston_surface(layout_surface);
wl_signal_add(&surface->commit_signal, &ivisurf->committed);
- wl_list_for_each(controller, &shell->list_controller, link) {
- if (controller->resource)
- ivi_wm_send_surface_created(controller->resource, id_surface);
- }
+ if (shell->bkgnd_surface_id != id_surface) {
+ wl_list_insert(&shell->list_surface, &ivisurf->link);
+
+ wl_list_for_each(controller, &shell->list_controller, link) {
+ if (controller->resource)
+ ivi_wm_send_surface_created(controller->resource, id_surface);
+ }
- ivisurf->property_changed.notify = send_surface_prop;
- lyt->surface_add_listener(layout_surface, &ivisurf->property_changed);
+ ivisurf->property_changed.notify = send_surface_prop;
+ lyt->surface_add_listener(layout_surface, &ivisurf->property_changed);
+ }
+ else {
+ shell->bkgnd_surface = ivisurf;
+ }
return ivisurf;
}
@@ -1649,7 +1765,8 @@ surface_event_create(struct wl_listener *listener, void *data)
return;
}
- wl_signal_emit(&shell->ivisurface_created_signal, ivisurf);
+ if (shell->bkgnd_surface_id != id_surface)
+ wl_signal_emit(&shell->ivisurface_created_signal, ivisurf);
}
static void
@@ -1685,6 +1802,12 @@ surface_event_remove(struct wl_listener *listener, void *data)
id_surface = shell->interface->get_id_of_surface(layout_surface);
+ if ((shell->bkgnd_surface_id == id_surface) &&
+ shell->bkgnd_view) {
+ weston_layer_entry_remove(&shell->bkgnd_view->layer_link);
+ weston_view_destroy(shell->bkgnd_view);
+ }
+
wl_list_for_each(controller, &shell->list_controller, link) {
if (controller->resource)
ivi_wm_send_surface_destroyed(controller->resource, id_surface);
@@ -1705,14 +1828,37 @@ surface_event_configure(struct wl_listener *listener, void *data)
uint32_t surface_id;
struct weston_surface *w_surface;
+ surface_id = lyt->get_id_of_surface(layout_surface);
+ if (shell->bkgnd_surface_id == surface_id) {
+ float red, green, blue, alpha;
+
+ w_surface = lyt->surface_get_weston_surface(layout_surface);
+ if (!shell->bkgnd_view) {
+ w_surface = lyt->surface_get_weston_surface(layout_surface);
+
+ alpha = ((shell->bkgnd_color >> 24) & 0xFF) / 255.0F;
+ red = ((shell->bkgnd_color >> 16) & 0xFF) / 255.0F;
+ green = ((shell->bkgnd_color >> 8) & 0xFF) / 255.0F;
+ blue = (shell->bkgnd_color & 0xFF) / 255.0F;
+
+ weston_surface_set_color(w_surface, red, green, blue, alpha);
+
+ wl_list_init(&shell->bkgnd_transform.link);
+ shell->bkgnd_view = weston_view_create(w_surface);
+ weston_layer_entry_insert(&shell->bkgnd_layer.view_list,
+ &shell->bkgnd_view->layer_link);
+ }
+
+ set_bkgnd_surface_prop(shell);
+ return;
+ }
+
ivisurf = get_surface(&shell->list_surface, layout_surface);
if (ivisurf == NULL) {
weston_log("id_surface is not created yet\n");
return;
}
- surface_id = lyt->get_id_of_surface(layout_surface);
-
if (ivisurf->type == IVI_WM_SURFACE_TYPE_DESKTOP) {
w_surface = lyt->surface_get_weston_surface(layout_surface);
lyt->surface_set_destination_rectangle(layout_surface,
@@ -1820,7 +1966,7 @@ destroy_screen_ids(struct ivishell *shell)
}
static void
-get_screen_ids(struct weston_compositor *compositor, struct ivishell *shell)
+get_config(struct weston_compositor *compositor, struct ivishell *shell)
{
struct weston_config_section *section = NULL;
struct weston_config *config = NULL;
@@ -1839,6 +1985,18 @@ get_screen_ids(struct weston_compositor *compositor, struct ivishell *shell)
"screen-id-offset",
&shell->screen_id_offset, 0);
+ weston_config_section_get_string(section,
+ "ivi-client-name",
+ &shell->ivi_client_name, NULL);
+
+ weston_config_section_get_int(section,
+ "bkgnd-surface-id",
+ &shell->bkgnd_surface_id, -1);
+
+ weston_config_section_get_color(section,
+ "bkgnd-color",
+ &shell->bkgnd_color, 0xFF000000);
+
wl_array_init(&shell->screen_ids);
while (weston_config_next_section(config, &section, &name)) {
@@ -1949,9 +2107,11 @@ init_ivi_shell(struct weston_compositor *ec, struct ivishell *shell)
shell->output_created.notify = output_created_event;
shell->output_destroyed.notify = output_destroyed_event;
+ shell->output_resized.notify = output_resized_event;
wl_signal_add(&ec->output_created_signal, &shell->output_created);
wl_signal_add(&ec->output_destroyed_signal, &shell->output_destroyed);
+ wl_signal_add(&ec->output_resized_signal, &shell->output_resized);
shell->destroy_listener.notify = ivi_shell_destroy;
wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
@@ -2004,6 +2164,22 @@ load_input_module(struct ivishell *shell)
return 0;
}
+static void
+launch_client_process(void *data)
+{
+ struct ivishell *shell =
+ (struct ivishell *)data;
+ char option[128] = {0};
+
+ sprintf(option, "%d", shell->bkgnd_surface_id);
+ setenv(IVI_CLIENT_SURFACE_ID_ENV_NAME, option, 0x1);
+
+ shell->client = weston_client_start(shell->compositor,
+ shell->ivi_client_name);
+
+ free(shell->ivi_client_name);
+}
+
WL_EXPORT int
controller_module_init(struct weston_compositor *compositor,
int *argc, char *argv[],
@@ -2011,6 +2187,7 @@ controller_module_init(struct weston_compositor *compositor,
size_t interface_version)
{
struct ivishell *shell;
+ struct wl_event_loop *loop = NULL;
(void)argc;
(void)argv;
@@ -2022,7 +2199,14 @@ controller_module_init(struct weston_compositor *compositor,
shell->interface = interface;
- get_screen_ids(compositor, shell);
+ get_config(compositor, shell);
+
+ /* Add background layer*/
+ if (shell->bkgnd_surface_id && shell->ivi_client_name) {
+ weston_layer_init(&shell->bkgnd_layer, compositor);
+ weston_layer_set_position(&shell->bkgnd_layer,
+ WESTON_LAYER_POSITION_BACKGROUND);
+ }
init_ivi_shell(compositor, shell);
@@ -2045,5 +2229,10 @@ controller_module_init(struct weston_compositor *compositor,
return -1;
}
+ if (shell->bkgnd_surface_id && shell->ivi_client_name) {
+ loop = wl_display_get_event_loop(compositor->wl_display);
+ wl_event_loop_add_idle(loop, launch_client_process, shell);
+ }
+
return 0;
}
diff --git a/weston-ivi-shell/src/ivi-controller.h b/weston-ivi-shell/src/ivi-controller.h
index 45d5fd7..7c82fc4 100644
--- a/weston-ivi-shell/src/ivi-controller.h
+++ b/weston-ivi-shell/src/ivi-controller.h
@@ -63,11 +63,22 @@ struct ivishell {
struct wl_listener output_created;
struct wl_listener output_destroyed;
+ struct wl_listener output_resized;
struct wl_listener destroy_listener;
struct wl_array screen_ids;
uint32_t screen_id_offset;
+
+ int32_t bkgnd_surface_id;
+ uint32_t bkgnd_color;
+ struct ivisurface *bkgnd_surface;
+ struct weston_layer bkgnd_layer;
+ struct weston_view *bkgnd_view;
+ struct weston_transform bkgnd_transform;
+
+ struct wl_client *client;
+ char *ivi_client_name;
};
#endif /* WESTON_IVI_SHELL_SRC_IVI_CONTROLLER_H_ */