You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
5.2 KiB

/*
* Copyright © 2010-2012 Intel Corporation
* Copyright © 2011-2012 Collabora, Ltd.
* Copyright © 2013 Raspberry Pi Foundation
*
* 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.
*/
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include <libweston/libweston.h>
#include <libweston/xwayland-api.h>
#include "weston-desktop-shell-server-protocol.h"
enum animation_type {
ANIMATION_NONE,
ANIMATION_ZOOM,
ANIMATION_FADE,
ANIMATION_DIM_LAYER,
};
enum fade_type {
FADE_IN,
FADE_OUT
};
struct focus_surface {
struct weston_curtain *curtain;
};
struct workspace {
struct weston_layer layer;
struct wl_list focus_list;
struct wl_listener seat_destroyed_listener;
struct focus_surface *fsurf_front;
struct focus_surface *fsurf_back;
struct weston_view_animation *focus_animation;
};
struct shell_output {
struct desktop_shell *shell;
struct weston_output *output;
struct wl_listener destroy_listener;
struct wl_list link;
struct weston_surface *panel_surface;
struct wl_listener panel_surface_listener;
struct weston_surface *background_surface;
struct wl_listener background_surface_listener;
struct {
desktop-shell: Reuse curtains for fades Use the common infrastructure we have, rather than open-coding again. In changing to the common weston_curtain infrastructure which was introduced in a previous commit, there are two small functional derivations. After adding the view to a layer, we explicitly call weston_view_geometry_dirty(). This is believed to have no functional impact, as weston_views have their geometry-dirty flag set when they are created. weston_surface_damage() is also called to ensure that the surface is scheduled for a repaint. As there is currently no good common mechanic in the common code to ensure that output repaint will occur, due to the damage propagating outwards from the weston_surface, we are forced to call this to predictably ensure that the output will be repainted after we have made this change to the scene graph which should result in the user observing the new content being repainted. It is possible that these changes are not strictly required in order for the correct behaviour to occur. However, it is felt that explicitly adding these calls is perhaps the least fragile way to ensure that the behaviour continues to be correct and breakage is not observed, especially with both view mapping and surface damage identified as areas for future work which could be beneficial to Weston. If it is felt that these calls can be removed, then this is certainly possible at a later stage. Lastly, there are many users within desktop-shell of the common pattern of creating a weston_curtain and inserting it into the scene graph to be painted. These users have been an area of both theoretical concern and real-life observed fragility and breakage recently. By making each user follow a common and predictable pattern of usage, each user is no longer its own special case. This should make it easier to make the desktop-shell codebase more robust, not only simplifying the codebase, but improving observed behaviour. In doing this, it is hoped that future structural and interface changes become easier to make, allowing us to improve some of the more difficult corners of the libweston API. Signed-off-by: Daniel Stone <daniels@collabora.com>
3 years ago
struct weston_curtain *curtain;
struct weston_view_animation *animation;
enum fade_type type;
struct wl_event_source *startup_timer;
} fade;
};
struct weston_desktop;
struct desktop_shell {
struct weston_compositor *compositor;
struct weston_desktop *desktop;
const struct weston_xwayland_surface_api *xwayland_surface_api;
struct wl_listener idle_listener;
struct wl_listener wake_listener;
struct wl_listener transform_listener;
struct wl_listener resized_listener;
struct wl_listener destroy_listener;
struct wl_listener show_input_panel_listener;
struct wl_listener hide_input_panel_listener;
struct wl_listener update_input_panel_listener;
struct weston_layer fullscreen_layer;
struct weston_layer panel_layer;
struct weston_layer background_layer;
struct weston_layer lock_layer;
struct weston_layer input_panel_layer;
struct wl_listener pointer_focus_listener;
struct weston_surface *grab_surface;
struct {
struct wl_client *client;
struct wl_resource *desktop_shell;
struct wl_listener client_destroy_listener;
unsigned deathcount;
struct timespec deathstamp;
} child;
bool locked;
bool showing_input_panels;
bool prepare_event_sent;
text_backend: make destructor call explicit We used to rely on the order in which the weston_compositor::destroy_signal callbacks happened, to not access freed memory. Don't know when, but this broke at least with ivi-shell, which caused crashes in random places on compositor shutdown. Valgrind found the following: Invalid write of size 8 at 0xC2EDC69: unbind_input_panel (input-panel-ivi.c:340) by 0x4E3B6BB: destroy_resource (wayland-server.c:537) by 0x4E3E085: for_each_helper.isra.0 (wayland-util.c:359) by 0x4E3E60D: wl_map_for_each (wayland-util.c:365) by 0x4E3BEC7: wl_client_destroy (wayland-server.c:675) by 0x4182F2: text_backend_notifier_destroy (text-backend.c:1047) by 0x4084FB: wl_signal_emit (wayland-server-core.h:264) by 0x4084FB: main (compositor.c:5465) Address 0x67ea360 is 208 bytes inside a block of size 232 free'd at 0x4C2A6BC: free (vg_replace_malloc.c:473) by 0x4084FB: wl_signal_emit (wayland-server-core.h:264) by 0x4084FB: main (compositor.c:5465) Invalid write of size 8 at 0x4E3E0D7: wl_list_remove (wayland-util.c:57) by 0xC2EDEE9: destroy_input_panel_surface (input-panel-ivi.c:191) by 0x4E3B6BB: destroy_resource (wayland-server.c:537) by 0x4E3BC7B: wl_resource_destroy (wayland-server.c:550) by 0x40DB8B: wl_signal_emit (wayland-server-core.h:264) by 0x40DB8B: weston_surface_destroy (compositor.c:1883) by 0x40DB8B: weston_surface_destroy (compositor.c:1873) by 0x4E3B6BB: destroy_resource (wayland-server.c:537) by 0x4E3E085: for_each_helper.isra.0 (wayland-util.c:359) by 0x4E3E60D: wl_map_for_each (wayland-util.c:365) by 0x4E3BEC7: wl_client_destroy (wayland-server.c:675) by 0x4182F2: text_backend_notifier_destroy (text-backend.c:1047) by 0x4084FB: wl_signal_emit (wayland-server-core.h:264) by 0x4084FB: main (compositor.c:5465) Address 0x67ea370 is 224 bytes inside a block of size 232 free'd at 0x4C2A6BC: free (vg_replace_malloc.c:473) by 0x4084FB: wl_signal_emit (wayland-server-core.h:264) by 0x4084FB: main (compositor.c:5465) Invalid write of size 8 at 0x4E3E0E7: wl_list_remove (wayland-util.c:58) by 0xC2EDEE9: destroy_input_panel_surface (input-panel-ivi.c:191) by 0x4E3B6BB: destroy_resource (wayland-server.c:537) by 0x4E3BC7B: wl_resource_destroy (wayland-server.c:550) by 0x40DB8B: wl_signal_emit (wayland-server-core.h:264) by 0x40DB8B: weston_surface_destroy (compositor.c:1883) by 0x40DB8B: weston_surface_destroy (compositor.c:1873) by 0x4E3B6BB: destroy_resource (wayland-server.c:537) by 0x4E3E085: for_each_helper.isra.0 (wayland-util.c:359) by 0x4E3E60D: wl_map_for_each (wayland-util.c:365) by 0x4E3BEC7: wl_client_destroy (wayland-server.c:675) by 0x4182F2: text_backend_notifier_destroy (text-backend.c:1047) by 0x4084FB: wl_signal_emit (wayland-server-core.h:264) by 0x4084FB: main (compositor.c:5465) Address 0x67ea368 is 216 bytes inside a block of size 232 free'd at 0x4C2A6BC: free (vg_replace_malloc.c:473) by 0x4084FB: wl_signal_emit (wayland-server-core.h:264) by 0x4084FB: main (compositor.c:5465) Looking at the first of these, unbind_input_panel() gets called when the text-backend destroys its helper client which has bound to input_panel interface. This happens after the shell's destroy_signal callback has been called, so the shell has already been freed. The other two errors come from wl_list_remove(&input_panel_surface->link); which has gone stale when the shell was destroyed (shell->input_panel.surfaces list). Rather than creating even more destroy listeners and hooking them up in spaghetti, modify text-backend to not hook up to the compositor destroy signal. Instead, make it the text_backend_init() callers' responsibility to also call text_backend_destroy() appropriately, before the shell goes away. This fixed all the above Valgrind errors, and avoid a crash with ivi-shell when exiting Weston. Also using desktop-shell exhibited similar Valgrind errors which are fixed by this patch, but those didn't happen to cause any crashes AFAIK. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-By: Derek Foreman <derekf@osg.samsung.com>
10 years ago
struct text_backend *text_backend;
struct {
struct weston_surface *surface;
pixman_box32_t cursor_rectangle;
} text_input;
struct weston_surface *lock_surface;
struct wl_listener lock_surface_listener;
struct workspace workspace;
struct {
struct wl_resource *binding;
struct wl_list surfaces;
} input_panel;
bool allow_zap;
uint32_t binding_modifier;
enum animation_type win_animation_type;
enum animation_type win_close_animation_type;
enum animation_type startup_animation_type;
enum animation_type focus_animation_type;
struct weston_layer minimized_layer;
struct wl_listener seat_create_listener;
struct wl_listener output_create_listener;
struct wl_listener output_move_listener;
struct wl_list output_list;
struct wl_list seat_list;
enum weston_desktop_shell_panel_position panel_position;
char *client;
struct timespec startup_time;
};
struct weston_output *
get_default_output(struct weston_compositor *compositor);
struct weston_view *
get_default_view(struct weston_surface *surface);
struct shell_surface *
get_shell_surface(struct weston_surface *surface);
struct workspace *
get_current_workspace(struct desktop_shell *shell);
void
get_output_work_area(struct desktop_shell *shell,
struct weston_output *output,
pixman_rectangle32_t *area);
void
lower_fullscreen_layer(struct desktop_shell *shell,
struct weston_output *lowering_output);
void
activate(struct desktop_shell *shell, struct weston_view *view,
struct weston_seat *seat, uint32_t flags);
int
input_panel_setup(struct desktop_shell *shell);
void
input_panel_destroy(struct desktop_shell *shell);
typedef void (*shell_for_each_layer_func_t)(struct desktop_shell *,
struct weston_layer *, void *);
void
shell_for_each_layer(struct desktop_shell *shell,
shell_for_each_layer_func_t func,
void *data);