mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-29 05:40:12 -04:00
backend/session: Remove session_impl
libseat provides all session functionality, so there is no longer need for a session backend abstraction. The libseat device ID, seat handle and event loop handle are moved to the main wlr_session and wlr_device structs.
This commit is contained in:
parent
3f87c2caea
commit
7f09085461
7 changed files with 140 additions and 284 deletions
|
|
@ -1,8 +1,10 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <assert.h>
|
||||
#include <libudev.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -10,7 +12,6 @@
|
|||
#include <time.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/backend/session/interface.h>
|
||||
#include <wlr/config.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <xf86drm.h>
|
||||
|
|
@ -18,15 +19,113 @@
|
|||
#include "backend/session/session.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
#include <libseat.h>
|
||||
|
||||
#define WAIT_GPU_TIMEOUT 10000 // ms
|
||||
|
||||
extern const struct session_impl session_libseat;
|
||||
static void handle_enable_seat(struct libseat *seat, void *data) {
|
||||
struct wlr_session *session = data;
|
||||
session->active = true;
|
||||
wlr_signal_emit_safe(&session->events.active, NULL);
|
||||
}
|
||||
|
||||
static const struct session_impl *const impls[] = {
|
||||
&session_libseat,
|
||||
NULL,
|
||||
static void handle_disable_seat(struct libseat *seat, void *data) {
|
||||
struct wlr_session *session = data;
|
||||
session->active = false;
|
||||
wlr_signal_emit_safe(&session->events.active, NULL);
|
||||
libseat_disable_seat(session->seat_handle);
|
||||
}
|
||||
|
||||
static int libseat_event(int fd, uint32_t mask, void *data) {
|
||||
struct wlr_session *session = data;
|
||||
if (libseat_dispatch(session->seat_handle, 0) == -1) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to dispatch libseat");
|
||||
wl_display_terminate(session->display);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct libseat_seat_listener seat_listener = {
|
||||
.enable_seat = handle_enable_seat,
|
||||
.disable_seat = handle_disable_seat,
|
||||
};
|
||||
|
||||
static enum wlr_log_importance libseat_log_level_to_wlr(
|
||||
enum libseat_log_level level) {
|
||||
switch (level) {
|
||||
case LIBSEAT_LOG_LEVEL_ERROR:
|
||||
return WLR_ERROR;
|
||||
case LIBSEAT_LOG_LEVEL_INFO:
|
||||
return WLR_INFO;
|
||||
default:
|
||||
return WLR_DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
static void log_libseat(enum libseat_log_level level,
|
||||
const char *fmt, va_list args) {
|
||||
enum wlr_log_importance importance = libseat_log_level_to_wlr(level);
|
||||
|
||||
static char wlr_fmt[1024];
|
||||
snprintf(wlr_fmt, sizeof(wlr_fmt), "[libseat] %s", fmt);
|
||||
|
||||
_wlr_vlog(importance, wlr_fmt, args);
|
||||
}
|
||||
|
||||
static int libseat_session_init(struct wlr_session *session, struct wl_display *disp) {
|
||||
libseat_set_log_handler(log_libseat);
|
||||
libseat_set_log_level(LIBSEAT_LOG_LEVEL_INFO);
|
||||
|
||||
// libseat will take care of updating the logind state if necessary
|
||||
setenv("XDG_SESSION_TYPE", "wayland", 1);
|
||||
|
||||
session->seat_handle = libseat_open_seat(&seat_listener, session);
|
||||
if (session->seat_handle == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "Unable to create seat");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *seat_name = libseat_seat_name(session->seat_handle);
|
||||
if (seat_name == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "Unable to get seat info");
|
||||
goto error;
|
||||
}
|
||||
snprintf(session->seat, sizeof(session->seat), "%s", seat_name);
|
||||
|
||||
struct wl_event_loop *event_loop = wl_display_get_event_loop(disp);
|
||||
session->libseat_event = wl_event_loop_add_fd(event_loop, libseat_get_fd(session->seat_handle),
|
||||
WL_EVENT_READABLE, libseat_event, session);
|
||||
if (session->libseat_event == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to create libseat event source");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// We may have received enable_seat immediately after the open_seat result,
|
||||
// so, dispatch once without timeout to speed up activation.
|
||||
if (libseat_dispatch(session->seat_handle, 0) == -1) {
|
||||
wlr_log_errno(WLR_ERROR, "libseat dispatch failed");
|
||||
goto error_dispatch;
|
||||
}
|
||||
|
||||
wlr_log(WLR_INFO, "Successfully loaded libseat session");
|
||||
return 0;
|
||||
|
||||
error_dispatch:
|
||||
wl_event_source_remove(session->libseat_event);
|
||||
session->libseat_event = NULL;
|
||||
error:
|
||||
libseat_close_seat(session->seat_handle);
|
||||
session->seat_handle = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void libseat_session_finish(struct wlr_session *session) {
|
||||
libseat_close_seat(session->seat_handle);
|
||||
wl_event_source_remove(session->libseat_event);
|
||||
session->seat_handle = NULL;
|
||||
session->libseat_event = NULL;
|
||||
}
|
||||
|
||||
static bool is_drm_card(const char *sysname) {
|
||||
const char prefix[] = "card";
|
||||
if (strncmp(sysname, prefix, strlen(prefix)) != 0) {
|
||||
|
|
@ -94,34 +193,21 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
|||
wlr_session_destroy(session);
|
||||
}
|
||||
|
||||
void session_init(struct wlr_session *session) {
|
||||
struct wlr_session *wlr_session_create(struct wl_display *disp) {
|
||||
struct wlr_session *session = calloc(1, sizeof(*session));
|
||||
if (!session) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_signal_init(&session->events.active);
|
||||
wl_signal_init(&session->events.add_drm_card);
|
||||
wl_signal_init(&session->events.destroy);
|
||||
wl_list_init(&session->devices);
|
||||
}
|
||||
|
||||
struct wlr_session *wlr_session_create(struct wl_display *disp) {
|
||||
struct wlr_session *session = NULL;
|
||||
|
||||
const char *env_wlr_session = getenv("WLR_SESSION");
|
||||
if (env_wlr_session) {
|
||||
if (strcmp(env_wlr_session, "libseat") == 0) {
|
||||
session = session_libseat.create(disp);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Unsupported WLR_SESSION: %s",
|
||||
env_wlr_session);
|
||||
}
|
||||
} else {
|
||||
const struct session_impl *const *iter;
|
||||
for (iter = impls; !session && *iter; ++iter) {
|
||||
session = (*iter)->create(disp);
|
||||
}
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
if (libseat_session_init(session, disp) == -1) {
|
||||
wlr_log(WLR_ERROR, "Failed to load session backend");
|
||||
return NULL;
|
||||
goto error_open;
|
||||
}
|
||||
|
||||
session->udev = udev_new();
|
||||
|
|
@ -161,7 +247,9 @@ error_mon:
|
|||
error_udev:
|
||||
udev_unref(session->udev);
|
||||
error_session:
|
||||
session->impl->destroy(session);
|
||||
libseat_session_finish(session);
|
||||
error_open:
|
||||
free(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -177,13 +265,16 @@ void wlr_session_destroy(struct wlr_session *session) {
|
|||
udev_monitor_unref(session->mon);
|
||||
udev_unref(session->udev);
|
||||
|
||||
session->impl->destroy(session);
|
||||
libseat_session_finish(session);
|
||||
free(session);
|
||||
}
|
||||
|
||||
struct wlr_device *wlr_session_open_file(struct wlr_session *session,
|
||||
const char *path) {
|
||||
int fd = session->impl->open(session, path);
|
||||
if (fd < 0) {
|
||||
int fd;
|
||||
int device_id = libseat_open_device(session->seat_handle, path, &fd);
|
||||
if (device_id == -1) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to open device: '%s'", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -201,12 +292,14 @@ struct wlr_device *wlr_session_open_file(struct wlr_session *session,
|
|||
|
||||
dev->fd = fd;
|
||||
dev->dev = st.st_rdev;
|
||||
dev->device_id = device_id;
|
||||
wl_signal_init(&dev->events.change);
|
||||
wl_list_insert(&session->devices, &dev->link);
|
||||
|
||||
return dev;
|
||||
|
||||
error:
|
||||
libseat_close_device(session->seat_handle, device_id);
|
||||
free(dev);
|
||||
close(fd);
|
||||
return NULL;
|
||||
|
|
@ -214,7 +307,9 @@ error:
|
|||
|
||||
void wlr_session_close_file(struct wlr_session *session,
|
||||
struct wlr_device *dev) {
|
||||
session->impl->close(session, dev->fd);
|
||||
if (libseat_close_device(session->seat_handle, dev->device_id) == -1) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to close device %d", dev->device_id);
|
||||
}
|
||||
wl_list_remove(&dev->link);
|
||||
free(dev);
|
||||
}
|
||||
|
|
@ -223,8 +318,7 @@ bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) {
|
|||
if (!session) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return session->impl->change_vt(session, vt);
|
||||
return libseat_switch_session(session->seat_handle, vt) == 0;
|
||||
}
|
||||
|
||||
/* Tests if 'path' is KMS compatible by trying to open it.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue