[PATCH 08/12] systemd-logind: Add systemd-logind "core"
David Herrmann
dh.herrmann at gmail.com
Mon Jan 27 23:52:21 PST 2014
Hi Peter
On Tue, Jan 28, 2014 at 8:15 AM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> On Wed, Jan 15, 2014 at 03:32:22PM +0100, Hans de Goede 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.
>>
>> 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])
>> +
>
> this looks a bit odd - don't we need to check for some systemd-specific bits as
> well here? if not, or if we're already checking for it, maybe note that in
> the commit message.
For the dbus-stuff it's fine to not check for any systemd stuff, but
the patch uses systemd/sd-login.h so we definitely need to check via
pkg-config here.
>> 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();
>
> just making sure: we won't have a namespace clash with a current or furture
> systemd_logind_*? could always go for the tried and tested xfoo naming
> convention (xsystemd_logind_...)
systemd uses sd_* as global prefix, so no problem with that.
>>
>> /* 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;
>
> hmm, is there some better way of checking this rather than a string
> comparison on the path?
You can use "devnum", but major/minor comparison is actually worse, so
seems fine to me.
>
>> +
>> + 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)
>
> I find it funny that you use get/put fd when the logind API itself calls it
> "take" and "release". maybe we should stick close to that naming?
> or get_fd and release_fd or so, I found put_fd a bit confusing.
+1 for dropping the weird kernel-style _get/put suffixes.
>
>> +{
>> + 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);
>
> I'm curious why you have all the errors above but here you're just briging
> down the server if it fails.
>
>> +
>> + 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
>
> typo: "than"
>
> Cheers,
> Peter
>
>> + * pairs as it should. Instead we just use the first resume / pause now.
>> + */
Actually you're supposed to send a Properties.GetAll() iff the
PropertiesChanged signal only contains the invalidation-information.
But the first resume/pause seems fine for xorg.
Thanks
David
>> +#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
>>
>> _______________________________________________
>> 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
>>
> _______________________________________________
> 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
More information about the xorg-devel
mailing list