diff --git a/libweston/compositor.c b/libweston/compositor.c index a9de4ac3..dbf61efe 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -4463,15 +4463,40 @@ weston_head_init(struct weston_head *head, const char *name) head->name = strdup(name); } +/** Send output heads changed signal + * + * \param output The output that changed. + * + * Notify that the enabled output gained and/or lost heads, or that the + * associated heads may have changed their connection status. This does not + * include cases where the output becomes enabled or disabled. The registered + * callbacks are called after the change has successfully happened. + * + * If connection status change causes the compositor to attach or detach a head + * to an enabled output, the registered callbacks may be called multiple times. + */ +static void +weston_output_emit_heads_changed(struct weston_output *output) +{ + wl_signal_emit(&output->compositor->output_heads_changed_signal, + output); +} + /** Idle task for emitting heads_changed_signal */ static void weston_compositor_call_heads_changed(void *data) { struct weston_compositor *compositor = data; + struct weston_head *head; compositor->heads_changed_source = NULL; wl_signal_emit(&compositor->heads_changed_signal, compositor); + + wl_list_for_each(head, &compositor->head_list, compositor_link) { + if (head->output && head->output->enabled) + weston_output_emit_heads_changed(head->output); + } } /** Schedule a call on idle to heads_changed callback @@ -4678,6 +4703,8 @@ weston_output_attach_head(struct weston_output *output, weston_log("Output '%s' updated to have head(s) %s\n", output->name, head_names); free(head_names); + + weston_output_emit_heads_changed(output); } return 0; @@ -4723,6 +4750,8 @@ weston_head_detach(struct weston_head *head) weston_log("Output '%s' updated to have head(s) %s\n", output->name, head_names); free(head_names); + + weston_output_emit_heads_changed(output); } } } @@ -6255,6 +6284,7 @@ weston_compositor_create(struct wl_display *display, void *user_data) wl_signal_init(&ec->output_moved_signal); wl_signal_init(&ec->output_resized_signal); wl_signal_init(&ec->heads_changed_signal); + wl_signal_init(&ec->output_heads_changed_signal); wl_signal_init(&ec->session_signal); ec->session_active = 1; diff --git a/libweston/compositor.h b/libweston/compositor.h index f3137dea..ca234075 100644 --- a/libweston/compositor.h +++ b/libweston/compositor.h @@ -963,6 +963,11 @@ struct weston_compositor { struct wl_signal output_moved_signal; struct wl_signal output_resized_signal; /* callback argument: resized output */ + /* Signal for output changes triggered by configuration from frontend + * or head state changes from backend. + */ + struct wl_signal output_heads_changed_signal; /* arg: weston_output */ + struct wl_signal session_signal; int session_active; @@ -1031,6 +1036,9 @@ struct weston_compositor { /* Whether to let the compositor run without any input device. */ bool require_input; + /* Signal for a backend to inform a frontend about possible changes + * in head status. + */ struct wl_signal heads_changed_signal; struct wl_event_source *heads_changed_source; }; diff --git a/libweston/libinput-seat.c b/libweston/libinput-seat.c index 3cece3a1..ac1e8e99 100644 --- a/libweston/libinput-seat.c +++ b/libweston/libinput-seat.c @@ -68,9 +68,16 @@ output_find_by_head_name(struct weston_compositor *compositor, if (!head_name) return NULL; - /* only enabled outputs */ + /* Only enabled outputs with connected heads. + * This means force-enabled outputs but with disconnected heads + * will be ignored; if the touchscreen doesn't have a video signal, + * touching it is meaningless. + */ wl_list_for_each(output, &compositor->output_list, link) { wl_list_for_each(head, &output->head_list, output_link) { + if (!weston_head_is_connected(head)) + continue; + if (strcmp(head_name, head->name) == 0) return output; } @@ -377,12 +384,9 @@ udev_seat_led_update(struct weston_seat *seat_base, enum weston_led leds) } static void -notify_output_create(struct wl_listener *listener, void *data) +udev_seat_output_changed(struct udev_seat *seat, struct weston_output *output) { - struct udev_seat *seat = container_of(listener, struct udev_seat, - output_create_listener); struct evdev_device *device; - struct weston_output *output = data; struct weston_output *found; wl_list_for_each(device, &seat->devices_list, link) { @@ -406,6 +410,26 @@ notify_output_create(struct wl_listener *listener, void *data) } } +static void +notify_output_create(struct wl_listener *listener, void *data) +{ + struct udev_seat *seat = container_of(listener, struct udev_seat, + output_create_listener); + struct weston_output *output = data; + + udev_seat_output_changed(seat, output); +} + +static void +notify_output_heads_changed(struct wl_listener *listener, void *data) +{ + struct udev_seat *seat = container_of(listener, struct udev_seat, + output_heads_listener); + struct weston_output *output = data; + + udev_seat_output_changed(seat, output); +} + static struct udev_seat * udev_seat_create(struct udev_input *input, const char *seat_name) { @@ -423,6 +447,10 @@ udev_seat_create(struct udev_input *input, const char *seat_name) wl_signal_add(&c->output_created_signal, &seat->output_create_listener); + seat->output_heads_listener.notify = notify_output_heads_changed; + wl_signal_add(&c->output_heads_changed_signal, + &seat->output_heads_listener); + wl_list_init(&seat->devices_list); return seat; @@ -440,6 +468,7 @@ udev_seat_destroy(struct udev_seat *seat) udev_seat_remove_devices(seat); weston_seat_release(&seat->base); wl_list_remove(&seat->output_create_listener.link); + wl_list_remove(&seat->output_heads_listener.link); free(seat); } diff --git a/libweston/libinput-seat.h b/libweston/libinput-seat.h index 65c9b64b..8c6a5bf7 100644 --- a/libweston/libinput-seat.h +++ b/libweston/libinput-seat.h @@ -39,6 +39,7 @@ struct udev_seat { struct weston_seat base; struct wl_list devices_list; struct wl_listener output_create_listener; + struct wl_listener output_heads_listener; }; typedef void (*udev_configure_device_t)(struct weston_compositor *compositor,