summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenny Levinsen <kl@kl.wtf>2020-10-21 21:36:57 +0200
committerPekka Paalanen <pq@iki.fi>2021-04-14 09:22:17 +0000
commit6c4a993a999048a2054ec97e71d32839b312c642 (patch)
tree7e13addf85b22e5d9a9b6cd8ad1a5521774b94fd
parent669d5737fa2cb26dbb197cfb4300fd8050068acb (diff)
downloadweston-6c4a993a999048a2054ec97e71d32839b312c642.tar.gz
libweston/launcher: libseat backend
This adds support for libseat as a seat backend. libseat provides seatd, (e)logind and direct seat backends as compile-time and runtime options. The backend is currently disabled by default. It can be enabled through the launcher-libseat option. Signed-off-by: Kenny Levinsen <kl@kl.wtf>
-rw-r--r--libweston/launcher-impl.h1
-rw-r--r--libweston/launcher-libseat.c255
-rw-r--r--libweston/launcher-util.c3
-rw-r--r--libweston/meson.build10
-rw-r--r--meson_options.txt7
5 files changed, 276 insertions, 0 deletions
diff --git a/libweston/launcher-impl.h b/libweston/launcher-impl.h
index a04647ef..6bcbbc54 100644
--- a/libweston/launcher-impl.h
+++ b/libweston/launcher-impl.h
@@ -45,6 +45,7 @@ struct weston_launcher {
const struct launcher_interface *iface;
};
+extern const struct launcher_interface launcher_libseat_iface;
extern const struct launcher_interface launcher_logind_iface;
extern const struct launcher_interface launcher_weston_launch_iface;
extern const struct launcher_interface launcher_direct_iface;
diff --git a/libweston/launcher-libseat.c b/libweston/launcher-libseat.c
new file mode 100644
index 00000000..6aa8ad0f
--- /dev/null
+++ b/libweston/launcher-libseat.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright © 2020 Kenny Levinsen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <libseat.h>
+
+#include <libweston/libweston.h>
+#include "backend.h"
+#include "dbus.h"
+#include "launcher-impl.h"
+
+struct launcher_libseat_device {
+ struct wl_list link;
+ int fd;
+ int device_id;
+ dev_t fsdev;
+};
+
+struct launcher_libseat {
+ struct weston_launcher base;
+ struct weston_compositor *compositor;
+ struct libseat *seat;
+
+ struct wl_event_source *seat_ctx;
+ struct wl_list devices;
+};
+
+static struct launcher_libseat_device *
+find_device_by_fd(struct launcher_libseat *wl, int fd)
+{
+ struct launcher_libseat_device *dev;
+ wl_list_for_each(dev, &wl->devices, link) {
+ if (dev->fd == fd) {
+ return dev;
+ }
+ }
+ return NULL;
+}
+
+static void
+handle_enable_seat(struct libseat *seat, void *data)
+{
+ struct launcher_libseat *wl = data;
+ if (wl->compositor->session_active)
+ return;
+
+ wl->compositor->session_active = true;
+
+ wl_signal_emit(&wl->compositor->session_signal,
+ wl->compositor);
+}
+
+static void
+handle_disable_seat(struct libseat *seat, void *data)
+{
+ struct launcher_libseat *wl = data;
+ if (!wl->compositor->session_active)
+ return;
+
+ wl->compositor->session_active = false;
+
+ wl_signal_emit(&wl->compositor->session_signal,
+ wl->compositor);
+ libseat_disable_seat(wl->seat);
+}
+
+static struct libseat_seat_listener seat_listener = {
+ .enable_seat = handle_enable_seat,
+ .disable_seat = handle_disable_seat,
+};
+
+static int
+seat_open_device(struct weston_launcher *launcher, const char *path, int flags)
+{
+ struct launcher_libseat *wl = wl_container_of(launcher, wl, base);
+ struct launcher_libseat_device *dev;
+ struct stat st;
+
+ dev = zalloc(sizeof(struct launcher_libseat_device));
+ if (dev == NULL) {
+ goto err_alloc;
+ }
+
+ dev->device_id = libseat_open_device(wl->seat, path, &dev->fd);
+ if (dev->device_id == -1) {
+ goto err_open;
+ }
+
+ if (fstat(dev->fd, &st) == -1) {
+ goto err_fd;
+ }
+ dev->fsdev = st.st_rdev;
+
+ wl_list_insert(&wl->devices, &dev->link);
+ return dev->fd;
+
+err_fd:
+ libseat_close_device(wl->seat, dev->device_id);
+ close(dev->fd);
+err_open:
+ free(dev);
+err_alloc:
+ return -1;
+}
+
+static void
+seat_close_device(struct weston_launcher *launcher, int fd)
+{
+ struct launcher_libseat *wl = wl_container_of(launcher, wl, base);
+ struct launcher_libseat_device *dev;
+
+ dev = find_device_by_fd(wl, fd);
+ if (dev == NULL) {
+ weston_log("libseat: No device with fd %d found\n", fd);
+ close(fd);
+ return;
+ }
+
+ if (libseat_close_device(wl->seat, dev->device_id) == -1) {
+ weston_log("libseat: Could not close device %d",
+ dev->device_id);
+ }
+
+ wl_list_remove(&dev->link);
+ free(dev);
+ close(fd);
+}
+
+static int
+seat_switch_session(struct weston_launcher *launcher, int vt)
+{
+ struct launcher_libseat *wl = wl_container_of(launcher, wl, base);
+ return libseat_switch_session(wl->seat, vt);
+}
+
+static int
+libseat_event(int fd, uint32_t mask, void *data)
+{
+ struct libseat *seat = data;
+ if (libseat_dispatch(seat, 0) == -1) {
+ weston_log("libseat: dispatch failed: %s\n", strerror(errno));
+ exit(-1);
+ }
+ return 1;
+}
+
+static int
+seat_open(struct weston_launcher **out, struct weston_compositor *compositor,
+ int tty, const char *seat_id, bool sync_drm)
+{
+ struct launcher_libseat *wl;
+ struct wl_event_loop *event_loop;
+
+ wl = zalloc(sizeof(*wl));
+ if (wl == NULL) {
+ goto err_out;
+ }
+
+ wl->base.iface = &launcher_libseat_iface;
+ wl->compositor = compositor;
+ wl_list_init(&wl->devices);
+
+ wl->seat = libseat_open_seat(&seat_listener, wl);
+ if (wl->seat == NULL) {
+ weston_log("libseat: could not open seat\n");
+ goto err_seat;
+ }
+
+ event_loop = wl_display_get_event_loop(compositor->wl_display);
+ wl->seat_ctx = wl_event_loop_add_fd(event_loop,
+ libseat_get_fd(wl->seat), WL_EVENT_READABLE,
+ libseat_event, wl->seat);
+ if (wl->seat_ctx == NULL) {
+ weston_log("libseat: could not register connection to event loop\n");
+ goto err_session;
+ }
+ if (libseat_dispatch(wl->seat, 0) == -1) {
+ weston_log("libseat: dispatch failed\n");
+ goto err_session;
+ }
+
+ weston_log("libseat: session control granted\n");
+ *out = &wl->base;
+ return 0;
+
+err_session:
+ libseat_close_seat(wl->seat);
+err_seat:
+ free(wl);
+err_out:
+ return -1;
+}
+
+static void
+seat_close(struct weston_launcher *launcher)
+{
+ struct launcher_libseat *wl = wl_container_of(launcher, wl, base);
+
+ if (wl->seat != NULL) {
+ libseat_close_seat(wl->seat);
+ }
+ wl_event_source_remove(wl->seat_ctx);
+ free(wl);
+}
+
+static int
+seat_get_vt(struct weston_launcher *launcher)
+{
+ return -ENOSYS;
+}
+
+const struct launcher_interface launcher_libseat_iface = {
+ .name = "libseat",
+ .connect = seat_open,
+ .destroy = seat_close,
+ .open = seat_open_device,
+ .close = seat_close_device,
+ .activate_vt = seat_switch_session,
+ .get_vt = seat_get_vt,
+};
diff --git a/libweston/launcher-util.c b/libweston/launcher-util.c
index 2e472aed..058b6ac0 100644
--- a/libweston/launcher-util.c
+++ b/libweston/launcher-util.c
@@ -36,6 +36,9 @@
#include <linux/input.h>
static const struct launcher_interface *ifaces[] = {
+#ifdef HAVE_LIBSEAT
+ &launcher_libseat_iface,
+#endif
#ifdef HAVE_SYSTEMD_LOGIN
&launcher_logind_iface,
#endif
diff --git a/libweston/meson.build b/libweston/meson.build
index 08d23ecd..ee1d128c 100644
--- a/libweston/meson.build
+++ b/libweston/meson.build
@@ -180,6 +180,16 @@ if get_option('launcher-logind')
systemd_dep,
]
endif
+if get_option('launcher-libseat')
+ libseat_dep = dependency('libseat', version: '>= 0.4')
+ config_h.set('HAVE_LIBSEAT', '1')
+ srcs_session_helper += [
+ 'launcher-libseat.c',
+ ]
+ deps_session_helper += [
+ libseat_dep,
+ ]
+endif
lib_session_helper = static_library(
'session-helper',
diff --git a/meson_options.txt b/meson_options.txt
index ea225a90..da4ccaab 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -159,6 +159,13 @@ option(
)
option(
+ 'launcher-libseat',
+ type: 'boolean',
+ value: false,
+ description: 'Compositor: support libseat'
+)
+
+option(
'image-jpeg',
type: 'boolean',
value: true,