setup_output_destroy_handler() deal with output created at
drm backend initialize time.
handle_output_create() deal with output created by hot plug handler
output_destroy_handler is removed when output was unplugged or
shell is destroyed.

Signed-off-by: Xiong Zhang <[email protected]>
---
 src/shell.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/src/shell.c b/src/shell.c
index f033e8c..2a9c024 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -85,6 +85,13 @@ struct input_panel_surface {
        uint32_t panel;
 };
 
+struct shell_output {
+       struct desktop_shell  *shell;
+       struct weston_output  *output;
+       struct wl_listener    destroy_listener;
+       struct wl_list        link;
+};
+
 struct desktop_shell {
        struct weston_compositor *compositor;
 
@@ -163,6 +170,9 @@ struct desktop_shell {
 
        uint32_t binding_modifier;
        enum animation_type win_animation_type;
+
+       struct wl_listener output_create_listener;
+       struct wl_list output_destroy_listener_list;
 };
 
 enum shell_surface_type {
@@ -4461,11 +4471,65 @@ workspace_move_surface_down_binding(struct weston_seat 
*seat, uint32_t time,
 }
 
 static void
+handle_output_destroy(struct wl_listener *listener, void *data)
+{
+       struct shell_output *output_listener =
+               container_of(listener, struct shell_output, destroy_listener);
+
+       wl_list_remove(&output_listener->destroy_listener.link);
+       wl_list_remove(&output_listener->link);
+       free(output_listener);
+}
+
+static void
+create_shell_output(struct desktop_shell *shell,
+                                       struct weston_output *output)
+{
+       struct shell_output *output_listener;
+
+       output_listener = malloc(sizeof(*output_listener));
+       memset(output_listener, 0, sizeof(*output_listener));
+       output_listener->output = output;
+       output_listener->shell = shell;
+       output_listener->destroy_listener.notify = handle_output_destroy;
+       wl_signal_add(&output->destroy_signal,
+                               &output_listener->destroy_listener);
+       wl_list_insert(shell->output_destroy_listener_list.prev,
+                               &output_listener->link);
+}
+
+static void
+handle_output_create(struct wl_listener *listener, void *data)
+{
+       struct desktop_shell *shell =
+               container_of(listener, struct desktop_shell, 
output_create_listener);
+       struct weston_output *output = (struct weston_output *)data;
+
+       create_shell_output(shell, output);
+}
+
+static void
+setup_output_destroy_handler(struct weston_compositor *ec,
+                                                       struct desktop_shell 
*shell)
+{
+       struct weston_output *output;
+
+       wl_list_init(&shell->output_destroy_listener_list);
+       wl_list_for_each(output, &ec->output_list, link)
+               create_shell_output(shell, output);
+
+       shell->output_create_listener.notify = handle_output_create;
+       wl_signal_add(&ec->output_created_signal,
+                               &shell->output_create_listener);
+}
+
+static void
 shell_destroy(struct wl_listener *listener, void *data)
 {
        struct desktop_shell *shell =
                container_of(listener, struct desktop_shell, destroy_listener);
        struct workspace **ws;
+       struct shell_output *output_listener, *tmp;
 
        if (shell->child.client)
                wl_client_destroy(shell->child.client);
@@ -4475,6 +4539,15 @@ shell_destroy(struct wl_listener *listener, void *data)
        wl_list_remove(&shell->show_input_panel_listener.link);
        wl_list_remove(&shell->hide_input_panel_listener.link);
 
+       wl_list_for_each_safe(output_listener, tmp, 
&shell->output_destroy_listener_list,
+                       link) {
+               wl_list_remove(&output_listener->destroy_listener.link);
+               wl_list_remove(&output_listener->link);
+               free(output_listener);
+       }
+
+       wl_list_remove(&shell->output_create_listener.link);
+
        wl_array_for_each(ws, &shell->workspaces.array)
                workspace_destroy(*ws);
        wl_array_release(&shell->workspaces.array);
@@ -4647,6 +4720,8 @@ module_init(struct weston_compositor *ec,
 
        shell->child.deathstamp = weston_compositor_get_time();
 
+       setup_output_destroy_handler(ec, shell);
+
        loop = wl_display_get_event_loop(ec->wl_display);
        wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell);
 
-- 
1.8.3.2

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to