aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2019-04-08 09:40:37 +0200
committerGerd Hoffmann <kraxel@redhat.com>2019-04-08 09:40:37 +0200
commit8d9f68be114324075ea2885bb4b16bfdd7eaf6c9 (patch)
tree39bedf0f1e43adaa34688ad5c17a54efb6d913ef
parent1f662102a3ae07db1370fac44ca9c7fe19d235f1 (diff)
downloaddrminfo-8d9f68be114324075ea2885bb4b16bfdd7eaf6c9.tar.gz
add logind support
-rw-r--r--drminfo.c6
-rw-r--r--drmtest.c4
-rw-r--r--drmtools.c11
-rw-r--r--egltest.c3
-rw-r--r--fbinfo.c3
-rw-r--r--fbtest.c3
-rw-r--r--fbtools.c17
-rw-r--r--logind.c206
-rw-r--r--meson.build36
-rw-r--r--prime.c15
-rw-r--r--virtiotest.c3
11 files changed, 283 insertions, 24 deletions
diff --git a/drminfo.c b/drminfo.c
index 2db4a45..5a62d6c 100644
--- a/drminfo.c
+++ b/drminfo.c
@@ -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;
}
diff --git a/drmtest.c b/drmtest.c
index 368452f..a8ab9a3 100644
--- a/drmtest.c
+++ b/drmtest.c
@@ -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;
}
diff --git a/drmtools.c b/drmtools.c
index 87fd979..79ab135 100644
--- a/drmtools.c
+++ b/drmtools.c
@@ -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);
diff --git a/egltest.c b/egltest.c
index 62eb577..ec54d18 100644
--- a/egltest.c
+++ b/egltest.c
@@ -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;
}
diff --git a/fbinfo.c b/fbinfo.c
index a2b4fb3..fe6fab2 100644
--- a/fbinfo.c
+++ b/fbinfo.c
@@ -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,
diff --git a/fbtest.c b/fbtest.c
index 2247640..5c17fef 100644
--- a/fbtest.c
+++ b/fbtest.c
@@ -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;
}
diff --git a/fbtools.c b/fbtools.c
index 5394b68..51339ce 100644
--- a/fbtools.c
+++ b/fbtools.c
@@ -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 ]
diff --git a/prime.c b/prime.c
index c2046a1..6ffff24 100644
--- a/prime.c
+++ b/prime.c
@@ -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;
}