diff options
-rwxr-xr-x | clients/agl-stream-pipewire-output | 39 | ||||
-rw-r--r-- | clients/meson.build | 2 | ||||
-rw-r--r-- | meson.build | 19 | ||||
-rw-r--r-- | protocol/agl-shell-desktop.xml | 163 | ||||
-rw-r--r-- | src/compositor.c | 556 | ||||
-rw-r--r-- | src/desktop.c | 28 | ||||
-rw-r--r-- | src/ivi-compositor.h | 23 | ||||
-rw-r--r-- | src/layout.c | 157 | ||||
-rw-r--r-- | src/shell.c | 561 |
9 files changed, 516 insertions, 1032 deletions
diff --git a/clients/agl-stream-pipewire-output b/clients/agl-stream-pipewire-output new file mode 100755 index 0000000..d7ac151 --- /dev/null +++ b/clients/agl-stream-pipewire-output @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright © 2024 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -z $1 -o -z $2 ]; then + echo "$0 host_ip host_port" + exit 127 +fi + +host=$1 +port=$2 + +gst-launch-1.0 rtpbin name=rtpbin ! pipewiresrc target-object=weston.pipewire ! videoconvert ! \ + video/x-raw,format=I420 ! jpegenc ! rtpjpegpay ! \ + rtpbin.send_rtp_sink_0 rtpbin.send_rtp_src_0 ! \ + udpsink name=sink host=${host} port=$port rtpbin.send_rtcp_src_0 ! \ + udpsink host=${host} port=$(($port + 1)) sync=false async=false udpsrc port=$(($port + 2)) ! \ + rtpbin.recv_rtcp_sink_0 + diff --git a/clients/meson.build b/clients/meson.build index e636894..4e0703e 100644 --- a/clients/meson.build +++ b/clients/meson.build @@ -37,3 +37,5 @@ foreach t: clients message('Building client ' + t_name) endforeach + +install_data('agl-stream-pipewire-output', install_dir: get_option('bindir')) diff --git a/meson.build b/meson.build index aa811ad..215b5ac 100644 --- a/meson.build +++ b/meson.build @@ -6,7 +6,7 @@ project('agl-compositor', 'c_std=gnu99', 'werror=true', ], - meson_version: '>= 0.53', + meson_version: '>= 1.0', license: 'MIT/Expat', ) @@ -44,9 +44,9 @@ endforeach dep_libsystemd = dependency('libsystemd', required: false) dep_scanner = dependency('wayland-scanner', native: true) -prog_scanner = find_program(dep_scanner.get_pkgconfig_variable('wayland_scanner')) +prog_scanner = find_program(dep_scanner.get_variable(pkgconfig: 'wayland_scanner')) dep_wp = dependency('wayland-protocols', version: '>= 1.18') -dir_wp_base = dep_wp.get_pkgconfig_variable('pkgdatadir') +dir_wp_base = dep_wp.get_variable(pkgconfig: 'pkgdatadir') depnames = [ 'gstreamer-1.0', 'gstreamer-allocators-1.0', @@ -64,14 +64,12 @@ foreach depname : depnames endforeach agl_shell_xml = files('protocol/agl-shell.xml') -agl_shell_desktop_xml = files('protocol/agl-shell-desktop.xml') xdg_shell_xml = join_paths(dir_wp_base, 'stable', 'xdg-shell', 'xdg-shell.xml') dep_libweston_protocols = dependency('libweston-13-protocols', version: '>= 13') dir_protocol_libweston = dep_libweston_protocols.get_pkgconfig_variable('pkgdatadir') protocols = [ { 'name': 'agl-shell', 'source': 'internal' }, - { 'name': 'agl-shell-desktop', 'source': 'internal' }, { 'name': 'xdg-shell', 'source': 'wp-stable' }, { 'name': 'xdg-output', 'source': 'unstable', 'version': 'v1' }, { 'name': 'weston-output-capture', 'source': 'libweston-protocols' }, @@ -144,9 +142,7 @@ srcs_agl_compositor = [ 'shared/os-compatibility.c', 'shared/process-util.c', agl_shell_server_protocol_h, - agl_shell_desktop_server_protocol_h, agl_shell_protocol_c, - agl_shell_desktop_protocol_c, xdg_shell_protocol_c, ] @@ -173,16 +169,19 @@ if libweston_dep.found() dir_path_x11_backend = join_paths(prefix_path, 'include', libweston_version, 'libweston', 'backend-x11.h') dir_path_wayland_backend = join_paths(prefix_path, 'include', libweston_version, 'libweston', 'backend-wayland.h') dir_path_rdp_backend = join_paths(prefix_path, 'include', libweston_version, 'libweston', 'backend-rdp.h') + dir_path_pipewire_backend = join_paths(prefix_path, 'include', libweston_version, 'libweston', 'backend-pipewire.h') else dir_path_x11_backend = join_paths(libweston_version, 'libweston', 'backend-x11.h') dir_path_wayland_backend = join_paths(libweston_version, 'libweston', 'backend-wayland.h') dir_path_rdp_backend = join_paths(libweston_version, 'libweston', 'backend-rdp.h') + dir_path_pipewire_backend = join_paths(libweston_version, 'libweston', 'backend-pipewire.h') endif else message('Building with cross environment') dir_path_x11_backend = join_paths(libweston_version, 'libweston', 'backend-x11.h') dir_path_wayland_backend = join_paths(libweston_version, 'libweston', 'backend-wayland.h') dir_path_rdp_backend = join_paths(libweston_version, 'libweston', 'backend-rdp.h') + dir_path_pipewire_backend = join_paths(libweston_version, 'libweston', 'backend-pipewire.h') endif # do the test @@ -200,6 +199,10 @@ if libweston_dep.found() config_h.set('HAVE_BACKEND_RDP', 1) message('Building with RDP backend') endif + if cc.has_header(dir_path_pipewire_backend) + config_h.set('HAVE_BACKEND_PIPEWIRE', 1) + message('Building with PipeWire backend') + endif endif if dep_libsystemd.found() @@ -266,7 +269,7 @@ pkgconfig.generate( ) install_data( - [ agl_shell_xml, agl_shell_desktop_xml ], + [ agl_shell_xml ], install_dir: join_paths(dir_data, dir_data_agl_compositor) ) diff --git a/protocol/agl-shell-desktop.xml b/protocol/agl-shell-desktop.xml deleted file mode 100644 index e4445bd..0000000 --- a/protocol/agl-shell-desktop.xml +++ /dev/null @@ -1,163 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<protocol name="agl_shell_desktop"> - <copyright> - Copyright © 2020 Collabora, Ltd. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice (including the next - paragraph) shall be included in all copies or substantial portions of the - Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - </copyright> - <interface name="agl_shell_desktop" version="2"> - <description summary="Private extension to allow applications activate other apps"> - This extension can be used by regular application to instruct to compositor - to activate or switch to other running (regular) applications. The client - is responsible for filtering their own app_id when receiving application id. - - The compositor will allow clients to bind to this interface only if the - policy engine allows it. - </description> - - <enum name="app_role"> - <entry name="popup" value="0"/> - <entry name="fullscreen" value="1"/> - <entry name="split_vertical" value="2"/> - <entry name="split_horizontal" value="3"/> - <entry name="remote" value="4"/> - </enum> - - <enum name="app_state"> - <entry name="activated" value="0"/> - <entry name="deactivated" value="1"/> - <entry name="destroyed" value="2"/> - </enum> - - <event name="application"> - <description summary="advertise application id"> - The compositor may choose to advertise one or more application ids which - can be used to activate/switch to. - - When this global is bound, the compositor will send all application ids - available for activation, but may send additional application id at any - time (when they've been mapped in the compositor). - </description> - <arg name="app_id" type="string"/> - </event> - - <request name="activate_app"> - <description summary="make client current window"> - Ask the compositor to make a toplevel to become the current/focused - window for window management purposes. - - See xdg_toplevel.set_app_id from the xdg-shell protocol for a - description of app_id. - </description> - <arg name="app_id" type="string"/> - <arg name="app_data" type="string" allow-null="true"/> - <arg name="output" type="object" interface="wl_output"/> - </request> - - <request name="set_app_property"> - <description summary="set properties for a client identified by app_id"> - Ask the compositor to make a top-level window obey the 'app_role' enum - and, depending on that role, to use some of the arguments as initial - values to take into account. - - Note that x, y, bx, by, width and height would only make sense for the - pop-up role, with the output argument being applicable to all the roles. - The width and height values define the maximum area which the - top-level window should be placed into. Note this doesn't correspond to - top-level surface size, but to a bounding box which will be used to - clip the surface to, in case the surface area extends that of this - bounding box. Both of these values need to be larger than 0 (zero) to be - taken into account by the compositor. Any negative values for the width - and height will be discarded. - - The x and y values will serve as the (initial) position values. - The bx and by values are the top-left x and y value of the bounding box. - Any clipping happening to the bounding box will not affect the surface - size or the position of the underlying surface backing the top-level - window. The bx and by values, like the positional values, could be - both set to zero, or even negative values. The compositor will pass - those on without any further validation. - - The initial position values and the bounding rectangle will still be - in effect on a subsequent activation request of the 'app_id', assuming - it was previously de-activated at some point in time. - - See xdg_toplevel.set_app_id from the xdg-shell protocol for a - description of app_id. - </description> - <arg name="app_id" type="string"/> - <arg name="role" type="uint" enum="app_role"/> - <arg name="x" type="int"/> - <arg name="y" type="int"/> - <arg name="bx" type="int"/> - <arg name="by" type="int"/> - <arg name="width" type="int"/> - <arg name="height" type="int"/> - <arg name="output" type="object" interface="wl_output"/> - </request> - - <request name="deactivate_app"> - <description summary="de-activate/hide window identified by app_id"> - Ask the compositor to hide the toplevel window for window - management purposes. Depending on the window role, this request - will either display the previously active window (or the background - in case there's no previously active surface) or temporarily (or - until a 'activate_app' is called upon) hide the surface. All - the surfaces are identifiable by using the app_id, and no actions are - taken in case the app_id is not/was not present. - - See xdg_toplevel.set_app_id from the xdg-shell protocol for a - description of app_id. - </description> - <arg name="app_id" type="string"/> - </request> - - <event name="state_app"> - <description summary="event sent when application has suffered state modification"> - Notifies application(s) when other application have suffered state modifications. - </description> - <arg name="app_id" type="string"/> - <arg name="app_data" type="string" allow-null="true"/> - <arg name="state" type="uint" enum="app_state"/> - <arg name="role" type="uint" enum="app_role"/> - </event> - - <!-- Version 2 addition --> - <request name="set_app_property_mode" since="2"> - <description summary="Request to change the application properties lifetime"> - Use this request to inform the compositor to maintain a pending state - for an app_id being set with set_app_property() request. Any - subsequent application matching that app_id would survive a potential - application destruction. Note that this request will take effect - globally on all applications. - - To turn it on, or off, use the 'permanent' argument. Initially, - the compositor will have this option set to off. Note that it - doesn't matter the order of this request with respect to - set_app_property() request, as the changes will only take effect - when the application itself does the commit with an app_id set, - therefore the only requirement is to call this request before - the app_id client does its first commit. - </description> - <arg name="permanent" type="uint"/> - </request> - - </interface> -</protocol> diff --git a/src/compositor.c b/src/compositor.c index bdff9ed..6aec416 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -39,8 +39,8 @@ #include <libweston/backend-drm.h> #include <libweston/backend-wayland.h> -#ifdef HAVE_BACKEND_RDP -#include <libweston/backend-rdp.h> +#ifdef HAVE_BACKEND_PIPEWIRE +#include <libweston/backend-pipewire.h> #endif #ifdef HAVE_BACKEND_X11 #include <libweston/backend-x11.h> @@ -57,9 +57,6 @@ #include "config.h" #include "agl-shell-server-protocol.h" -#ifdef HAVE_REMOTING -#include "remote.h" -#endif #define WINDOWED_DEFAULT_WIDTH 1024 #define WINDOWED_DEFAULT_HEIGHT 768 @@ -67,6 +64,9 @@ static int cached_tm_mday = -1; static struct weston_log_scope *log_scope; +static void +weston_output_lazy_align(struct weston_output *output); + struct ivi_compositor * to_ivi_compositor(struct weston_compositor *ec) { @@ -104,6 +104,25 @@ ivi_init_parsed_options(struct weston_compositor *compositor) } static void +ivi_backend_destroy(struct ivi_backend *b) +{ + wl_list_remove(&b->link); + wl_list_remove(&b->heads_changed.link); + + free(b); +} + + +static void +ivi_compositor_destroy_backends(struct ivi_compositor *ivi) +{ + struct ivi_backend *b, *tmp; + + wl_list_for_each_safe(b, tmp, &ivi->backends, link) + ivi_backend_destroy(b); +} + +static void screenshot_allow_all(struct wl_listener *l, struct weston_output_capture_attempt *att) { att->authorized = true; @@ -133,6 +152,7 @@ struct { } backend_name_map[] = { { "drm", "drm-backend.so", WESTON_BACKEND_DRM }, { "rdp", "rdp-backend.so", WESTON_BACKEND_RDP }, + { "pipewire", "pipewire-backend.so", WESTON_BACKEND_PIPEWIRE }, { "wayland", "wayland-backend.so", WESTON_BACKEND_WAYLAND }, { "x11", "x11-backend.so", WESTON_BACKEND_X11 }, }; @@ -228,8 +248,8 @@ ivi_output_configure_app_id(struct ivi_output *ivi_output) } static struct ivi_output * -ivi_ensure_output(struct ivi_compositor *ivi, char *name, - struct weston_config_section *config, +ivi_ensure_output(struct ivi_compositor *ivi, struct ivi_backend *ivi_backend, + char *name, struct weston_config_section *config, struct weston_head *head) { struct ivi_output *output = NULL; @@ -266,8 +286,8 @@ ivi_ensure_output(struct ivi_compositor *ivi, char *name, weston_output_add_destroy_listener(output->output, &output->output_destroy); - if (ivi->simple_output_configure) { - int ret = ivi->simple_output_configure(output->output); + if (ivi_backend->simple_output_configure) { + int ret = ivi_backend->simple_output_configure(output->output); if (ret < 0) { weston_log("Configuring output \"%s\" failed.\n", weston_head_get_name(head)); @@ -276,6 +296,8 @@ ivi_ensure_output(struct ivi_compositor *ivi, char *name, return NULL; } + weston_output_lazy_align(output->output); + if (weston_output_enable(output->output) < 0) { weston_log("Enabling output \"%s\" failed.\n", weston_head_get_name(head)); @@ -620,6 +642,19 @@ process_output(struct ivi_output *output) return try_attach_enable_heads(output); } +static struct weston_head * +ivi_backend_iterate_heads(struct ivi_compositor *ivi, struct ivi_backend *wb, + struct weston_head *iter) +{ + while ((iter = weston_compositor_iterate_heads(ivi->compositor, iter))) { + if (iter->backend == wb->backend) + break; + } + + return iter; +} + + static void drm_head_disable(struct ivi_compositor *ivi, struct weston_head *head) { @@ -691,7 +726,7 @@ find_controlling_output_config(struct weston_config *config, } static void -drm_head_prepare_enable(struct ivi_compositor *ivi, struct weston_head *head) +drm_head_prepare_enable(struct ivi_compositor *ivi, struct ivi_backend *ivi_backend, struct weston_head *head) { const char *name = weston_head_get_name(head); struct weston_config_section *section; @@ -719,7 +754,7 @@ drm_head_prepare_enable(struct ivi_compositor *ivi, struct weston_head *head) if (!output_name) return; - output = ivi_ensure_output(ivi, output_name, section, head); + output = ivi_ensure_output(ivi, ivi_backend, output_name, section, head); if (!output) return; @@ -736,15 +771,17 @@ drm_heads_changed(struct wl_listener *listener, void *arg) struct weston_head *head = NULL; struct ivi_compositor *ivi = to_ivi_compositor(compositor); struct ivi_output *output; + struct ivi_backend *ivi_backend = + container_of(listener, struct ivi_backend, heads_changed); - while ((head = weston_compositor_iterate_heads(ivi->compositor, head))) { + while ((head = ivi_backend_iterate_heads(ivi, ivi_backend, head))) { bool connected = weston_head_is_connected(head); bool enabled = weston_head_is_enabled(head); bool changed = weston_head_is_device_changed(head); bool non_desktop = weston_head_is_non_desktop(head); if (connected && !enabled && !non_desktop) - drm_head_prepare_enable(ivi, head); + drm_head_prepare_enable(ivi, ivi_backend, head); else if (!connected && enabled) drm_head_disable(ivi, head); else if (enabled && changed) @@ -767,7 +804,8 @@ drm_heads_changed(struct wl_listener *listener, void *arg) } static void -simple_head_enable(struct ivi_compositor *ivi, struct weston_head *head) +simple_head_enable(struct ivi_compositor *ivi, struct ivi_backend *ivi_backend, + struct weston_head *head) { struct ivi_output *output; struct weston_config_section *section; @@ -794,7 +832,7 @@ simple_head_enable(struct ivi_compositor *ivi, struct weston_head *head) if (!output_name) return; - output = ivi_ensure_output(ivi, output_name, section, head); + output = ivi_ensure_output(ivi, ivi_backend, output_name, section, head); if (!output) { weston_log("Failed to create output %s\n", output_name); return; @@ -829,15 +867,17 @@ simple_heads_changed(struct wl_listener *listener, void *arg) bool enabled; bool changed; bool non_desktop; + struct ivi_backend *ivi_backend = + container_of(listener, struct ivi_backend, heads_changed); - while ((head = weston_compositor_iterate_heads(ivi->compositor, head))) { + while ((head = ivi_backend_iterate_heads(ivi, ivi_backend, head))) { connected = weston_head_is_connected(head); enabled = weston_head_is_enabled(head); changed = weston_head_is_device_changed(head); non_desktop = weston_head_is_non_desktop(head); if (connected && !enabled && !non_desktop) { - simple_head_enable(ivi, head); + simple_head_enable(ivi, ivi_backend, head); } else if (!connected && enabled) { simple_head_disable(head); } else if (enabled && changed) { @@ -849,211 +889,6 @@ simple_heads_changed(struct wl_listener *listener, void *arg) } } - -#ifdef HAVE_REMOTING -static int -drm_backend_remoted_output_configure(struct weston_output *output, - struct weston_config_section *section, - char *modeline, - const struct weston_remoting_api *api) -{ - char *gbm_format = NULL; - char *seat = NULL; - char *host = NULL; - char *pipeline = NULL; - int port, ret; - int32_t scale = 1; - uint32_t transform = WL_OUTPUT_TRANSFORM_NORMAL; - char *trans; - - ret = api->set_mode(output, modeline); - if (ret < 0) { - weston_log("Cannot configure an output \"%s\" using " - "weston_remoting_api. Invalid mode\n", - output->name); - return -1; - } - - weston_config_section_get_int(section, "scale", &scale, 1); - weston_output_set_scale(output, scale); - - weston_config_section_get_string(section, "transform", &trans, "normal"); - if (parse_transform(trans, &transform) < 0) { - weston_log("Invalid transform \"%s\" for output %s\n", - trans, output->name); - } - weston_output_set_transform(output, transform); - - weston_config_section_get_string(section, "gbm-format", - &gbm_format, NULL); - api->set_gbm_format(output, gbm_format); - free(gbm_format); - - weston_config_section_get_string(section, "seat", &seat, ""); - - api->set_seat(output, seat); - free(seat); - - weston_config_section_get_string(section, "gst-pipeline", &pipeline, - NULL); - if (pipeline) { - api->set_gst_pipeline(output, pipeline); - free(pipeline); - return 0; - } - - weston_config_section_get_string(section, "host", &host, NULL); - weston_config_section_get_int(section, "port", &port, 0); - if (!host || port <= 0 || 65533 < port) { - weston_log("Cannot configure an output \"%s\". " - "Need to specify gst-pipeline or " - "host and port (1-65533).\n", output->name); - } - api->set_host(output, host); - free(host); - api->set_port(output, port); - - return 0; -} - - -static int -remote_output_init(struct ivi_output *ivi_output, - struct weston_compositor *compositor, - struct weston_config_section *section, - const struct weston_remoting_api *api) -{ - char *output_name, *modeline = NULL; - int ret = -1; - - weston_config_section_get_string(section, "name", &output_name, NULL); - if (!output_name) - return ret; - - weston_config_section_get_string(section, "mode", &modeline, "off"); - if (strcmp(modeline, "off") == 0) - goto err; - - ivi_output->output = api->create_output(compositor, output_name); - if (!ivi_output->output) { - weston_log("Cannot create remoted output \"%s\".\n", - output_name); - goto err; - } - - ret = drm_backend_remoted_output_configure(ivi_output->output, section, - modeline, api); - if (ret < 0) { - weston_log("Cannot configure remoted output \"%s\".\n", - output_name); - goto err; - } - - if ((ret = weston_output_enable(ivi_output->output)) < 0) { - weston_log("Enabling remoted output \"%s\" failed.\n", - output_name); - goto err; - } - - free(modeline); - free(output_name); - weston_log("remoted output '%s' enabled\n", ivi_output->output->name); - - return 0; - -err: - free(modeline); - free(output_name); - if (ivi_output->output) - weston_output_destroy(ivi_output->output); - - return ret; -} - -static void -ivi_enable_remote_outputs(struct ivi_compositor *ivi) -{ - struct weston_config_section *remote_section = NULL; - const char *section_name; - struct weston_config *config = ivi->config; - - while (weston_config_next_section(config, &remote_section, §ion_name)) { - if (strcmp(section_name, "remote-output")) - continue; - - struct ivi_output *ivi_output = NULL; - bool output_found = false; - char *_name = NULL; - - weston_config_section_get_string(remote_section, - "name", &_name, NULL); - wl_list_for_each(ivi_output, &ivi->outputs, link) { - if (!strcmp(ivi_output->name, _name)) { - output_found = true; - break; - } - } - - if (output_found) { - free(_name); - continue; - } - - ivi_output = zalloc(sizeof(*ivi_output)); - if (!ivi_output) { - free(_name); - continue; - } - - ivi_output->ivi = ivi; - ivi_output->name = _name; - ivi_output->config = remote_section; - ivi_output->type = OUTPUT_REMOTE; - - if (remote_output_init(ivi_output, ivi->compositor, - remote_section, ivi->remoting_api)) { - free(ivi_output->name); - free(ivi_output); - continue; - } - - ivi_output->output_destroy.notify = handle_output_destroy; - weston_output_add_destroy_listener(ivi_output->output, - &ivi_output->output_destroy); - - wl_list_insert(&ivi->outputs, &ivi_output->link); - ivi_output_configure_app_id(ivi_output); - } -} - -static int -load_remoting_plugin(struct ivi_compositor *ivi, struct weston_config *config) -{ - struct weston_compositor *compositor = ivi->compositor; - int (*module_init)(struct weston_compositor *wc); - - module_init = weston_load_module("remoting-plugin.so", - "weston_module_init", - LIBWESTON_MODULEDIR); - if (!module_init) - return -1; - - if (module_init(compositor) < 0) - return -1; - - ivi->remoting_api = weston_remoting_get_api(compositor); - if (!ivi->remoting_api) - return -1; - return 0; -} -#else -static int -load_remoting_plugin(struct weston_compositor *compositor, struct weston_config *config) -{ - return -1; -} -#endif - static int load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[], enum weston_renderer_type renderer) @@ -1069,6 +904,7 @@ load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[], bool force_pixman = false; bool use_shadow; bool without_input = false; + struct ivi_backend *ivi_backend = NULL; const struct weston_option options[] = { { WESTON_OPTION_STRING, "seat", 0, &config.seat_id }, @@ -1098,24 +934,26 @@ load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[], if (without_input) ivi->compositor->require_input = !without_input; - ivi->heads_changed.notify = drm_heads_changed; - weston_compositor_add_heads_changed_listener(ivi->compositor, - &ivi->heads_changed); - - if (!weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_DRM, - &config.base)) { + ivi_backend = zalloc(sizeof(struct ivi_backend)); + ivi_backend->backend = + weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_DRM, + &config.base); + if (!ivi_backend->backend) { weston_log("Failed to load DRM backend\n"); return -1; } + ivi_backend->heads_changed.notify = drm_heads_changed; + weston_compositor_add_heads_changed_listener(ivi->compositor, + &ivi_backend->heads_changed); + wl_list_insert(&ivi->backends, &ivi_backend->link); + ivi->drm_api = weston_drm_output_get_api(ivi->compositor); if (!ivi->drm_api) { weston_log("Cannot use drm output api.\n"); goto error; } - load_remoting_plugin(ivi, ivi->config); - return 0; error: @@ -1152,6 +990,7 @@ windowed_parse_common_options(struct ivi_compositor *ivi, int *argc, char *argv[ static int windowed_create_outputs(struct ivi_compositor *ivi, int output_count, + struct weston_backend *backend, const char *match_prefix, const char *name_prefix) { struct weston_config_section *section = NULL; @@ -1177,7 +1016,7 @@ windowed_create_outputs(struct ivi_compositor *ivi, int output_count, continue; } - if (ivi->window_api->create_head(ivi->backend, output_name) < 0) { + if (ivi->window_api->create_head(backend, output_name) < 0) { free(output_name); return -1; } @@ -1190,7 +1029,7 @@ windowed_create_outputs(struct ivi_compositor *ivi, int output_count, if (asprintf(&default_output, "%s%d", name_prefix, i) < 0) return -1; - if (ivi->window_api->create_head(ivi->backend, default_output) < 0) { + if (ivi->window_api->create_head(backend, default_output) < 0) { free(default_output); return -1; } @@ -1236,6 +1075,7 @@ load_wayland_backend(struct ivi_compositor *ivi, int *argc, char *argv[], int sprawl = 0; int output_count; bool force_pixman = false; + struct ivi_backend *ivi_backend = NULL; const struct weston_option options[] = { { WESTON_OPTION_STRING, "display", 0, &config.display_name }, @@ -1254,23 +1094,25 @@ load_wayland_backend(struct ivi_compositor *ivi, int *argc, char *argv[], weston_config_section_get_int(section, "cursor-size", &config.cursor_size, 32); - ivi->simple_output_configure = wayland_backend_output_configure; - ivi->heads_changed.notify = simple_heads_changed; - weston_compositor_add_heads_changed_listener(ivi->compositor, - &ivi->heads_changed); - - ivi->backend = weston_compositor_load_backend(ivi->compositor, + ivi_backend = zalloc(sizeof(struct ivi_backend)); + ivi_backend->backend = weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_WAYLAND, &config.base); - if (!ivi->backend) { - weston_log("Failed to create Wayland backend!\n"); - } - free(config.cursor_theme); free(config.display_name); - if (!ivi->backend) + if (!ivi_backend->backend) { + weston_log("Failed to create Wayland backend!\n"); return -1; + } + + ivi_backend->simple_output_configure = wayland_backend_output_configure; + ivi_backend->heads_changed.notify = simple_heads_changed; + weston_compositor_add_heads_changed_listener(ivi->compositor, + &ivi_backend->heads_changed); + + + wl_list_insert(&ivi->backends, &ivi_backend->link); ivi->window_api = weston_windowed_output_get_api(ivi->compositor); @@ -1284,7 +1126,7 @@ load_wayland_backend(struct ivi_compositor *ivi, int *argc, char *argv[], if (ivi->window_api == NULL) return 0; - return windowed_create_outputs(ivi, output_count, "WL", "wayland"); + return windowed_create_outputs(ivi, output_count, ivi_backend->backend, "WL", "wayland"); } #ifdef HAVE_BACKEND_X11 @@ -1322,6 +1164,7 @@ load_x11_backend(struct ivi_compositor *ivi, int *argc, char *argv[], int no_input = 0; int output_count; bool force_pixman = false; + struct ivi_backend *ivi_backend = NULL; const struct weston_option options[] = { { WESTON_OPTION_BOOLEAN, "no-input", 0, &no_input }, @@ -1337,27 +1180,31 @@ load_x11_backend(struct ivi_compositor *ivi, int *argc, char *argv[], config.renderer = WESTON_RENDERER_AUTO; config.no_input = no_input; - ivi->simple_output_configure = x11_backend_output_configure; - - ivi->heads_changed.notify = simple_heads_changed; - weston_compositor_add_heads_changed_listener(ivi->compositor, - &ivi->heads_changed); - ivi->backend = weston_compositor_load_backend(ivi->compositor, + ivi_backend = zalloc(sizeof(struct ivi_backend)); + ivi_backend->backend = weston_compositor_load_backend(ivi->compositor, WESTON_BACKEND_X11, &config.base); - if (!ivi->backend) { + if (!ivi_backend->backend) { weston_log("Failed to create X11 backend!\n"); return -1; } + ivi_backend->simple_output_configure = x11_backend_output_configure; + ivi_backend->heads_changed.notify = simple_heads_changed; + weston_compositor_add_heads_changed_listener(ivi->compositor, + &ivi_backend->heads_changed); + + ivi->window_api = weston_windowed_output_get_api(ivi->compositor); if (!ivi->window_api) { weston_log("Cannot use weston_windowed_output_api.\n"); return -1; } - return windowed_create_outputs(ivi, output_count, "X", "screen"); + wl_list_insert(&ivi->backends, &ivi_backend->link); + + return windowed_create_outputs(ivi, output_count, ivi_backend->backend, "X", "screen"); } #else static int @@ -1458,6 +1305,7 @@ load_rdp_backend(struct ivi_compositor *ivi, int *argc, char **argv, struct weston_rdp_backend_config config = {}; struct weston_config_section *section; bool no_remotefx_codec = false; + struct ivi_backend *ivi_backend = NULL; struct ivi_output_config *parsed_options = ivi_init_parsed_options(ivi->compositor); if (!parsed_options) @@ -1499,23 +1347,28 @@ load_rdp_backend(struct ivi_compositor *ivi, int *argc, char **argv, parse_options(rdp_options, ARRAY_LENGTH(rdp_options), argc, argv); weston_log("No clients resize: %d\n", config.no_clients_resize); - ivi->simple_output_configure = rdp_backend_output_configure; - - ivi->heads_changed.notify = simple_heads_changed; - weston_compositor_add_heads_changed_listener(ivi->compositor, - &ivi->heads_changed); - if (!weston_compositor_load_backend(ivi->compositor, - WESTON_BACKEND_RDP, &config.base)) { + ivi_backend = zalloc(sizeof(struct ivi_backend)); + ivi_backend->backend = weston_compositor_load_backend(ivi->compositor, + WESTON_BACKEND_RDP, &config.base); + if (!ivi_backend->backend) { weston_log("Failed to create RDP backend\n"); return -1; } + ivi_backend->simple_output_configure = rdp_backend_output_configure; + ivi_backend->heads_changed.notify = simple_heads_changed; + weston_compositor_add_heads_changed_listener(ivi->compositor, + &ivi_backend->heads_changed); + + free(config.bind_address); free(config.rdp_key); free(config.server_cert); free(config.server_key); + wl_list_insert(&ivi->backends, &ivi_backend->link); + return 0; } #else @@ -1527,6 +1380,125 @@ load_rdp_backend(struct ivi_compositor *ivi, int *argc, char **argv, } #endif +#ifdef HAVE_BACKEND_PIPEWIRE +static void +pipewire_backend_config_init(struct weston_pipewire_backend_config *config) +{ + config->base.struct_version = WESTON_PIPEWIRE_BACKEND_CONFIG_VERSION; + config->base.struct_size = sizeof(struct weston_pipewire_backend_config); +} + +static int +pipewire_backend_output_configure(struct weston_output *output) +{ + int width = 640; + int height = 480; + struct ivi_compositor *ivi = to_ivi_compositor(output->compositor); + struct ivi_output_config *parsed_options = ivi->parsed_options; + + const struct weston_pipewire_output_api *api = + weston_pipewire_output_get_api(output->compositor); + struct weston_config_section *section; + char *gbm_format = NULL; + uint32_t transform = WL_OUTPUT_TRANSFORM_NORMAL; + int scale = 1; + + assert(parsed_options); + + if (!api) { + weston_log("Cannot use weston_pipewire_output_api.\n"); + return -1; + } + + section = weston_config_get_section(ivi->config, + "output", "name", output->name); + + weston_config_section_get_int(section, "width", &width, width); + weston_config_section_get_int(section, "height", &height, height); + + if (parsed_options->width) + width = parsed_options->width; + + if (parsed_options->height) + height = parsed_options->height; + + weston_config_section_get_string(section, "gbm-format", &gbm_format, NULL); + + weston_output_set_scale(output, scale); + weston_output_set_transform(output, transform); + + api->set_gbm_format(output, gbm_format); + free(gbm_format); + + if (api->output_set_size(output, width, height) < 0) { + weston_log("Cannot configure output \"%s\" using weston_pipewire_output_api.\n", + output->name); + return -1; + } + weston_log("pipewire_backend_output_configure.. Done\n"); + + return 0; +} + + +static int +load_pipewire_backend(struct ivi_compositor *ivi, int *argc, char **argv, + enum weston_renderer_type renderer) +{ + struct weston_pipewire_backend_config config = {}; + struct weston_config_section *section; + struct ivi_output_config *parsed_options = + ivi_init_parsed_options(ivi->compositor); + struct ivi_backend *ivi_backend = NULL; + + if (!parsed_options) + return -1; + + pipewire_backend_config_init(&config); + + const struct weston_option pipewire_options[] = { + { WESTON_OPTION_INTEGER, "width", 0, &parsed_options->width }, + { WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height }, + }; + + parse_options(pipewire_options, ARRAY_LENGTH(pipewire_options), argc, argv); + + config.renderer = renderer; + + section = weston_config_get_section(ivi->config, "core", NULL, NULL); + weston_config_section_get_string(section, "gbm-format", + &config.gbm_format, NULL); + + section = weston_config_get_section(ivi->config, "pipewire", NULL, NULL); + weston_config_section_get_int(section, "num-outputs", + &config.num_outputs, 1); + + + ivi_backend = zalloc(sizeof(struct ivi_backend)); + ivi_backend->backend = weston_compositor_load_backend(ivi->compositor, + WESTON_BACKEND_PIPEWIRE, &config.base); + if (!ivi_backend->backend) { + weston_log("Failed to create PipeWire backend\n"); + return -1; + } + + ivi_backend->simple_output_configure = pipewire_backend_output_configure; + ivi_backend->heads_changed.notify = simple_heads_changed; + weston_compositor_add_heads_changed_listener(ivi->compositor, + &ivi_backend->heads_changed); + + wl_list_insert(&ivi->backends, &ivi_backend->link); + + return 0; +} +#else +static int +load_pipewire_backend(struct ivi_compositor *ivi, int *argc, char **argv, + enum weston_renderer_type renderer) +{ + return -1; +} +#endif static int load_backend(struct ivi_compositor *ivi, int *argc, char **argv, @@ -1550,6 +1522,8 @@ load_backend(struct ivi_compositor *ivi, int *argc, char **argv, return load_drm_backend(ivi, argc, argv, renderer); case WESTON_BACKEND_RDP: return load_rdp_backend(ivi, argc, argv, renderer); + case WESTON_BACKEND_PIPEWIRE: + return load_pipewire_backend(ivi, argc, argv, renderer); case WESTON_BACKEND_WAYLAND: return load_wayland_backend(ivi, argc, argv, renderer); case WESTON_BACKEND_X11: @@ -1562,6 +1536,33 @@ load_backend(struct ivi_compositor *ivi, int *argc, char **argv, } static int +load_backends(struct ivi_compositor *ivi, const char *backends, + int *argc, char **argv, const char *renderer) +{ + const char *p, *end; + char buffer[256]; + + if (backends == NULL) + return 0; + + p = backends; + while (*p) { + end = strchrnul(p, ','); + snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p); + + if (load_backend(ivi, argc, argv, buffer, renderer) < 0) + return -1; + + p = end; + while (*p == ',') + p++; + } + + return 0; +} + + +static int load_modules(struct ivi_compositor *ivi, const char *modules, int *argc, char *argv[], bool *xwayland) { @@ -1845,7 +1846,7 @@ log_timestamp(char *buf, size_t len) strftime(timestr, sizeof(timestr), "%H:%M:%S", brokendown_time); /* if datestr is empty it prints only timestr*/ - snprintf(buf, len, "%s[%s.%03li]", datestr, + snprintf(buf, len, "%s[%s.%03"PRIi64"]", datestr, timestr, (tv.tv_usec / 1000)); return buf; @@ -2033,7 +2034,7 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da struct wl_event_source *signals[3] = { 0 }; struct weston_config_section *section; /* Command line options */ - char *backend = NULL; + char *backends = NULL; char *socket_name = NULL; char *log = NULL; char *modules = NULL; @@ -2049,19 +2050,22 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da struct weston_log_subscriber *logger; int ret = EXIT_FAILURE; bool xwayland = false; + bool no_black_curtain = false; struct sigaction action; char *renderer = NULL; struct wet_process *process, *process_tmp; const struct weston_option core_options[] = { { WESTON_OPTION_STRING, "renderer", 'r', &renderer }, - { WESTON_OPTION_STRING, "backend", 'B', &backend }, + { WESTON_OPTION_STRING, "backend", 'B', &backends }, + { WESTON_OPTION_STRING, "backends", 0, &backends }, { WESTON_OPTION_STRING, "socket", 'S', &socket_name }, { WESTON_OPTION_STRING, "log", 0, &log }, { WESTON_OPTION_BOOLEAN, "help", 'h', &help }, { WESTON_OPTION_BOOLEAN, "version", 0, &version }, { WESTON_OPTION_BOOLEAN, "no-config", 0, &no_config }, { WESTON_OPTION_BOOLEAN, "debug", 0, &debug }, + { WESTON_OPTION_BOOLEAN, "no-black-curtain", false, &no_black_curtain }, { WESTON_OPTION_STRING, "config", 'c', &config_file }, { WESTON_OPTION_STRING, "modules", 0, &option_modules }, { WESTON_OPTION_STRING, "debug-scopes", 'l', &debug_scopes }, @@ -2077,6 +2081,7 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da wl_list_init(&ivi.split_pending_apps); wl_list_init(&ivi.remote_pending_apps); wl_list_init(&ivi.desktop_clients); + wl_list_init(&ivi.backends); wl_list_init(&ivi.child_process_list); wl_list_init(&ivi.pending_apps); @@ -2117,11 +2122,11 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da if (load_config(&ivi.config, no_config, config_file) < 0) goto error_signals; section = weston_config_get_section(ivi.config, "core", NULL, NULL); - if (!backend) { - weston_config_section_get_string(section, "backend", &backend, + if (!backends) { + weston_config_section_get_string(section, "backend", &backends, NULL); - if (!backend) - backend = choose_default_backend(); + if (!backends) + backends = choose_default_backend(); } display = wl_display_create(); @@ -2167,8 +2172,9 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da if (compositor_init_config(&ivi) < 0) goto error_compositor; - if (load_backend(&ivi, &argc, argv, backend, renderer) < 0) { - weston_log("fatal: failed to create compositor backend.\n"); + ivi.compositor->multi_backend = backends && strchr(backends, ','); + if (load_backends(&ivi, backends, &argc, argv, renderer) < 0) { + weston_log("fatal: failed to create compositor backend\n"); goto error_compositor; } @@ -2225,13 +2231,13 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da add_bindings(ivi.compositor); - if (ivi.remoting_api) - ivi_enable_remote_outputs(&ivi); - if (create_listening_socket(display, socket_name) < 0) goto error_compositor; - ivi_shell_init_black_fs(&ivi); + if (!no_black_curtain) { + weston_log("Installing black curtains\n"); + ivi_shell_init_black_fs(&ivi); + } ivi.compositor->exit = handle_exit; @@ -2255,11 +2261,13 @@ int wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_da ret = ivi.compositor->exit_code; + ivi_compositor_destroy_backends(&ivi); + wl_display_destroy_clients(display); error_compositor: - free(backend); - backend = NULL; + free(backends); + backends = NULL; free(modules); modules = NULL; diff --git a/src/desktop.c b/src/desktop.c index d3c1d4e..ab53601 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -34,8 +34,6 @@ #include <libweston/xwayland-api.h> #endif -#include "agl-shell-desktop-server-protocol.h" - static void ivi_layout_destroy_saved_outputs(struct ivi_compositor *ivi) { @@ -51,16 +49,6 @@ ivi_layout_destroy_saved_outputs(struct ivi_compositor *ivi) } static void -desktop_advertise_app(struct wl_listener *listener, void *data) -{ - struct ivi_surface *surface; - - surface = wl_container_of(listener, surface, listener_advertise_app); - - agl_shell_desktop_advertise_application_id(surface->ivi, surface); -} - -static void desktop_ping_timeout(struct weston_desktop_client *dclient, void *userdata) { /* not supported */ @@ -207,16 +195,9 @@ desktop_surface_added(struct weston_desktop_surface *dsurface, void *userdata) surface->dsurface = dsurface; surface->role = IVI_SURFACE_ROLE_NONE; surface->mapped = false; - surface->advertised_on_launch = false; surface->checked_pending = false; wl_list_init(&surface->link); - wl_signal_init(&surface->signal_advertise_app); - - surface->listener_advertise_app.notify = desktop_advertise_app; - wl_signal_add(&surface->signal_advertise_app, - &surface->listener_advertise_app); - weston_desktop_surface_set_user_data(dsurface, surface); if (ivi->policy && ivi->policy->api.surface_create && @@ -297,10 +278,6 @@ desktop_surface_removed(struct weston_desktop_surface *dsurface, void *userdata) ivi_seat = get_ivi_shell_seat(wseat); output = ivi_layout_get_output_from_surface(surface); - - wl_list_remove(&surface->listener_advertise_app.link); - surface->listener_advertise_app.notify = NULL; - app_id = weston_desktop_surface_get_app_id(dsurface); /* special corner-case, pending_surfaces which are never activated or @@ -393,8 +370,6 @@ skip_output_asignment: app_id, ivi_layout_get_surface_role_name(surface)); if (app_id && output && output->output) { - shell_advertise_app_state(output->ivi, app_id, - NULL, AGL_SHELL_DESKTOP_APP_STATE_DESTROYED); if (output->ivi->shell_client.ready) shell_send_app_state(output->ivi, app_id, AGL_SHELL_APP_STATE_TERMINATED); } @@ -440,9 +415,6 @@ desktop_committed(struct weston_desktop_surface *dsurface, shell_send_app_state(ivi, app_id, AGL_SHELL_APP_STATE_STARTED); } - if (!surface->advertised_on_launch && - !wl_list_empty(&surface->ivi->desktop_clients)) - wl_signal_emit(&surface->signal_advertise_app, surface); /* this repaint schedule is needed to allow resizing to work with the * help of the hidden layer: diff --git a/src/ivi-compositor.h b/src/ivi-compositor.h index 695cf95..1e8c55a 100644 --- a/src/ivi-compositor.h +++ b/src/ivi-compositor.h @@ -59,14 +59,18 @@ struct ivi_output_config { uint32_t transform; }; +struct ivi_backend { + struct weston_backend *backend; + struct wl_listener heads_changed; + int (*simple_output_configure)(struct weston_output *output); + struct wl_list link; +}; + struct ivi_compositor { struct weston_compositor *compositor; - struct weston_backend *backend; struct weston_config *config; struct ivi_output_config *parsed_options; - struct wl_listener heads_changed; - int (*simple_output_configure)(struct weston_output *output); bool init_failed; bool disable_cursor; @@ -89,10 +93,8 @@ struct ivi_compositor { } cmdline; const struct weston_windowed_output_api *window_api; const struct weston_drm_output_api *drm_api; - const struct weston_remoting_api *remoting_api; struct wl_global *agl_shell; - struct wl_global *agl_shell_desktop; struct wl_global *agl_shell_ext; struct { @@ -119,6 +121,7 @@ struct ivi_compositor { struct wl_list outputs; /* ivi_output.link */ struct wl_list saved_outputs; /* ivi_output.link */ struct wl_list surfaces; /* ivi_surface.link */ + struct wl_list backends; struct weston_desktop *desktop; struct wl_listener seat_created_listener; @@ -318,7 +321,6 @@ struct ivi_surface { int32_t width, height; } pending; bool mapped; - bool advertised_on_launch; bool checked_pending; enum { NORMAL, @@ -339,9 +341,6 @@ struct ivi_surface { struct ivi_remote_surface remote; }; - struct wl_listener listener_advertise_app; - struct wl_signal signal_advertise_app; - struct { bool is_set; int32_t x; @@ -501,9 +500,6 @@ void ivi_seat_reset_caps_sent(struct ivi_compositor *ivi); void -agl_shell_desktop_advertise_application_id(struct ivi_compositor *ivi, - struct ivi_surface *surface); -void ivi_check_pending_surface_desktop(struct ivi_surface *surface, enum ivi_surface_role *role); @@ -572,4 +568,7 @@ ivi_init_parsed_options(struct weston_compositor *compositor); void ivi_process_destroy(struct wet_process *process, int status, bool call_cleanup); +void +create_black_curtain_view(struct ivi_output *output); + #endif diff --git a/src/layout.c b/src/layout.c index 48c478e..12c3524 100644 --- a/src/layout.c +++ b/src/layout.c @@ -34,8 +34,6 @@ #include <libweston/libweston.h> #include <libweston/desktop.h> -#include "agl-shell-desktop-server-protocol.h" - #define AGL_COMP_DEBUG static const char *ivi_roles_as_string[] = { @@ -144,14 +142,14 @@ ivi_background_init(struct ivi_compositor *ivi, struct ivi_output *output) struct weston_output *woutput = output->output; struct ivi_surface *bg = output->background; struct weston_view *view; - struct weston_surface *wsurface = - weston_desktop_surface_get_surface(bg->dsurface); + struct weston_surface *wsurface; if (!bg) { weston_log("WARNING: Output does not have a background\n"); return; } + wsurface = weston_desktop_surface_get_surface(bg->dsurface); assert(bg->role == IVI_SURFACE_ROLE_BACKGROUND); view = bg->view; @@ -323,12 +321,6 @@ ivi_layout_activate_complete(struct ivi_output *output, bool update_previous = true; struct weston_coord_global pos; - if (weston_view_is_mapped(view)) { - weston_layer_entry_remove(&view->layer_link); - } else { - weston_view_update_transform(view); - } - if (output_has_black_curtain(output)) { if (!output->background) { weston_log("Found that we have no background surface " @@ -340,11 +332,7 @@ ivi_layout_activate_complete(struct ivi_output *output, /* use the black curtain as background when we have * none added by the shell client. */ - weston_layer_entry_remove(&ev->layer_link); - weston_layer_entry_insert(&ivi->normal.view_list, - &ev->layer_link); - weston_view_geometry_dirty(ev); - weston_surface_damage(ev->surface); + weston_view_move_to_layer(ev, &ivi->normal.view_list); } else { remove_black_curtain(output); } @@ -369,9 +357,6 @@ ivi_layout_activate_complete(struct ivi_output *output, weston_desktop_surface_set_orientation(surf->dsurface, surf->orientation); } - view->is_mapped = true; - surf->mapped = true; - view->surface->is_mapped = true; /* handle a movement from one output to another */ if (surf->current_completed_output && @@ -382,11 +367,12 @@ ivi_layout_activate_complete(struct ivi_output *output, struct weston_view *ev = surf->current_completed_output->active->view; - weston_layer_entry_remove(&ev->layer_link); surf->current_completed_output->previous_active = surf->current_completed_output->active; surf->current_completed_output->active = NULL; + weston_view_move_to_layer(ev, NULL); + /* damage all possible outputs to avoid stale views */ weston_compositor_damage_all(ivi->compositor); } @@ -395,12 +381,9 @@ ivi_layout_activate_complete(struct ivi_output *output, if (output->active) { /* keep the background surface mapped at all times */ if (output->active->role != IVI_SURFACE_ROLE_BACKGROUND && - !output->active->sticky) { - - output->active->view->is_mapped = false; - output->active->view->surface->is_mapped = false; - - weston_layer_entry_remove(&output->active->view->layer_link); + !output->active->sticky && output->active != surf) { + weston_surface_unmap(output->active->view->surface); + weston_view_move_to_layer(output->active->view, NULL); } } @@ -422,12 +405,22 @@ ivi_layout_activate_complete(struct ivi_output *output, output->active = surf; surf->current_completed_output = output; - weston_layer_entry_insert(&ivi->normal.view_list, &view->layer_link); - weston_view_geometry_dirty(view); - weston_surface_damage(view->surface); + if (!weston_surface_is_mapped(view->surface)) { + weston_surface_map(view->surface); + weston_view_move_to_layer(view, &ivi->normal.view_list); + + weston_log("Activation completed for app_id %s, role %s, output %s\n", + app_id, + ivi_layout_get_surface_role_name(surf), output->name); + + shell_send_app_state(ivi, app_id, AGL_SHELL_APP_STATE_ACTIVATED); + + if (ivi_seat) + ivi_shell_activate_surface(surf, ivi_seat, WESTON_ACTIVATE_FLAG_NONE); + } else { + weston_view_update_transform(view); + } - if (ivi_seat) - ivi_shell_activate_surface(surf, ivi_seat, WESTON_ACTIVATE_FLAG_NONE); /* * the 'remote' role now makes use of this part so make sure we don't @@ -439,12 +432,6 @@ ivi_layout_activate_complete(struct ivi_output *output, surf->desktop.last_output = surf->desktop.pending_output; surf->desktop.pending_output = NULL; } - - weston_log("Activation completed for app_id %s, role %s, output %s\n", - app_id, - ivi_layout_get_surface_role_name(surf), output->name); - - shell_send_app_state(ivi, app_id, AGL_SHELL_APP_STATE_ACTIVATED); } static bool @@ -527,8 +514,10 @@ ivi_layout_add_to_hidden_layer(struct ivi_surface *surf, ivi_output->area.width, ivi_output->area.height); surf->hidden_layer_output = ivi_output; + weston_view_set_output(ev, ivi_output->output); - weston_layer_entry_insert(&ivi->hidden.view_list, &ev->layer_link); + weston_view_move_to_layer(ev, &ivi->hidden.view_list); + weston_log("Placed app_id %s, type %s in hidden layer on output %s\n", app_id, ivi_layout_get_surface_role_name(surf), ivi_output->output->name); @@ -540,10 +529,6 @@ ivi_layout_add_to_hidden_layer(struct ivi_surface *surf, /* we might have another output to activate */ if (surf->hidden_layer_output && surf->hidden_layer_output != ivi_output) { - weston_layer_entry_remove(&ev->layer_link); - weston_view_geometry_dirty(ev); - weston_surface_damage(ev->surface); - if (ivi_output->area.width != surf->hidden_layer_output->area.width || ivi_output->area.height != surf->hidden_layer_output->area.height) { weston_desktop_surface_set_maximized(dsurf, true); @@ -558,7 +543,7 @@ ivi_layout_add_to_hidden_layer(struct ivi_surface *surf, surf->hidden_layer_output = ivi_output; weston_view_set_output(ev, ivi_output->output); - weston_layer_entry_insert(&ivi->hidden.view_list, &ev->layer_link); + weston_view_move_to_layer(ev, &ivi->hidden.view_list); weston_log("Placed app_id %s, type %s in hidden layer on output %s\n", app_id, ivi_layout_get_surface_role_name(surf), ivi_output->output->name); @@ -774,7 +759,7 @@ ivi_layout_fullscreen_committed(struct ivi_surface *surface) surface->state = RESIZING; weston_view_set_output(view, output->output); - weston_layer_entry_insert(&ivi->hidden.view_list, &view->layer_link); + weston_view_move_to_layer(view, &ivi->hidden.view_list); return; } @@ -793,25 +778,15 @@ ivi_layout_fullscreen_committed(struct ivi_surface *surface) /* this implies we resized correctly */ if (!weston_view_is_mapped(view) || surface->state != FULLSCREEN) { - weston_layer_entry_remove(&view->layer_link); + surface->state = FULLSCREEN; weston_view_set_output(view, woutput); weston_view_set_position(view, woutput->pos); - weston_layer_entry_insert(&ivi->fullscreen.view_list, &view->layer_link); - - wsurface->is_mapped = true; - surface->view->is_mapped = true; - surface->state = FULLSCREEN; - - weston_view_geometry_dirty(view); - weston_surface_damage(view->surface); + weston_surface_map(wsurface); + weston_view_move_to_layer(view, &ivi->fullscreen.view_list); if (ivi_seat) ivi_shell_activate_surface(surface, ivi_seat, WESTON_ACTIVATE_FLAG_NONE); - - shell_advertise_app_state(ivi, app_id, - NULL, AGL_SHELL_DESKTOP_APP_STATE_ACTIVATED); - weston_log("Activation completed for app_id %s, role %s, " "output %s\n", app_id, ivi_layout_get_surface_role_name(surface), @@ -923,20 +898,12 @@ ivi_layout_split_committed(struct ivi_surface *surface) weston_view_set_output(view, woutput); weston_view_set_position(view, pos); - weston_layer_entry_insert(&ivi->normal.view_list, &view->layer_link); - weston_view_geometry_dirty(view); - weston_surface_damage(view->surface); + weston_surface_map(wsurface); + weston_view_move_to_layer(view, &ivi->normal.view_list); if (ivi_seat) ivi_shell_activate_surface(surface, ivi_seat, WESTON_ACTIVATE_FLAG_NONE); - - wsurface->is_mapped = true; - surface->view->is_mapped = true; - - shell_advertise_app_state(ivi, app_id, - NULL, AGL_SHELL_DESKTOP_APP_STATE_ACTIVATED); - weston_log("Activation completed for app_id %s, role %s, output %s\n", app_id, ivi_layout_get_surface_role_name(surface), output->name); } @@ -994,14 +961,15 @@ ivi_layout_popup_committed(struct ivi_surface *surface) !surface->mapped) return; - if (surface->view->is_mapped || surface->state == HIDDEN) + if (weston_view_is_mapped(view) || surface->state == HIDDEN) return; assert(surface->role == IVI_SURFACE_ROLE_POPUP); /* remove it from hidden layer if present */ - if (ivi_surf_in_hidden_layer(ivi, surface)) - weston_layer_entry_remove(&view->layer_link); + if (ivi_surf_in_hidden_layer(ivi, surface)) { + weston_view_move_to_layer(view, NULL); + } weston_view_set_output(view, woutput); @@ -1017,20 +985,12 @@ ivi_layout_popup_committed(struct ivi_surface *surface) weston_view_set_mask(view, surface->popup.bb.x, surface->popup.bb.y, surface->popup.bb.width, surface->popup.bb.height); - weston_layer_entry_insert(&ivi->popup.view_list, &view->layer_link); - - weston_view_geometry_dirty(view); - weston_surface_damage(view->surface); + weston_view_move_to_layer(view, &ivi->popup.view_list); if (ivi_seat) ivi_shell_activate_surface(surface, ivi_seat, WESTON_ACTIVATE_FLAG_NONE); - wsurface->is_mapped = true; - surface->view->is_mapped = true; - - shell_advertise_app_state(ivi, app_id, - NULL, AGL_SHELL_DESKTOP_APP_STATE_ACTIVATED); - + weston_surface_map(wsurface); weston_log("Activation completed for app_id %s, role %s, output %s\n", app_id, ivi_layout_get_surface_role_name(surface), output->name); } @@ -1046,10 +1006,8 @@ ivi_layout_popup_re_add(struct ivi_surface *surface) struct weston_surface *wsurface = weston_desktop_surface_get_surface(dsurface); - weston_layer_entry_remove(&view->layer_link); - - wsurface->is_mapped = false; - view->is_mapped = false; + weston_view_move_to_layer(view, NULL); + weston_surface_unmap(wsurface); } /* reset the activate by default in order to (still) allow the surface @@ -1072,10 +1030,8 @@ ivi_layout_fullscreen_re_add(struct ivi_surface *surface) struct weston_surface *wsurface = weston_desktop_surface_get_surface(dsurface); - weston_layer_entry_remove(&view->layer_link); - - wsurface->is_mapped = false; - view->is_mapped = false; + weston_view_move_to_layer(view, NULL); + weston_surface_unmap(wsurface); } /* reset the activate by default in order to (still) allow the surface @@ -1138,19 +1094,17 @@ ivi_layout_reset_split_surfaces(struct ivi_compositor *ivi) struct weston_view *ev = output->previous_active->view; struct weston_output *woutput = output->output; - if (!weston_view_is_mapped(ev)) + if (!weston_view_is_mapped(ev)) { weston_view_update_transform(ev); - else - weston_layer_entry_remove(&ev->layer_link); + } else { + weston_surface_map(ev->surface); + weston_view_move_to_layer(ev, &ivi->normal.view_list); + } - ev->is_mapped = true; - ev->surface->is_mapped = true; output->previous_active->mapped = true; weston_view_set_output(ev, woutput); - weston_layer_entry_insert(&ivi->normal.view_list, &ev->layer_link); - _ivi_set_shell_surface_split(output->previous_active, NULL, 0, AGL_SHELL_TILE_ORIENTATION_NONE, false, false); @@ -1358,12 +1312,8 @@ ivi_layout_deactivate(struct ivi_compositor *ivi, const char *app_id) struct weston_view *view; view = ivi_output->active->view; - view->is_mapped = false; - view->surface->is_mapped = false; - - weston_layer_entry_remove(&view->layer_link); - weston_view_geometry_dirty(view); - weston_surface_damage(view->surface); + weston_view_unmap(view); + weston_view_move_to_layer(view, NULL); ivi_output->active = NULL; } } else { @@ -1379,12 +1329,9 @@ ivi_layout_deactivate(struct ivi_compositor *ivi, const char *app_id) surf->role == IVI_SURFACE_ROLE_FULLSCREEN) { struct weston_view *view = surf->view; - weston_view_unmap(view); surf->state = HIDDEN; - - weston_layer_entry_remove(&view->layer_link); - weston_view_geometry_dirty(view); - weston_surface_damage(view->surface); + weston_view_unmap(view); + weston_view_move_to_layer(view, NULL); } shell_send_app_state(ivi, app_id, AGL_SHELL_APP_STATE_DEACTIVATED); diff --git a/src/shell.c b/src/shell.c index c29d89e..a529010 100644 --- a/src/shell.c +++ b/src/shell.c @@ -44,10 +44,6 @@ #include "shared/process-util.h" #include "agl-shell-server-protocol.h" -#include "agl-shell-desktop-server-protocol.h" - -static void -create_black_curtain_view(struct ivi_output *output); static uint32_t reverse_orientation(uint32_t orientation); @@ -56,115 +52,67 @@ const char * split_orientation_to_string(uint32_t orientation); void -agl_shell_desktop_advertise_application_id(struct ivi_compositor *ivi, - struct ivi_surface *surface) -{ - struct desktop_client *dclient; - static bool display_adv = false; - - if (surface->advertised_on_launch) - return; - - /* advertise to all desktop clients the new surface */ - wl_list_for_each(dclient, &ivi->desktop_clients, link) { - const char *app_id = - weston_desktop_surface_get_app_id(surface->dsurface); - if (app_id == NULL) { - if (!display_adv) { - weston_log("WARNING app_is is null, unable to advertise\n"); - display_adv = true; - } - return; - } - agl_shell_desktop_send_application(dclient->resource, app_id); - surface->advertised_on_launch = true; - } -} - -void ivi_set_desktop_surface(struct ivi_surface *surface) { struct ivi_compositor *ivi = surface->ivi; assert(surface->role == IVI_SURFACE_ROLE_NONE); surface->role = IVI_SURFACE_ROLE_DESKTOP; - wl_list_insert(&surface->ivi->surfaces, &surface->link); - - agl_shell_desktop_advertise_application_id(ivi, surface); -} - -static void -ivi_set_background_surface(struct ivi_surface *surface) -{ - struct ivi_compositor *ivi = surface->ivi; - assert(surface->role == IVI_SURFACE_ROLE_BACKGROUND); - - wl_list_insert(&surface->ivi->surfaces, &surface->link); - agl_shell_desktop_advertise_application_id(ivi, surface); + wl_list_insert(&ivi->surfaces, &surface->link); } -static void +void ivi_set_desktop_surface_popup(struct ivi_surface *surface) { - struct ivi_compositor *ivi = surface->ivi; - assert(surface->role == IVI_SURFACE_ROLE_NONE); - - surface->role = IVI_SURFACE_ROLE_POPUP; - wl_list_insert(&ivi->surfaces, &surface->link); + struct ivi_compositor *ivi = surface->ivi; + assert(surface->role == IVI_SURFACE_ROLE_NONE); - agl_shell_desktop_advertise_application_id(ivi, surface); + surface->role = IVI_SURFACE_ROLE_POPUP; + wl_list_insert(&ivi->surfaces, &surface->link); } -static void +void ivi_set_desktop_surface_fullscreen(struct ivi_surface *surface) { - struct ivi_compositor *ivi = surface->ivi; - assert(surface->role == IVI_SURFACE_ROLE_NONE); - - surface->role = IVI_SURFACE_ROLE_FULLSCREEN; - wl_list_insert(&ivi->surfaces, &surface->link); + struct ivi_compositor *ivi = surface->ivi; + assert(surface->role == IVI_SURFACE_ROLE_NONE); - agl_shell_desktop_advertise_application_id(ivi, surface); + surface->role = IVI_SURFACE_ROLE_FULLSCREEN; + wl_list_insert(&ivi->surfaces, &surface->link); } -static void +void ivi_set_desktop_surface_remote(struct ivi_surface *surface) { - struct ivi_compositor *ivi = surface->ivi; - struct weston_view *view; - struct ivi_output *output = surface->remote.output; + struct ivi_compositor *ivi = surface->ivi; + struct weston_view *view; + struct ivi_output *output = surface->remote.output; - assert(surface->role == IVI_SURFACE_ROLE_NONE); + assert(surface->role == IVI_SURFACE_ROLE_NONE); - /* remote type are the same as desktop just that client can tell - * the compositor to start on another output */ - surface->role = IVI_SURFACE_ROLE_REMOTE; + /* remote type are the same as desktop just that client can tell + * the compositor to start on another output */ + surface->role = IVI_SURFACE_ROLE_REMOTE; - /* if thew black surface view is mapped on the mean we need - * to remove it in order to start showing the 'remote' surface - * just being added */ - view = output->fullscreen_view.fs->view; - if (view->is_mapped || view->surface->is_mapped) - remove_black_curtain(output); + /* if thew black surface view is mapped on the mean we need + * to remove it in order to start showing the 'remote' surface + * just being added */ + if (output->fullscreen_view.fs) { + view = output->fullscreen_view.fs->view; + if (view->is_mapped || view->surface->is_mapped) + remove_black_curtain(output); + } - wl_list_insert(&ivi->surfaces, &surface->link); + wl_list_insert(&ivi->surfaces, &surface->link); } - -static void -ivi_set_desktop_surface_split(struct ivi_surface *surface) +void +ivi_set_background_surface(struct ivi_surface *surface) { struct ivi_compositor *ivi = surface->ivi; - assert(surface->role == IVI_SURFACE_ROLE_NONE); - - if (surface->split.orientation == AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL) - surface->role = IVI_SURFACE_ROLE_SPLIT_V; - else - surface->role = IVI_SURFACE_ROLE_SPLIT_H; + assert(surface->role == IVI_SURFACE_ROLE_BACKGROUND); wl_list_insert(&ivi->surfaces, &surface->link); - - agl_shell_desktop_advertise_application_id(ivi, surface); } static struct pending_popup * @@ -343,42 +291,6 @@ ivi_set_pending_desktop_surface_fullscreen(struct ivi_output *ioutput, wl_list_insert(&ivi->fullscreen_pending_apps, &p_fullscreen->link); } -static void -ivi_set_pending_desktop_surface_split(struct ivi_output *ioutput, - const char *app_id, uint32_t orientation) -{ - struct ivi_compositor *ivi = ioutput->ivi; - struct ivi_surface *surf; - size_t len_app_id = strlen(app_id); - struct pending_split *split; - - if (orientation != AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL && - orientation != AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL) - return; - - /* more than one is un-supported, do note we need to do - * conversion for surface roles instead of using the protocol ones */ - wl_list_for_each(surf, &ivi->surfaces, link) - if (surf->role == IVI_SURFACE_ROLE_SPLIT_V || - surf->role == IVI_SURFACE_ROLE_SPLIT_H) - return; - - split = zalloc(sizeof(*split)); - if (!split) - return; - split->app_id = zalloc(sizeof(char) * (len_app_id + 1)); - if (!split->app_id) { - free(split); - return; - } - memcpy(split->app_id, app_id, len_app_id); - - split->ioutput = ioutput; - split->orientation = orientation; - - wl_list_insert(&ivi->split_pending_apps, &split->link); -} - void ivi_set_pending_desktop_surface_remote(struct ivi_output *ioutput, const char *app_id) @@ -434,6 +346,73 @@ ivi_remove_pending_desktop_surface_remote(struct pending_remote *remote) free(remote); } +void +ivi_check_pending_surface_desktop(struct ivi_surface *surface, + enum ivi_surface_role *role) +{ + struct ivi_compositor *ivi = surface->ivi; + struct wl_list *role_pending_list; + struct pending_popup *p_popup; + struct pending_split *p_split; + struct pending_fullscreen *p_fullscreen; + struct pending_remote *p_remote; + const char *app_id = + weston_desktop_surface_get_app_id(surface->dsurface); + + role_pending_list = &ivi->popup_pending_apps; + wl_list_for_each(p_popup, role_pending_list, link) { + if (app_id && !strcmp(app_id, p_popup->app_id)) { + *role = IVI_SURFACE_ROLE_POPUP; + return; + } + } + + role_pending_list = &ivi->split_pending_apps; + wl_list_for_each(p_split, role_pending_list, link) { + if (app_id && !strcmp(app_id, p_split->app_id)) { + *role = IVI_SURFACE_ROLE_SPLIT_V; + return; + } + } + + role_pending_list = &ivi->fullscreen_pending_apps; + wl_list_for_each(p_fullscreen, role_pending_list, link) { + if (app_id && !strcmp(app_id, p_fullscreen->app_id)) { + *role = IVI_SURFACE_ROLE_FULLSCREEN; + return; + } + } + + role_pending_list = &ivi->remote_pending_apps; + wl_list_for_each(p_remote, role_pending_list, link) { + if (app_id && !strcmp(app_id, p_remote->app_id)) { + *role = IVI_SURFACE_ROLE_REMOTE; + return; + } + } + + /* else, we are a regular desktop surface */ + *role = IVI_SURFACE_ROLE_DESKTOP; +} + +struct pending_app * +ivi_check_pending_app_type(struct ivi_surface *surface, enum ivi_surface_role role) +{ + struct pending_app *papp; + const char *app_id = NULL; + + app_id = weston_desktop_surface_get_app_id(surface->dsurface); + if (!app_id) + return NULL; + + wl_list_for_each(papp, &surface->ivi->pending_apps, link) { + if (strcmp(app_id, papp->app_id) == 0 && papp->role == role) + return papp; + } + + return NULL; +} + static bool ivi_compositor_keep_pending_surfaces(struct ivi_surface *surface) { @@ -446,13 +425,13 @@ ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) struct ivi_compositor *ivi = surface->ivi; struct pending_popup *p_popup, *next_p_popup; const char *_app_id = - weston_desktop_surface_get_app_id(surface->dsurface); + weston_desktop_surface_get_app_id(surface->dsurface); if (wl_list_empty(&ivi->popup_pending_apps) || !_app_id) return false; wl_list_for_each_safe(p_popup, next_p_popup, - &ivi->popup_pending_apps, link) { + &ivi->popup_pending_apps, link) { if (!strcmp(_app_id, p_popup->app_id)) { surface->popup.output = p_popup->ioutput; surface->popup.x = p_popup->x; @@ -473,43 +452,18 @@ ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface) } static bool -ivi_check_pending_desktop_surface_split(struct ivi_surface *surface) -{ - struct pending_split *split_surf, *next_split_surf; - struct ivi_compositor *ivi = surface->ivi; - const char *_app_id = - weston_desktop_surface_get_app_id(surface->dsurface); - - if (wl_list_empty(&ivi->split_pending_apps) || !_app_id) - return false; - - wl_list_for_each_safe(split_surf, next_split_surf, - &ivi->split_pending_apps, link) { - if (!strcmp(_app_id, split_surf->app_id)) { - surface->split.output = split_surf->ioutput; - surface->split.orientation = split_surf->orientation; - if (!ivi_compositor_keep_pending_surfaces(surface)) - ivi_remove_pending_desktop_surface_split(split_surf); - return true; - } - } - - return false; -} - -static bool ivi_check_pending_desktop_surface_fullscreen(struct ivi_surface *surface) { struct pending_fullscreen *fs_surf, *next_fs_surf; struct ivi_compositor *ivi = surface->ivi; const char *_app_id = - weston_desktop_surface_get_app_id(surface->dsurface); + weston_desktop_surface_get_app_id(surface->dsurface); if (wl_list_empty(&ivi->fullscreen_pending_apps) || !_app_id) return false; wl_list_for_each_safe(fs_surf, next_fs_surf, - &ivi->fullscreen_pending_apps, link) { + &ivi->fullscreen_pending_apps, link) { if (!strcmp(_app_id, fs_surf->app_id)) { surface->fullscreen.output = fs_surf->ioutput; if (!ivi_compositor_keep_pending_surfaces(surface)) @@ -533,7 +487,7 @@ ivi_check_pending_desktop_surface_remote(struct ivi_surface *surface) return false; wl_list_for_each_safe(remote_surf, next_remote_surf, - &ivi->remote_pending_apps, link) { + &ivi->remote_pending_apps, link) { if (!strcmp(_app_id, remote_surf->app_id)) { surface->remote.output = remote_surf->ioutput; if (!ivi_compositor_keep_pending_surfaces(surface)) @@ -544,73 +498,6 @@ ivi_check_pending_desktop_surface_remote(struct ivi_surface *surface) return false; } -void -ivi_check_pending_surface_desktop(struct ivi_surface *surface, - enum ivi_surface_role *role) -{ - struct ivi_compositor *ivi = surface->ivi; - struct wl_list *role_pending_list; - struct pending_popup *p_popup; - struct pending_split *p_split; - struct pending_fullscreen *p_fullscreen; - struct pending_remote *p_remote; - const char *app_id = - weston_desktop_surface_get_app_id(surface->dsurface); - - role_pending_list = &ivi->popup_pending_apps; - wl_list_for_each(p_popup, role_pending_list, link) { - if (app_id && !strcmp(app_id, p_popup->app_id)) { - *role = IVI_SURFACE_ROLE_POPUP; - return; - } - } - - role_pending_list = &ivi->split_pending_apps; - wl_list_for_each(p_split, role_pending_list, link) { - if (app_id && !strcmp(app_id, p_split->app_id)) { - *role = IVI_SURFACE_ROLE_SPLIT_V; - return; - } - } - - role_pending_list = &ivi->fullscreen_pending_apps; - wl_list_for_each(p_fullscreen, role_pending_list, link) { - if (app_id && !strcmp(app_id, p_fullscreen->app_id)) { - *role = IVI_SURFACE_ROLE_FULLSCREEN; - return; - } - } - - role_pending_list = &ivi->remote_pending_apps; - wl_list_for_each(p_remote, role_pending_list, link) { - if (app_id && !strcmp(app_id, p_remote->app_id)) { - *role = IVI_SURFACE_ROLE_REMOTE; - return; - } - } - - /* else, we are a regular desktop surface */ - *role = IVI_SURFACE_ROLE_DESKTOP; -} - -struct pending_app * -ivi_check_pending_app_type(struct ivi_surface *surface, enum ivi_surface_role role) -{ - struct pending_app *papp; - const char *app_id = NULL; - - app_id = weston_desktop_surface_get_app_id(surface->dsurface); - if (!app_id) - return NULL; - - wl_list_for_each(papp, &surface->ivi->pending_apps, link) { - if (strcmp(app_id, papp->app_id) == 0 && papp->role == role) - return papp; - } - - return NULL; -} - void ivi_check_pending_desktop_surface(struct ivi_surface *surface) @@ -624,13 +511,6 @@ ivi_check_pending_desktop_surface(struct ivi_surface *surface) return; } - ret = ivi_check_pending_desktop_surface_split(surface); - if (ret) { - ivi_set_desktop_surface_split(surface); - ivi_layout_split_committed(surface); - return; - } - ret = ivi_check_pending_desktop_surface_fullscreen(surface); if (ret) { ivi_set_desktop_surface_fullscreen(surface); @@ -785,7 +665,7 @@ ivi_shell_finalize(struct ivi_compositor *ivi) weston_layer_fini(&ivi->fullscreen); } -static void +void ivi_shell_advertise_xdg_surfaces(struct ivi_compositor *ivi, struct wl_resource *resource) { struct ivi_surface *surface; @@ -797,7 +677,6 @@ ivi_shell_advertise_xdg_surfaces(struct ivi_compositor *ivi, struct wl_resource weston_log("WARNING app_is is null, unable to advertise\n"); return; } - agl_shell_desktop_send_application(resource, app_id); } } @@ -1034,8 +913,7 @@ curtain_surface_committed(struct weston_surface *es, struct weston_coord_surface } - -static void +void create_black_curtain_view(struct ivi_output *output) { struct weston_surface *surface = NULL; @@ -1386,37 +1264,6 @@ shell_set_panel(struct wl_client *client, weston_desktop_surface_set_size(dsurface, width, height); } -void -shell_advertise_app_state(struct ivi_compositor *ivi, const char *app_id, - const char *data, uint32_t app_state) -{ - struct desktop_client *dclient; - uint32_t app_role; - struct ivi_surface *surf = ivi_find_app(ivi, app_id); - struct ivi_policy *policy = ivi->policy; - - /* FIXME: should queue it here and see when binding agl-shell-desktop - * if there are any to be sent */ - if (!surf) - return; - - if (!app_id) - return; - - if (policy && policy->api.surface_advertise_state_change && - !policy->api.surface_advertise_state_change(surf, surf->ivi)) { - return; - } - - app_role = surf->role; - if (app_role == IVI_SURFACE_ROLE_POPUP) - app_role = AGL_SHELL_DESKTOP_APP_ROLE_POPUP; - - wl_list_for_each(dclient, &ivi->desktop_clients, link) - agl_shell_desktop_send_state_app(dclient->resource, app_id, - data, app_state, app_role); -} - static void shell_activate_app(struct wl_client *client, struct wl_resource *shell_res, @@ -1452,7 +1299,7 @@ shell_activate_app(struct wl_client *client, } static void -shell_new_deactivate_app(struct wl_client *client, struct wl_resource *shell_res, +shell_deactivate_app(struct wl_client *client, struct wl_resource *shell_res, const char *app_id) { struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res); @@ -1497,9 +1344,7 @@ shell_set_app_float(struct wl_client *client, struct wl_resource *shell_res, if (prev_activate_app_id && strcmp(app_id, prev_activate_app_id)) { ivi_layout_deactivate(ivi, app_id); } else if (prev_activate_app_id) { - weston_layer_entry_remove(&ev->layer_link); - weston_view_geometry_dirty(ev); - weston_surface_damage(ev->surface); + weston_view_move_to_layer(ev, NULL); } surf->hidden_layer_output = ivi_output; @@ -1524,7 +1369,7 @@ shell_set_app_float(struct wl_client *client, struct wl_resource *shell_res, weston_desktop_surface_set_size(dsurf, 0, 0); /* add to hidden layer */ - weston_layer_entry_insert(&ivi->hidden.view_list, &ev->layer_link); + weston_view_move_to_layer(ev, &ivi->hidden.view_list); weston_compositor_schedule_repaint(ivi->compositor); } else if (!surf || (surf && surf->role != IVI_SURFACE_ROLE_POPUP)) { @@ -1554,10 +1399,6 @@ shell_set_app_fullscreen(struct wl_client *client, if (surf != ivi_output->active) return; - weston_layer_entry_remove(&surf->view->layer_link); - weston_view_geometry_dirty(surf->view); - weston_surface_damage(surf->view->surface); - surf->hidden_layer_output = ivi_output; /* set attributes */ @@ -1578,7 +1419,7 @@ shell_set_app_fullscreen(struct wl_client *client, ivi_output->output->height); /* add to hidden layer */ - weston_layer_entry_insert(&ivi->hidden.view_list, &ev->layer_link); + weston_view_move_to_layer(ev, &ivi->hidden.view_list); weston_compositor_schedule_repaint(ivi->compositor); } else if (!surf || (surf && surf->role != IVI_SURFACE_ROLE_FULLSCREEN)) { ivi_set_pending_desktop_surface_fullscreen(ivi_output, app_id); @@ -1607,10 +1448,6 @@ shell_set_app_normal(struct wl_client *client, struct wl_resource *shell_res, dsurf = surf->dsurface; ivi_output = to_ivi_output(output); - weston_layer_entry_remove(&surf->view->layer_link); - weston_view_geometry_dirty(surf->view); - weston_surface_damage(surf->view->surface); - /* change the role */ surf->role = IVI_SURFACE_ROLE_NONE; surf->state = NORMAL; @@ -1634,41 +1471,12 @@ shell_set_app_normal(struct wl_client *client, struct wl_resource *shell_res, weston_desktop_surface_set_size(dsurf, area.width, area.height); /* add to hidden layer */ - weston_layer_entry_insert(&ivi->hidden.view_list, - &surf->view->layer_link); + weston_view_move_to_layer(surf->view, &ivi->hidden.view_list); weston_compositor_schedule_repaint(ivi->compositor); } static void -shell_desktop_activate_app(struct wl_client *client, - struct wl_resource *shell_res, - const char *app_id, const char *data, - struct wl_resource *output_res) -{ - struct weston_head *head = weston_head_from_resource(output_res); - struct weston_output *woutput = weston_head_get_output(head); - struct ivi_output *output = to_ivi_output(woutput); - - ivi_layout_activate(output, app_id); - shell_advertise_app_state(output->ivi, app_id, - data, AGL_SHELL_DESKTOP_APP_STATE_ACTIVATED); -} - -static void -shell_deactivate_app(struct wl_client *client, - struct wl_resource *shell_res, - const char *app_id) -{ - struct desktop_client *dclient = wl_resource_get_user_data(shell_res); - struct ivi_compositor *ivi = dclient->ivi; - - ivi_layout_deactivate(ivi, app_id); - shell_advertise_app_state(ivi, app_id, - NULL, AGL_SHELL_DESKTOP_APP_STATE_DEACTIVATED); -} - -static void shell_destroy(struct wl_client *client, struct wl_resource *res) { struct ivi_compositor *ivi = wl_resource_get_user_data(res); @@ -1938,14 +1746,10 @@ _ivi_set_shell_surface_split(struct ivi_surface *surface, struct ivi_output *iou if (!weston_view_is_mapped(ev)) weston_view_update_transform(ev); - else - weston_layer_entry_remove(&ev->layer_link); // mark view as mapped - ev->is_mapped = true; - ev->surface->is_mapped = true; - surface->mapped = true; + weston_surface_map(ev->surface); // update older/new active surface output->previous_active = output->active; @@ -1953,9 +1757,7 @@ _ivi_set_shell_surface_split(struct ivi_surface *surface, struct ivi_output *iou // add to the layer and inflict damage weston_view_set_output(ev, output->output); - weston_layer_entry_insert(&ivi->normal.view_list, &ev->layer_link); - weston_view_geometry_dirty(ev); - weston_surface_damage(ev->surface); + weston_view_move_to_layer(ev, &ivi->normal.view_list); // handle input / keyboard if (ivi_seat) @@ -2047,24 +1849,14 @@ void shell_set_app_split(struct wl_client *client, struct wl_resource *res, if (orientation != AGL_SHELL_TILE_ORIENTATION_NONE) { if (!weston_view_is_mapped(ev)) weston_view_update_transform(ev); - else - weston_layer_entry_remove(&ev->layer_link); - ev->is_mapped = true; - ev->surface->is_mapped = true; - output->previous_active->mapped = true; + weston_surface_map(ev->surface); weston_view_set_output(ev, woutput); - weston_layer_entry_insert(&ivi->normal.view_list, - &ev->layer_link); + weston_view_move_to_layer(ev, &ivi->normal.view_list); } else { - ev->is_mapped = false; - ev->surface->is_mapped = false; - - weston_layer_entry_remove(&ev->layer_link); - - weston_view_geometry_dirty(ev); - weston_surface_damage(ev->surface); + weston_surface_unmap(ev->surface); + weston_view_move_to_layer(ev, NULL); } /* a 0 width means we have no explicit width set-up */ @@ -2131,7 +1923,7 @@ static const struct agl_shell_interface agl_shell_implementation = { .activate_app = shell_activate_app, .destroy = shell_destroy, .set_activate_region = shell_set_activate_region, - .deactivate_app = shell_new_deactivate_app, + .deactivate_app = shell_deactivate_app, .set_app_float = shell_set_app_float, .set_app_normal = shell_set_app_normal, .set_app_fullscreen = shell_set_app_fullscreen, @@ -2146,38 +1938,6 @@ static const struct agl_shell_ext_interface agl_shell_ext_implementation = { .doas_shell_client = shell_ext_doas, }; -static void -shell_desktop_set_app_property(struct wl_client *client, - struct wl_resource *shell_res, - const char *app_id, uint32_t role, - int x, int y, int bx, int by, - int width, int height, - struct wl_resource *output_res) -{ - struct weston_head *head = weston_head_from_resource(output_res); - struct weston_output *woutput = weston_head_get_output(head); - struct ivi_output *output = to_ivi_output(woutput); - - switch (role) { - case AGL_SHELL_DESKTOP_APP_ROLE_POPUP: - ivi_set_pending_desktop_surface_popup(output, x, y, bx, by, - width, height, app_id); - break; - case AGL_SHELL_DESKTOP_APP_ROLE_FULLSCREEN: - ivi_set_pending_desktop_surface_fullscreen(output, app_id); - break; - case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL: - case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL: - ivi_set_pending_desktop_surface_split(output, app_id, role); - break; - case AGL_SHELL_DESKTOP_APP_ROLE_REMOTE: - ivi_set_pending_desktop_surface_remote(output, app_id); - break; - default: - break; - } -} - void ivi_compositor_destroy_pending_surfaces(struct ivi_compositor *ivi) { @@ -2204,27 +1964,6 @@ ivi_compositor_destroy_pending_surfaces(struct ivi_compositor *ivi) } static void -shell_desktop_set_app_property_mode(struct wl_client *client, - struct wl_resource *shell_res, uint32_t perm) -{ - struct desktop_client *dclient = wl_resource_get_user_data(shell_res); - if (perm) { - dclient->ivi->keep_pending_surfaces = true; - } else { - dclient->ivi->keep_pending_surfaces = false; - /* remove any previous pending surfaces */ - ivi_compositor_destroy_pending_surfaces(dclient->ivi); - } -} - -static const struct agl_shell_desktop_interface agl_shell_desktop_implementation = { - .activate_app = shell_desktop_activate_app, - .set_app_property = shell_desktop_set_app_property, - .deactivate_app = shell_deactivate_app, - .set_app_property_mode = shell_desktop_set_app_property_mode, -}; - -static void unbind_agl_shell(struct wl_resource *resource) { struct ivi_compositor *ivi; @@ -2247,12 +1986,10 @@ unbind_agl_shell(struct wl_resource *resource) if (output->active) { struct weston_geometry area = {}; - output->active->view->is_mapped = false; - output->active->view->surface->is_mapped = false; + weston_surface_unmap(output->active->view->surface); + weston_view_move_to_layer(output->active->view, NULL); - weston_layer_entry_remove(&output->active->view->layer_link); output->active = NULL; - output->area_activation = area; } @@ -2388,58 +2125,6 @@ bind_agl_shell_ext(struct wl_client *client, ivi->shell_client_ext.resource = resource; } -static void -unbind_agl_shell_desktop(struct wl_resource *resource) -{ - struct desktop_client *dclient = wl_resource_get_user_data(resource); - - wl_list_remove(&dclient->link); - free(dclient); -} - -static void -bind_agl_shell_desktop(struct wl_client *client, - void *data, uint32_t version, uint32_t id) -{ - struct ivi_compositor *ivi = data; - struct wl_resource *resource; - struct ivi_policy *policy; - struct desktop_client *dclient; - void *interface; - - policy = ivi->policy; - interface = (void *) &agl_shell_desktop_interface; - if (policy && policy->api.shell_bind_interface && - !policy->api.shell_bind_interface(client, interface)) { - wl_client_post_implementation_error(client, - "client not authorized to use agl_shell_desktop"); - return; - } - - dclient = zalloc(sizeof(*dclient)); - if (!dclient) { - wl_client_post_no_memory(client); - return; - } - - resource = wl_resource_create(client, &agl_shell_desktop_interface, - version, id); - dclient->ivi = ivi; - if (!resource) { - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(resource, &agl_shell_desktop_implementation, - dclient, unbind_agl_shell_desktop); - - dclient->resource = resource; - wl_list_insert(&ivi->desktop_clients, &dclient->link); - - /* advertise xdg surfaces */ - ivi_shell_advertise_xdg_surfaces(ivi, resource); -} - int ivi_shell_create_global(struct ivi_compositor *ivi) { @@ -2459,13 +2144,5 @@ ivi_shell_create_global(struct ivi_compositor *ivi) return -1; } - ivi->agl_shell_desktop = wl_global_create(ivi->compositor->wl_display, - &agl_shell_desktop_interface, 2, - ivi, bind_agl_shell_desktop); - if (!ivi->agl_shell_desktop) { - weston_log("Failed to create wayland global (agl_shell_desktop).\n"); - return -1; - } - return 0; } |