Multiseat fixes

This commit is contained in:
Scott Anderson 2018-06-14 20:46:16 +12:00
parent 9a1f0e2d5f
commit 47985d2dc5
5 changed files with 50 additions and 29 deletions

View file

@ -55,8 +55,8 @@ static bool backend_start(struct wlr_backend *_backend) {
return false; return false;
} }
// TODO: Let user customize seat used if (libinput_udev_assign_seat(backend->libinput_context,
if (libinput_udev_assign_seat(backend->libinput_context, "seat0") != 0) { backend->session->seat) != 0) {
wlr_log(L_ERROR, "Failed to assign libinput seat"); wlr_log(L_ERROR, "Failed to assign libinput seat");
return false; return false;
} }

View file

@ -1,5 +1,6 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/kd.h> #include <linux/kd.h>
#include <linux/major.h> #include <linux/major.h>
@ -76,30 +77,39 @@ static void direct_session_close(struct wlr_session *base, int fd) {
static bool direct_change_vt(struct wlr_session *base, unsigned vt) { static bool direct_change_vt(struct wlr_session *base, unsigned vt) {
struct direct_session *session = wl_container_of(base, session, base); struct direct_session *session = wl_container_of(base, session, base);
// Only seat0 has VTs associated with it
if (strcmp(session->base.seat, "seat0") == 0) {
return true;
}
return ioctl(session->tty_fd, VT_ACTIVATE, (int)vt) == 0; return ioctl(session->tty_fd, VT_ACTIVATE, (int)vt) == 0;
} }
static void direct_session_destroy(struct wlr_session *base) { static void direct_session_destroy(struct wlr_session *base) {
struct direct_session *session = wl_container_of(base, session, base); struct direct_session *session = wl_container_of(base, session, base);
struct vt_mode mode = {
.mode = VT_AUTO,
};
errno = 0; if (strcmp(session->base.seat, "seat0") == 0) {
struct vt_mode mode = {
.mode = VT_AUTO,
};
errno = 0;
ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode); ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode);
ioctl(session->tty_fd, KDSETMODE, KD_TEXT); ioctl(session->tty_fd, KDSETMODE, KD_TEXT);
ioctl(session->tty_fd, VT_SETMODE, &mode); ioctl(session->tty_fd, VT_SETMODE, &mode);
if (errno) { if (errno) {
wlr_log(L_ERROR, "Failed to restore tty"); wlr_log(L_ERROR, "Failed to restore tty");
}
wl_event_source_remove(session->vt_source);
close(session->tty_fd);
} }
direct_ipc_finish(session->sock, session->child); direct_ipc_finish(session->sock, session->child);
close(session->sock); close(session->sock);
wl_event_source_remove(session->vt_source);
close(session->tty_fd);
free(session); free(session);
} }
@ -138,19 +148,19 @@ static int vt_handler(int signo, void *data) {
} }
static bool setup_tty(struct direct_session *session, struct wl_display *display) { static bool setup_tty(struct direct_session *session, struct wl_display *display) {
int fd = dup(STDIN_FILENO); int fd = open("/dev/tty", O_RDWR);
if (fd == -1) { if (fd == -1) {
wlr_log_errno(L_ERROR, "Cannot open tty"); wlr_log_errno(L_ERROR, "Cannot open /dev/tty");
return false; return false;
} }
struct stat st; struct vt_stat vt_stat;
if (fstat(fd, &st) == -1 || major(st.st_rdev) != TTY_MAJOR || minor(st.st_rdev) == 0) { if (ioctl(fd, VT_GETSTATE, &vt_stat)) {
wlr_log(L_ERROR, "Not running from a virtual terminal"); wlr_log_errno(L_ERROR, "Could not get current tty number");
goto error; goto error;
} }
int tty = minor(st.st_rdev); int tty = vt_stat.v_active;
int ret, kd_mode, old_kbmode; int ret, kd_mode, old_kbmode;
ret = ioctl(fd, KDGETMODE, &kd_mode); ret = ioctl(fd, KDGETMODE, &kd_mode);
@ -224,20 +234,24 @@ static struct wlr_session *direct_session_create(struct wl_display *disp) {
goto error_session; goto error_session;
} }
if (!setup_tty(session, disp)) {
goto error_ipc;
}
// XXX: Is it okay to trust the environment like this?
const char *seat = getenv("XDG_SEAT"); const char *seat = getenv("XDG_SEAT");
if (!seat) { if (!seat) {
seat = "seat0"; seat = "seat0";
} }
wlr_log(L_INFO, "Successfully loaded direct session"); if (strcmp(seat, "seat0") == 0) {
if (!setup_tty(session, disp)) {
goto error_ipc;
}
} else {
session->base.vtnr = 0;
session->tty_fd = -1;
}
snprintf(session->base.seat, sizeof(session->base.seat), "%s", seat); snprintf(session->base.seat, sizeof(session->base.seat), "%s", seat);
session->base.impl = &session_direct; session->base.impl = &session_direct;
wlr_log(L_INFO, "Successfully loaded direct session");
return &session->base; return &session->base;
error_ipc: error_ipc:

View file

@ -109,6 +109,11 @@ static void logind_release_device(struct wlr_session *base, int fd) {
static bool logind_change_vt(struct wlr_session *base, unsigned vt) { static bool logind_change_vt(struct wlr_session *base, unsigned vt) {
struct logind_session *session = wl_container_of(base, session, base); struct logind_session *session = wl_container_of(base, session, base);
// Only seat0 has VTs associated with it
if (strcmp(session->base.seat, "seat0") != 0) {
return true;
}
int ret; int ret;
sd_bus_message *msg = NULL; sd_bus_message *msg = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_error error = SD_BUS_ERROR_NULL;

View file

@ -19,9 +19,7 @@ extern const struct session_impl session_logind;
extern const struct session_impl session_direct; extern const struct session_impl session_direct;
static const struct session_impl *impls[] = { static const struct session_impl *impls[] = {
#ifdef WLR_HAS_SYSTEMD #if defined(WLR_HAS_SYSTEMD) || defined(WLR_HAS_ELOGIND)
&session_logind,
#elif defined(WLR_HAS_ELOGIND)
&session_logind, &session_logind,
#endif #endif
&session_direct, &session_direct,

View file

@ -25,8 +25,12 @@ struct wlr_session {
struct wl_signal session_signal; struct wl_signal session_signal;
bool active; bool active;
/*
* 0 if virtual terminals are not supported
* i.e. seat != "seat0"
*/
unsigned vtnr; unsigned vtnr;
char seat[8]; char seat[256];
struct udev *udev; struct udev *udev;
struct udev_monitor *mon; struct udev_monitor *mon;