diff options
-rw-r--r-- | fbcon.c | 10 | ||||
-rw-r--r-- | kbd.c | 175 | ||||
-rw-r--r-- | kbd.h | 7 | ||||
-rw-r--r-- | logind.c | 196 | ||||
-rw-r--r-- | logind.h | 12 | ||||
-rw-r--r-- | meson.build | 6 |
6 files changed, 222 insertions, 184 deletions
@@ -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); @@ -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); @@ -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 ] |