[gdm] multi-seat patch
Lennart Poettering
lennart at fedoraproject.org
Tue Feb 7 23:21:47 UTC 2012
commit cd51e710738ec9bfecd17cdddf5127e44cc57d11
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 8 00:21:40 2012 +0100
multi-seat patch
gdm.spec | 78 +-
multi-seat.patch | 2372 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 2414 insertions(+), 36 deletions(-)
---
diff --git a/gdm.spec b/gdm.spec
index 97463ce..78862ac 100644
--- a/gdm.spec
+++ b/gdm.spec
@@ -8,14 +8,13 @@
%define desktop_file_utils_version 0.2.90
%define gail_version 1.2.0
%define nss_version 3.11.1
-%define consolekit_version 0.3.0-9
%define fontconfig_version 2.6.0
%define _default_patch_fuzz 999
Summary: The GNOME Display Manager
Name: gdm
Version: 3.2.1.1
-Release: 10%{?dist}
+Release: 11%{?dist}
Epoch: 1
License: GPLv2+
Group: User Interface/X
@@ -42,7 +41,7 @@ Requires: system-logos
Requires: xorg-x11-server-utils
Requires: setxkbmap
Requires: xorg-x11-xinit
-Requires: ConsoleKit >= %{consolekit_version}
+Requires: systemd >= 39
Requires: accountsservice
Requires: gnome-settings-daemon >= 2.21.92
Requires: iso-codes
@@ -104,6 +103,9 @@ Provides: gdm-plugin-fingerprint = %{epoch}:%{version}-%{release}
# already upstream
Patch0: auth-fixes.patch
+# Multi-seat stuff
+Patch50: multi-seat.patch
+
# Fedora-specific
Patch98: plymouth.patch
Patch99: gdm-3.0.0-fedora-logo.patch
@@ -136,6 +138,7 @@ Development files and headers for writing GDM greeters.
%prep
%setup -q
%patch0 -p1 -b .auth-fixes
+%patch50 -p1 -b .multi-seat
%patch98 -p1 -b .plymouth
%patch99 -p1 -b .fedora-logo
@@ -387,6 +390,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
%{_libdir}/girepository-1.0/GdmGreeter-1.0.typelib
%changelog
+* Tue Feb 7 2012 Lennart Poettering <lpoetter at redhat.com> - 1:3.2.1.1-11
+- Add multi-seat patch from gdm git master
+
* Thu Jan 26 2012 Ray Strode <rstrode at redhat.com> 3.2.1.1-10
- Drop system-icon-theme requirement since we don't depend
on it anymore
@@ -860,7 +866,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
- Rework "force X on vt1" code to work after the user logs out
* Wed Oct 15 2008 Matthias Clasen <mclasen at redhat.com> - 1:2.24.0-9
-- Save some space
+- Save some space
* Fri Oct 3 2008 Matthias Clasen <mclasen at redhat.com> - 1:2.24.0-8
- Don't show a non-functional help menuitem
@@ -1186,7 +1192,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
* Fri Nov 30 2007 Matthias Clasen <mclasen at redhat.com> - 1:2.21.2-0.2007.11.20.4
- Use the new "substack" support in pam to make keyring unlocking work
-
+
* Tue Nov 20 2007 Ray Strode <rstrode at redhat.com> - 1:2.21.2-0.2007.11.20.3
- use metacity for now
@@ -1244,7 +1250,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
* Mon Oct 1 2007 Ray Strode <rstrode at redhat.com> - 1:2.20.0-10
- apply upstream patch from Brady Anderson <brady.anderson at gmail.com>
- to fix writing out .dmrc file when setting default language
+ to fix writing out .dmrc file when setting default language
(upstream bug 453916)
* Fri Sep 28 2007 Ray Strode <rstrode at redhat.com> - 1:2.20.0-9
@@ -1324,7 +1330,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
- Require gnome-keyring-pam
* Mon Aug 6 2007 Ray Strode <rstrode at redhat.com> - 1:2.19.5-5
-- change previous patch to drop even more code
+- change previous patch to drop even more code
* Mon Aug 6 2007 Ray Strode <rstrode at redhat.com> - 1:2.19.5-4
- turn off dwellmouselistener if devices don't send core events.
@@ -1506,7 +1512,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
in gdmsetup
* Tue Sep 19 2006 Ray Strode <rstrode at redhat.com> - 1:2.16.0-8.fc6
-- Add as_IN, si_LK to language list (bug 203917)
+- Add as_IN, si_LK to language list (bug 203917)
* Mon Sep 18 2006 Ray Strode <rstrode at redhat.com> - 1:2.16.0-7.fc6
- fix a problem recently introduced in the smart card forking
@@ -1676,7 +1682,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
* Tue Feb 28 2006 Ray Strode <rstrode at redhat.com> - 1:2.13.0.9-1
- Update to 2.13.0.9
-- Use new %%post section, written by
+- Use new %%post section, written by
Michal Jaegermann <michal at harddata.com> (bug 183082)
* Sat Feb 25 2006 Ray Strode <rstrode at redhat.com> - 1:2.13.0.8-6
@@ -1732,7 +1738,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
- add new theme by Diana Fong, Máirín Duffy, and me
* Mon Jan 16 2006 Ray Strode <rstrode at redhat.com> - 1:2.13.0.4-4
-- improve migration snippet (bug 177443).
+- improve migration snippet (bug 177443).
* Fri Jan 13 2006 Ray Strode <rstrode at redhat.com> - 1:2.13.0.4-3
- migrate X server configuration for pre-modular X configurations.
@@ -1818,7 +1824,7 @@ p
* Mon May 23 2005 Ray Strode <rstrode at redhat.com> 1:2.6.0.8-16
- Make sure username/password incorrect message gets displayed
(bug 158127).
-- reread system locale before starting gdm in early login mode
+- reread system locale before starting gdm in early login mode
(bug 158376).
* Thu May 19 2005 Ray Strode <rstrode at redhat.com> 1:2.6.0.8-15
@@ -1842,7 +1848,7 @@ p
- silence %%postun
* Tue Apr 26 2005 Ray Strode <rstrode at redhat.com> 1:2.6.0.8-9
-- Change default standard greeter theme to clearlooks and
+- Change default standard greeter theme to clearlooks and
default graphical greeter theme to Bluecurve specifically.
- Change default path values (bug 154280)
@@ -1898,7 +1904,7 @@ p
user's home directory (fixes bug 149899)
* Thu Feb 10 2005 Ray Strode <rstrode at redhat.com> 1:2.6.0.7-2
-- Turn off "switchdesk" mode by default which accidentally got
+- Turn off "switchdesk" mode by default which accidentally got
turned on by default in 2.6.0.5-4
* Wed Feb 2 2005 Matthias Clasen <mclasen at redhat.com> 1:2.6.0.7-1
@@ -1911,28 +1917,28 @@ p
* Thu Dec 9 2004 Dan Walsh <dwalsh at redhat.com> 1:2.6.0.5-10
- Remove pam_selinux from gdmsetup pam file
-* Wed Dec 1 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-9
-- Look up and use username instead of assuming that user entered
+* Wed Dec 1 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-9
+- Look up and use username instead of assuming that user entered
login is cannonical. Patch from
Mike Patnode <mike.patnode at centrify.com> (fixes bug 141380).
-* Thu Nov 11 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-8
+* Thu Nov 11 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-8
- Sort session list so that default session comes out on top
(fixes bug 107324)
-* Wed Nov 10 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-7
+* Wed Nov 10 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-7
- Make desktop file symlink instead of absolute (bug 104390)
- Add flexiserver back to menus
-* Wed Oct 20 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-6
+* Wed Oct 20 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-6
- Clean up xses if the session was successfullly completed.
(fixes bug #136382)
-* Tue Oct 19 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-5
+* Tue Oct 19 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-5
- Prefer nb_NO over no_NO for Norwegian (fixes bug #136033)
* Thu Oct 7 2004 Alexander Larsson <alexl at redhat.com> - 1:2.6.0.5-4
-- Change default greeter theme to "Default", require
+- Change default greeter theme to "Default", require
redhat-artwork with Default symlink.
* Wed Sep 29 2004 Ray Strode <rstrode at redhat.com> 1:2.6.0.5-3
@@ -2171,14 +2177,14 @@ p
* Wed Aug 28 2002 Havoc Pennington <hp at redhat.com>
- put /usr/X11R6/bin in path for now fixes #72781
- use proper i18n algorithm for word wrap, #71937
-- remove greek text from language picker due to lack
+- remove greek text from language picker due to lack
of greek font
- reorder PAM config file #72657
* Wed Aug 28 2002 Havoc Pennington <hp at redhat.com>
- improve gdmsetup icon
- remove GNOME session, we will instead put it in gnome-session
-- apply patch from george to make gdmphotosetup file selector
+- apply patch from george to make gdmphotosetup file selector
work
* Mon Aug 26 2002 Elliot Lee <sopwith at redhat.com> 2.4.0.7-6
@@ -2198,7 +2204,7 @@ p
- rename Gnome session to GNOME, this was just bugging me
* Thu Aug 8 2002 Havoc Pennington <hp at redhat.com>
-- 2.4.0.7 with bugfixes George kindly did for me,
+- 2.4.0.7 with bugfixes George kindly did for me,
including mnemonics for the graphical greeter
- use Wonderland gtk theme for the nongraphical greeter
- remove patches that are now upstream
@@ -2213,7 +2219,7 @@ p
* Tue Jun 25 2002 Owen Taylor <otaylor at redhat.com>
- Require redhat-artwork, make the default greeter theme Wonderland
-- Look for all configuration in .gnome2 not .gnome. This avoids problems
+- Look for all configuration in .gnome2 not .gnome. This avoids problems
with changes in the set of session/lang.
- Remove English from locale.alias, make most locales UTF-8
- Call find_lang with the right name
@@ -2295,7 +2301,7 @@ p
* Thu Jul 19 2001 Havoc Pennington <hp at redhat.com>
- depend on usermode, xinitrc
-
+
* Thu Jul 19 2001 Havoc Pennington <hp at redhat.com>
- build requires pam-devel, should fix #49448
@@ -2315,7 +2321,7 @@ p
- upgrade to 2.2.3.1, pray this fixes more than it breaks
* Thu Jul 05 2001 Havoc Pennington <hp at redhat.com>
-- add "rpm" user to those not to show in greeter
+- add "rpm" user to those not to show in greeter
* Tue Jul 03 2001 Havoc Pennington <hp at redhat.com>
- Upgrade to 2.2.3
@@ -2325,7 +2331,7 @@ p
- Prereq for scrollkeeper-update
* Thu May 30 2001 Havoc Pennington <hp at redhat.com>
-- New CVS snap with the "no weird sessions" options;
+- New CVS snap with the "no weird sessions" options;
more default settings changes
* Wed May 30 2001 Havoc Pennington <hp at redhat.com>
@@ -2334,8 +2340,8 @@ p
* Wed May 30 2001 Havoc Pennington <hp at redhat.com>
- After, oh, 2 years or so, finally upgrade version and set
release to 1. Remove all hacks and patches, pretty much;
- this will break a few things, will be putting them back
- via GNOME CVS. All changes should go in 'gdm2' module in
+ this will break a few things, will be putting them back
+ via GNOME CVS. All changes should go in 'gdm2' module in
CVS for now.
This RPM enables all kinds of features that I'm going to turn
@@ -2371,7 +2377,7 @@ p
* Sun Aug 13 2000 Owen Taylor <otaylor at redhat.com>
- Return to toplevel main loop and start Xdcmp if enabled
- (Bug #16106)
+ (Bug #16106)
* Fri Aug 11 2000 Jonathan Blandford <jrb at redhat.com>
- Up Epoch and release
@@ -2417,7 +2423,7 @@ p
* Fri Feb 04 2000 Havoc Pennington <hp at redhat.com>
- Modify Default.session and Failsafe.session not to add -login option to bash
- exec the session scripts with the user's shell with a hyphen prepended
-- doesn't seem to actually work yet with tcsh, but it doesn't seem to
+- doesn't seem to actually work yet with tcsh, but it doesn't seem to
break anything. needs a look to see why it doesn't work
* Fri Feb 04 2000 Havoc Pennington <hp at redhat.com>
@@ -2429,12 +2435,12 @@ p
- remove docs/gdm-manual.txt which doesn't seem to exist from %doc
* Fri Feb 04 2000 Havoc Pennington <hp at redhat.com>
-- Enhance 8877 fix by not deleting the "Please login"
+- Enhance 8877 fix by not deleting the "Please login"
message
* Fri Feb 04 2000 Havoc Pennington <hp at redhat.com>
-- Try to fix bug 8877 by clearing the message below
- the entry box when the prompt changes. may turn
+- Try to fix bug 8877 by clearing the message below
+ the entry box when the prompt changes. may turn
out to be a bad idea.
* Mon Jan 17 2000 Elliot Lee <sopwith at redhat.com>
@@ -2474,10 +2480,10 @@ p
* Mon Apr 19 1999 Michael Fulbright <drmike at redhat.com>
- fix to handling ancient gdm config files with non-standard language specs
- dont close display connection for xdmcp connections, else we die if remote
- end dies.
+ end dies.
* Fri Apr 16 1999 Michael Fulbright <drmike at redhat.com>
-- fix language handling to set GDM_LANG variable so gnome-session
+- fix language handling to set GDM_LANG variable so gnome-session
can pick it up
* Wed Apr 14 1999 Michael Fulbright <drmike at redhat.com>
diff --git a/multi-seat.patch b/multi-seat.patch
new file mode 100644
index 0000000..b966da6
--- /dev/null
+++ b/multi-seat.patch
@@ -0,0 +1,2372 @@
+From 3ed96cac0c49d0687fc273d11bad51772d8233ed Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 24 Jan 2012 04:16:24 +0100
+Subject: [PATCH 01/11] slave: whitespace cleanup
+
+---
+ daemon/gdm-slave.c | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
+index 787ef89..c0705fd 100644
+--- a/daemon/gdm-slave.c
++++ b/daemon/gdm-slave.c
+@@ -541,8 +541,8 @@ gdm_slave_set_windowpath (GdmSlave *slave)
+ return;
+ }
+ if (XGetWindowProperty (slave->priv->server_display,
+- DefaultRootWindow (slave->priv->server_display), prop, 0, 1,
+- False, AnyPropertyType, &actualtype, &actualformat,
++ DefaultRootWindow (slave->priv->server_display), prop, 0, 1,
++ False, AnyPropertyType, &actualtype, &actualformat,
+ &nitems, &bytes_after, &buf)) {
+ g_debug ("no XFree86_VT property\n");
+ return;
+--
+1.7.9
+
+
+From 1a5f9a0f7a65e796e044ff2f3f793e8268d31623 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 13 Jan 2012 03:53:15 +0100
+Subject: [PATCH 02/11] welcome-session: get rid of register-ck-session
+ property since it is unused
+
+Nothing was using register-ck-session and it has no effect, hence let's
+get rid of this dead code.
+---
+ daemon/Makefile.am | 6 ------
+ daemon/gdm-chooser-session.c | 1 -
+ daemon/gdm-greeter-session.c | 1 -
+ daemon/gdm-welcome-session.c | 25 +------------------------
+ 4 files changed, 1 insertions(+), 32 deletions(-)
+
+diff --git a/daemon/Makefile.am b/daemon/Makefile.am
+index 65e82b8..a153c43 100644
+--- a/daemon/Makefile.am
++++ b/daemon/Makefile.am
+@@ -115,8 +115,6 @@ gdm_simple_slave_SOURCES = \
+ simple-slave-main.c \
+ gdm-greeter-server.c \
+ gdm-greeter-server.h \
+- ck-connector.h \
+- ck-connector.c \
+ gdm-welcome-session.c \
+ gdm-welcome-session.h \
+ gdm-greeter-session.c \
+@@ -156,8 +154,6 @@ gdm_factory_slave_SOURCES = \
+ factory-slave-main.c \
+ gdm-greeter-server.c \
+ gdm-greeter-server.h \
+- ck-connector.h \
+- ck-connector.c \
+ gdm-welcome-session.c \
+ gdm-welcome-session.h \
+ gdm-greeter-session.c \
+@@ -232,8 +228,6 @@ gdm_xdmcp_chooser_slave_SOURCES = \
+ xdmcp-chooser-slave-main.c \
+ gdm-chooser-server.c \
+ gdm-chooser-server.h \
+- ck-connector.h \
+- ck-connector.c \
+ gdm-session.c \
+ gdm-session.h \
+ gdm-session-direct.c \
+diff --git a/daemon/gdm-chooser-session.c b/daemon/gdm-chooser-session.c
+index da0f2ab..6aa60a6 100644
+--- a/daemon/gdm-chooser-session.c
++++ b/daemon/gdm-chooser-session.c
+@@ -81,7 +81,6 @@ gdm_chooser_session_new (const char *display_name,
+ "server-dbus-path", GDM_CHOOSER_SERVER_DBUS_PATH,
+ "server-dbus-interface", GDM_CHOOSER_SERVER_DBUS_INTERFACE,
+ "server-env-var-name", "GDM_CHOOSER_DBUS_ADDRESS",
+- "register-ck-session", FALSE,
+ "x11-display-name", display_name,
+ "x11-display-device", display_device,
+ "x11-display-hostname", display_hostname,
+diff --git a/daemon/gdm-greeter-session.c b/daemon/gdm-greeter-session.c
+index 8032065..44259ab 100644
+--- a/daemon/gdm-greeter-session.c
++++ b/daemon/gdm-greeter-session.c
+@@ -82,7 +82,6 @@ gdm_greeter_session_new (const char *display_name,
+ "server-dbus-path", GDM_GREETER_SERVER_DBUS_PATH,
+ "server-dbus-interface", GDM_GREETER_SERVER_DBUS_INTERFACE,
+ "server-env-var-name", "GDM_GREETER_DBUS_ADDRESS",
+- "register-ck-session", TRUE,
+ "x11-display-name", display_name,
+ "x11-display-seat-id", seat_id,
+ "x11-display-device", display_device,
+diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c
+index 41144a8..8721fe7 100644
+--- a/daemon/gdm-welcome-session.c
++++ b/daemon/gdm-welcome-session.c
+@@ -42,7 +42,6 @@
+ #include <dbus/dbus-glib-lowlevel.h>
+
+ #include "gdm-common.h"
+-#include "ck-connector.h"
+
+ #include "gdm-session.h"
+ #include "gdm-session-direct.h"
+@@ -78,7 +77,6 @@ struct GdmWelcomeSessionPrivate
+ char *server_dbus_path;
+ char *server_dbus_interface;
+ char *server_env_var_name;
+- gboolean register_ck_session;
+
+ char *server_address;
+ };
+@@ -98,8 +96,7 @@ enum {
+ PROP_COMMAND,
+ PROP_SERVER_DBUS_PATH,
+ PROP_SERVER_DBUS_INTERFACE,
+- PROP_SERVER_ENV_VAR_NAME,
+- PROP_REGISTER_CK_SESSION,
++ PROP_SERVER_ENV_VAR_NAME
+ };
+
+ enum {
+@@ -1040,13 +1037,6 @@ _gdm_welcome_session_set_server_env_var_name (GdmWelcomeSession *welcome_session
+ }
+
+ static void
+-_gdm_welcome_session_set_register_ck_session (GdmWelcomeSession *welcome_session,
+- gboolean val)
+-{
+- welcome_session->priv->register_ck_session = val;
+-}
+-
+-static void
+ gdm_welcome_session_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+@@ -1093,9 +1083,6 @@ gdm_welcome_session_set_property (GObject *object,
+ case PROP_SERVER_DBUS_INTERFACE:
+ _gdm_welcome_session_set_server_dbus_interface (self, g_value_get_string (value));
+ break;
+- case PROP_REGISTER_CK_SESSION:
+- _gdm_welcome_session_set_register_ck_session (self, g_value_get_boolean (value));
+- break;
+ case PROP_SERVER_ENV_VAR_NAME:
+ _gdm_welcome_session_set_server_env_var_name (self, g_value_get_string (value));
+ break;
+@@ -1155,9 +1142,6 @@ gdm_welcome_session_get_property (GObject *object,
+ case PROP_SERVER_DBUS_INTERFACE:
+ g_value_set_string (value, self->priv->server_dbus_interface);
+ break;
+- case PROP_REGISTER_CK_SESSION:
+- g_value_set_boolean (value, self->priv->register_ck_session);
+- break;
+ case PROP_SERVER_ENV_VAR_NAME:
+ g_value_set_string (value, self->priv->server_env_var_name);
+ break;
+@@ -1279,13 +1263,6 @@ gdm_welcome_session_class_init (GdmWelcomeSessionClass *klass)
+ "command",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+- g_object_class_install_property (object_class,
+- PROP_REGISTER_CK_SESSION,
+- g_param_spec_boolean ("register-ck-session",
+- NULL,
+- NULL,
+- FALSE,
+- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ signals [STARTED] =
+ g_signal_new ("started",
+ G_OBJECT_CLASS_TYPE (object_class),
+--
+1.7.9
+
+
+From 02697e774c2f669d1d4109fc1de975407740409b Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 27 Jul 2011 01:18:55 +0200
+Subject: [PATCH 03/11] build-sys: add configure option --with-systemd
+
+---
+ configure.ac | 25 +++++++++++++++++++++++++
+ 1 files changed, 25 insertions(+), 0 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 30397c5..dec31a9 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -272,6 +272,11 @@ AC_ARG_WITH(console-kit,
+ [Add ConsoleKit support @<:@default=auto@:>@]),,
+ with_console_kit=auto)
+
++AC_ARG_WITH(systemd,
++ AS_HELP_STRING([--with-systemd],
++ [Add systemd support @<:@default=auto@:>@]),,
++ with_systemd=auto)
++
+ AC_ARG_WITH(at-spi-registryd-directory,
+ AS_HELP_STRING([--with-at-spi-registryd-directory],
+ [Specify the directory of at-spi-registryd @<:@default=libexecdir@:>@])],,
+@@ -927,6 +932,25 @@ AM_CONDITIONAL(WITH_CONSOLE_KIT, test x$use_console_kit = xyes)
+ AC_SUBST(WITH_CONSOLE_KIT)
+
+ dnl ---------------------------------------------------------------------------
++dnl - Check for systemd support
++dnl ---------------------------------------------------------------------------
++
++use_systemd=no
++if test "x$with_systemd" != "xno" ; then
++ PKG_CHECK_MODULES(SYSTEMD,
++ libsystemd-daemon
++ libsystemd-login
++ )
++ AC_SUBST(SYSTEMD_CFLAGS)
++ AC_SUBST(SYSTEMD_LIBS)
++
++ use_systemd=yes
++ AC_DEFINE(WITH_SYSTEMD, 1, [Define to enable systemd support])
++fi
++AM_CONDITIONAL(WITH_SYSTEMD, test x$use_systemd = xyes)
++AC_SUBST(WITH_SYSTEMD)
++
++dnl ---------------------------------------------------------------------------
+ dnl - Check for D-Bus
+ dnl ---------------------------------------------------------------------------
+
+@@ -1511,6 +1535,7 @@ echo \
+ XDMCP support: ${XDMCP_SUPPORT}
+ SELinux support: ${with_selinux}
+ ConsoleKit support: ${use_console_kit}
++ systemd support: ${use_systemd}
+ UPower support: ${have_upower}
+ Build with RBAC: ${msg_rbac_shutdown}
+ "
+--
+1.7.9
+
+
+From a58b27ff573109f0d9a8971fbc80e797d6cc2733 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 24 Jan 2012 04:15:26 +0100
+Subject: [PATCH 04/11] slave: add native systemd implementations of
+ locking/session activation
+
+---
+ daemon/Makefile.am | 5 +
+ daemon/gdm-slave.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 242 insertions(+), 14 deletions(-)
+
+diff --git a/daemon/Makefile.am b/daemon/Makefile.am
+index a153c43..43d416e 100644
+--- a/daemon/Makefile.am
++++ b/daemon/Makefile.am
+@@ -24,6 +24,7 @@ AM_CPPFLAGS = \
+ $(XLIB_CFLAGS) \
+ $(WARN_CFLAGS) \
+ $(DEBUG_CFLAGS) \
++ $(SYSTEMD_CFLAGS) \
+ -DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \
+ $(NULL)
+
+@@ -148,6 +149,7 @@ gdm_simple_slave_LDADD = \
+ $(DAEMON_LIBS) \
+ $(EXTRA_DAEMON_LIBS) \
+ $(LIBXKLAVIER_LIBS) \
++ $(SYSTEMD_LIBS) \
+ $(NULL)
+
+ gdm_factory_slave_SOURCES = \
+@@ -188,6 +190,7 @@ gdm_factory_slave_LDADD = \
+ $(top_builddir)/common/libgdmcommon.la \
+ $(XLIB_LIBS) \
+ $(DAEMON_LIBS) \
++ $(SYSTEMD_LIBS) \
+ $(NULL)
+
+ gdm_product_slave_SOURCES = \
+@@ -222,6 +225,7 @@ gdm_product_slave_LDADD = \
+ $(DAEMON_LIBS) \
+ $(EXTRA_DAEMON_LIBS) \
+ $(LIBXKLAVIER_LIBS) \
++ $(SYSTEMD_LIBS) \
+ $(NULL)
+
+ gdm_xdmcp_chooser_slave_SOURCES = \
+@@ -254,6 +258,7 @@ gdm_xdmcp_chooser_slave_LDADD = \
+ $(DAEMON_LIBS) \
+ $(EXTRA_DAEMON_LIBS) \
+ $(LIBXKLAVIER_LIBS) \
++ $(SYSTEMD_LIBS) \
+ $(top_builddir)/common/libgdmcommon.la \
+ $(NULL)
+
+diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
+index c0705fd..371b9bd 100644
+--- a/daemon/gdm-slave.c
++++ b/daemon/gdm-slave.c
+@@ -51,6 +51,11 @@
+ #include <libxklavier/xklavier.h>
+ #endif
+
++#ifdef WITH_SYSTEMD
++#include <systemd/sd-login.h>
++#include <systemd/sd-daemon.h>
++#endif
++
+ #include "gdm-common.h"
+ #include "gdm-xerrors.h"
+
+@@ -1198,6 +1203,8 @@ _get_uid_and_gid_for_user (const char *username,
+ return TRUE;
+ }
+
++#ifdef WITH_CONSOLE_KIT
++
+ static gboolean
+ x11_session_is_on_seat (GdmSlave *slave,
+ const char *session_id,
+@@ -1295,9 +1302,63 @@ x11_session_is_on_seat (GdmSlave *slave,
+ return ret;
+ }
+
+-char *
+-gdm_slave_get_primary_session_id_for_user (GdmSlave *slave,
+- const char *username)
++#endif
++
++#ifdef WITH_SYSTEMD
++static char*
++gdm_slave_get_primary_session_id_for_user_from_systemd (GdmSlave *slave,
++ const char *username)
++{
++ int res, i;
++ char **sessions;
++ uid_t uid;
++ char *primary_ssid;
++
++ primary_ssid = NULL;
++
++ res = sd_seat_can_multi_session (slave->priv->display_seat_id);
++ if (res < 0) {
++ g_warning ("GdmSlave: Failed to determine whether seat is multi-session capable: %s", strerror (-res));
++ return NULL;
++ } else if (res == 0) {
++ g_debug ("GdmSlave: seat is unable to activate sessions");
++ return NULL;
++ }
++
++ if (! _get_uid_and_gid_for_user (username, &uid, NULL)) {
++ g_debug ("GdmSlave: unable to determine uid for user: %s", username);
++ return NULL;
++ }
++
++ res = sd_seat_get_sessions (slave->priv->display_seat_id, &sessions, NULL, NULL);
++ if (res < 0) {
++ g_warning ("GdmSlave: Failed to get sessions on seat: %s", strerror (-res));
++ return NULL;
++ }
++
++ for (i = 0; sessions[i] != NULL; i++) {
++
++ if (primary_ssid == NULL) {
++ uid_t other;
++
++ res = sd_session_get_uid (sessions[i], &other);
++ if (res > 0 && other == uid) {
++ primary_ssid = g_strdup (sessions[i]);
++ }
++ }
++
++ free (sessions[i]);
++ }
++
++ free (sessions);
++ return primary_ssid;
++}
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++static char *
++gdm_slave_get_primary_session_id_for_user_from_ck (GdmSlave *slave,
++ const char *username)
+ {
+ gboolean res;
+ gboolean can_activate_sessions;
+@@ -1309,11 +1370,6 @@ gdm_slave_get_primary_session_id_for_user (GdmSlave *slave,
+ int i;
+ uid_t uid;
+
+- if (slave->priv->display_seat_id == NULL || slave->priv->display_seat_id[0] == '\0') {
+- g_debug ("GdmSlave: display seat ID is not set; can't switch sessions");
+- return NULL;
+- }
+-
+ manager_proxy = NULL;
+ primary_ssid = NULL;
+ sessions = NULL;
+@@ -1396,11 +1452,91 @@ gdm_slave_get_primary_session_id_for_user (GdmSlave *slave,
+
+ return primary_ssid;
+ }
++#endif
++
++char *
++gdm_slave_get_primary_session_id_for_user (GdmSlave *slave,
++ const char *username)
++{
++
++ if (slave->priv->display_seat_id == NULL || slave->priv->display_seat_id[0] == '\0') {
++ g_debug ("GdmSlave: display seat ID is not set; can't switch sessions");
++ return NULL;
++ }
+
++#ifdef WITH_SYSTEMD
++ if (sd_booted () > 0) {
++ return gdm_slave_get_primary_session_id_for_user_from_systemd (slave, username);
++ }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++ return gdm_slave_get_primary_session_id_for_user_from_ck (slave, username);
++#else
++ return NULL;
++#endif
++}
++
++#ifdef WITH_SYSTEMD
+ static gboolean
+-activate_session_id (GdmSlave *slave,
+- const char *seat_id,
+- const char *session_id)
++activate_session_id_for_systemd (GdmSlave *slave,
++ const char *seat_id,
++ const char *session_id)
++{
++ DBusError local_error;
++ DBusMessage *message;
++ DBusMessage *reply;
++ gboolean ret;
++
++ ret = FALSE;
++ reply = NULL;
++
++ dbus_error_init (&local_error);
++
++ message = dbus_message_new_method_call ("org.freedesktop.login1",
++ "/org/freedesktop/login1",
++ "org.freedesktop.login1.Manager",
++ "ActivateSessionOnSeat");
++ if (message == NULL) {
++ goto out;
++ }
++
++ if (! dbus_message_append_args (message,
++ DBUS_TYPE_STRING, &session_id,
++ DBUS_TYPE_STRING, &seat_id,
++ DBUS_TYPE_INVALID)) {
++ goto out;
++ }
++
++ reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (slave->priv->connection),
++ message,
++ -1,
++ &local_error);
++ if (dbus_error_is_set (&local_error)) {
++ g_warning ("GdmSlave: Unable to activate session: %s", local_error.message);
++ dbus_error_free (&local_error);
++ goto out;
++ }
++
++ ret = TRUE;
++
++ out:
++ if (message != NULL) {
++ dbus_message_unref (message);
++ }
++ if (reply != NULL) {
++ dbus_message_unref (reply);
++ }
++
++ return ret;
++}
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++static gboolean
++activate_session_id_for_ck (GdmSlave *slave,
++ const char *seat_id,
++ const char *session_id)
+ {
+ DBusError local_error;
+ DBusMessage *message;
+@@ -1448,16 +1584,82 @@ activate_session_id (GdmSlave *slave,
+
+ return ret;
+ }
++#endif
++
++static gboolean
++activate_session_id (GdmSlave *slave,
++ const char *seat_id,
++ const char *session_id)
++{
++
++#ifdef WITH_SYSTEMD
++ if (sd_booted () > 0) {
++ return activate_session_id_for_systemd (slave, seat_id, session_id);
++ }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++ return activate_session_id_for_ck (slave, seat_id, session_id);
++#else
++ return FALSE;
++#endif
++}
+
++#ifdef WITH_SYSTEMD
+ static gboolean
+-session_unlock (GdmSlave *slave,
+- const char *ssid)
++session_unlock_for_systemd (GdmSlave *slave,
++ const char *ssid)
++{
++ DBusError error;
++ DBusMessage *message;
++ DBusMessage *reply;
++
++ dbus_error_init (&error);
++
++ message = dbus_message_new_method_call ("org.freedesktop.login",
++ "/org/freedesktop/login1",
++ "org.freedesktop.login1.Manager",
++ "UnlockSession");
++
++ if (message == NULL) {
++ g_debug ("GdmSlave: couldn't allocate the D-Bus message");
++ return FALSE;
++ }
++
++ if (! dbus_message_append_args (message,
++ DBUS_TYPE_STRING, &ssid,
++ DBUS_TYPE_INVALID)) {
++ g_debug ("GdmSlave: couldn't attach the D-Bus message data");
++ return FALSE;
++ }
++
++ reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (slave->priv->connection),
++ message,
++ -1, &error);
++ dbus_message_unref(message);
++ if (reply != NULL) {
++ dbus_message_unref(reply);
++ }
++
++ if (dbus_error_is_set (&error)) {
++ g_warning ("GdmSlave: Unable to unlock session: %s", error.message);
++ dbus_error_free (&error);
++ return FALSE;
++ }
++
++ return TRUE;
++}
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++static gboolean
++session_unlock_for_ck (GdmSlave *slave,
++ const char *ssid)
+ {
+ DBusError error;
+ DBusMessage *message;
+ DBusMessage *reply;
+
+- g_debug ("ConsoleKit: Unlocking session %s", ssid);
+ message = dbus_message_new_method_call (CK_NAME,
+ ssid,
+ CK_SESSION_INTERFACE,
+@@ -1485,6 +1687,27 @@ session_unlock (GdmSlave *slave,
+
+ return TRUE;
+ }
++#endif
++
++static gboolean
++session_unlock (GdmSlave *slave,
++ const char *ssid)
++{
++
++ g_debug ("ConsoleKit: Unlocking session %s", ssid);
++
++#ifdef WITH_SYSTEMD
++ if (sd_booted () > 0) {
++ return session_unlock_for_systemd (slave, ssid);
++ }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++ return session_unlock_for_ck (slave, ssid);
++#else
++ return TRUE;
++#endif
++}
+
+ gboolean
+ gdm_slave_switch_to_user_session (GdmSlave *slave,
+--
+1.7.9
+
+
+From c77c03e6ca67ea670de89babbbfd9648b2fec9bd Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 27 Jul 2011 01:27:22 +0200
+Subject: [PATCH 05/11] build-sys: make CK support optional
+
+---
+ daemon/Makefile.am | 8 ++++++--
+ 1 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/daemon/Makefile.am b/daemon/Makefile.am
+index 43d416e..b228fea 100644
+--- a/daemon/Makefile.am
++++ b/daemon/Makefile.am
+@@ -264,8 +264,6 @@ gdm_xdmcp_chooser_slave_LDADD = \
+
+ gdm_session_worker_SOURCES = \
+ session-worker-main.c \
+- ck-connector.h \
+- ck-connector.c \
+ gdm-session-settings.h \
+ gdm-session-settings.c \
+ gdm-session-auditor.h \
+@@ -274,6 +272,12 @@ gdm_session_worker_SOURCES = \
+ gdm-session-worker.c \
+ $(NULL)
+
++if WITH_CONSOLE_KIT
++gdm_session_worker_SOURCES += \
++ ck-connector.h \
++ ck-connector.c
++endif
++
+ if HAVE_LIBAUDIT
+ gdm_session_worker_SOURCES += gdm-session-linux-auditor.h \
+ gdm-session-linux-auditor.c
+--
+1.7.9
+
+
+From 54abef19f0b338d7c57c4629f6ca2cf441bcb553 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 27 Jul 2011 01:30:09 +0200
+Subject: [PATCH 06/11] slave: pass seat id from product/simple slave to
+ worker, via the direct session
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Pass seat id from product and simple slave to the direct sessions
+created by it (along with the other display meta data we pass already).
+
+Pass seat id from session to worker (via D-Bus) along with the other
+display meta data.
+
+We need the seat information for the PAM conversation (later patch)
+hence we need to pass it from the slaves down to the workers.
+
+(Note that the seat ID has always been passed from the display to the
+slave, we just need to pass it on the worker now, so that the chain is
+complete: display → slave → session → worker)
+---
+ daemon/gdm-product-slave.c | 3 ++
+ daemon/gdm-session-direct.c | 60 ++++++++++++++++++++++++++++++++++++++++++
+ daemon/gdm-session-direct.h | 2 +
+ daemon/gdm-session-worker.c | 12 +++++++-
+ daemon/gdm-simple-slave.c | 3 ++
+ daemon/gdm-welcome-session.c | 1 +
+ daemon/test-session.c | 1 +
+ 7 files changed, 81 insertions(+), 1 deletions(-)
+
+diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c
+index d56a74b..629c6e7 100644
+--- a/daemon/gdm-product-slave.c
++++ b/daemon/gdm-product-slave.c
+@@ -998,6 +998,7 @@ create_new_session (GdmProductSlave *slave)
+ char *display_name;
+ char *display_hostname;
+ char *display_device;
++ char *display_seat_id;
+ char *display_x11_authority_file;
+
+ g_debug ("GdmProductSlave: Creating new session");
+@@ -1008,6 +1009,7 @@ create_new_session (GdmProductSlave *slave)
+ "display-hostname", &display_hostname,
+ "display-is-local", &display_is_local,
+ "display-x11-authority-file", &display_x11_authority_file,
++ "display-seat-id", &display_seat_id,
+ NULL);
+
+ /* FIXME: we don't yet have a display device! */
+@@ -1017,6 +1019,7 @@ create_new_session (GdmProductSlave *slave)
+ display_name,
+ display_hostname,
+ display_device,
++ display_seat_id,
+ display_x11_authority_file,
+ display_is_local);
+ g_free (display_id);
+diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
+index bb2bff8..9f750f2 100644
+--- a/daemon/gdm-session-direct.c
++++ b/daemon/gdm-session-direct.c
+@@ -103,6 +103,7 @@ struct _GdmSessionDirectPrivate
+ char *display_name;
+ char *display_hostname;
+ char *display_device;
++ char *display_seat_id;
+ char *display_x11_authority_file;
+ gboolean display_is_local;
+
+@@ -121,6 +122,7 @@ enum {
+ PROP_DISPLAY_HOSTNAME,
+ PROP_DISPLAY_IS_LOCAL,
+ PROP_DISPLAY_DEVICE,
++ PROP_DISPLAY_SEAT_ID,
+ PROP_DISPLAY_X11_AUTHORITY_FILE,
+ PROP_USER_X11_AUTHORITY_FILE,
+ };
+@@ -1389,6 +1391,7 @@ do_introspect (DBusConnection *connection,
+ " <arg name=\"service_name\" type=\"s\"/>\n"
+ " <arg name=\"x11_display_name\" type=\"s\"/>\n"
+ " <arg name=\"display_device\" type=\"s\"/>\n"
++ " <arg name=\"display_seat\" type=\"s\"/>\n"
+ " <arg name=\"hostname\" type=\"s\"/>\n"
+ " <arg name=\"x11_authority_file\" type=\"s\"/>\n"
+ " </signal>\n"
+@@ -1396,6 +1399,7 @@ do_introspect (DBusConnection *connection,
+ " <arg name=\"service_name\" type=\"s\"/>\n"
+ " <arg name=\"x11_display_name\" type=\"s\"/>\n"
+ " <arg name=\"display_device\" type=\"s\"/>\n"
++ " <arg name=\"display_seat\" type=\"s\"/>\n"
+ " <arg name=\"hostname\" type=\"s\"/>\n"
+ " <arg name=\"x11_authority_file\" type=\"s\"/>\n"
+ " <arg name=\"username\" type=\"s\"/>\n"
+@@ -1404,6 +1408,7 @@ do_introspect (DBusConnection *connection,
+ " <arg name=\"service_name\" type=\"s\"/>\n"
+ " <arg name=\"x11_display_name\" type=\"s\"/>\n"
+ " <arg name=\"display_device\" type=\"s\"/>\n"
++ " <arg name=\"display_seat\" type=\"s\"/>\n"
+ " <arg name=\"hostname\" type=\"s\"/>\n"
+ " <arg name=\"x11_authority_file\" type=\"s\"/>\n"
+ " <arg name=\"log_file\" type=\"s\"/>\n"
+@@ -1975,6 +1980,7 @@ send_setup (GdmSessionDirect *session,
+ DBusMessageIter iter;
+ const char *display_name;
+ const char *display_device;
++ const char *display_seat_id;
+ const char *display_hostname;
+ const char *display_x11_authority_file;
+ GdmSessionConversation *conversation;
+@@ -1996,6 +2002,11 @@ send_setup (GdmSessionDirect *session,
+ } else {
+ display_device = "";
+ }
++ if (session->priv->display_seat_id != NULL) {
++ display_seat_id = session->priv->display_seat_id;
++ } else {
++ display_seat_id = "";
++ }
+ if (session->priv->display_x11_authority_file != NULL) {
+ display_x11_authority_file = session->priv->display_x11_authority_file;
+ } else {
+@@ -2012,6 +2023,7 @@ send_setup (GdmSessionDirect *session,
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
+
+@@ -2031,6 +2043,7 @@ send_setup_for_user (GdmSessionDirect *session,
+ DBusMessageIter iter;
+ const char *display_name;
+ const char *display_device;
++ const char *display_seat_id;
+ const char *display_hostname;
+ const char *display_x11_authority_file;
+ const char *selected_user;
+@@ -2053,6 +2066,11 @@ send_setup_for_user (GdmSessionDirect *session,
+ } else {
+ display_device = "";
+ }
++ if (session->priv->display_seat_id != NULL) {
++ display_seat_id = session->priv->display_seat_id;
++ } else {
++ display_seat_id = "";
++ }
+ if (session->priv->display_x11_authority_file != NULL) {
+ display_x11_authority_file = session->priv->display_x11_authority_file;
+ } else {
+@@ -2074,6 +2092,7 @@ send_setup_for_user (GdmSessionDirect *session,
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user);
+@@ -2095,6 +2114,7 @@ send_setup_for_program (GdmSessionDirect *session,
+ DBusMessageIter iter;
+ const char *display_name;
+ const char *display_device;
++ const char *display_seat_id;
+ const char *display_hostname;
+ const char *display_x11_authority_file;
+ GdmSessionConversation *conversation;
+@@ -2116,6 +2136,11 @@ send_setup_for_program (GdmSessionDirect *session,
+ } else {
+ display_device = "";
+ }
++ if (session->priv->display_seat_id != NULL) {
++ display_seat_id = session->priv->display_seat_id;
++ } else {
++ display_seat_id = "";
++ }
+ if (session->priv->display_x11_authority_file != NULL) {
+ display_x11_authority_file = session->priv->display_x11_authority_file;
+ } else {
+@@ -2132,6 +2157,7 @@ send_setup_for_program (GdmSessionDirect *session,
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &service_name);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_name);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_device);
++ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_seat_id);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &log_file);
+@@ -2587,6 +2613,14 @@ gdm_session_direct_get_display_device (GdmSessionDirect *session)
+ return g_strdup (session->priv->display_device);
+ }
+
++char *
++gdm_session_direct_get_display_seat_id (GdmSessionDirect *session)
++{
++ g_return_val_if_fail (session != NULL, NULL);
++
++ return g_strdup (session->priv->display_seat_id);
++}
++
+ gboolean
+ gdm_session_direct_bypasses_xsession (GdmSessionDirect *session_direct)
+ {
+@@ -2754,6 +2788,14 @@ _gdm_session_direct_set_display_device (GdmSessionDirect *session,
+ }
+
+ static void
++_gdm_session_direct_set_display_seat_id (GdmSessionDirect *session,
++ const char *name)
++{
++ g_free (session->priv->display_seat_id);
++ session->priv->display_seat_id = g_strdup (name);
++}
++
++static void
+ _gdm_session_direct_set_user_x11_authority_file (GdmSessionDirect *session,
+ const char *name)
+ {
+@@ -2799,6 +2841,9 @@ gdm_session_direct_set_property (GObject *object,
+ case PROP_DISPLAY_DEVICE:
+ _gdm_session_direct_set_display_device (self, g_value_get_string (value));
+ break;
++ case PROP_DISPLAY_SEAT_ID:
++ _gdm_session_direct_set_display_seat_id (self, g_value_get_string (value));
++ break;
+ case PROP_USER_X11_AUTHORITY_FILE:
+ _gdm_session_direct_set_user_x11_authority_file (self, g_value_get_string (value));
+ break;
+@@ -2837,6 +2882,9 @@ gdm_session_direct_get_property (GObject *object,
+ case PROP_DISPLAY_DEVICE:
+ g_value_set_string (value, self->priv->display_device);
+ break;
++ case PROP_DISPLAY_SEAT_ID:
++ g_value_set_string (value, self->priv->display_seat_id);
++ break;
+ case PROP_USER_X11_AUTHORITY_FILE:
+ g_value_set_string (value, self->priv->user_x11_authority_file);
+ break;
+@@ -2875,6 +2923,9 @@ gdm_session_direct_dispose (GObject *object)
+ g_free (session->priv->display_device);
+ session->priv->display_device = NULL;
+
++ g_free (session->priv->display_seat_id);
++ session->priv->display_seat_id = NULL;
++
+ g_free (session->priv->display_x11_authority_file);
+ session->priv->display_x11_authority_file = NULL;
+
+@@ -3063,6 +3114,13 @@ gdm_session_direct_class_init (GdmSessionDirectClass *session_class)
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
++ g_object_class_install_property (object_class,
++ PROP_DISPLAY_SEAT_ID,
++ g_param_spec_string ("display-seat-id",
++ "display seat id",
++ "display seat id",
++ NULL,
++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ dbus_g_object_type_install_info (GDM_TYPE_SESSION_DIRECT, &dbus_glib_gdm_session_direct_object_info);
+ }
+@@ -3072,6 +3130,7 @@ gdm_session_direct_new (const char *display_id,
+ const char *display_name,
+ const char *display_hostname,
+ const char *display_device,
++ const char *display_seat_id,
+ const char *display_x11_authority_file,
+ gboolean display_is_local)
+ {
+@@ -3082,6 +3141,7 @@ gdm_session_direct_new (const char *display_id,
+ "display-name", display_name,
+ "display-hostname", display_hostname,
+ "display-device", display_device,
++ "display-seat-id", display_seat_id,
+ "display-x11-authority-file", display_x11_authority_file,
+ "display-is-local", display_is_local,
+ NULL);
+diff --git a/daemon/gdm-session-direct.h b/daemon/gdm-session-direct.h
+index 8023bf9..e35fa35 100644
+--- a/daemon/gdm-session-direct.h
++++ b/daemon/gdm-session-direct.h
+@@ -52,11 +52,13 @@ GdmSessionDirect * gdm_session_direct_new (const char *disp
+ const char *display_name,
+ const char *display_hostname,
+ const char *display_device,
++ const char *display_seat_id,
+ const char *display_x11_authority_file,
+ gboolean display_is_local) G_GNUC_MALLOC;
+
+ char * gdm_session_direct_get_username (GdmSessionDirect *session_direct);
+ char * gdm_session_direct_get_display_device (GdmSessionDirect *session_direct);
++char * gdm_session_direct_get_display_seat_id (GdmSessionDirect *session_direct);
+ gboolean gdm_session_direct_bypasses_xsession (GdmSessionDirect *session_direct);
+
+ /* Exported methods */
+diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
+index c402e6c..1fe0aaf 100644
+--- a/daemon/gdm-session-worker.c
++++ b/daemon/gdm-session-worker.c
+@@ -118,6 +118,7 @@ struct GdmSessionWorkerPrivate
+ char *x11_display_name;
+ char *x11_authority_file;
+ char *display_device;
++ char *display_seat_id;
+ char *hostname;
+ char *username;
+ char *log_file;
+@@ -2494,6 +2495,7 @@ on_setup (GdmSessionWorker *worker,
+ const char *x11_display_name;
+ const char *x11_authority_file;
+ const char *console;
++ const char *seat_id;
+ const char *hostname;
+ dbus_bool_t res;
+
+@@ -2508,6 +2510,7 @@ on_setup (GdmSessionWorker *worker,
+ DBUS_TYPE_STRING, &service,
+ DBUS_TYPE_STRING, &x11_display_name,
+ DBUS_TYPE_STRING, &console,
++ DBUS_TYPE_STRING, &seat_id,
+ DBUS_TYPE_STRING, &hostname,
+ DBUS_TYPE_STRING, &x11_authority_file,
+ DBUS_TYPE_INVALID);
+@@ -2516,6 +2519,7 @@ on_setup (GdmSessionWorker *worker,
+ worker->priv->x11_display_name = g_strdup (x11_display_name);
+ worker->priv->x11_authority_file = g_strdup (x11_authority_file);
+ worker->priv->display_device = g_strdup (console);
++ worker->priv->display_seat_id = g_strdup (seat_id);
+ worker->priv->hostname = g_strdup (hostname);
+ worker->priv->username = NULL;
+
+@@ -2536,6 +2540,7 @@ on_setup_for_user (GdmSessionWorker *worker,
+ const char *x11_display_name;
+ const char *x11_authority_file;
+ const char *console;
++ const char *seat_id;
+ const char *hostname;
+ const char *username;
+ dbus_bool_t res;
+@@ -2551,6 +2556,7 @@ on_setup_for_user (GdmSessionWorker *worker,
+ DBUS_TYPE_STRING, &service,
+ DBUS_TYPE_STRING, &x11_display_name,
+ DBUS_TYPE_STRING, &console,
++ DBUS_TYPE_STRING, &seat_id,
+ DBUS_TYPE_STRING, &hostname,
+ DBUS_TYPE_STRING, &x11_authority_file,
+ DBUS_TYPE_STRING, &username,
+@@ -2560,6 +2566,7 @@ on_setup_for_user (GdmSessionWorker *worker,
+ worker->priv->x11_display_name = g_strdup (x11_display_name);
+ worker->priv->x11_authority_file = g_strdup (x11_authority_file);
+ worker->priv->display_device = g_strdup (console);
++ worker->priv->display_seat_id = g_strdup (seat_id);
+ worker->priv->hostname = g_strdup (hostname);
+ worker->priv->username = g_strdup (username);
+
+@@ -2598,6 +2605,7 @@ on_setup_for_program (GdmSessionWorker *worker,
+ char *service;
+ char *x11_display_name;
+ char *console;
++ char *seat_id;
+ char *hostname;
+ char *x11_authority_file;
+ char *log_file;
+@@ -2614,6 +2622,7 @@ on_setup_for_program (GdmSessionWorker *worker,
+ DBUS_TYPE_STRING, &service,
+ DBUS_TYPE_STRING, &x11_display_name,
+ DBUS_TYPE_STRING, &console,
++ DBUS_TYPE_STRING, &seat_id,
+ DBUS_TYPE_STRING, &hostname,
+ DBUS_TYPE_STRING, &x11_authority_file,
+ DBUS_TYPE_STRING, &log_file,
+@@ -2627,6 +2636,7 @@ on_setup_for_program (GdmSessionWorker *worker,
+ worker->priv->x11_display_name = g_strdup (x11_display_name);
+ worker->priv->hostname = g_strdup (hostname);
+ worker->priv->display_device = g_strdup (console);
++ worker->priv->display_seat_id = g_strdup (seat_id);
+ worker->priv->x11_authority_file = g_strdup (x11_authority_file);
+ worker->priv->log_file = g_strdup (log_file);
+ worker->priv->is_program_session = TRUE;
+@@ -2945,6 +2955,7 @@ gdm_session_worker_finalize (GObject *object)
+ g_free (worker->priv->x11_display_name);
+ g_free (worker->priv->x11_authority_file);
+ g_free (worker->priv->display_device);
++ g_free (worker->priv->display_seat_id);
+ g_free (worker->priv->hostname);
+ g_free (worker->priv->username);
+ g_free (worker->priv->server_address);
+@@ -2964,4 +2975,3 @@ gdm_session_worker_new (const char *address)
+
+ return GDM_SESSION_WORKER (object);
+ }
+-
+diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
+index b9165fd..873b7f9 100644
+--- a/daemon/gdm-simple-slave.c
++++ b/daemon/gdm-simple-slave.c
+@@ -750,6 +750,7 @@ create_new_session (GdmSimpleSlave *slave)
+ char *display_name;
+ char *display_hostname;
+ char *display_device;
++ char *display_seat_id;
+ char *display_x11_authority_file;
+
+ g_debug ("GdmSimpleSlave: Creating new session");
+@@ -760,6 +761,7 @@ create_new_session (GdmSimpleSlave *slave)
+ "display-hostname", &display_hostname,
+ "display-is-local", &display_is_local,
+ "display-x11-authority-file", &display_x11_authority_file,
++ "display-seat-id", &display_seat_id,
+ NULL);
+
+ display_device = NULL;
+@@ -771,6 +773,7 @@ create_new_session (GdmSimpleSlave *slave)
+ display_name,
+ display_hostname,
+ display_device,
++ display_seat_id,
+ display_x11_authority_file,
+ display_is_local);
+ g_free (display_id);
+diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c
+index 8721fe7..26af552 100644
+--- a/daemon/gdm-welcome-session.c
++++ b/daemon/gdm-welcome-session.c
+@@ -849,6 +849,7 @@ gdm_welcome_session_start (GdmWelcomeSession *welcome_session)
+ welcome_session->priv->x11_display_name,
+ welcome_session->priv->x11_display_hostname,
+ welcome_session->priv->x11_display_device,
++ welcome_session->priv->x11_display_seat_id,
+ welcome_session->priv->x11_authority_file,
+ welcome_session->priv->x11_display_is_local));
+
+diff --git a/daemon/test-session.c b/daemon/test-session.c
+index fe78230..f75d5ed 100644
+--- a/daemon/test-session.c
++++ b/daemon/test-session.c
+@@ -268,6 +268,7 @@ main (int argc,
+ ":0",
+ g_get_host_name (),
+ ttyname (STDIN_FILENO),
++ "",
+ getenv("XAUTHORITY"),
+ TRUE);
+ g_debug ("GdmSessionDirect object created successfully");
+--
+1.7.9
+
+
+From 69a8b09c993669e324c785be463136313be2cdb4 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 27 Jul 2011 01:31:16 +0200
+Subject: [PATCH 07/11] pam: pass XDG_SEAT env var into PAM to inform PAM
+ modules about seat id
+
+This optionally replaces the current CK session registration logic with
+support for passing seat information to pam_systemd (and hence rely on
+pam_systemd's session registration).
+
+With this patch applied we can register sessions in systemd and in CK
+with the same binary.
+---
+ daemon/Makefile.am | 1 +
+ daemon/gdm-session-worker.c | 34 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 35 insertions(+), 0 deletions(-)
+
+diff --git a/daemon/Makefile.am b/daemon/Makefile.am
+index b228fea..8f8eedf 100644
+--- a/daemon/Makefile.am
++++ b/daemon/Makefile.am
+@@ -296,6 +296,7 @@ gdm_session_worker_LDFLAGS = \
+ gdm_session_worker_LDADD = \
+ $(top_builddir)/common/libgdmcommon.la \
+ $(DAEMON_LIBS) \
++ $(SYSTEMD_LIBS) \
+ $(NULL)
+
+ sbin_PROGRAMS = \
+diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
+index 1fe0aaf..acf820c 100644
+--- a/daemon/gdm-session-worker.c
++++ b/daemon/gdm-session-worker.c
+@@ -46,7 +46,13 @@
+
+ #include <X11/Xauth.h>
+
++#ifdef WITH_SYSTEMD
++#include <systemd/sd-daemon.h>
++#endif
++
++#ifdef WITH_CONSOLE_KIT
+ #include "ck-connector.h"
++#endif
+
+ #include "gdm-common.h"
+ #include "gdm-log.h"
+@@ -107,7 +113,9 @@ struct GdmSessionWorkerPrivate
+
+ int exit_code;
+
++#ifdef WITH_CONSOLE_KIT
+ CkConnector *ckc;
++#endif
+ pam_handle_t *pam_handle;
+
+ GPid child_pid;
+@@ -151,8 +159,13 @@ static void gdm_session_worker_class_init (GdmSessionWorkerClass *klass);
+ static void gdm_session_worker_init (GdmSessionWorker *session_worker);
+ static void gdm_session_worker_finalize (GObject *object);
+
++static void gdm_session_worker_set_environment_variable (GdmSessionWorker *worker,
++ const char *key,
++ const char *value);
++
+ static void queue_state_change (GdmSessionWorker *worker);
+
++
+ typedef int (* GdmSessionWorkerPamNewMessagesFunc) (int,
+ const struct pam_message **,
+ struct pam_response **,
+@@ -171,6 +184,7 @@ gdm_session_worker_error_quark (void)
+ return error_quark;
+ }
+
++#ifdef WITH_CONSOLE_KIT
+ static gboolean
+ open_ck_session (GdmSessionWorker *worker)
+ {
+@@ -257,6 +271,7 @@ open_ck_session (GdmSessionWorker *worker)
+ out:
+ return ret;
+ }
++#endif
+
+ /* adapted from glib script_execute */
+ static void
+@@ -1057,6 +1072,7 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
+ const char *x11_display_name,
+ const char *x11_authority_file,
+ const char *display_device,
++ const char *seat_id,
+ GError **error)
+ {
+ struct pam_conv pam_conversation;
+@@ -1138,6 +1154,13 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker,
+ goto out;
+ }
+
++#ifdef WITH_SYSTEMD
++ /* set seat ID */
++ if (seat_id != NULL && seat_id[0] != '\0' && sd_booted() > 0) {
++ gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id);
++ }
++#endif
++
+ #ifdef PAM_XDISPLAY
+ /* set XDISPLAY */
+ error_code = pam_set_item (worker->priv->pam_handle, PAM_XDISPLAY, x11_display_name);
+@@ -1571,6 +1594,13 @@ register_ck_session (GdmSessionWorker *worker)
+ const char *session_cookie;
+ gboolean res;
+
++#ifdef WITH_SYSTEMD
++ if (sd_booted() > 0) {
++ return;
++ }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
+ session_cookie = NULL;
+ res = open_ck_session (worker);
+ if (res) {
+@@ -1581,6 +1611,7 @@ register_ck_session (GdmSessionWorker *worker)
+ "XDG_SESSION_COOKIE",
+ session_cookie);
+ }
++#endif
+ }
+
+ static void
+@@ -1611,11 +1642,13 @@ session_worker_child_watch (GPid pid,
+ num);
+ }
+
++#ifdef WITH_CONSOLE_KIT
+ if (worker->priv->ckc != NULL) {
+ ck_connector_close_session (worker->priv->ckc, NULL);
+ ck_connector_unref (worker->priv->ckc);
+ worker->priv->ckc = NULL;
+ }
++#endif
+
+ gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
+
+@@ -2140,6 +2173,7 @@ do_setup (GdmSessionWorker *worker)
+ worker->priv->x11_display_name,
+ worker->priv->x11_authority_file,
+ worker->priv->display_device,
++ worker->priv->display_seat_id,
+ &error);
+ if (! res) {
+ if (g_error_matches (error,
+--
+1.7.9
+
+
+From 6e9fb3fb4df7d05c803cc01fe638eb9cf88c4beb Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 27 Jul 2011 01:32:54 +0200
+Subject: [PATCH 08/11] local-display-factory: subscribe to new seats being
+ created and removed
+
+logind will notify us when ever a new seat becomes available in the
+system, or an existing seat is removed. We simply create a new display
+for each seat showing up and remove a display when a seat goes away.
+---
+ daemon/Makefile.am | 1 +
+ daemon/gdm-local-display-factory.c | 239 +++++++++++++++++++++++++++++++++---
+ 2 files changed, 224 insertions(+), 16 deletions(-)
+
+diff --git a/daemon/Makefile.am b/daemon/Makefile.am
+index 8f8eedf..ffbaf9b 100644
+--- a/daemon/Makefile.am
++++ b/daemon/Makefile.am
+@@ -363,6 +363,7 @@ gdm_binary_LDADD = \
+ $(DAEMON_LIBS) \
+ $(XDMCP_LIBS) \
+ $(LIBWRAP_LIBS) \
++ $(SYSTEMD_LIBS) \
+ $(NULL)
+
+ if WITH_CONSOLE_KIT
+diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
+index 349c7b2..988b2ff 100644
+--- a/daemon/gdm-local-display-factory.c
++++ b/daemon/gdm-local-display-factory.c
+@@ -27,6 +27,13 @@
+ #include <glib/gi18n.h>
+ #include <glib-object.h>
+
++#include <dbus/dbus.h>
++#include <dbus/dbus-glib-lowlevel.h>
++
++#ifdef WITH_SYSTEMD
++#include <systemd/sd-daemon.h>
++#endif
++
+ #include "gdm-display-factory.h"
+ #include "gdm-local-display-factory.h"
+ #include "gdm-local-display-factory-glue.h"
+@@ -64,7 +71,8 @@ static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryC
+ static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory);
+ static void gdm_local_display_factory_finalize (GObject *object);
+
+-static GdmDisplay *create_display (GdmLocalDisplayFactory *factory);
++static GdmDisplay *create_display (GdmLocalDisplayFactory *factory,
++ const char *seat_id);
+
+ static gpointer local_display_factory_object = NULL;
+
+@@ -282,6 +290,7 @@ on_static_display_status_changed (GdmDisplay *display,
+ int status;
+ GdmDisplayStore *store;
+ int num;
++ char *seat_id = NULL;
+
+ num = -1;
+ gdm_display_get_x11_display_number (display, &num, NULL);
+@@ -289,6 +298,8 @@ on_static_display_status_changed (GdmDisplay *display,
+
+ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+
++ g_object_get (display, "seat-id", &seat_id, NULL);
++
+ status = gdm_display_get_status (display);
+
+ g_debug ("GdmLocalDisplayFactory: static display status changed: %d", status);
+@@ -300,7 +311,7 @@ on_static_display_status_changed (GdmDisplay *display,
+ gdm_display_store_remove (store, display);
+ /* reset num failures */
+ factory->priv->num_failures = 0;
+- create_display (factory);
++ create_display (factory, seat_id);
+ break;
+ case GDM_DISPLAY_FAILED:
+ /* leave the display number in factory->priv->displays
+@@ -313,7 +324,7 @@ on_static_display_status_changed (GdmDisplay *display,
+ /* FIXME: should monitor hardware changes to
+ try again when seats change */
+ } else {
+- create_display (factory);
++ create_display (factory, seat_id);
+ }
+ break;
+ case GDM_DISPLAY_UNMANAGED:
+@@ -326,13 +337,44 @@ on_static_display_status_changed (GdmDisplay *display,
+ g_assert_not_reached ();
+ break;
+ }
++
++ g_free (seat_id);
++}
++
++static gboolean
++lookup_by_seat_id (const char *id,
++ GdmDisplay *display,
++ gpointer user_data)
++{
++ const char *looking_for = user_data;
++ char *current;
++ gboolean res;
++
++ g_object_get (G_OBJECT (display), "seat-id", ¤t, NULL);
++
++ res = g_strcmp0 (current, looking_for) == 0;
++
++ g_free(current);
++
++ return res;
+ }
+
+ static GdmDisplay *
+-create_display (GdmLocalDisplayFactory *factory)
++create_display (GdmLocalDisplayFactory *factory,
++ const char *seat_id)
+ {
+- GdmDisplay *display;
+- guint32 num;
++ GdmDisplayStore *store;
++ GdmDisplay *display;
++ guint32 num;
++
++ /* Ensure we don't create the same display more than once */
++ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
++ display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
++ if (display != NULL) {
++ return NULL;
++ }
++
++ g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
+
+ num = take_next_display_number (factory);
+
+@@ -342,8 +384,7 @@ create_display (GdmLocalDisplayFactory *factory)
+ display = gdm_static_display_new (num);
+ #endif
+
+- /* FIXME: don't hardcode seat1? */
+- g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
++ g_object_set (display, "seat-id", seat_id, NULL);
+
+ g_signal_connect (display,
+ "notify::status",
+@@ -362,24 +403,182 @@ create_display (GdmLocalDisplayFactory *factory)
+ return display;
+ }
+
++#ifdef WITH_SYSTEMD
++
++static void
++delete_display (GdmLocalDisplayFactory *factory,
++ const char *seat_id) {
++
++ GdmDisplayStore *store;
++
++ g_debug ("GdmLocalDisplayFactory: Removing displays on seat %s", seat_id);
++
++ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
++ gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id);
++}
++
++static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory)
++{
++ DBusError error;
++ DBusMessage *message, *reply;
++ DBusMessageIter iter, sub, sub2;
++
++ dbus_error_init (&error);
++
++ message = dbus_message_new_method_call (
++ "org.freedesktop.login1",
++ "/org/freedesktop/login1",
++ "org.freedesktop.login1.Manager",
++ "ListSeats");
++ if (message == NULL) {
++ g_warning ("GdmLocalDisplayFactory: Failed to allocate message");
++ return FALSE;
++ }
++
++ reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (factory->priv->connection), message, -1, &error);
++ dbus_message_unref (message);
++
++ if (reply == NULL) {
++ g_warning ("GdmLocalDisplayFactory: Failed to issue method call: %s", error.message);
++ dbus_error_free (&error);
++ return FALSE;
++ }
++
++ if (!dbus_message_iter_init (reply, &iter) ||
++ dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY ||
++ dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRUCT) {
++ g_warning ("GdmLocalDisplayFactory: Failed to parse reply.");
++ dbus_message_unref (reply);
++ return FALSE;
++ }
++
++ dbus_message_iter_recurse (&iter, &sub);
++
++ while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID) {
++ const char *seat;
++
++ if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_STRUCT) {
++ g_warning ("GdmLocalDisplayFactory: Failed to parse reply.");
++ dbus_message_unref (reply);
++ return FALSE;
++ }
++
++ dbus_message_iter_recurse (&sub, &sub2);
++
++ if (dbus_message_iter_get_arg_type (&sub2) != DBUS_TYPE_STRING) {
++ g_warning ("GdmLocalDisplayFactory: Failed to parse reply.");
++ dbus_message_unref (reply);
++ return FALSE;
++ }
++
++ dbus_message_iter_get_basic (&sub2, &seat);
++ create_display (factory, seat);
++
++ dbus_message_iter_next (&sub);
++ }
++
++ dbus_message_unref (reply);
++ return TRUE;
++}
++
++static DBusHandlerResult
++on_seat_signal (DBusConnection *connection,
++ DBusMessage *message,
++ void *user_data)
++{
++ GdmLocalDisplayFactory *factory = user_data;
++ DBusError error;
++
++ dbus_error_init (&error);
++
++ if (dbus_message_is_signal (message, "org.freedesktop.login1.Manager", "SeatNew") ||
++ dbus_message_is_signal (message, "org.freedesktop.login1.Manager", "SeatRemoved")) {
++ const char *seat;
++
++ dbus_message_get_args (message,
++ &error,
++ DBUS_TYPE_STRING, &seat,
++ DBUS_TYPE_INVALID);
++
++ if (dbus_error_is_set (&error)) {
++ g_warning ("GdmLocalDisplayFactory: Failed to decode seat message: %s", error.message);
++ dbus_error_free (&error);
++ } else {
++
++ if (strcmp (dbus_message_get_member (message), "SeatNew") == 0) {
++ create_display (factory, seat);
++ } else {
++ delete_display (factory, seat);
++ }
++ }
++ }
++
++ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++}
++
++static void
++gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory)
++{
++ DBusError error;
++
++ dbus_error_init (&error);
++
++ dbus_bus_add_match (dbus_g_connection_get_connection (factory->priv->connection),
++ "type='signal',"
++ "sender='org.freedesktop.login1',"
++ "path='/org/freedesktop/login1',"
++ "interface='org.freedesktop.login1.Manager',"
++ "member='SeatNew'",
++ &error);
++
++ if (dbus_error_is_set (&error)) {
++ g_warning ("GdmLocalDisplayFactory: Failed to add match for SeatNew: %s", error.message);
++ dbus_error_free (&error);
++ }
++
++ dbus_bus_add_match (dbus_g_connection_get_connection (factory->priv->connection),
++ "type='signal',"
++ "sender='org.freedesktop.login1',"
++ "path='/org/freedesktop/login1',"
++ "interface='org.freedesktop.login1.Manager',"
++ "member='SeatRemoved'",
++ &error);
++
++ if (dbus_error_is_set (&error)) {
++ g_warning ("GdmLocalDisplayFactory: Failed to add match for SeatNew: %s", error.message);
++ dbus_error_free (&error);
++ }
++
++ dbus_connection_add_filter (dbus_g_connection_get_connection (factory->priv->connection), on_seat_signal, factory, NULL);
++}
++
++static void
++gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
++{
++ dbus_connection_remove_filter (dbus_g_connection_get_connection (factory->priv->connection), on_seat_signal, factory);
++}
++
++#endif
++
+ static gboolean
+ gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
+ {
+- gboolean ret;
+ GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory);
+ GdmDisplay *display;
+
+ g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
+
+- ret = TRUE;
+-
+- /* FIXME: use seat configuration */
+- display = create_display (factory);
+- if (display == NULL) {
+- ret = FALSE;
++#ifdef WITH_SYSTEMD
++ if (sd_booted () > 0) {
++ gdm_local_display_factory_start_monitor (factory);
++ return gdm_local_display_factory_sync_seats (factory);
+ }
++#endif
+
+- return ret;
++ /* On ConsoleKit just create Seat1, and that's it. */
++ display = create_display (factory, CK_SEAT1_PATH);
++
++ return display != NULL;
+ }
+
+ static gboolean
+@@ -389,6 +588,10 @@ gdm_local_display_factory_stop (GdmDisplayFactory *base_factory)
+
+ g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
+
++#ifdef WITH_SYSTEMD
++ gdm_local_display_factory_stop_monitor (factory);
++#endif
++
+ return TRUE;
+ }
+
+@@ -499,6 +702,10 @@ gdm_local_display_factory_finalize (GObject *object)
+
+ g_hash_table_destroy (factory->priv->displays);
+
++#ifdef WITH_SYSTEMD
++ gdm_local_display_factory_stop_monitor (factory);
++#endif
++
+ G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object);
+ }
+
+--
+1.7.9
+
+
+From 51a27a199e36fcb5e90e8332c1f025e8a282fbd5 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 27 Jul 2011 04:06:10 +0200
+Subject: [PATCH 09/11] server: pass seat id to server
+
+When we spawn a new X server, let's pass the seat id to it via the
+"-seat" parameter, which has been available since a while in upstream
+Xorg.
+
+-seat causes the X server to only make use of hardware that is assigned
+to the seat specified, and leave all other hardware untouched.
+---
+ daemon/gdm-factory-slave.c | 4 +++-
+ daemon/gdm-product-slave.c | 4 +++-
+ daemon/gdm-server.c | 37 ++++++++++++++++++++++++++++++++++++-
+ daemon/gdm-server.h | 1 +
+ daemon/gdm-simple-slave.c | 4 +++-
+ 5 files changed, 46 insertions(+), 4 deletions(-)
+
+diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
+index 6154cd3..3538627 100644
+--- a/daemon/gdm-factory-slave.c
++++ b/daemon/gdm-factory-slave.c
+@@ -674,12 +674,14 @@ static gboolean
+ gdm_factory_slave_run (GdmFactorySlave *slave)
+ {
+ char *display_name;
++ char *seat_id;
+ char *auth_file;
+ gboolean display_is_local;
+
+ g_object_get (slave,
+ "display-is-local", &display_is_local,
+ "display-name", &display_name,
++ "display-seat-id", &seat_id,
+ "display-x11-authority-file", &auth_file,
+ NULL);
+
+@@ -688,7 +690,7 @@ gdm_factory_slave_run (GdmFactorySlave *slave)
+ if (display_is_local) {
+ gboolean res;
+
+- slave->priv->server = gdm_server_new (display_name, auth_file);
++ slave->priv->server = gdm_server_new (display_name, seat_id, auth_file);
+ g_signal_connect (slave->priv->server,
+ "exited",
+ G_CALLBACK (on_server_exited),
+diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c
+index 629c6e7..844af48 100644
+--- a/daemon/gdm-product-slave.c
++++ b/daemon/gdm-product-slave.c
+@@ -479,11 +479,13 @@ gdm_product_slave_create_server (GdmProductSlave *slave)
+ {
+ char *display_name;
+ char *auth_file;
++ char *seat_id;
+ gboolean display_is_local;
+
+ g_object_get (slave,
+ "display-is-local", &display_is_local,
+ "display-name", &display_name,
++ "display-seat-id", &seat_id,
+ "display-x11-authority-file", &auth_file,
+ NULL);
+
+@@ -492,7 +494,7 @@ gdm_product_slave_create_server (GdmProductSlave *slave)
+ if (display_is_local) {
+ gboolean res;
+
+- slave->priv->server = gdm_server_new (display_name, auth_file);
++ slave->priv->server = gdm_server_new (display_name, seat_id, auth_file);
+ g_signal_connect (slave->priv->server,
+ "exited",
+ G_CALLBACK (on_server_exited),
+diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
+index 62ffca1..9a11ba0 100644
+--- a/daemon/gdm-server.c
++++ b/daemon/gdm-server.c
+@@ -38,6 +38,10 @@
+ #include <sys/prctl.h>
+ #endif
+
++#ifdef WITH_SYSTEMD
++#include <systemd/sd-daemon.h>
++#endif
++
+ #include <glib.h>
+ #include <glib/gi18n.h>
+ #include <glib/gstdio.h>
+@@ -77,6 +81,7 @@ struct GdmServerPrivate
+ char *log_dir;
+ char *display_name;
+ char *display_device;
++ char *display_seat_id;
+ char *auth_file;
+
+ gboolean is_parented;
+@@ -90,6 +95,7 @@ struct GdmServerPrivate
+ enum {
+ PROP_0,
+ PROP_DISPLAY_NAME,
++ PROP_DISPLAY_SEAT_ID,
+ PROP_DISPLAY_DEVICE,
+ PROP_AUTH_FILE,
+ PROP_IS_PARENTED,
+@@ -284,7 +290,7 @@ gdm_server_resolve_command_line (GdmServer *server,
+ query_in_arglist = TRUE;
+ }
+
+- argv = g_renew (char *, argv, len + 10);
++ argv = g_renew (char *, argv, len + 12);
+ /* shift args down one */
+ for (i = len - 1; i >= 1; i--) {
+ argv[i+1] = argv[i];
+@@ -299,6 +305,11 @@ gdm_server_resolve_command_line (GdmServer *server,
+ argv[len++] = g_strdup (server->priv->auth_file);
+ }
+
++ if (sd_booted () > 0 && server->priv->display_seat_id != NULL) {
++ argv[len++] = g_strdup ("-seat");
++ argv[len++] = g_strdup (server->priv->display_seat_id);
++ }
++
+ if (server->priv->chosen_hostname) {
+ /* run just one session */
+ argv[len++] = g_strdup ("-terminate");
+@@ -753,6 +764,14 @@ _gdm_server_set_display_name (GdmServer *server,
+ }
+
+ static void
++_gdm_server_set_display_seat_id (GdmServer *server,
++ const char *name)
++{
++ g_free (server->priv->display_seat_id);
++ server->priv->display_seat_id = g_strdup (name);
++}
++
++static void
+ _gdm_server_set_auth_file (GdmServer *server,
+ const char *auth_file)
+ {
+@@ -789,6 +808,9 @@ gdm_server_set_property (GObject *object,
+ case PROP_DISPLAY_NAME:
+ _gdm_server_set_display_name (self, g_value_get_string (value));
+ break;
++ case PROP_DISPLAY_SEAT_ID:
++ _gdm_server_set_display_seat_id (self, g_value_get_string (value));
++ break;
+ case PROP_AUTH_FILE:
+ _gdm_server_set_auth_file (self, g_value_get_string (value));
+ break;
+@@ -818,6 +840,9 @@ gdm_server_get_property (GObject *object,
+ case PROP_DISPLAY_NAME:
+ g_value_set_string (value, self->priv->display_name);
+ break;
++ case PROP_DISPLAY_SEAT_ID:
++ g_value_set_string (value, self->priv->display_seat_id);
++ break;
+ case PROP_DISPLAY_DEVICE:
+ g_value_take_string (value,
+ gdm_server_get_display_device (self));
+@@ -889,6 +914,13 @@ gdm_server_class_init (GdmServerClass *klass)
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
++ PROP_DISPLAY_SEAT_ID,
++ g_param_spec_string ("display-seat-id",
++ "Seat ID",
++ "ID of the seat this display is running on",
++ NULL,
++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
++ g_object_class_install_property (object_class,
+ PROP_DISPLAY_DEVICE,
+ g_param_spec_string ("display-device",
+ "Display Device",
+@@ -954,6 +986,7 @@ gdm_server_finalize (GObject *object)
+ g_free (server->priv->session_args);
+ g_free (server->priv->log_dir);
+ g_free (server->priv->display_name);
++ g_free (server->priv->display_seat_id);
+ g_free (server->priv->display_device);
+ g_free (server->priv->auth_file);
+ g_free (server->priv->parent_display_name);
+@@ -965,12 +998,14 @@ gdm_server_finalize (GObject *object)
+
+ GdmServer *
+ gdm_server_new (const char *display_name,
++ const char *seat_id,
+ const char *auth_file)
+ {
+ GObject *object;
+
+ object = g_object_new (GDM_TYPE_SERVER,
+ "display-name", display_name,
++ "display-seat-id", seat_id,
+ "auth-file", auth_file,
+ NULL);
+
+diff --git a/daemon/gdm-server.h b/daemon/gdm-server.h
+index 535a69a..b53d68e 100644
+--- a/daemon/gdm-server.h
++++ b/daemon/gdm-server.h
+@@ -54,6 +54,7 @@ typedef struct
+
+ GType gdm_server_get_type (void);
+ GdmServer * gdm_server_new (const char *display_id,
++ const char *seat_id,
+ const char *auth_file);
+ gboolean gdm_server_start (GdmServer *server);
+ gboolean gdm_server_stop (GdmServer *server);
+diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
+index 873b7f9..9d1347a 100644
+--- a/daemon/gdm-simple-slave.c
++++ b/daemon/gdm-simple-slave.c
+@@ -1437,11 +1437,13 @@ gdm_simple_slave_run (GdmSimpleSlave *slave)
+ {
+ char *display_name;
+ char *auth_file;
++ char *seat_id;
+ gboolean display_is_local;
+
+ g_object_get (slave,
+ "display-is-local", &display_is_local,
+ "display-name", &display_name,
++ "display-seat-id", &seat_id,
+ "display-x11-authority-file", &auth_file,
+ NULL);
+
+@@ -1451,7 +1453,7 @@ gdm_simple_slave_run (GdmSimpleSlave *slave)
+ gboolean res;
+ gboolean disable_tcp;
+
+- slave->priv->server = gdm_server_new (display_name, auth_file);
++ slave->priv->server = gdm_server_new (display_name, seat_id, auth_file);
+
+ disable_tcp = TRUE;
+ if (gdm_settings_client_get_boolean (GDM_KEY_DISALLOW_TCP,
+--
+1.7.9
+
+
+From 2b24451c3816ecea30fdbfff2c249a6ac527e1b6 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 24 Jan 2012 00:03:10 +0100
+Subject: [PATCH 10/11] server: invoke X with the systemd multi seat X wrapper
+ if necessary
+
+systemd 39 and newer provide a small wrapper for X which works around
+the fact that XOrg upstream currently support multi-seat hotplug for
+displays. Let's make use of this as a stop-gap until this feature is
+added to XOrg upstream.
+
+This code tries to be as defensive as possible and makes use of the
+wrapper only if the system as actually booted with systemd, the wrapper
+is available and we actually use a seat != "seat0".
+---
+ configure.ac | 6 +++++-
+ daemon/gdm-server.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 54 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index dec31a9..855948d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -939,7 +939,7 @@ use_systemd=no
+ if test "x$with_systemd" != "xno" ; then
+ PKG_CHECK_MODULES(SYSTEMD,
+ libsystemd-daemon
+- libsystemd-login
++ libsystemd-login >= 39
+ )
+ AC_SUBST(SYSTEMD_CFLAGS)
+ AC_SUBST(SYSTEMD_LIBS)
+@@ -950,6 +950,10 @@ fi
+ AM_CONDITIONAL(WITH_SYSTEMD, test x$use_systemd = xyes)
+ AC_SUBST(WITH_SYSTEMD)
+
++AC_PATH_PROG(SYSTEMD_X_SERVER, systemd-multi-seat-x, [/lib/systemd/systemd-multi-seat-x], [/lib/systemd:/usr/lib/systemd:$PATH])
++AC_SUBST(SYSTEMD_X_SERVER)
++AC_DEFINE_UNQUOTED(SYSTEMD_X_SERVER,"$SYSTEMD_X_SERVER",[Path to systemd X server wrapper])
++
+ dnl ---------------------------------------------------------------------------
+ dnl - Check for D-Bus
+ dnl ---------------------------------------------------------------------------
+diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
+index 9a11ba0..54bf8b3 100644
+--- a/daemon/gdm-server.c
++++ b/daemon/gdm-server.c
+@@ -260,6 +260,52 @@ connect_to_parent (GdmServer *server)
+ }
+ #endif
+
++static void
++gdm_server_init_command (GdmServer *server)
++{
++
++ if (server->priv->command != NULL) {
++ return;
++ }
++
++#ifdef WITH_SYSTEMD
++
++ /* This is a temporary hack to work around the fact that XOrg
++ * currently lacks support for multi-seat hotplugging for
++ * display devices. This bit should be removed as soon as XOrg
++ * gains native support for automatically enumerating usb
++ * based graphics adapters at start-up via udev. */
++
++ /* systemd ships an X server wrapper tool which simply invokes
++ * the usual X but ensures it only uses the display devices of
++ * the seat. */
++
++ /* We do not rely on this wrapper server if, a) the machine
++ * wasn't booted using systemd, or b) the wrapper tool is
++ * missing, or c) we are running for the main seat 'seat0'. */
++
++ if (sd_booted () <= 0) {
++ goto fallback;
++ }
++
++ if (g_access (SYSTEMD_X_SERVER, X_OK) < 0) {
++ goto fallback;
++ }
++
++ if (server->priv->display_seat_id == NULL ||
++ strcmp (server->priv->display_seat_id, "seat0") == 0) {
++ goto fallback;
++ }
++
++ server->priv->command = g_strdup (SYSTEMD_X_SERVER " -br -verbose -logverbose 7");
++ return;
++
++fallback:
++#endif
++
++ server->priv->command = g_strdup (X_SERVER " -br -verbose -logverbose 7");
++}
++
+ static gboolean
+ gdm_server_resolve_command_line (GdmServer *server,
+ const char *vtarg,
+@@ -273,6 +319,8 @@ gdm_server_resolve_command_line (GdmServer *server,
+ gboolean gotvtarg = FALSE;
+ gboolean query_in_arglist = FALSE;
+
++ gdm_server_init_command (server);
++
+ g_shell_parse_argv (server->priv->command, &argc, &argv, NULL);
+
+ for (len = 0; argv != NULL && argv[len] != NULL; len++) {
+@@ -959,7 +1007,7 @@ gdm_server_init (GdmServer *server)
+ server->priv = GDM_SERVER_GET_PRIVATE (server);
+
+ server->priv->pid = -1;
+- server->priv->command = g_strdup (X_SERVER " -br -verbose -logverbose 7");
++
+ server->priv->log_dir = g_strdup (LOGDIR);
+
+ add_ready_handler (server);
+--
+1.7.9
+
+
+From 28c7f9e6d875076bfe0c79cdee98fc6aefc29874 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 7 Feb 2012 22:48:40 +0100
+Subject: [PATCH 11/11] gdmflexiserver: port gdmflexiserver to
+ libsystemd-logind
+
+Port over gdmflexiserver to use native systemd calls with a fallback on
+CK.
+---
+ utils/Makefile.am | 3 +-
+ utils/gdmflexiserver.c | 256 ++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 239 insertions(+), 20 deletions(-)
+
+diff --git a/utils/Makefile.am b/utils/Makefile.am
+index 379c3d5..1cda413 100644
+--- a/utils/Makefile.am
++++ b/utils/Makefile.am
+@@ -10,6 +10,7 @@ AM_CPPFLAGS = \
+ $(CANBERRA_GTK_CFLAGS) \
+ $(GTK_CFLAGS) \
+ $(XLIB_CFLAGS) \
++ $(SYSTEMD_CFLAGS) \
+ $(COMMON_CFLAGS) \
+ $(NULL)
+
+@@ -31,6 +32,7 @@ gdmflexiserver_SOURCES = \
+ gdmflexiserver_LDADD = \
+ $(GTK_LIBS) \
+ $(COMMON_LIBS) \
++ $(SYSTEMD_LIBS) \
+ $(NULL)
+
+ gdm_screenshot_SOURCES = \
+@@ -49,4 +51,3 @@ CLEANFILES = \
+
+ DISTCLEANFILES = \
+ $(NULL)
+-
+diff --git a/utils/gdmflexiserver.c b/utils/gdmflexiserver.c
+index f7fac33..59bccd1 100644
+--- a/utils/gdmflexiserver.c
++++ b/utils/gdmflexiserver.c
+@@ -29,6 +29,11 @@
+ #include <glib/gi18n.h>
+ #include <gtk/gtk.h>
+
++#ifdef WITH_SYSTEMD
++#include <systemd/sd-daemon.h>
++#include <systemd/sd-login.h>
++#endif
++
+ #define DBUS_API_SUBJECT_TO_CHANGE
+ #include <dbus/dbus-glib.h>
+ #include <dbus/dbus-glib-lowlevel.h>
+@@ -37,6 +42,7 @@
+ #define GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH "/org/gnome/DisplayManager/LocalDisplayFactory"
+ #define GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE "org.gnome.DisplayManager.LocalDisplayFactory"
+
++#ifdef WITH_CONSOLE_KIT
+ #define CK_NAME "org.freedesktop.ConsoleKit"
+ #define CK_PATH "/org/freedesktop/ConsoleKit"
+ #define CK_INTERFACE "org.freedesktop.ConsoleKit"
+@@ -45,6 +51,7 @@
+ #define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+ #define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
+ #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
++#endif
+
+ static const char *send_command = NULL;
+ static gboolean use_xnest = FALSE;
+@@ -206,6 +213,8 @@ create_transient_display (DBusConnection *connection,
+ return ret;
+ }
+
++#ifdef WITH_CONSOLE_KIT
++
+ static gboolean
+ get_current_session_id (DBusConnection *connection,
+ char **session_id)
+@@ -335,9 +344,9 @@ get_current_seat_id (DBusConnection *connection)
+ }
+
+ static gboolean
+-activate_session_id (DBusConnection *connection,
+- const char *seat_id,
+- const char *session_id)
++activate_session_id_for_ck (DBusConnection *connection,
++ const char *seat_id,
++ const char *session_id)
+ {
+ DBusError local_error;
+ DBusMessage *message;
+@@ -609,9 +618,9 @@ seat_get_sessions (DBusConnection *connection,
+ }
+
+ static gboolean
+-get_login_window_session_id (DBusConnection *connection,
+- const char *seat_id,
+- char **session_id)
++get_login_window_session_id_for_ck (DBusConnection *connection,
++ const char *seat_id,
++ char **session_id)
+ {
+ gboolean can_activate_sessions;
+ char **sessions;
+@@ -645,46 +654,225 @@ get_login_window_session_id (DBusConnection *connection,
+ }
+
+ static gboolean
+-goto_login_session (GError **error)
++goto_login_session_for_ck (DBusConnection *connection,
++ GError **error)
+ {
+ gboolean ret;
+ gboolean res;
+ char *session_id;
+ char *seat_id;
+- DBusError local_error;
+- DBusConnection *connection;
+
+ ret = FALSE;
+
++ /* First look for any existing LoginWindow sessions on the seat.
++ If none are found, create a new one. */
++
++ seat_id = get_current_seat_id (connection);
++ if (seat_id == NULL || seat_id[0] == '\0') {
++ g_debug ("seat id is not set; can't switch sessions");
++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Could not identify the current session."));
++
++ return FALSE;
++ }
++
++ res = get_login_window_session_id_for_ck (connection, seat_id, &session_id);
++ if (! res) {
++ g_set_error (error, GDM_FLEXISERVER_ERROR, 1, _("User unable to switch sessions."));
++ return FALSE;
++ }
++
++ if (session_id != NULL) {
++ res = activate_session_id_for_ck (connection, seat_id, session_id);
++ if (res) {
++ ret = TRUE;
++ }
++ }
++
++ if (! ret) {
++ res = create_transient_display (connection, error);
++ if (res) {
++ ret = TRUE;
++ }
++ }
++
++ return ret;
++}
++#endif
++
++#ifdef WITH_SYSTEMD
++
++static gboolean
++activate_session_id_for_systemd (DBusConnection *connection,
++ const char *seat_id,
++ const char *session_id)
++{
++ DBusError local_error;
++ DBusMessage *message;
++ DBusMessage *reply;
++ gboolean ret;
++
++ ret = FALSE;
++ reply = NULL;
++
++ g_debug ("Switching to session %s", session_id);
++
++ message = dbus_message_new_method_call ("org.freedesktop.login1",
++ "/org/freedesktop/login1",
++ "org.freedesktop.login1.Manager",
++ "ActivateSessionOnSeat");
++ if (message == NULL) {
++ goto out;
++ }
++
++ if (! dbus_message_append_args (message,
++ DBUS_TYPE_STRING, &session_id,
++ DBUS_TYPE_STRING, &seat_id,
++ DBUS_TYPE_INVALID)) {
++ goto out;
++ }
++
+ dbus_error_init (&local_error);
+- connection = dbus_bus_get (DBUS_BUS_SYSTEM, &local_error);
+- if (connection == NULL) {
+- g_debug ("Failed to connect to the D-Bus daemon: %s", local_error.message);
+- g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "%s", local_error.message);
++ reply = dbus_connection_send_with_reply_and_block (connection,
++ message,
++ -1,
++ &local_error);
++ if (dbus_error_is_set (&local_error)) {
++ g_warning ("Unable to activate session: %s", local_error.message);
+ dbus_error_free (&local_error);
++ goto out;
++ }
++
++ ret = TRUE;
++out:
++ if (message != NULL) {
++ dbus_message_unref (message);
++ }
++ if (reply != NULL) {
++ dbus_message_unref (reply);
++ }
++
++ return ret;
++}
++
++static gboolean
++get_login_window_session_id_for_systemd (const char *seat_id,
++ char **session_id)
++{
++ gboolean ret;
++ int res, i;
++ char **sessions;
++ char *service_id;
++
++ res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL);
++ if (res < 0) {
++ g_debug ("Failed to determine sessions: %s", strerror (-res));
+ return FALSE;
+ }
+
++ if (sessions == NULL || sessions[0] == NULL) {
++ *session_id = NULL;
++ ret = TRUE;
++ goto out;
++ }
++
++ for (i = 0; sessions[i]; i ++) {
++
++ res = sd_session_get_service (sessions[i], &service_id);
++ if (res < 0) {
++ g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res));
++ ret = FALSE;
++ goto out;
++ }
++
++ if (strcmp (service_id, "gdm-welcome") == 0) {
++ *session_id = g_strdup (sessions[i]);
++ ret = TRUE;
++
++ free (service_id);
++ goto out;
++ }
++
++ free (service_id);
++ }
++
++ *session_id = NULL;
++ ret = TRUE;
++
++out:
++ for (i = 0; sessions[i]; i ++) {
++ free (sessions[i]);
++ }
++
++ free (sessions);
++
++ return ret;
++}
++
++static gboolean
++goto_login_session_for_systemd (DBusConnection *connection,
++ GError **error)
++{
++ gboolean ret;
++ int res;
++ char *our_session;
++ char *session_id;
++ char *seat_id;
++
++ ret = FALSE;
++
+ /* First look for any existing LoginWindow sessions on the seat.
+ If none are found, create a new one. */
+
+- seat_id = get_current_seat_id (connection);
+- if (seat_id == NULL || seat_id[0] == '\0') {
+- g_debug ("seat id is not set; can't switch sessions");
++ /* Note that we mostly use free () here, instead of g_free ()
++ * since the data allocated is from libsystemd-logind, which
++ * does not use GLib's g_malloc (). */
++
++ res = sd_pid_get_session (0, &our_session);
++ if (res < 0) {
++ g_debug ("failed to determine own session: %s", strerror (-res));
+ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Could not identify the current session."));
+
+ return FALSE;
+ }
+
+- res = get_login_window_session_id (connection, seat_id, &session_id);
++ res = sd_session_get_seat (our_session, &seat_id);
++ free (our_session);
++ if (res < 0) {
++ g_debug ("failed to determine own seat: %s", strerror (-res));
++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Could not identify the current seat."));
++
++ return FALSE;
++ }
++
++ res = sd_seat_can_multi_session (seat_id);
++ if (res < 0) {
++ free (seat_id);
++
++ g_debug ("failed to determine whether seat can do multi session: %s", strerror (-res));
++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Could not identify multi session property."));
++
++ return FALSE;
++ }
++
++ if (res == 0) {
++ free (seat_id);
+
++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, _("Seat can't do multi session"));
++
++ return FALSE;
++ }
++
++ res = get_login_window_session_id_for_systemd (seat_id, &session_id);
+ if (! res) {
+- g_set_error (error, GDM_FLEXISERVER_ERROR, 1, _("User unable to switch sessions."));
++ free (seat_id);
++
++ g_set_error (error, GDM_FLEXISERVER_ERROR, 1, _("User unable to determine login session."));
+ return FALSE;
+ }
+
+ if (session_id != NULL) {
+- res = activate_session_id (connection, seat_id, session_id);
++ res = activate_session_id_for_systemd (connection, seat_id, session_id);
++
+ if (res) {
+ ret = TRUE;
+ }
+@@ -697,8 +885,38 @@ goto_login_session (GError **error)
+ }
+ }
+
++ free (seat_id);
++ g_free (session_id);
++
+ return ret;
+ }
++#endif
++
++static gboolean
++goto_login_session (GError **error)
++{
++ DBusError local_error;
++ DBusConnection *connection;
++
++ dbus_error_init (&local_error);
++ connection = dbus_bus_get (DBUS_BUS_SYSTEM, &local_error);
++ if (connection == NULL) {
++ g_debug ("Failed to connect to the D-Bus daemon: %s", local_error.message);
++ g_set_error (error, GDM_FLEXISERVER_ERROR, 0, "%s", local_error.message);
++ dbus_error_free (&local_error);
++ return FALSE;
++ }
++
++#ifdef WITH_SYSTEMD
++ if (sd_booted () > 0) {
++ return goto_login_session_for_systemd (connection, error);
++ }
++#endif
++
++#ifdef WITH_CONSOLE_KIT
++ return goto_login_session_for_ck (connection, error);
++#endif
++}
+
+ int
+ main (int argc, char *argv[])
+--
+1.7.9
+
More information about the scm-commits
mailing list