aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fbcon.c10
-rw-r--r--kbd.c175
-rw-r--r--kbd.h7
-rw-r--r--logind.c196
-rw-r--r--logind.h12
-rw-r--r--meson.build6
6 files changed, 222 insertions, 184 deletions
diff --git a/fbcon.c b/fbcon.c
index 94b060d..2f2f99f 100644
--- a/fbcon.c
+++ b/fbcon.c
@@ -33,6 +33,7 @@
#include "drmtools.h"
#include "vt.h"
#include "kbd.h"
+#include "logind.h"
/* ---------------------------------------------------------------------- */
@@ -519,6 +520,7 @@ int main(int argc, char *argv[])
const char *drm_node = NULL;
const char *fb_node = NULL;
const char *xdg_seat, *xdg_session_id;
+ bool logind = false;
int input;
pid_t child;
@@ -530,7 +532,8 @@ int main(int argc, char *argv[])
if (xdg_seat)
seat_name = xdg_seat;
if (xdg_seat && xdg_session_id)
- logind_init();
+ if (logind_init() == 0)
+ logind = true;
/* look for gfx devices */
udev = udev_new();
@@ -594,7 +597,10 @@ int main(int argc, char *argv[])
fbcon_cairo_update(font_name, font_size);
/* init libinput */
- kbd = libinput_udev_create_context(&libinput_interface, NULL, udev);
+ kbd = libinput_udev_create_context(logind
+ ? &libinput_if_logind
+ : &libinput_if_default,
+ NULL, udev);
libinput_udev_assign_seat(kbd, seat_name);
input = libinput_get_fd(kbd);
diff --git a/kbd.c b/kbd.c
index ed39220..d9ce8b3 100644
--- a/kbd.c
+++ b/kbd.c
@@ -11,11 +11,6 @@
#include <sys/stat.h>
-#include "config.h"
-#ifdef HAVE_SYSTEMD
-# include <systemd/sd-bus.h>
-#endif
-
#include "kbd.h"
/* ---------------------------------------------------------------------- */
@@ -199,157 +194,6 @@ static int file_wait(int fd, int timeout)
/* ---------------------------------------------------------------------- */
-#ifdef HAVE_SYSTEMD
-
-static sd_bus *logind_dbus = NULL;
-
-void logind_init(void)
-{
- sd_bus_error error = SD_BUS_ERROR_NULL;
- sd_bus_message *m = NULL;
- int r;
-
- r = sd_bus_open_system(&logind_dbus);
- if (r < 0) {
- fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
- return;
- }
-
- r = sd_bus_call_method(logind_dbus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1/session/self",
- "org.freedesktop.login1.Session",
- "TakeControl",
- &error,
- &m,
- "b",
- false);
- if (r < 0) {
- fprintf(stderr, "TakeControl failed: %s\n", error.message);
- sd_bus_error_free(&error);
- sd_bus_unref(logind_dbus);
- logind_dbus = NULL;
- return;
- }
-
- fprintf(stderr, "Opening input devices via logind.\n");
-}
-
-bool use_logind(void)
-{
- return logind_dbus != NULL;
-}
-
-int logind_open(const char *path)
-{
- sd_bus_error error = SD_BUS_ERROR_NULL;
- sd_bus_message *m = NULL;
- struct stat st;
- unsigned int maj, min;
- int inactive;
- int handle, fd, r;
-
- r = stat(path, &st);
- if (r < 0) {
- fprintf(stderr, "stat %s failed: %s\n", path, strerror(errno));
- return -1;
- }
-
- maj = major(st.st_rdev);
- min = minor(st.st_rdev);
- r = sd_bus_call_method(logind_dbus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1/session/self",
- "org.freedesktop.login1.Session",
- "TakeDevice",
- &error,
- &m,
- "uu",
- maj,
- min);
- if (r < 0) {
- fprintf(stderr, "TakeDevice failed: %s\n", error.message);
- sd_bus_error_free(&error);
- return -1;
- }
-
- handle = -1;
- inactive = -1;
- r = sd_bus_message_read(m, "hb", &handle, &inactive);
- if (r < 0) {
- fd = -1;
- fprintf(stderr, "Parsing TakeDevice reply failed: %s\n", strerror(-r));
- } else {
- fd = fcntl(handle, F_DUPFD_CLOEXEC, 0);
- fprintf(stderr, "open %s: got fd %d via logind.\n",
- path, fd);
- }
- sd_bus_message_unref(m);
-
- return fd;
-}
-
-void logind_close(int fd)
-{
- sd_bus_error error = SD_BUS_ERROR_NULL;
- sd_bus_message *m = NULL;
- struct stat st;
- unsigned int maj, min;
- int r;
-
- r = fstat(fd, &st);
- if (r < 0) {
- fprintf(stderr, "fstat failed: %s\n", strerror(errno));
- return;
- }
- close(fd);
-
- maj = major(st.st_rdev);
- min = minor(st.st_rdev);
- r = sd_bus_call_method(logind_dbus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1/session/self",
- "org.freedesktop.login1.Session",
- "ReleaseDevice",
- &error,
- &m,
- "uu",
- maj,
- min);
- if (r < 0) {
- fprintf(stderr, "ReleaseDevice failed: %s\n", error.message);
- sd_bus_error_free(&error);
- return;
- }
- sd_bus_message_unref(m);
-}
-
-#else
-
-void logind_init(void)
-{
- fprintf(stderr, "warning: compiled without logind support.\n");
-}
-
-bool use_logind(void)
-{
- return false;
-}
-
-int logind_open(const char *path)
-{
- errno = ENOSYS;
- return -1;
-}
-
-void logind_close(int fd)
-{
-}
-
-#endif
-
-/* ---------------------------------------------------------------------- */
-
int libinput_devcount;
int libinput_deverror;
@@ -357,15 +201,6 @@ static int open_restricted(const char *path, int flags, void *user_data)
{
int fd;
- if (use_logind()) {
- fd = logind_open(path);
- if (fd < 0)
- libinput_deverror++;
- else
- libinput_devcount++;
- return fd;
- }
-
fd = open(path, flags | O_CLOEXEC);
if (fd < 0) {
fprintf(stderr, "kbd: open %s: %s\n", path, strerror(errno));
@@ -381,18 +216,12 @@ static int open_restricted(const char *path, int flags, void *user_data)
static void close_restricted(int fd, void *user_data)
{
- if (use_logind()) {
- logind_close(fd);
- libinput_devcount--;
- return;
- }
-
ioctl(fd, EVIOCGRAB, 0);
close(fd);
libinput_devcount--;
}
-const struct libinput_interface libinput_interface = {
+const struct libinput_interface libinput_if_default = {
.open_restricted = open_restricted,
.close_restricted = close_restricted,
};
@@ -412,7 +241,7 @@ void kbd_init(int use_libinput, dev_t gfx)
seat = udev_device_get_property_value(ugfx, "ID_SEAT");
if (!seat)
seat = "seat0";
- ctx = libinput_udev_create_context(&libinput_interface, NULL, udev);
+ ctx = libinput_udev_create_context(&libinput_if_default, NULL, udev);
libinput_udev_assign_seat(ctx, seat);
fprintf(stderr, "kbd: using libinput (%d devices, %s)\n",
libinput_devcount, seat);
diff --git a/kbd.h b/kbd.h
index 3b5faef..fc5048e 100644
--- a/kbd.h
+++ b/kbd.h
@@ -10,7 +10,7 @@
extern int libinput_devcount;
extern int libinput_deverror;
-extern const struct libinput_interface libinput_interface;
+extern const struct libinput_interface libinput_if_default;
void kbd_init(int use_libinput, dev_t gfx);
int kbd_wait(int timeout);
@@ -19,8 +19,3 @@ int kbd_read(char *buf, uint32_t len,
void kbd_suspend(void);
void kbd_resume(void);
void kbd_fini(void);
-
-void logind_init(void);
-bool use_logind(void);
-int logind_open(const char *path);
-void logind_close(int fd);
diff --git a/logind.c b/logind.c
new file mode 100644
index 0000000..b426609
--- /dev/null
+++ b/logind.c
@@ -0,0 +1,196 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+#include <time.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <termios.h>
+
+#include <sys/stat.h>
+
+#include "config.h"
+#ifdef HAVE_SYSTEMD
+# include <systemd/sd-bus.h>
+#endif
+
+#include "logind.h"
+#include "kbd.h"
+
+#ifdef HAVE_SYSTEMD
+
+/* ---------------------------------------------------------------------- */
+
+static sd_bus *logind_dbus = NULL;
+
+int logind_init(void)
+{
+ int r;
+
+ r = sd_bus_open_system(&logind_dbus);
+ if (r < 0) {
+ fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
+ return -1;
+ }
+
+ r = logind_take_control();
+ if (r < 0) {
+ sd_bus_unref(logind_dbus);
+ logind_dbus = NULL;
+ return -1;
+ }
+
+ fprintf(stderr, "Opening input devices via logind.\n");
+ return 0;
+}
+
+int logind_take_control(void)
+{
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_message *m = NULL;
+ int r;
+
+ r = sd_bus_call_method(logind_dbus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/session/self",
+ "org.freedesktop.login1.Session",
+ "TakeControl",
+ &error,
+ &m,
+ "b",
+ false);
+ if (r < 0) {
+ fprintf(stderr, "TakeControl failed: %s\n", error.message);
+ sd_bus_error_free(&error);
+ }
+ sd_bus_message_unref(m);
+
+ return r;
+}
+
+int logind_open(const char *path, int flags, void *user_data)
+{
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_message *m = NULL;
+ struct stat st;
+ unsigned int maj, min;
+ int inactive;
+ int handle, fd, r;
+
+ r = stat(path, &st);
+ if (r < 0) {
+ fprintf(stderr, "stat %s failed: %s\n", path, strerror(errno));
+ libinput_deverror++;
+ return -1;
+ }
+
+ maj = major(st.st_rdev);
+ min = minor(st.st_rdev);
+ r = sd_bus_call_method(logind_dbus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/session/self",
+ "org.freedesktop.login1.Session",
+ "TakeDevice",
+ &error,
+ &m,
+ "uu",
+ maj,
+ min);
+ if (r < 0) {
+ fprintf(stderr, "TakeDevice failed: %s\n", error.message);
+ sd_bus_error_free(&error);
+ libinput_deverror++;
+ return -1;
+ }
+
+ handle = -1;
+ inactive = -1;
+ r = sd_bus_message_read(m, "hb", &handle, &inactive);
+ if (r < 0) {
+ fd = -1;
+ fprintf(stderr, "Parsing TakeDevice reply failed: %s\n", strerror(-r));
+ libinput_deverror++;
+ } else {
+ fd = fcntl(handle, F_DUPFD_CLOEXEC, 0);
+ fprintf(stderr, "open %s: got fd %d via logind.\n",
+ path, fd);
+ libinput_devcount++;
+ }
+ sd_bus_message_unref(m);
+
+ return fd;
+}
+
+void logind_close(int fd, void *user_data)
+{
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_message *m = NULL;
+ struct stat st;
+ unsigned int maj, min;
+ int r;
+
+ r = fstat(fd, &st);
+ if (r < 0) {
+ fprintf(stderr, "fstat failed: %s\n", strerror(errno));
+ return;
+ }
+ close(fd);
+
+ maj = major(st.st_rdev);
+ min = minor(st.st_rdev);
+ r = sd_bus_call_method(logind_dbus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/session/self",
+ "org.freedesktop.login1.Session",
+ "ReleaseDevice",
+ &error,
+ &m,
+ "uu",
+ maj,
+ min);
+ if (r < 0) {
+ fprintf(stderr, "ReleaseDevice failed: %s\n", error.message);
+ sd_bus_error_free(&error);
+ }
+ sd_bus_message_unref(m);
+ libinput_devcount--;
+ return;
+}
+
+#else
+
+/* ---------------------------------------------------------------------- */
+
+int logind_init(void)
+{
+ fprintf(stderr, "warning: compiled without logind support.\n");
+ return -1;
+}
+
+int logind_take_control(void)
+{
+ return -1;
+}
+
+int logind_open(const char *path, int flags, void *user_data)
+{
+ fprintf(stderr, "error: compiled without logind support.\n");
+ libinput_deverror++;
+ errno = ENOSYS;
+ return -1;
+}
+
+void logind_close(int fd, void *user_data)
+{
+}
+
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+const struct libinput_interface libinput_if_logind = {
+ .open_restricted = logind_open,
+ .close_restricted = logind_close,
+};
diff --git a/logind.h b/logind.h
new file mode 100644
index 0000000..6aca13c
--- /dev/null
+++ b/logind.h
@@ -0,0 +1,12 @@
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include <libudev.h>
+#include <libinput.h>
+
+extern const struct libinput_interface libinput_if_logind;
+
+int logind_init(void);
+int logind_take_control(void);
+int logind_open(const char *path, int flags, void *user_data);
+void logind_close(int fd, void *user_data);
diff --git a/meson.build b/meson.build
index 1505d6d..7da73ba 100644
--- a/meson.build
+++ b/meson.build
@@ -93,7 +93,7 @@ fbi_srcs = [ 'fbi.c', 'fb-gui.c', 'desktop.c',
trans_src, read_srcs ]
fbi_deps = [ drm_dep, pixman_dep, cairo_dep,
exif_dep, image_deps,
- math_dep, udev_dep, input_dep, systemd_dep ]
+ math_dep, udev_dep, input_dep ]
executable('fbi',
sources : fbi_srcs,
@@ -125,7 +125,7 @@ fbpdf_srcs = [ 'fbpdf.c', 'parseconfig.c', 'fbiconfig.c',
'vt.c', 'kbd.c', 'fbtools.c', 'drmtools.c', 'gfx.c' ]
fbpdf_deps = [ drm_dep, gbm_dep, epoxy_dep,
pixman_dep, poppler_dep, cairo_dep,
- udev_dep, input_dep, systemd_dep ]
+ udev_dep, input_dep ]
executable('fbpdf',
sources : fbpdf_srcs,
@@ -133,7 +133,7 @@ executable('fbpdf',
install : true)
# build fbcon
-fbcon_srcs = [ 'fbcon.c', 'drmtools.c', 'fbtools.c', 'gfx.c', 'vt.c', 'kbd.c' ]
+fbcon_srcs = [ 'fbcon.c', 'drmtools.c', 'fbtools.c', 'gfx.c', 'vt.c', 'kbd.c', 'logind.c' ]
fbcon_deps = [ drm_dep, cairo_dep, util_dep, udev_dep, input_dep, xkb_dep, glib_dep,
tsm_dep, systemd_dep ]