<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>