<div dir="ltr"><div><div>Something I noticed here is that you use GetSessionByPID(). This works right now, but with systemd user sessions, the display server will run outside of a session. We have to decide what to do in this case.<br>
<br></div>One idea is to pass the object path of the logind session on the command line from the display manager:<br><br>    Xorg -background none -retro -logind-session /org/freedesktop/login1/session/_1 :0<br><br></div>
<div>Another option, which is what Colin did when he was bringing up systemd user sessions, is to only allow one graphical session per user. In this case, you'd call ListSessions(); and scan for the first "x11" session you can find.<br>
<br></div><div>It might be a bit inappropriate to encode such a policy in the X server, but if it's only under a command-line switch, it should be OK.<br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Tue, Feb 4, 2014 at 6:49 AM, Hans de Goede <span dir="ltr"><<a href="mailto:hdegoede@redhat.com" target="_blank">hdegoede@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This commits add the bulk of the systemd-logind integration code, but does<br>
not hook it up yet other then calling its init and fini functions, which<br>
don't do that much.<br>
<br>
Note the configure bits check for udev since systemd-logind use will only be<br>
supported in combination with udev. Besides that it only checks for dbus<br>
since all communication with systemd-logind is happening over dbus, so<br>
no further libs are needed.<br>
<br>
Signed-off-by: Hans de Goede <<a href="mailto:hdegoede@redhat.com">hdegoede@redhat.com</a>><br>
---<br>
 <a href="http://configure.ac" target="_blank">configure.ac</a>                                 |  21 ++<br>
 hw/xfree86/common/xf86Init.c                 |   3 +<br>
 hw/xfree86/common/xf86platformBus.c          |   2 +-<br>
 hw/xfree86/common/xf86platformBus.h          |   2 +<br>
 hw/xfree86/os-support/linux/Makefile.am      |   6 +<br>
 hw/xfree86/os-support/linux/systemd-logind.c | 529 +++++++++++++++++++++++++++<br>
 include/Makefile.am                          |   1 +<br>
 include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a>                      |   3 +<br>
 include/systemd-logind.h                     |  45 +++<br>
 9 files changed, 611 insertions(+), 1 deletion(-)<br>
 create mode 100644 hw/xfree86/os-support/linux/systemd-logind.c<br>
 create mode 100644 include/systemd-logind.h<br>
<br>
diff --git a/<a href="http://configure.ac" target="_blank">configure.ac</a> b/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
index fe9b783..bc89bfe 100644<br>
--- a/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
+++ b/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
@@ -626,6 +626,7 @@ AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg<br>
 AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes])<br>
 AC_ARG_ENABLE(linux_acpi, AS_HELP_STRING([--disable-linux-acpi], [Disable building ACPI support on Linux (if available).]), [enable_linux_acpi=$enableval], [enable_linux_acpi=yes])<br>
 AC_ARG_ENABLE(linux_apm, AS_HELP_STRING([--disable-linux-apm], [Disable building APM support on Linux (if available).]), [enable_linux_apm=$enableval], [enable_linux_apm=yes])<br>
+AC_ARG_ENABLE(systemd-logind, AC_HELP_STRING([--enable-systemd-logind], [Build systemd-logind support (default: auto)]), [SYSTEMD_LOGIND=$enableval], [SYSTEMD_LOGIND=auto])<br>
<br>
 dnl DDXes.<br>
 AC_ARG_ENABLE(xorg,                  AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])<br>
@@ -901,6 +902,26 @@ if test "x$CONFIG_HAL" = xyes; then<br>
 fi<br>
 AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])<br>
