diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2019-04-08 09:40:37 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2019-04-08 09:40:37 +0200 |
commit | 8d9f68be114324075ea2885bb4b16bfdd7eaf6c9 (patch) | |
tree | 39bedf0f1e43adaa34688ad5c17a54efb6d913ef | |
parent | 1f662102a3ae07db1370fac44ca9c7fe19d235f1 (diff) | |
download | drminfo-8d9f68be114324075ea2885bb4b16bfdd7eaf6c9.tar.gz |
add logind support
-rw-r--r-- | drminfo.c | 6 | ||||
-rw-r--r-- | drmtest.c | 4 | ||||
-rw-r--r-- | drmtools.c | 11 | ||||
-rw-r--r-- | egltest.c | 3 | ||||
-rw-r--r-- | fbinfo.c | 3 | ||||
-rw-r--r-- | fbtest.c | 3 | ||||
-rw-r--r-- | fbtools.c | 17 | ||||
-rw-r--r-- | logind.c | 206 | ||||
-rw-r--r-- | meson.build | 36 | ||||
-rw-r--r-- | prime.c | 15 | ||||
-rw-r--r-- | virtiotest.c | 3 |
11 files changed, 283 insertions, 24 deletions
@@ -19,6 +19,7 @@ #include <pixman.h> #include "drmtools.h" +#include "logind.h" static int ttycols = 80; @@ -533,6 +534,8 @@ int main(int argc, char **argv) } } + logind_init(); + fd = drm_open(card); if (misc) drm_info_misc(fd); @@ -544,5 +547,8 @@ int main(int argc, char **argv) drm_info_planes(fd, modifiers, properties); if (format) drm_info_fmts(fd, listonly); + + logind_fini(); + return 0; } @@ -22,6 +22,7 @@ #include <pixman.h> #include "ttytools.h" +#include "logind.h" #include "drmtools.h" #include "render.h" #include "image.h" @@ -266,6 +267,7 @@ int main(int argc, char **argv) } } + logind_init(); drm_init_dev(card, output, modename, false); if (!fmt) { @@ -316,5 +318,7 @@ int main(int argc, char **argv) tty_restore(); drm_fini_dev(); + logind_fini(); + return 0; } @@ -19,6 +19,7 @@ #include <pixman.h> #include "drmtools.h" +#include "logind.h" /* ------------------------------------------------------------------ */ @@ -714,15 +715,19 @@ void drm_init_dev(int devnr, const char *output, char dev[64]; char name[64]; char m[64]; - int i, rc; + int i, rc, err; uint64_t has_dumb; /* open device */ snprintf(dev, sizeof(dev), DRM_DEV_NAME, DRM_DIR_NAME, devnr); drm_fd = open(dev, O_RDWR); if (drm_fd < 0) { - fprintf(stderr, "open %s: %s\n", dev, strerror(errno)); - exit(1); + err = errno; + drm_fd = logind_open(dev); + if (drm_fd < 0) { + fprintf(stderr, "open %s: %s\n", dev, strerror(err)); + exit(1); + } } version = drmGetVersion(drm_fd); @@ -19,6 +19,7 @@ #include <pixman.h> #include "drmtools.h" +#include "logind.h" #include "ttytools.h" /* ------------------------------------------------------------------ */ @@ -104,6 +105,7 @@ int main(int argc, char **argv) } } + logind_init(); drm_init_dev(card, output, modename, false); drm_setup_egl(); @@ -125,5 +127,6 @@ int main(int argc, char **argv) done: drm_fini_dev(); + logind_fini(); return 0; } @@ -13,6 +13,7 @@ #include <cairo.h> #include "fbtools.h" +#include "logind.h" /* ------------------------------------------------------------------ */ @@ -50,7 +51,9 @@ int main(int argc, char **argv) } } + logind_init(); fb_query(framebuffer); + logind_fini(); fprintf(stderr, "fb%d: %s, %dx%d, %d bpp, r/g/b/a %d/%d/%d/%d\n", framebuffer, @@ -14,6 +14,7 @@ #include <pixman.h> #include "fbtools.h" +#include "logind.h" #include "ttytools.h" #include "render.h" #include "image.h" @@ -105,6 +106,7 @@ int main(int argc, char **argv) } } + logind_init(); fb_init(framebuffer); cs = cairo_image_surface_create_for_data(fb_mem + fb_mem_offset, fb_format, @@ -121,5 +123,6 @@ int main(int argc, char **argv) tty_restore(); fb_fini(); + logind_fini(); return 0; } @@ -27,6 +27,7 @@ #include <cairo.h> #include "fbtools.h" +#include "logind.h" /* -------------------------------------------------------------------- */ /* internal variables */ @@ -138,11 +139,15 @@ void fb_fini(void) void fb_query(int cardno) { char device[64]; + int err; snprintf(device, sizeof(device), "/dev/fb%d", cardno); if (-1 == (fb = open(device,O_RDWR | O_CLOEXEC))) { - fprintf(stderr,"open %s: %s\n",device,strerror(errno)); - exit(1); + err = errno; + if (-1 == (fb = logind_open(device))) { + fprintf(stderr,"open %s: %s\n",device,strerror(err)); + exit(1); + } } if (-1 == ioctl(fb,FBIOGET_FSCREENINFO,&fb_fix)) { perror("ioctl FBIOGET_FSCREENINFO"); @@ -158,6 +163,7 @@ void fb_init(int cardno) { unsigned long page_mask; char device[64]; + int err; snprintf(device, sizeof(device), "/dev/fb%d", cardno); @@ -169,8 +175,11 @@ void fb_init(int cardno) /* get current settings (which we have to restore) */ if (-1 == (fb = open(device,O_RDWR | O_CLOEXEC))) { - fprintf(stderr,"open %s: %s\n",device,strerror(errno)); - exit(1); + err = errno; + if (-1 == (fb = logind_open(device))) { + fprintf(stderr,"open %s: %s\n",device,strerror(err)); + exit(1); + } } if (-1 == ioctl(fb,FBIOGET_VSCREENINFO,&fb_ovar)) { perror("ioctl FBIOGET_VSCREENINFO"); diff --git a/logind.c b/logind.c new file mode 100644 index 0000000..f1573a8 --- /dev/null +++ b/logind.c @@ -0,0 +1,206 @@ +#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" + +#ifdef HAVE_SYSTEMD + +/* ---------------------------------------------------------------------- */ + +static int logind_debug = 0; +static sd_bus *logind_dbus = NULL; + +/* ---------------------------------------------------------------------- */ + +static int logind_take_control(void) +{ + sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus_message *m = NULL; + int r; + + if (!logind_dbus) + return -1; + + if (logind_debug) + fprintf(stderr, "call : TakeControl()\n"); + 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, "error : TakeControl failed: %s\n", + error.message); + sd_bus_error_free(&error); + } + sd_bus_message_unref(m); + + return r; +} + +static int logind_release_control(void) +{ + sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus_message *m = NULL; + int r; + + if (!logind_dbus) + return -1; + + if (logind_debug) + fprintf(stderr, "call : ReleaseControl()\n"); + r = sd_bus_call_method(logind_dbus, + "org.freedesktop.login1", + "/org/freedesktop/login1/session/self", + "org.freedesktop.login1.Session", + "ReleaseControl", + &error, + &m, + ""); + if (r < 0) { + fprintf(stderr, "error : ReleaseControl failed: %s\n", + error.message); + sd_bus_error_free(&error); + } + sd_bus_message_unref(m); + + return r; +} + +/* ---------------------------------------------------------------------- */ + +void logind_init(void) +{ + const char *session_id, *seat; + int r; + + if (logind_dbus) + return; + + seat = getenv("XDG_SEAT"); + session_id = getenv("XDG_SESSION_ID"); + if (!seat || !session_id) + return; + + r = sd_bus_open_system(&logind_dbus); + if (r < 0) { + fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); + return; + } + + r = logind_take_control(); + if (r < 0) + goto err; + + return; + +err: + sd_bus_unref(logind_dbus); + logind_dbus = NULL; +} + +void logind_fini(void) +{ + if (!logind_dbus) + return; + + logind_release_control(); + sd_bus_unref(logind_dbus); + 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; + + if (!logind_dbus) + return -1; + + 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); + if (logind_debug) + fprintf(stderr, "call : TakeDevice(%d,%d)\n", maj, min); + 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, "error : 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, "error : 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; +} + +#else + +/* ---------------------------------------------------------------------- */ + +void logind_init(void) +{ +} + +void logind_fini(void) +{ +} + +int logind_open(const char *path) +{ + fprintf(stderr, "%s(%s): compiled without logind support.\n", + __func__, path); + return -1; +} + +#endif diff --git a/meson.build b/meson.build index 82cba82..ff44250 100644 --- a/meson.build +++ b/meson.build @@ -11,29 +11,37 @@ epoxy_dep = dependency('epoxy') cairo_dep = dependency('cairo') pixman_dep = dependency('pixman-1') gtk3_dep = dependency('gtk+-3.0') +systemd_dep = dependency('libsystemd', required : false, version : '>=221') + +# configuration +config = configuration_data() +if systemd_dep.found() + config.set('HAVE_SYSTEMD', true) +endif +configure_file(output : 'config.h', configuration : config) # libjpeg dep jpeg_dep = declare_dependency(link_args : '-ljpeg') -drminfo_srcs = [ 'drminfo.c', 'drmtools.c' ] -drmtest_srcs = [ 'drmtest.c', 'drmtools.c', 'ttytools.c', 'render.c', 'image.c' ] -fbinfo_srcs = [ 'fbinfo.c', 'fbtools.c' ] -fbtest_srcs = [ 'fbtest.c', 'fbtools.c', 'ttytools.c', 'render.c', 'image.c' ] -prime_srcs = [ 'prime.c' ] -viotest_srcs = [ 'virtiotest.c', 'drmtools.c', 'ttytools.c', 'render.c' ] -egltest_srcs = [ 'egltest.c', 'drmtools.c', 'drmtools-egl.c', 'ttytools.c' ] +drminfo_srcs = [ 'drminfo.c', 'drmtools.c', 'logind.c' ] +drmtest_srcs = [ 'drmtest.c', 'drmtools.c', 'logind.c', 'ttytools.c', 'render.c', 'image.c' ] +fbinfo_srcs = [ 'fbinfo.c', 'fbtools.c', 'logind.c' ] +fbtest_srcs = [ 'fbtest.c', 'fbtools.c', 'logind.c' , 'ttytools.c', 'render.c', 'image.c' ] +prime_srcs = [ 'prime.c', 'logind.c' ] +viotest_srcs = [ 'virtiotest.c', 'drmtools.c', 'logind.c', 'ttytools.c', 'render.c' ] +egltest_srcs = [ 'egltest.c', 'drmtools.c', 'drmtools-egl.c', 'logind.c', 'ttytools.c' ] gtktest_srcs = [ 'gtktest.c', 'render.c', 'image.c' ] -drminfo_deps = [ libdrm_dep, cairo_dep, pixman_dep ] +drminfo_deps = [ libdrm_dep, cairo_dep, pixman_dep, systemd_dep ] drmtest_deps = [ libdrm_dep, gbm_dep, epoxy_dep, - cairo_dep, pixman_dep, jpeg_dep ] -fbinfo_deps = [ cairo_dep ] -fbtest_deps = [ cairo_dep, pixman_dep, jpeg_dep ] -prime_deps = [ libdrm_dep, gbm_dep ] + cairo_dep, pixman_dep, jpeg_dep, systemd_dep ] +fbinfo_deps = [ cairo_dep, systemd_dep ] +fbtest_deps = [ cairo_dep, pixman_dep, jpeg_dep, systemd_dep ] +prime_deps = [ libdrm_dep, gbm_dep, systemd_dep ] viotest_deps = [ libdrm_dep, gbm_dep, epoxy_dep, - cairo_dep, pixman_dep, jpeg_dep ] + cairo_dep, pixman_dep, jpeg_dep, systemd_dep ] egltest_deps = [ libdrm_dep, gbm_dep, epoxy_dep, - cairo_dep, pixman_dep ] + cairo_dep, pixman_dep, systemd_dep ] gtktest_deps = [ gtk3_dep, cairo_dep, pixman_dep, jpeg_dep ] @@ -16,6 +16,8 @@ #include <gbm.h> +#include "logind.h" + #define TEST_WIDTH 640 #define TEST_HEIGHT 480 #define TEST_SIZE (TEST_WIDTH * TEST_HEIGHT * 4) @@ -53,13 +55,17 @@ static int drm_init_dev(const char *devname, bool *import, bool *export) { drmVersion *ver; uint64_t prime; - int fd, rc; + int fd, rc, err; /* open device */ fd = open(devname, O_RDWR); if (fd < 0) { - fprintf(stderr, "open %s: %s\n", devname, strerror(errno)); - exit(1); + err = errno; + fd = logind_open(devname); + if (fd < 0) { + fprintf(stderr, "open %s: %s\n", devname, strerror(err)); + exit(1); + } } ver = drmGetVersion(fd); @@ -251,6 +257,8 @@ int main(int argc, char **argv) } } + logind_init(); + for (i = 0;; i++) { snprintf(devname, sizeof(devname), DRM_DEV_NAME, DRM_DIR_NAME, i); if (access(devname, R_OK | W_OK) != 0) @@ -297,5 +305,6 @@ int main(int argc, char **argv) if (!list && gbm_ex && gbm_im) gbm_export_import(gbm_ex, gbm_im, ex, im); + logind_fini(); return 0; } diff --git a/virtiotest.c b/virtiotest.c index 53ec77d..e108232 100644 --- a/virtiotest.c +++ b/virtiotest.c @@ -23,6 +23,7 @@ #include <pixman.h> #include "drmtools.h" +#include "logind.h" #include "ttytools.h" #include "render.h" @@ -290,6 +291,7 @@ int main(int argc, char **argv) } assert(fmt != NULL); + logind_init(); drm_init_dev(card, output, modename, false); if (printinfo) @@ -313,5 +315,6 @@ int main(int argc, char **argv) done: drm_fini_dev(); + logind_fini(); return 0; } |