[PATCH 08/12] systemd-logind: Add systemd-logind "core"

Hans de Goede hdegoede at redhat.com
Wed Jan 15 06:32:22 PST 2014


This commits add the bulk of the systemd-logind integration code, but does
not hook it up yet other then calling its init and fini functions, which
don't do that much.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 configure.ac                                 |  21 ++
 hw/xfree86/common/xf86Init.c                 |   3 +
 hw/xfree86/common/xf86platformBus.c          |   2 +-
 hw/xfree86/common/xf86platformBus.h          |   1 +
 hw/xfree86/os-support/linux/Makefile.am      |   6 +
 hw/xfree86/os-support/linux/systemd-logind.c | 493 +++++++++++++++++++++++++++
 include/Makefile.am                          |   1 +
 include/dix-config.h.in                      |   3 +
 include/systemd-logind.h                     |  46 +++
 9 files changed, 575 insertions(+), 1 deletion(-)
 create mode 100644 hw/xfree86/os-support/linux/systemd-logind.c
 create mode 100644 include/systemd-logind.h

diff --git a/configure.ac b/configure.ac
index c277593..cb8d770 100644
--- a/configure.ac
+++ b/configure.ac
@@ -628,6 +628,7 @@ AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg
 AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes])
 AC_ARG_ENABLE(linux_acpi, AC_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes])
 AC_ARG_ENABLE(linux_apm, AC_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes])
+AC_ARG_ENABLE(systemd-logind, AC_HELP_STRING([--enable-systemd-logind], [Build systemd-logind support (default: auto)]), [SYSTEMD_LOGIND=$enableval], [SYSTEMD_LOGIND=auto])
 
 dnl DDXes.
 AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
@@ -902,6 +903,26 @@ if test "x$CONFIG_HAL" = xyes; then
 fi
 AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])
 
+if test "x$SYSTEMD_LOGIND" = xauto; then
+        if test "x$HAVE_DBUS" = xyes -a "x$CONFIG_UDEV" = xyes ; then
+                SYSTEMD_LOGIND=yes
+        else
+                SYSTEMD_LOGIND=no
+        fi
+fi
+if test "x$SYSTEMD_LOGIND" = xyes; then
+        if ! test "x$HAVE_DBUS" = xyes; then
+                AC_MSG_ERROR([systemd-logind requested, but D-Bus is not installed.])
+        fi
+        if ! test "x$CONFIG_UDEV" = xyes ; then
+                AC_MSG_ERROR([systemd-logind is only supported in combination with udev configuration.])
+        fi
+
+        AC_DEFINE(SYSTEMD_LOGIND, 1, [Enable systemd-logind integration])
+        NEED_DBUS="yes"
+fi
+AM_CONDITIONAL(SYSTEMD_LOGIND, [test "x$SYSTEMD_LOGIND" = xyes])
+
 if test "x$NEED_DBUS" = xyes; then
         AC_DEFINE(NEED_DBUS, 1, [Enable D-Bus core])
 fi
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 815f679..380a70e 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -54,6 +54,7 @@
 #include "site.h"
 #include "mi.h"
 #include "dbus-core.h"
+#include "systemd-logind.h"
 
 #include "compiler.h"
 
@@ -458,6 +459,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             DoShowOptions();
 
         dbus_core_init();
+        systemd_logind_init();
 
         /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
         xf86BusProbe();
@@ -1062,6 +1064,7 @@ ddxGiveUp(enum ExitCode error)
     if (xorgHWOpenConsole)
         xf86CloseConsole();
 
+    systemd_logind_fini();
     dbus_core_fini();
 
     xf86CloseLog(error);
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
index 993d6a4..1b4b50f 100644
--- a/hw/xfree86/common/xf86platformBus.c
+++ b/hw/xfree86/common/xf86platformBus.c
@@ -52,7 +52,7 @@ int platformSlotClaimed;
 
 int xf86_num_platform_devices;
 
-static struct xf86_platform_device *xf86_platform_devices;
+struct xf86_platform_device *xf86_platform_devices;
 
 int
 xf86_add_platform_device(struct OdevAttributes *attribs)
diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h
index 4e17578..b986715 100644
--- a/hw/xfree86/common/xf86platformBus.h
+++ b/hw/xfree86/common/xf86platformBus.h
@@ -37,6 +37,7 @@ int xf86platformProbe(void);
 int xf86platformProbeDev(DriverPtr drvp);
 
 extern int xf86_num_platform_devices;
+extern struct xf86_platform_device *xf86_platform_devices;
 
 extern char *
 xf86_get_platform_attrib(int index, int attrib_id);
diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am
index 83e7e00..1686dc2 100644
--- a/hw/xfree86/os-support/linux/Makefile.am
+++ b/hw/xfree86/os-support/linux/Makefile.am
@@ -21,6 +21,11 @@ APM_SRCS = lnx_apm.c
 XORG_CFLAGS += -DHAVE_APM
 endif
 
+if SYSTEMD_LOGIND
+LOGIND_SRCS = systemd-logind.c
+XORG_CFLAGS += $(DBUS_CFLAGS)
+endif
+
 liblinux_la_SOURCES = lnx_init.c lnx_video.c \
                      lnx_agp.c lnx_kmod.c lnx_bell.c lnx_platform.c \
                      $(srcdir)/../shared/bios_mmap.c \
@@ -30,6 +35,7 @@ liblinux_la_SOURCES = lnx_init.c lnx_video.c \
 		     $(srcdir)/../shared/sigio.c \
                      $(ACPI_SRCS) \
                      $(APM_SRCS) \
+                     $(LOGIND_SRCS) \
                      $(PLATFORM_PCI_SUPPORT)
 
 AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES)
diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
new file mode 100644
index 0000000..f8be375
--- /dev/null
+++ b/hw/xfree86/os-support/linux/systemd-logind.c
@@ -0,0 +1,493 @@
+/*
+ * Copyright © 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Hans de Goede <hdegoede at redhat.com>
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <dbus/dbus.h>
+#include <string.h>
+#include <sys/types.h>
+#include <systemd/sd-login.h>
+#include <unistd.h>
+
+#include "os.h"
+#include "dbus-core.h"
+#include "xf86.h"
+#include "xf86platformBus.h"
+#include "xf86Xinput.h"
+
+#include "systemd-logind.h"
+
+#define DBUS_TIMEOUT 500 /* Wait max 0.5 seconds */
+
+struct systemd_logind_info {
+    DBusConnection *conn;
+    char *session;
+    Bool active;
+    Bool vt_active;
+};
+
+static struct systemd_logind_info logind_info;
+
+int
+systemd_logind_get_fd(dev_t devnum, const char *path, Bool *paused_ret)
+{
+    struct systemd_logind_info *info = &logind_info;
+    DBusError error;
+    DBusMessage *msg = NULL;
+    DBusMessage *reply = NULL;
+    dbus_int32_t minor = minor(devnum);
+    dbus_int32_t major = major(devnum);
+    dbus_bool_t paused;
+    int fd = -1;
+
+    if (!info->session || devnum == 0)
+        return -1;
+
+    /* logind does not support mouse devs (with evdev we don't need them) */
+    if (strstr(path, "mouse"))
+        return -1;
+
+    dbus_error_init(&error);
+
+    msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
+            "org.freedesktop.login1.Session", "TakeDevice");
+    if (!msg) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
+                                       DBUS_TYPE_UINT32, &minor,
+                                       DBUS_TYPE_INVALID)) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
+                                                      DBUS_TIMEOUT, &error);
+    if (!reply) {
+        LogMessage(X_ERROR, "systemd-logind: failed to take device %s: %s\n",
+                   path, error.message);
+        goto cleanup;
+    }
+
+    if (!dbus_message_get_args(reply, &error,
+                               DBUS_TYPE_UNIX_FD, &fd,
+                               DBUS_TYPE_BOOLEAN, &paused,
+                               DBUS_TYPE_INVALID)) {
+        LogMessage(X_ERROR, "systemd-logind: TakeDevice %s: %s\n",
+                   path, error.message);
+        goto cleanup;
+    }
+
+    *paused_ret = paused;
+
+    LogMessage(X_INFO, "systemd-logind: got fd for %s %u:%u fd %d paused %d\n",
+               path, major, minor, fd, paused);
+
+cleanup:
+    if (msg)
+        dbus_message_unref(msg);
+    if (reply)
+        dbus_message_unref(reply);
+    dbus_error_free(&error);
+
+    return fd;
+}
+
+void
+systemd_logind_put_fd(dev_t devnum)
+{
+    struct systemd_logind_info *info = &logind_info;
+    DBusError error;
+    DBusMessage *msg = NULL;
+    DBusMessage *reply = NULL;
+    dbus_int32_t minor = minor(devnum);
+    dbus_int32_t major = major(devnum);
+
+    if (!info->session || devnum == 0)
+        return;
+
+    dbus_error_init(&error);
+
+    msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
+            "org.freedesktop.login1.Session", "ReleaseDevice");
+    if (!msg) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
+                                       DBUS_TYPE_UINT32, &minor,
+                                       DBUS_TYPE_INVALID)) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
+                                                      DBUS_TIMEOUT, &error);
+    if (!reply)
+        LogMessage(X_ERROR, "systemd-logind: failed to release device: %s\n",
+                   error.message);
+
+cleanup:
+    if (msg)
+        dbus_message_unref(msg);
+    if (reply)
+        dbus_message_unref(reply);
+    dbus_error_free(&error);
+}
+
+int
+systemd_logind_controls_session(void)
+{
+    return logind_info.session ? 1 : 0;
+}
+
+void
+systemd_logind_vtenter(void)
+{
+    struct systemd_logind_info *info = &logind_info;
+    InputInfoPtr pInfo;
+    int i;
+
+    if (!info->session)
+        return; /* Not using systemd-logind */
+
+    if (!info->active)
+        return; /* Session not active */
+
+    if (info->vt_active)
+        return; /* Already did vtenter */
+
+    for (i = 0; i < xf86_num_platform_devices; i++) {
+        struct OdevAttributes *attr = xf86_platform_devices[i].attribs;
+        if (attr->server_fd && attr->paused)
+            break;
+    }
+    if (i != xf86_num_platform_devices)
+        return; /* Some drm nodes are still paused wait for resume */
+
+    xf86VTEnter();
+    info->vt_active = TRUE;
+
+    /* Activate any input devices which were resumed before the drm nodes */
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
+        if ((pInfo->flags & XI86_SERVER_FD) && pInfo->fd != -1)
+            xf86EnableInputDeviceForVTSwitch(pInfo);
+}
+
+static InputInfoPtr
+systemd_logind_find_info_ptr_by_devnum(int major, int minor)
+{
+    InputInfoPtr pInfo;
+
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
+        if (pInfo->major == major && pInfo->minor == minor &&
+                (pInfo->flags & XI86_SERVER_FD))
+            return pInfo;
+
+    return NULL;
+}
+
+static void
+systemd_logind_ack_pause(struct systemd_logind_info *info,
+                         dbus_int32_t minor, dbus_int32_t major)
+{
+    DBusError error;
+    DBusMessage *msg = NULL;
+    DBusMessage *reply = NULL;
+
+    dbus_error_init(&error);
+
+    msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,
+            "org.freedesktop.login1.Session", "PauseDeviceComplete");
+    if (!msg) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,
+                                       DBUS_TYPE_UINT32, &minor,
+                                       DBUS_TYPE_INVALID)) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    reply = dbus_connection_send_with_reply_and_block(info->conn, msg,
+                                                      DBUS_TIMEOUT, &error);
+    if (!reply)
+        LogMessage(X_ERROR, "systemd-logind: failed to ack pause: %s\n",
+                   error.message);
+
+cleanup:
+    if (msg)
+        dbus_message_unref(msg);
+    if (reply)
+        dbus_message_unref(reply);
+    dbus_error_free(&error);
+}
+
+static DBusHandlerResult
+message_filter(DBusConnection * connection, DBusMessage * message, void *data)
+{
+    struct systemd_logind_info *info = data;
+    struct xf86_platform_device *pdev = NULL;
+    InputInfoPtr pInfo = NULL;
+    int ack = 0, pause = 0, fd = -1;
+    DBusError error;
+    dbus_int32_t major, minor;
+    char *pause_str;
+
+    if (strcmp(dbus_message_get_path(message), info->session) != 0)
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    dbus_error_init(&error);
+
+    if (dbus_message_is_signal(message, "org.freedesktop.login1.Session",
+                               "PauseDevice")) {
+        if (!dbus_message_get_args(message, &error,
+                               DBUS_TYPE_UINT32, &major,
+                               DBUS_TYPE_UINT32, &minor,
+                               DBUS_TYPE_STRING, &pause_str,
+                               DBUS_TYPE_INVALID)) {
+            LogMessage(X_ERROR, "systemd-logind: PauseDevice: %s\n",
+                       error.message);
+            dbus_error_free(&error);
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        }
+
+        if (strcmp(pause_str, "pause") == 0) {
+            pause = 1;
+            ack = 1;
+        }
+        else if (strcmp(pause_str, "force") == 0) {
+            pause = 1;
+        }
+        else if (strcmp(pause_str, "gone") == 0) {
+            /* Device removal is handled through udev */
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        }
+        else {
+            LogMessage(X_WARNING, "systemd-logind: unknown pause type: %s\n",
+                       pause_str);
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        }
+    }
+    else if (dbus_message_is_signal(message, "org.freedesktop.login1.Session",
+                                    "ResumeDevice")) {
+        if (!dbus_message_get_args(message, &error,
+                                   DBUS_TYPE_UINT32, &major,
+                                   DBUS_TYPE_UINT32, &minor,
+                                   DBUS_TYPE_UNIX_FD, &fd,
+                                   DBUS_TYPE_INVALID)) {
+            LogMessage(X_ERROR, "systemd-logind: ResumeDevice: %s\n",
+                       error.message);
+            dbus_error_free(&error);
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        }
+    } else
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    LogMessage(X_INFO, "systemd-logind: got %s for %u:%u\n",
+               pause ? "pause" : "resume", major, minor);
+
+    pdev = xf86_find_platform_device_by_devnum(major, minor);        
+    if (!pdev)
+        pInfo = systemd_logind_find_info_ptr_by_devnum(major, minor);
+    if (!pdev && !pInfo) {
+        LogMessage(X_WARNING, "systemd-logind: could not find dev %u:%u\n",
+                   major, minor);
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
+
+    if (pause) {
+        /* Our VT_PROCESS usage guarantees we've already given up the vt */
+        info->active = info->vt_active = FALSE;
+        /* Note the actual vtleave has already been handled by xf86Events.c */
+        if (pdev)
+            pdev->attribs->paused = TRUE;
+        else {
+            close(pInfo->fd);
+            pInfo->fd = -1;
+        }
+        if (ack)
+            systemd_logind_ack_pause(info, major, minor);
+    }
+    else {
+        /* info->vt_active gets set by systemd_logind_vtenter() */
+        info->active = TRUE;
+
+        if (pdev) {
+            pdev->attribs->paused = FALSE;
+            systemd_logind_vtenter();
+        }
+        else {
+            pInfo->fd = fd;
+            if (info->vt_active)
+                xf86EnableInputDeviceForVTSwitch(pInfo);
+        }
+    }
+    return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+connect_hook(DBusConnection *connection, void *data)
+{
+    struct systemd_logind_info *info = data;
+    DBusError error;
+    DBusMessage *msg = NULL;
+    DBusMessage *reply = NULL;
+    dbus_int32_t arg;
+    char *session = NULL;
+
+    dbus_error_init(&error);
+
+    msg = dbus_message_new_method_call("org.freedesktop.login1",
+            "/org/freedesktop/login1", "org.freedesktop.login1.Manager",
+            "GetSessionByPID");
+    if (!msg) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    arg = getpid();
+    if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &arg,
+                                  DBUS_TYPE_INVALID)) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    reply = dbus_connection_send_with_reply_and_block(connection, msg,
+                                                      DBUS_TIMEOUT, &error);
+    if (!reply) {
+        LogMessage(X_ERROR, "systemd-logind: failed to get session: %s\n",
+                   error.message);
+        goto cleanup;
+    }
+    dbus_message_unref(msg);
+
+    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &session,
+                               DBUS_TYPE_INVALID)) {
+        LogMessage(X_ERROR, "systemd-logind: GetSessionByPID: %s\n",
+                   error.message);
+        goto cleanup;
+    }
+    session = XNFstrdup(session);
+
+    dbus_message_unref(reply);
+    reply = NULL;
+
+
+    msg = dbus_message_new_method_call("org.freedesktop.login1",
+            session, "org.freedesktop.login1.Session", "TakeControl");
+    if (!msg) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    arg = FALSE;
+    if (!dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &arg,
+                                  DBUS_TYPE_INVALID)) {
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");
+        goto cleanup;
+    }
+
+    reply = dbus_connection_send_with_reply_and_block(connection, msg,
+                                                      DBUS_TIMEOUT, &error);
+    if (!reply) {
+        LogMessage(X_ERROR, "systemd-logind: TakeControl failed: %s\n",
+                   error.message);
+        goto cleanup;
+    }
+
+    /*
+     * HdG: This is not useful with systemd <= 208 since the signal only
+     * contains invalidated property names there, rather then property, val
+     * pairs as it should.  Instead we just use the first resume / pause now.
+     */
+#if 0
+    snprintf(match, sizeof(match),
+        "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='%s'",
+        session);
+    dbus_bus_add_match(connection, match, &error);
+    if (dbus_error_is_set(&error)) {
+        LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n",
+                   error.message);
+        goto cleanup;
+    }
+#endif
+
+    if (!dbus_connection_add_filter(connection, message_filter, info, NULL)) {
+        LogMessage(X_ERROR, "systemd-logind: could not add filter: %s\n",
+                   error.message);
+        goto cleanup;
+    }
+
+    LogMessage(X_INFO, "systemd-logind: took control of session %s\n",
+               session);
+    info->conn = connection;
+    info->session = session;
+    info->vt_active = info->active = TRUE; /* The server owns the vt during init */
+    session = NULL;
+
+cleanup:
+    free(session);
+    if (msg)
+        dbus_message_unref(msg);
+    if (reply)
+        dbus_message_unref(reply);
+    dbus_error_free(&error);
+}
+
+static void
+disconnect_hook(void *data)
+{
+    struct systemd_logind_info *info = data;
+
+    free(info->session);
+    info->session = NULL;
+    info->conn = NULL;
+}
+
+static struct dbus_core_hook core_hook = {
+    .connect = connect_hook,
+    .disconnect = disconnect_hook,
+    .data = &logind_info,
+};
+
+int
+systemd_logind_init(void)
+{
+    return dbus_core_add_hook(&core_hook);
+}
+
+void
+systemd_logind_fini(void)
+{
+    dbus_core_remove_hook(&core_hook);
+}
diff --git a/include/Makefile.am b/include/Makefile.am
index fa6da00..6578038 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -72,4 +72,5 @@ EXTRA_DIST = 	\
 	dix-config-apple-verbatim.h \
 	dixfontstubs.h eventconvert.h eventstr.h inpututils.h \
 	protocol-versions.h \
