aboutsummaryrefslogtreecommitdiff
path: root/libseat/backend/noop.c
diff options
context:
space:
mode:
Diffstat (limited to 'libseat/backend/noop.c')
-rw-r--r--libseat/backend/noop.c107
1 files changed, 103 insertions, 4 deletions
diff --git a/libseat/backend/noop.c b/libseat/backend/noop.c
index 18f26c3..3b63616 100644
--- a/libseat/backend/noop.c
+++ b/libseat/backend/noop.c
@@ -5,11 +5,13 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
#include <sys/socket.h>
#include <unistd.h>
#include "backend.h"
#include "log.h"
+#include "terminal.h"
struct backend_noop {
struct libseat base;
@@ -18,10 +20,29 @@ struct backend_noop {
bool initial_setup;
int sockets[2];
+
};
+static int vt;
+bool should_reenable;
+
extern const struct seat_impl noop_impl;
+static int vt_toggle(int vt, bool enable) {
+ int ttyfd = terminal_open(vt);
+ if (ttyfd == -1) {
+ log_errorf("Could not open terminal to switch to VT %d: %s", vt, strerror(errno));
+ return -1;
+ }
+
+ terminal_set_process_switching(ttyfd, true);
+ terminal_set_keyboard(ttyfd, !enable);
+ terminal_set_graphics(ttyfd, enable);
+
+ close(ttyfd);
+ return 0;
+}
+
static struct backend_noop *backend_noop_from_libseat_backend(struct libseat *base) {
assert(base->impl == &noop_impl);
return (struct backend_noop *)base;
@@ -33,6 +54,35 @@ static void destroy(struct backend_noop *backend) {
free(backend);
}
+static void vt_acq(int signal) {
+ (void)signal;
+ int ttyfd = terminal_open(vt);
+ if (ttyfd == -1) {
+ log_errorf("Could not open terminal to switch to VT %d: %s", vt, strerror(errno));
+ return;
+ }
+
+ terminal_ack_acquire(ttyfd);
+
+ close(ttyfd);
+}
+
+static void vt_rel(int signal) {
+ (void)signal;
+ int ttyfd = terminal_open(vt);
+ if (ttyfd == -1) {
+ log_errorf("Could not open terminal to switch to VT %d: %s",
+ vt, strerror(errno));
+ return;
+ }
+
+ terminal_ack_release(ttyfd);
+
+ vt_toggle(vt, false);
+
+ close(ttyfd);
+}
+
static int close_seat(struct libseat *base) {
struct backend_noop *backend = backend_noop_from_libseat_backend(base);
destroy(backend);
@@ -69,10 +119,21 @@ static int close_device(struct libseat *base, int device_id) {
}
static int switch_session(struct libseat *base, int s) {
- (void)base;
- (void)s;
- log_errorf("No-op backend cannot switch to session %d", s);
- return -1;
+ struct backend_noop *backend = backend_noop_from_libseat_backend(base);
+
+ int ttyfd = terminal_open(vt);
+ if (ttyfd == -1) {
+ log_errorf("Could not open terminal to switch to VT %d: %s", vt, strerror(errno));
+ return -1;
+ }
+
+ backend->seat_listener->disable_seat(&backend->base, backend->seat_listener_data);
+
+ int ret = terminal_switch_vt(ttyfd, s);
+ should_reenable = false;
+
+ close(ttyfd);
+ return ret;
}
static int get_fd(struct libseat *base) {
@@ -80,6 +141,10 @@ static int get_fd(struct libseat *base) {
return backend->sockets[0];
}
+static void noop(int signal) {
+ log_debugf("Handling sig %d", signal);
+}
+
static int dispatch_background(struct libseat *base, int timeout) {
struct backend_noop *backend = backend_noop_from_libseat_backend(base);
@@ -88,6 +153,12 @@ static int dispatch_background(struct libseat *base, int timeout) {
backend->seat_listener->enable_seat(&backend->base, backend->seat_listener_data);
}
+ if (should_reenable) {
+ backend->seat_listener->enable_seat(&backend->base, backend->seat_listener_data);
+ vt_toggle(vt, true);
+ should_reenable = false;
+ }
+
struct pollfd fd = {
.fd = backend->sockets[0],
.events = POLLIN,
@@ -115,10 +186,38 @@ static struct libseat *noop_open_seat(const struct libseat_seat_listener *listen
return NULL;
}
+ int _vt;
+ const char *vt_env = getenv("LIBSEAT_VT");
+ if (!vt_env || (_vt = atoi(vt_env)) == 0) {
+ log_error("LIBSEAT_VT must be set to the current VT for the noop backend");
+ free(backend);
+ return NULL;
+ }
+
+ vt = _vt;
+
+ vt_toggle(vt, true);
+
+ {
+ struct sigaction sa;
+ sa.sa_handler = vt_rel;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGUSR1, &sa, NULL);
+ }
+ {
+ struct sigaction sa;
+ sa.sa_handler = vt_acq;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGUSR2, &sa, NULL);
+ }
+
backend->initial_setup = true;
backend->seat_listener = listener;
backend->seat_listener_data = data;
backend->base.impl = &noop_impl;
+ should_reenable = false;
return &backend->base;
}