window, desktop-shell: deal with output unplug on client side
authorXiong Zhang <xiong.y.zhang@intel.com>
Wed, 23 Oct 2013 05:58:35 +0000 (13:58 +0800)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 24 Oct 2013 05:36:37 +0000 (22:36 -0700)
when output is removed, weston-desktop-shell should destroy panel
and background surface on destroyed output.

Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com>
clients/desktop-shell.c
clients/window.c
clients/window.h

index d864a65..4e7a815 100644 (file)
@@ -95,6 +95,7 @@ struct background {
 
 struct output {
        struct wl_output *output;
+       uint32_t server_output_id;
        struct wl_list link;
 
        struct panel *panel;
@@ -1213,6 +1214,7 @@ create_output(struct desktop *desktop, uint32_t id)
 
        output->output =
                display_bind(desktop->display, id, &wl_output_interface, 2);
+       output->server_output_id = id;
 
        wl_output_add_listener(output->output, &output_listener, output);
 
@@ -1242,6 +1244,23 @@ global_handler(struct display *display, uint32_t id,
 }
 
 static void
+global_handler_remove(struct display *display, uint32_t id,
+              const char *interface, uint32_t version, void *data)
+{
+       struct desktop *desktop = data;
+       struct output *output;
+
+       if (!strcmp(interface, "wl_output")) {
+               wl_list_for_each(output, &desktop->outputs, link) {
+                       if (output->server_output_id == id) {
+                               output_destroy(output);
+                               break;
+                       }
+               }
+       }
+}
+
+static void
 panel_add_launchers(struct panel *panel, struct desktop *desktop)
 {
        struct weston_config_section *s;
@@ -1298,6 +1317,7 @@ int main(int argc, char *argv[])
 
        display_set_user_data(desktop.display, &desktop);
        display_set_global_handler(desktop.display, global_handler);
+       display_set_global_handler_remove(desktop.display, global_handler_remove);
 
        /* Create panel and background for outputs processed before the shell
         * global interface was processed */
index 17d16ed..331569a 100644 (file)
@@ -117,6 +117,7 @@ struct display {
 
        display_output_handler_t output_configure_handler;
        display_global_handler_t global_handler;
+       display_global_handler_t global_handler_remove;
 
        void *user_data;
 
@@ -339,6 +340,7 @@ struct input {
 struct output {
        struct display *display;
        struct wl_output *output;
+       uint32_t server_output_id;
        struct rectangle allocation;
        struct wl_list link;
        int transform;
@@ -4606,6 +4608,7 @@ display_add_output(struct display *d, uint32_t id)
        output->scale = 1;
        output->output =
                wl_registry_bind(d->registry, id, &wl_output_interface, 2);
+       output->server_output_id = id;
        wl_list_insert(d->output_list.prev, &output->link);
 
        wl_output_add_listener(output->output, &output_listener, output);
@@ -4622,6 +4625,19 @@ output_destroy(struct output *output)
        free(output);
 }
 
+static void
+display_destroy_output(struct display *d, uint32_t id)
+{
+       struct output *output;
+
+       wl_list_for_each(output, &d->output_list, link) {
+               if (output->server_output_id == id) {
+                       output_destroy(output);
+                       break;
+               }
+       }
+}
+
 void
 display_set_global_handler(struct display *display,
                           display_global_handler_t handler)
@@ -4639,6 +4655,15 @@ display_set_global_handler(struct display *display,
 }
 
 void
+display_set_global_handler_remove(struct display *display,
+                          display_global_handler_t remove_handler)
+{
+       display->global_handler_remove = remove_handler;
+       if (!remove_handler)
+               return;
+}
+
+void
 display_set_output_configure_handler(struct display *display,
                                     display_output_handler_t handler)
 {
@@ -4872,9 +4897,15 @@ registry_handle_global_remove(void *data, struct wl_registry *registry,
                if (global->name != name)
                        continue;
 
-               /* XXX: Should destroy bound globals, and call
-                * the counterpart of display::global_handler
-                */
+               if (strcmp(global->interface, "wl_output") == 0)
+                       display_destroy_output(d, name);
+
+               /* XXX: Should destroy remaining bound globals */
+
+               if (d->global_handler_remove)
+                       d->global_handler_remove(d, name, global->interface,
+                                       global->version, d->user_data);
+
                wl_list_remove(&global->link);
                free(global->interface);
                free(global);
index 461ec1e..ff7c87b 100644 (file)
@@ -104,6 +104,9 @@ typedef void (*display_global_handler_t)(struct display *display,
 void
 display_set_global_handler(struct display *display,
                           display_global_handler_t handler);
+void
+display_set_global_handler_remove(struct display *display,
+                          display_global_handler_t remove_handler);
 void *
 display_bind(struct display *display, uint32_t name,
             const struct wl_interface *interface, uint32_t version);