launcher-logind: Remove old VT switching code, move to SwitchTo/Activate
In the time since this code was written, logind has gained new APIs to handle VT switching automatically and activate sessions. Switch to that. Reviewed-by: Derek Foreman <derekf@osg.samsung.com>
This commit is contained in:
committed by
Bryce Harrington
parent
72dea06d79
commit
ae5df83f8e
+40
-179
@@ -27,17 +27,12 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/vt.h>
|
|
||||||
#include <linux/kd.h>
|
|
||||||
#include <linux/major.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/signalfd.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <systemd/sd-login.h>
|
#include <systemd/sd-login.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -48,10 +43,6 @@
|
|||||||
|
|
||||||
#define DRM_MAJOR 226
|
#define DRM_MAJOR 226
|
||||||
|
|
||||||
#ifndef KDSKBMUTE
|
|
||||||
#define KDSKBMUTE 0x4B51
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct launcher_logind {
|
struct launcher_logind {
|
||||||
struct weston_launcher base;
|
struct weston_launcher base;
|
||||||
struct weston_compositor *compositor;
|
struct weston_compositor *compositor;
|
||||||
@@ -61,8 +52,6 @@ struct launcher_logind {
|
|||||||
unsigned int vtnr;
|
unsigned int vtnr;
|
||||||
int vt;
|
int vt;
|
||||||
int kb_mode;
|
int kb_mode;
|
||||||
int sfd;
|
|
||||||
struct wl_event_source *sfd_source;
|
|
||||||
|
|
||||||
DBusConnection *dbus;
|
DBusConnection *dbus;
|
||||||
struct wl_event_source *dbus_ctx;
|
struct wl_event_source *dbus_ctx;
|
||||||
@@ -242,27 +231,37 @@ launcher_logind_close(struct weston_launcher *launcher, int fd)
|
|||||||
static void
|
static void
|
||||||
launcher_logind_restore(struct weston_launcher *launcher)
|
launcher_logind_restore(struct weston_launcher *launcher)
|
||||||
{
|
{
|
||||||
struct launcher_logind *wl = wl_container_of(launcher, wl, base);
|
|
||||||
struct vt_mode mode = { 0 };
|
|
||||||
|
|
||||||
ioctl(wl->vt, KDSETMODE, KD_TEXT);
|
|
||||||
ioctl(wl->vt, KDSKBMUTE, 0);
|
|
||||||
ioctl(wl->vt, KDSKBMODE, wl->kb_mode);
|
|
||||||
mode.mode = VT_AUTO;
|
|
||||||
ioctl(wl->vt, VT_SETMODE, &mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
launcher_logind_activate_vt(struct weston_launcher *launcher, int vt)
|
launcher_logind_activate_vt(struct weston_launcher *launcher, int vt)
|
||||||
{
|
{
|
||||||
struct launcher_logind *wl = wl_container_of(launcher, wl, base);
|
struct launcher_logind *wl = wl_container_of(launcher, wl, base);
|
||||||
|
DBusMessage *m;
|
||||||
|
bool b;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = ioctl(wl->vt, VT_ACTIVATE, vt);
|
m = dbus_message_new_method_call("org.freedesktop.login1",
|
||||||
if (r < 0)
|
"/org/freedesktop/login1/seat/self",
|
||||||
return -1;
|
"org.freedesktop.login1.Seat",
|
||||||
|
"SwitchTo");
|
||||||
|
if (!m)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
return 0;
|
b = dbus_message_append_args(m,
|
||||||
|
DBUS_TYPE_UINT32, &vt,
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
if (!b) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto err_unref;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_connection_send(wl->dbus, m, NULL);
|
||||||
|
r = 0;
|
||||||
|
|
||||||
|
err_unref:
|
||||||
|
dbus_message_unref(m);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -677,157 +676,6 @@ launcher_logind_release_control(struct launcher_logind *wl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
signal_event(int fd, uint32_t mask, void *data)
|
|
||||||
{
|
|
||||||
struct launcher_logind *wl = data;
|
|
||||||
struct signalfd_siginfo sig;
|
|
||||||
|
|
||||||
if (read(fd, &sig, sizeof sig) != sizeof sig) {
|
|
||||||
weston_log("logind: cannot read signalfd: %m\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sig.ssi_signo == (unsigned int)SIGRTMIN)
|
|
||||||
ioctl(wl->vt, VT_RELDISP, 1);
|
|
||||||
else if (sig.ssi_signo == (unsigned int)SIGRTMIN + 1)
|
|
||||||
ioctl(wl->vt, VT_RELDISP, VT_ACKACQ);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
launcher_logind_setup_vt(struct launcher_logind *wl)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
char buf[64];
|
|
||||||
struct vt_mode mode = { 0 };
|
|
||||||
int r;
|
|
||||||
sigset_t mask;
|
|
||||||
struct wl_event_loop *loop;
|
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "/dev/tty%u", wl->vtnr);
|
|
||||||
buf[sizeof(buf) - 1] = 0;
|
|
||||||
|
|
||||||
wl->vt = open(buf, O_RDWR|O_CLOEXEC|O_NONBLOCK);
|
|
||||||
|
|
||||||
if (wl->vt < 0) {
|
|
||||||
r = -errno;
|
|
||||||
weston_log("logind: cannot open VT %s: %m\n", buf);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fstat(wl->vt, &st) == -1 ||
|
|
||||||
major(st.st_rdev) != TTY_MAJOR || minor(st.st_rdev) <= 0 ||
|
|
||||||
minor(st.st_rdev) >= 64) {
|
|
||||||
r = -EINVAL;
|
|
||||||
weston_log("logind: TTY %s is no virtual terminal\n", buf);
|
|
||||||
goto err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*r = setsid();
|
|
||||||
if (r < 0 && errno != EPERM) {
|
|
||||||
r = -errno;
|
|
||||||
weston_log("logind: setsid() failed: %m\n");
|
|
||||||
goto err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = ioctl(wl->vt, TIOCSCTTY, 0);
|
|
||||||
if (r < 0)
|
|
||||||
weston_log("logind: VT %s already in use\n", buf);*/
|
|
||||||
|
|
||||||
if (ioctl(wl->vt, KDGKBMODE, &wl->kb_mode) < 0) {
|
|
||||||
weston_log("logind: cannot read keyboard mode on %s: %m\n",
|
|
||||||
buf);
|
|
||||||
wl->kb_mode = K_UNICODE;
|
|
||||||
} else if (wl->kb_mode == K_OFF) {
|
|
||||||
wl->kb_mode = K_UNICODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl(wl->vt, KDSKBMUTE, 1) < 0 &&
|
|
||||||
ioctl(wl->vt, KDSKBMODE, K_OFF) < 0) {
|
|
||||||
r = -errno;
|
|
||||||
weston_log("logind: cannot set K_OFF KB-mode on %s: %m\n",
|
|
||||||
buf);
|
|
||||||
goto err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl(wl->vt, KDSETMODE, KD_GRAPHICS) < 0) {
|
|
||||||
r = -errno;
|
|
||||||
weston_log("logind: cannot set KD_GRAPHICS mode on %s: %m\n",
|
|
||||||
buf);
|
|
||||||
goto err_kbmode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
|
|
||||||
* as VT-acquire signal. Note that SIGRT* must be tested on runtime, as
|
|
||||||
* their exact values are not known at compile-time. POSIX requires 32
|
|
||||||
* of them to be available, though.
|
|
||||||
*/
|
|
||||||
if (SIGRTMIN + 1 > SIGRTMAX) {
|
|
||||||
weston_log("logind: not enough RT signals available: %u-%u\n",
|
|
||||||
SIGRTMIN, SIGRTMAX);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
sigemptyset(&mask);
|
|
||||||
sigaddset(&mask, SIGRTMIN);
|
|
||||||
sigaddset(&mask, SIGRTMIN + 1);
|
|
||||||
sigprocmask(SIG_BLOCK, &mask, NULL);
|
|
||||||
|
|
||||||
wl->sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
|
|
||||||
if (wl->sfd < 0) {
|
|
||||||
r = -errno;
|
|
||||||
weston_log("logind: cannot create signalfd: %m\n");
|
|
||||||
goto err_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
loop = wl_display_get_event_loop(wl->compositor->wl_display);
|
|
||||||
wl->sfd_source = wl_event_loop_add_fd(loop, wl->sfd,
|
|
||||||
WL_EVENT_READABLE,
|
|
||||||
signal_event, wl);
|
|
||||||
if (!wl->sfd_source) {
|
|
||||||
r = -errno;
|
|
||||||
weston_log("logind: cannot create signalfd source: %m\n");
|
|
||||||
goto err_sfd;
|
|
||||||
}
|
|
||||||
|
|
||||||
mode.mode = VT_PROCESS;
|
|
||||||
mode.relsig = SIGRTMIN;
|
|
||||||
mode.acqsig = SIGRTMIN + 1;
|
|
||||||
if (ioctl(wl->vt, VT_SETMODE, &mode) < 0) {
|
|
||||||
r = -errno;
|
|
||||||
weston_log("logind: cannot take over VT: %m\n");
|
|
||||||
goto err_sfd_source;
|
|
||||||
}
|
|
||||||
|
|
||||||
weston_log("logind: using VT %s\n", buf);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_sfd_source:
|
|
||||||
wl_event_source_remove(wl->sfd_source);
|
|
||||||
err_sfd:
|
|
||||||
close(wl->sfd);
|
|
||||||
err_mode:
|
|
||||||
ioctl(wl->vt, KDSETMODE, KD_TEXT);
|
|
||||||
err_kbmode:
|
|
||||||
ioctl(wl->vt, KDSKBMUTE, 0);
|
|
||||||
ioctl(wl->vt, KDSKBMODE, wl->kb_mode);
|
|
||||||
err_close:
|
|
||||||
close(wl->vt);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
launcher_logind_destroy_vt(struct launcher_logind *wl)
|
|
||||||
{
|
|
||||||
launcher_logind_restore(&wl->base);
|
|
||||||
wl_event_source_remove(wl->sfd_source);
|
|
||||||
close(wl->sfd);
|
|
||||||
close(wl->vt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
weston_sd_session_get_vt(const char *sid, unsigned int *out)
|
weston_sd_session_get_vt(const char *sid, unsigned int *out)
|
||||||
{
|
{
|
||||||
@@ -851,6 +699,22 @@ weston_sd_session_get_vt(const char *sid, unsigned int *out)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
launcher_logind_activate(struct launcher_logind *wl)
|
||||||
|
{
|
||||||
|
DBusMessage *m;
|
||||||
|
|
||||||
|
m = dbus_message_new_method_call("org.freedesktop.login1",
|
||||||
|
wl->spath,
|
||||||
|
"org.freedesktop.login1.Session",
|
||||||
|
"Activate");
|
||||||
|
if (!m)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
dbus_connection_send(wl->dbus, m, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
launcher_logind_connect(struct weston_launcher **out, struct weston_compositor *compositor,
|
launcher_logind_connect(struct weston_launcher **out, struct weston_compositor *compositor,
|
||||||
int tty, const char *seat_id, bool sync_drm)
|
int tty, const char *seat_id, bool sync_drm)
|
||||||
@@ -923,16 +787,14 @@ launcher_logind_connect(struct weston_launcher **out, struct weston_compositor *
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err_dbus_cleanup;
|
goto err_dbus_cleanup;
|
||||||
|
|
||||||
r = launcher_logind_setup_vt(wl);
|
r = launcher_logind_activate(wl);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err_control;
|
goto err_dbus_cleanup;
|
||||||
|
|
||||||
weston_log("logind: session control granted\n");
|
weston_log("logind: session control granted\n");
|
||||||
* (struct launcher_logind **) out = wl;
|
* (struct launcher_logind **) out = wl;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_control:
|
|
||||||
launcher_logind_release_control(wl);
|
|
||||||
err_dbus_cleanup:
|
err_dbus_cleanup:
|
||||||
launcher_logind_destroy_dbus(wl);
|
launcher_logind_destroy_dbus(wl);
|
||||||
err_dbus:
|
err_dbus:
|
||||||
@@ -959,7 +821,6 @@ launcher_logind_destroy(struct weston_launcher *launcher)
|
|||||||
dbus_pending_call_unref(wl->pending_active);
|
dbus_pending_call_unref(wl->pending_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher_logind_destroy_vt(wl);
|
|
||||||
launcher_logind_release_control(wl);
|
launcher_logind_release_control(wl);
|
||||||
launcher_logind_destroy_dbus(wl);
|
launcher_logind_destroy_dbus(wl);
|
||||||
weston_dbus_close(wl->dbus, wl->dbus_ctx);
|
weston_dbus_close(wl->dbus, wl->dbus_ctx);
|
||||||
|
|||||||
Reference in New Issue
Block a user