+	systemd-logind.h \
 	xsha1.h
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index caea9b2..4931b9a 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -420,6 +420,9 @@
 /* Support HAL for hotplug */
 #undef CONFIG_HAL
 
+/* Enable systemd-logind integration */
+#undef SYSTEMD_LOGIND 1
+
 /* Have a monotonic clock from clock_gettime() */
 #undef MONOTONIC_CLOCK
 
diff --git a/include/systemd-logind.h b/include/systemd-logind.h
new file mode 100644
index 0000000..96ae6db
--- /dev/null
+++ b/include/systemd-logind.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Hans de Goede <hdegoede at redhat.com>
+ */
+
+#ifndef SYSTEMD_LOGIND_H
+#define SYSTEMD_LOGIND_H
+
+#include <sys/types.h>
+
+#ifdef SYSTEMD_LOGIND
+int systemd_logind_init(void);
+void systemd_logind_fini(void);
+int systemd_logind_get_fd(dev_t devnum, const char *path, Bool *paused_ret);
+void systemd_logind_put_fd(dev_t devnum);
+int systemd_logind_controls_session(void);
+void systemd_logind_vtenter(void);
+#else
+#define systemd_logind_init()
+#define systemd_logind_fini()
+#define systemd_logind_get_fd(dev) -1
+#define systemd_logind_controls_session() 0
+#define systemd_logind_vtenter()
+#endif
+
+#endif
-- 
1.8.4.2



More information about the xorg-devel mailing list