[PATCH v2 10/14] systemd-logind: Add systemd-logind "core"
Jasper St. Pierre
jstpierre at mecheye.net
Mon Feb 10 21:58:24 CET 2014
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.
One idea is to pass the object path of the logind session on the command
line from the display manager:
Xorg -background none -retro -logind-session
/org/freedesktop/login1/session/_1 :0
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.
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.
On Tue, Feb 4, 2014 at 6:49 AM, Hans de Goede <hdegoede at redhat.com> wrote:
> 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.
>
> Note the configure bits check for udev since systemd-logind use will only
> be
> supported in combination with udev. Besides that it only checks for dbus
> since all communication with systemd-logind is happening over dbus, so
> no further libs are needed.
>
> 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 | 2 +
> hw/xfree86/os-support/linux/Makefile.am | 6 +
> hw/xfree86/os-support/linux/systemd-logind.c | 529
> +++++++++++++++++++++++++++
> include/Makefile.am | 1 +
> include/dix-config.h.in | 3 +
> include/systemd-logind.h | 45 +++
> 9 files changed, 611 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 fe9b783..bc89bfe 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -626,6 +626,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, AS_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, AS_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])
> @@ -901,6 +902,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 ff4d38f..4579ff5 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 e1d7bd0..4447e19 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, Bool unowned)
> diff --git a/hw/xfree86/common/xf86platformBus.h
> b/hw/xfree86/common/xf86platformBus.h
> index 3e27d34..78b5a5b 100644
> --- a/hw/xfree86/common/xf86platformBus.h
> +++ b/hw/xfree86/common/xf86platformBus.h
> @@ -36,12 +36,14 @@ struct xf86_platform_device {
> /* xf86_platform_device flags */
> #define XF86_PDEV_UNOWNED 0x01
> #define XF86_PDEV_SERVER_FD 0x02
> +#define XF86_PDEV_PAUSED 0x04
>
> #ifdef XSERVER_PLATFORM_BUS
> 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..176defd
> --- /dev/null
> +++ b/hw/xfree86/os-support/linux/systemd-logind.c
> @@ -0,0 +1,529 @@
> +/*
> + * 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 <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_take_fd(int _major, int _minor, const char *path,
> + Bool *paused_ret)
> +{
> + struct systemd_logind_info *info = &logind_info;
> + DBusError error;
> + DBusMessage *msg = NULL;
> + DBusMessage *reply = NULL;
> + dbus_int32_t major = _major;
> + dbus_int32_t minor = _minor;
> + dbus_bool_t paused;
> + int fd = -1;
> +
> + if (!info->session || major == 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_release_fd(int _major, int _minor)
> +{
> + struct systemd_logind_info *info = &logind_info;
> + DBusError error;
> + DBusMessage *msg = NULL;
> + DBusMessage *reply = NULL;
> + dbus_int32_t major = _major;
> + dbus_int32_t minor = _minor;
> +
> + if (!info->session || major == 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++) {
> + if (xf86_platform_devices[i].flags & XF86_PDEV_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->flags |= XF86_PDEV_PAUSED;
> + else {
> + close(pInfo->fd);
> + pInfo->fd = -1;
> + pInfo->options = xf86ReplaceIntOption(pInfo->options, "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->flags &= ~XF86_PDEV_PAUSED;
> + systemd_logind_vtenter();
> + }
> + else {
> + pInfo->fd = fd;
> + pInfo->options = xf86ReplaceIntOption(pInfo->options, "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 than 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
> +systemd_logind_release_control(struct systemd_logind_info *info)
> +{
> + 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",
> "ReleaseControl");
> + if (!msg) {
> + 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: ReleaseControl failed: %s\n",
> + error.message);
> + goto cleanup;
> + }
> +
> +cleanup:
> + 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)
> +{
> + if (logind_info.session)
> + systemd_logind_release_control(&logind_info);
> +
> + 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 7c77956..3865d5e 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..7acc4ff
> --- /dev/null
> +++ b/include/systemd-logind.h
> @@ -0,0 +1,45 @@
> +/*
> + * 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
> +
> +#ifdef SYSTEMD_LOGIND
> +int systemd_logind_init(void);
> +void systemd_logind_fini(void);
> +int systemd_logind_take_fd(int major, int minor, const char *path, Bool
> *paus);
> +void systemd_logind_release_fd(int major, int minor);
> +int systemd_logind_controls_session(void);
> +void systemd_logind_vtenter(void);
> +#else
> +#define systemd_logind_init()
> +#define systemd_logind_fini()
> +#define systemd_logind_take_fd(major, minor, path) -1
> +#define systemd_logind_rekease_fd(dev)
> +#define systemd_logind_controls_session() 0
> +#define systemd_logind_vtenter()
> +#endif
> +
> +#endif
> --
> 1.8.5.3
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
--
Jasper
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.x.org/archives/xorg-devel/attachments/20140210/fbf65b7f/attachment-0001.html>
More information about the xorg-devel
mailing list