[PATCH v2 5/6] window, desktop-shell: deal with output unplug on client side

Kristian Høgsberg hoegsberg at gmail.com
Thu Oct 24 07:36:24 CEST 2013


On Wed, Oct 23, 2013 at 01:58:35PM +0800, Xiong Zhang wrote:
> when output is removed, weston-desktop-shell should destroy panel
> and background surface on destroyed output.
> 
> Signed-off-by: Xiong Zhang <xiong.y.zhang at intel.com>
> ---
>  clients/desktop-shell.c | 20 ++++++++++++++++++++
>  clients/window.c        | 32 ++++++++++++++++++++++++++++++++
>  clients/window.h        |  3 +++
>  3 files changed, 55 insertions(+)

This one looks good, applied.

Kristian

> diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
> index 599c0a5..1a034da 100644
> --- a/clients/desktop-shell.c
> +++ b/clients/desktop-shell.c
> @@ -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 */
> diff --git a/clients/window.c b/clients/window.c
> index 5b20da5..b35be3c 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -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;
> @@ -4836,6 +4838,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);
> @@ -4852,6 +4855,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)
> @@ -4869,6 +4885,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)
>  {
> @@ -5102,9 +5127,16 @@ registry_handle_global_remove(void *data, struct wl_registry *registry,
>  		if (global->name != name)
>  			continue;
>  
> +		if (strcmp(global->interface, "wl_output") == 0)
> +			display_destroy_output(d, name);
> +
>  		/* XXX: Should destroy bound globals, and call
>  		 * the counterpart of display::global_handler
>  		 */

I updated this comment to reflect that we now have global remove
handler, it's now just:

                /* 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);
> diff --git a/clients/window.h b/clients/window.h
> index 4427ab5..96ecd23 100644
> --- a/clients/window.h
> +++ b/clients/window.h
> @@ -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);
> -- 
> 1.8.3.2
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list