diff options
author | Eugen Friedrich <efriedrich@de.adit-jv.com> | 2017-08-31 17:35:03 +0200 |
---|---|---|
committer | Eugen Friedrich <efriedrich@de.adit-jv.com> | 2017-08-31 17:35:03 +0200 |
commit | 521be17d32dcae0f2e05884e3e6b49a96b4568ed (patch) | |
tree | c7ff397e9e97fbfb28207152904cddceea5a21a7 | |
parent | 8ac50edecf0b79093385a2fe25107178086af1fe (diff) | |
parent | f42d5b0dc5a3d03e5e940c360f67b5e8c4bb7cc3 (diff) | |
download | wayland-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.txt | 1 | ||||
-rw-r--r-- | ivi-layermanagement-examples/simple-weston-client/CMakeLists.txt | 55 | ||||
-rw-r--r-- | ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c | 491 | ||||
-rw-r--r-- | weston-ivi-shell/src/ivi-controller.c | 213 | ||||
-rw-r--r-- | weston-ivi-shell/src/ivi-controller.h | 11 |
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, + ®istry_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, §ion, &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_ */ |