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
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;
weston_log("Output '%s' updated to have head(s) %s\n",
output->name, head_names);
free(head_names);
+
+ weston_output_emit_heads_changed(output);
}
}
}
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;
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;
/* 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;
};
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;
}
}
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) {
}
}
+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)
{
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;
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);
}
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,