<br>
+if test "x$SYSTEMD_LOGIND" = xauto; then<br>
+        if test "x$HAVE_DBUS" = xyes -a "x$CONFIG_UDEV" = xyes ; then<br>
+                SYSTEMD_LOGIND=yes<br>
+        else<br>
+                SYSTEMD_LOGIND=no<br>
+        fi<br>
+fi<br>
+if test "x$SYSTEMD_LOGIND" = xyes; then<br>
+        if ! test "x$HAVE_DBUS" = xyes; then<br>
+                AC_MSG_ERROR([systemd-logind requested, but D-Bus is not installed.])<br>
+        fi<br>
+        if ! test "x$CONFIG_UDEV" = xyes ; then<br>
+                AC_MSG_ERROR([systemd-logind is only supported in combination with udev configuration.])<br>
+        fi<br>
+<br>
+        AC_DEFINE(SYSTEMD_LOGIND, 1, [Enable systemd-logind integration])<br>
+        NEED_DBUS="yes"<br>
+fi<br>
+AM_CONDITIONAL(SYSTEMD_LOGIND, [test "x$SYSTEMD_LOGIND" = xyes])<br>
+<br>
 if test "x$NEED_DBUS" = xyes; then<br>
         AC_DEFINE(NEED_DBUS, 1, [Enable D-Bus core])<br>
 fi<br>
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c<br>
index ff4d38f..4579ff5 100644<br>
--- a/hw/xfree86/common/xf86Init.c<br>
+++ b/hw/xfree86/common/xf86Init.c<br>
@@ -54,6 +54,7 @@<br>
 #include "site.h"<br>
 #include "mi.h"<br>
 #include "dbus-core.h"<br>
+#include "systemd-logind.h"<br>
<br>
 #include "compiler.h"<br>
<br>
@@ -458,6 +459,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)<br>
             DoShowOptions();<br>
<br>
         dbus_core_init();<br>
+        systemd_logind_init();<br>
<br>
         /* Do a general bus probe.  This will be a PCI probe for x86 platforms */<br>
         xf86BusProbe();<br>
@@ -1062,6 +1064,7 @@ ddxGiveUp(enum ExitCode error)<br>
     if (xorgHWOpenConsole)<br>
         xf86CloseConsole();<br>
<br>
+    systemd_logind_fini();<br>
     dbus_core_fini();<br>
<br>
     xf86CloseLog(error);<br>
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c<br>
index e1d7bd0..4447e19 100644<br>
--- a/hw/xfree86/common/xf86platformBus.c<br>
+++ b/hw/xfree86/common/xf86platformBus.c<br>
@@ -52,7 +52,7 @@ int platformSlotClaimed;<br>
<br>
 int xf86_num_platform_devices;<br>
<br>
-static struct xf86_platform_device *xf86_platform_devices;<br>
+struct xf86_platform_device *xf86_platform_devices;<br>
<br>
 int<br>
 xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned)<br>
diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h<br>
index 3e27d34..78b5a5b 100644<br>
--- a/hw/xfree86/common/xf86platformBus.h<br>
+++ b/hw/xfree86/common/xf86platformBus.h<br>
@@ -36,12 +36,14 @@ struct xf86_platform_device {<br>
 /* xf86_platform_device flags */<br>
 #define XF86_PDEV_UNOWNED       0x01<br>
 #define XF86_PDEV_SERVER_FD     0x02<br>
+#define XF86_PDEV_PAUSED        0x04<br>
<br>
 #ifdef XSERVER_PLATFORM_BUS<br>
 int xf86platformProbe(void);<br>
 int xf86platformProbeDev(DriverPtr drvp);<br>
<br>
 extern int xf86_num_platform_devices;<br>
+extern struct xf86_platform_device *xf86_platform_devices;<br>
<br>
 extern char *<br>
 xf86_get_platform_attrib(int index, int attrib_id);<br>
diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am<br>
index 83e7e00..1686dc2 100644<br>
--- a/hw/xfree86/os-support/linux/Makefile.am<br>
+++ b/hw/xfree86/os-support/linux/Makefile.am<br>
@@ -21,6 +21,11 @@ APM_SRCS = lnx_apm.c<br>
 XORG_CFLAGS += -DHAVE_APM<br>
 endif<br>
<br>
+if SYSTEMD_LOGIND<br>
+LOGIND_SRCS = systemd-logind.c<br>
+XORG_CFLAGS += $(DBUS_CFLAGS)<br>
+endif<br>
+<br>
 liblinux_la_SOURCES = lnx_init.c lnx_video.c \<br>
                      lnx_agp.c lnx_kmod.c lnx_bell.c lnx_platform.c \<br>
                      $(srcdir)/../shared/bios_mmap.c \<br>
@@ -30,6 +35,7 @@ liblinux_la_SOURCES = lnx_init.c lnx_video.c \<br>
                     $(srcdir)/../shared/sigio.c \<br>
                      $(ACPI_SRCS) \<br>
                      $(APM_SRCS) \<br>
+                     $(LOGIND_SRCS) \<br>
                      $(PLATFORM_PCI_SUPPORT)<br>
<br>
 AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(DIX_CFLAGS) $(XORG_CFLAGS) $(PLATFORM_DEFINES)<br>
diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c<br>
new file mode 100644<br>
index 0000000..176defd<br>
--- /dev/null<br>
+++ b/hw/xfree86/os-support/linux/systemd-logind.c<br>
@@ -0,0 +1,529 @@<br>
+/*<br>
+ * Copyright © 2013 Red Hat Inc.<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER<br>
+ * DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ * Author: Hans de Goede <<a href="mailto:hdegoede@redhat.com">hdegoede@redhat.com</a>><br>
+ */<br>
+<br>
+#ifdef HAVE_XORG_CONFIG_H<br>
+#include <xorg-config.h><br>
+#endif<br>
+<br>
+#include <dbus/dbus.h><br>
+#include <string.h><br>
+#include <sys/types.h><br>
+#include <unistd.h><br>
+<br>
+#include "os.h"<br>
+#include "dbus-core.h"<br>
+#include "xf86.h"<br>
+#include "xf86platformBus.h"<br>
+#include "xf86Xinput.h"<br>
+<br>
+#include "systemd-logind.h"<br>
+<br>
+#define DBUS_TIMEOUT 500 /* Wait max 0.5 seconds */<br>
+<br>
+struct systemd_logind_info {<br>
+    DBusConnection *conn;<br>
+    char *session;<br>
+    Bool active;<br>
+    Bool vt_active;<br>
+};<br>
+<br>
+static struct systemd_logind_info logind_info;<br>
+<br>
+int<br>
+systemd_logind_take_fd(int _major, int _minor, const char *path,<br>
+                       Bool *paused_ret)<br>
+{<br>
+    struct systemd_logind_info *info = &logind_info;<br>
+    DBusError error;<br>
+    DBusMessage *msg = NULL;<br>
+    DBusMessage *reply = NULL;<br>
+    dbus_int32_t major = _major;<br>
+    dbus_int32_t minor = _minor;<br>
+    dbus_bool_t paused;<br>
+    int fd = -1;<br>
+<br>
+    if (!info->session || major == 0)<br>
+        return -1;<br>
+<br>
+    /* logind does not support mouse devs (with evdev we don't need them) */<br>
+    if (strstr(path, "mouse"))<br>
+        return -1;<br>
+<br>
+    dbus_error_init(&error);<br>
+<br>
+    msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,<br>
+            "org.freedesktop.login1.Session", "TakeDevice");<br>
+    if (!msg) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,<br>
+                                       DBUS_TYPE_UINT32, &minor,<br>
+                                       DBUS_TYPE_INVALID)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    reply = dbus_connection_send_with_reply_and_block(info->conn, msg,<br>
+                                                      DBUS_TIMEOUT, &error);<br>
+    if (!reply) {<br>
+        LogMessage(X_ERROR, "systemd-logind: failed to take device %s: %s\n",<br>
+                   path, error.message);<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    if (!dbus_message_get_args(reply, &error,<br>
+                               DBUS_TYPE_UNIX_FD, &fd,<br>
+                               DBUS_TYPE_BOOLEAN, &paused,<br>
+                               DBUS_TYPE_INVALID)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: TakeDevice %s: %s\n",<br>
+                   path, error.message);<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    *paused_ret = paused;<br>
+<br>
+    LogMessage(X_INFO, "systemd-logind: got fd for %s %u:%u fd %d paused %d\n",<br>
+               path, major, minor, fd, paused);<br>
+<br>
+cleanup:<br>
+    if (msg)<br>
+        dbus_message_unref(msg);<br>
+    if (reply)<br>
+        dbus_message_unref(reply);<br>
+    dbus_error_free(&error);<br>
+<br>
+    return fd;<br>
+}<br>
+<br>
+void<br>
+systemd_logind_release_fd(int _major, int _minor)<br>
+{<br>
+    struct systemd_logind_info *info = &logind_info;<br>
+    DBusError error;<br>
+    DBusMessage *msg = NULL;<br>
+    DBusMessage *reply = NULL;<br>
+    dbus_int32_t major = _major;<br>
+    dbus_int32_t minor = _minor;<br>
+<br>
+    if (!info->session || major == 0)<br>
+        return;<br>
+<br>
+    dbus_error_init(&error);<br>
+<br>
+    msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,<br>
+            "org.freedesktop.login1.Session", "ReleaseDevice");<br>
+    if (!msg) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,<br>
+                                       DBUS_TYPE_UINT32, &minor,<br>
+                                       DBUS_TYPE_INVALID)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    reply = dbus_connection_send_with_reply_and_block(info->conn, msg,<br>
+                                                      DBUS_TIMEOUT, &error);<br>
+    if (!reply)<br>
+        LogMessage(X_ERROR, "systemd-logind: failed to release device: %s\n",<br>
+                   error.message);<br>
+<br>
+cleanup:<br>
+    if (msg)<br>
+        dbus_message_unref(msg);<br>
+    if (reply)<br>
+        dbus_message_unref(reply);<br>
+    dbus_error_free(&error);<br>
+}<br>
+<br>
+int<br>
+systemd_logind_controls_session(void)<br>
+{<br>
+    return logind_info.session ? 1 : 0;<br>
+}<br>
+<br>
+void<br>
+systemd_logind_vtenter(void)<br>
+{<br>
+    struct systemd_logind_info *info = &logind_info;<br>
+    InputInfoPtr pInfo;<br>
+    int i;<br>
+<br>
+    if (!info->session)<br>
+        return; /* Not using systemd-logind */<br>
+<br>
+    if (!info->active)<br>
+        return; /* Session not active */<br>
+<br>
+    if (info->vt_active)<br>
+        return; /* Already did vtenter */<br>
+<br>
+    for (i = 0; i < xf86_num_platform_devices; i++) {<br>
+        if (xf86_platform_devices[i].flags & XF86_PDEV_PAUSED)<br>
+            break;<br>
+    }<br>
+    if (i != xf86_num_platform_devices)<br>
+        return; /* Some drm nodes are still paused wait for resume */<br>
+<br>
+    xf86VTEnter();<br>
+    info->vt_active = TRUE;<br>
+<br>
+    /* Activate any input devices which were resumed before the drm nodes */<br>
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)<br>
+        if ((pInfo->flags & XI86_SERVER_FD) && pInfo->fd != -1)<br>
+            xf86EnableInputDeviceForVTSwitch(pInfo);<br>
+}<br>
+<br>
+static InputInfoPtr<br>
+systemd_logind_find_info_ptr_by_devnum(int major, int minor)<br>
+{<br>
+    InputInfoPtr pInfo;<br>
+<br>
+    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)<br>
+        if (pInfo->major == major && pInfo->minor == minor &&<br>
+                (pInfo->flags & XI86_SERVER_FD))<br>
+            return pInfo;<br>
+<br>
+    return NULL;<br>
+}<br>
+<br>
+static void<br>
+systemd_logind_ack_pause(struct systemd_logind_info *info,<br>
+                         dbus_int32_t minor, dbus_int32_t major)<br>
+{<br>
+    DBusError error;<br>
+    DBusMessage *msg = NULL;<br>
+    DBusMessage *reply = NULL;<br>
+<br>
+    dbus_error_init(&error);<br>
+<br>
+    msg = dbus_message_new_method_call("org.freedesktop.login1", info->session,<br>
+            "org.freedesktop.login1.Session", "PauseDeviceComplete");<br>
+    if (!msg) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &major,<br>
+                                       DBUS_TYPE_UINT32, &minor,<br>
+                                       DBUS_TYPE_INVALID)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    reply = dbus_connection_send_with_reply_and_block(info->conn, msg,<br>
+                                                      DBUS_TIMEOUT, &error);<br>
+    if (!reply)<br>
+        LogMessage(X_ERROR, "systemd-logind: failed to ack pause: %s\n",<br>
+                   error.message);<br>
+<br>
+cleanup:<br>
+    if (msg)<br>
+        dbus_message_unref(msg);<br>
+    if (reply)<br>
+        dbus_message_unref(reply);<br>
+    dbus_error_free(&error);<br>
+}<br>
+<br>
+static DBusHandlerResult<br>
+message_filter(DBusConnection * connection, DBusMessage * message, void *data)<br>
+{<br>
+    struct systemd_logind_info *info = data;<br>
+    struct xf86_platform_device *pdev = NULL;<br>
+    InputInfoPtr pInfo = NULL;<br>
+    int ack = 0, pause = 0, fd = -1;<br>
+    DBusError error;<br>
+    dbus_int32_t major, minor;<br>
+    char *pause_str;<br>
+<br>
+    if (strcmp(dbus_message_get_path(message), info->session) != 0)<br>
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;<br>
+<br>
+    dbus_error_init(&error);<br>
+<br>
+    if (dbus_message_is_signal(message, "org.freedesktop.login1.Session",<br>
+                               "PauseDevice")) {<br>
+        if (!dbus_message_get_args(message, &error,<br>
+                               DBUS_TYPE_UINT32, &major,<br>
+                               DBUS_TYPE_UINT32, &minor,<br>
+                               DBUS_TYPE_STRING, &pause_str,<br>
+                               DBUS_TYPE_INVALID)) {<br>
+            LogMessage(X_ERROR, "systemd-logind: PauseDevice: %s\n",<br>
+                       error.message);<br>
+            dbus_error_free(&error);<br>
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;<br>
+        }<br>
+<br>
+        if (strcmp(pause_str, "pause") == 0) {<br>
+            pause = 1;<br>
+            ack = 1;<br>
+        }<br>
+        else if (strcmp(pause_str, "force") == 0) {<br>
+            pause = 1;<br>
+        }<br>
+        else if (strcmp(pause_str, "gone") == 0) {<br>
+            /* Device removal is handled through udev */<br>
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;<br>
+        }<br>
+        else {<br>
+            LogMessage(X_WARNING, "systemd-logind: unknown pause type: %s\n",<br>
+                       pause_str);<br>
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;<br>
+        }<br>
+    }<br>
+    else if (dbus_message_is_signal(message, "org.freedesktop.login1.Session",<br>
+                                    "ResumeDevice")) {<br>
+        if (!dbus_message_get_args(message, &error,<br>
+                                   DBUS_TYPE_UINT32, &major,<br>
+                                   DBUS_TYPE_UINT32, &minor,<br>
+                                   DBUS_TYPE_UNIX_FD, &fd,<br>
+                                   DBUS_TYPE_INVALID)) {<br>
+            LogMessage(X_ERROR, "systemd-logind: ResumeDevice: %s\n",<br>
+                       error.message);<br>
+            dbus_error_free(&error);<br>
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;<br>
+        }<br>
+    } else<br>
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;<br>
+<br>
+    LogMessage(X_INFO, "systemd-logind: got %s for %u:%u\n",<br>
+               pause ? "pause" : "resume", major, minor);<br>
+<br>
+    pdev = xf86_find_platform_device_by_devnum(major, minor);<br>
+    if (!pdev)<br>
+        pInfo = systemd_logind_find_info_ptr_by_devnum(major, minor);<br>
+    if (!pdev && !pInfo) {<br>
+        LogMessage(X_WARNING, "systemd-logind: could not find dev %u:%u\n",<br>
+                   major, minor);<br>
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;<br>
+    }<br>
+<br>
+    if (pause) {<br>
+        /* Our VT_PROCESS usage guarantees we've already given up the vt */<br>
+        info->active = info->vt_active = FALSE;<br>
+        /* Note the actual vtleave has already been handled by xf86Events.c */<br>
+        if (pdev)<br>
+            pdev->flags |= XF86_PDEV_PAUSED;<br>
+        else {<br>
+            close(pInfo->fd);<br>
+            pInfo->fd = -1;<br>
+            pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", -1);<br>
+        }<br>
+        if (ack)<br>
+            systemd_logind_ack_pause(info, major, minor);<br>
+    }<br>
+    else {<br>
+        /* info->vt_active gets set by systemd_logind_vtenter() */<br>
+        info->active = TRUE;<br>
+<br>
+        if (pdev) {<br>
+            pdev->flags &= ~XF86_PDEV_PAUSED;<br>
+            systemd_logind_vtenter();<br>
+        }<br>
+        else {<br>
+            pInfo->fd = fd;<br>
+            pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd);<br>
+            if (info->vt_active)<br>
+                xf86EnableInputDeviceForVTSwitch(pInfo);<br>
+        }<br>
+    }<br>
+    return DBUS_HANDLER_RESULT_HANDLED;<br>
+}<br>
+<br>
+static void<br>
+connect_hook(DBusConnection *connection, void *data)<br>
+{<br>
+    struct systemd_logind_info *info = data;<br>
+    DBusError error;<br>
+    DBusMessage *msg = NULL;<br>
+    DBusMessage *reply = NULL;<br>
+    dbus_int32_t arg;<br>
+    char *session = NULL;<br>
+<br>
+    dbus_error_init(&error);<br>
+<br>
+    msg = dbus_message_new_method_call("org.freedesktop.login1",<br>
+            "/org/freedesktop/login1", "org.freedesktop.login1.Manager",<br>
+            "GetSessionByPID");<br>
+    if (!msg) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    arg = getpid();<br>
+    if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &arg,<br>
+                                  DBUS_TYPE_INVALID)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    reply = dbus_connection_send_with_reply_and_block(connection, msg,<br>
+                                                      DBUS_TIMEOUT, &error);<br>
+    if (!reply) {<br>
+        LogMessage(X_ERROR, "systemd-logind: failed to get session: %s\n",<br>
+                   error.message);<br>
+        goto cleanup;<br>
+    }<br>
+    dbus_message_unref(msg);<br>
+<br>
+    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &session,<br>
+                               DBUS_TYPE_INVALID)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: GetSessionByPID: %s\n",<br>
+                   error.message);<br>
+        goto cleanup;<br>
+    }<br>
+    session = XNFstrdup(session);<br>
+<br>
+    dbus_message_unref(reply);<br>
+    reply = NULL;<br>
+<br>
+<br>
+    msg = dbus_message_new_method_call("org.freedesktop.login1",<br>
+            session, "org.freedesktop.login1.Session", "TakeControl");<br>
+    if (!msg) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    arg = FALSE;<br>
+    if (!dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &arg,<br>
+                                  DBUS_TYPE_INVALID)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    reply = dbus_connection_send_with_reply_and_block(connection, msg,<br>
+                                                      DBUS_TIMEOUT, &error);<br>
+    if (!reply) {<br>
+        LogMessage(X_ERROR, "systemd-logind: TakeControl failed: %s\n",<br>
+                   error.message);<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    /*<br>
+     * HdG: This is not useful with systemd <= 208 since the signal only<br>
+     * contains invalidated property names there, rather than property, val<br>
+     * pairs as it should.  Instead we just use the first resume / pause now.<br>
+     */<br>
+#if 0<br>
+    snprintf(match, sizeof(match),<br>
+        "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='%s'",<br>
+        session);<br>
+    dbus_bus_add_match(connection, match, &error);<br>
+    if (dbus_error_is_set(&error)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n",<br>
+                   error.message);<br>
+        goto cleanup;<br>
+    }<br>
+#endif<br>
+<br>
+    if (!dbus_connection_add_filter(connection, message_filter, info, NULL)) {<br>
+        LogMessage(X_ERROR, "systemd-logind: could not add filter: %s\n",<br>
+                   error.message);<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    LogMessage(X_INFO, "systemd-logind: took control of session %s\n",<br>
+               session);<br>
+    info->conn = connection;<br>
+    info->session = session;<br>
+    info->vt_active = info->active = TRUE; /* The server owns the vt during init */<br>
+    session = NULL;<br>
+<br>
+cleanup:<br>
+    free(session);<br>
+    if (msg)<br>
+        dbus_message_unref(msg);<br>
+    if (reply)<br>
+        dbus_message_unref(reply);<br>
+    dbus_error_free(&error);<br>
+}<br>
+<br>
+static void<br>
+systemd_logind_release_control(struct systemd_logind_info *info)<br>
+{<br>
+    DBusError error;<br>
+    DBusMessage *msg = NULL;<br>
+    DBusMessage *reply = NULL;<br>
+<br>
+    dbus_error_init(&error);<br>
+<br>
+    msg = dbus_message_new_method_call("org.freedesktop.login1",<br>
+            info->session, "org.freedesktop.login1.Session", "ReleaseControl");<br>
+    if (!msg) {<br>
+        LogMessage(X_ERROR, "systemd-logind: out of memory\n");<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+    reply = dbus_connection_send_with_reply_and_block(info->conn, msg,<br>
+                                                      DBUS_TIMEOUT, &error);<br>
+    if (!reply) {<br>
+        LogMessage(X_ERROR, "systemd-logind: ReleaseControl failed: %s\n",<br>
+                   error.message);<br>
+        goto cleanup;<br>
+    }<br>
+<br>
+cleanup:<br>
+    if (msg)<br>
+        dbus_message_unref(msg);<br>
+    if (reply)<br>
+        dbus_message_unref(reply);<br>
+    dbus_error_free(&error);<br>
+}<br>
+<br>
+static void<br>
+disconnect_hook(void *data)<br>
+{<br>
+    struct systemd_logind_info *info = data;<br>
+<br>
+    free(info->session);<br>
+    info->session = NULL;<br>
+    info->conn = NULL;<br>
+}<br>
+<br>
+static struct dbus_core_hook core_hook = {<br>
+    .connect = connect_hook,<br>
+    .disconnect = disconnect_hook,<br>
+    .data = &logind_info,<br>
+};<br>
+<br>
+int<br>
+systemd_logind_init(void)<br>
+{<br>
+    return dbus_core_add_hook(&core_hook);<br>
+}<br>
+<br>
+void<br>
+systemd_logind_fini(void)<br>
+{<br>
+    if (logind_info.session)<br>
+        systemd_logind_release_control(&logind_info);<br>
+<br>
+    dbus_core_remove_hook(&core_hook);<br>
+}<br>
diff --git a/include/Makefile.am b/include/Makefile.am<br>
index fa6da00..6578038 100644<br>
--- a/include/Makefile.am<br>
+++ b/include/Makefile.am<br>
@@ -72,4 +72,5 @@ EXTRA_DIST =  \<br>
        dix-config-apple-verbatim.h \<br>
        dixfontstubs.h eventconvert.h eventstr.h inpututils.h \<br>
        protocol-versions.h \<br>
+       systemd-logind.h \<br>
        xsha1.h<br>
diff --git a/include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a> b/include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a><br>
index 7c77956..3865d5e 100644<br>
--- a/include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a><br>
+++ b/include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a><br>
@@ -420,6 +420,9 @@<br>
 /* Support HAL for hotplug */<br>
 #undef CONFIG_HAL<br>
<br>
+/* Enable systemd-logind integration */<br>
+#undef SYSTEMD_LOGIND 1<br>
+<br>
 /* Have a monotonic clock from clock_gettime() */<br>
 #undef MONOTONIC_CLOCK<br>
<br>
diff --git a/include/systemd-logind.h b/include/systemd-logind.h<br>
new file mode 100644<br>
index 0000000..7acc4ff<br>
--- /dev/null<br>
+++ b/include/systemd-logind.h<br>
@@ -0,0 +1,45 @@<br>
+/*<br>
+ * Copyright © 2013 Red Hat, Inc.<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER<br>
+ * DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ * Author: Hans de Goede <<a href="mailto:hdegoede@redhat.com">hdegoede@redhat.com</a>><br>
+ */<br>
+<br>
+#ifndef SYSTEMD_LOGIND_H<br>
+#define SYSTEMD_LOGIND_H<br>
+<br>
+#ifdef SYSTEMD_LOGIND<br>
+int systemd_logind_init(void);<br>
+void systemd_logind_fini(void);<br>
+int systemd_logind_take_fd(int major, int minor, const char *path, Bool *paus);<br>
+void systemd_logind_release_fd(int major, int minor);<br>
+int systemd_logind_controls_session(void);<br>
+void systemd_logind_vtenter(void);<br>
+#else<br>
+#define systemd_logind_init()<br>
+#define systemd_logind_fini()<br>
+#define systemd_logind_take_fd(major, minor, path) -1<br>
+#define systemd_logind_rekease_fd(dev)<br>
+#define systemd_logind_controls_session() 0<br>
+#define systemd_logind_vtenter()<br>
+#endif<br>
+<br>
+#endif<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.5.3<br>
<br>
_______________________________________________<br>
<a href="mailto:xorg-devel@lists.x.org">xorg-devel@lists.x.org</a>: X.Org development<br>
Archives: <a href="http://lists.x.org/archives/xorg-devel" target="_blank">http://lists.x.org/archives/xorg-devel</a><br>
Info: <a href="http://lists.x.org/mailman/listinfo/xorg-devel" target="_blank">http://lists.x.org/mailman/listinfo/xorg-devel</a></font></span></blockquote></div><br><br clear="all"><br>-- <br>  Jasper<br>
</div>