summaryrefslogtreecommitdiffstats
path: root/gdm/patch
diff options
context:
space:
mode:
authorpiernov <piernov@piernov.org>2011-09-02 19:07:00 +0200
committerpiernov <piernov@piernov.org>2011-09-02 19:07:39 +0200
commit1d5a9bd5a8a877707f4bf5cdb2c8941babc73382 (patch)
treeaa949b596cfcb273578d6dd15f626e9788d81f99 /gdm/patch
parentcef6a4403b5fbfc34d243942bcd89495dee54296 (diff)
downloadgnome3-1d5a9bd5a8a877707f4bf5cdb2c8941babc73382.tar.gz
gnome3-1d5a9bd5a8a877707f4bf5cdb2c8941babc73382.tar.bz2
gnome3-1d5a9bd5a8a877707f4bf5cdb2c8941babc73382.tar.xz
gnome3-1d5a9bd5a8a877707f4bf5cdb2c8941babc73382.zip
gdm 3.1.90-3 ajout patchs
Diffstat (limited to 'gdm/patch')
-rw-r--r--gdm/patch/default_session.patch396
-rw-r--r--gdm/patch/disable-fatal-criticals.patch182
-rw-r--r--gdm/patch/fix_external_program_paths.patch24
-rw-r--r--gdm/patch/switch_user.patch617
-rw-r--r--gdm/patch/time_display_on_greeter.patch104
-rw-r--r--gdm/patch/vt-allocation-hack.patch118
6 files changed, 1441 insertions, 0 deletions
diff --git a/gdm/patch/default_session.patch b/gdm/patch/default_session.patch
new file mode 100644
index 0000000..de459b3
--- /dev/null
+++ b/gdm/patch/default_session.patch
@@ -0,0 +1,396 @@
+Description: Choose default session in /etc/gdm/custom.conf using DBus
+ Add /usr/lib/gdm-set-default-session to properly define default session:
+ Use DBus when gdm daemon is on and filing the file when it's off
+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=594733
+Bug-Ubuntu: https://launchpad.net/bugs/403291
+
+Index: gdm-3.0.4/configure.ac
+===================================================================
+--- gdm-3.0.4.orig/configure.ac 2011-08-10 18:29:07.705952647 +0200
++++ gdm-3.0.4/configure.ac 2011-08-10 18:29:07.749952857 +0200
+@@ -145,6 +145,13 @@
+ AC_SUBST(UPOWER_CFLAGS)
+ AC_SUBST(UPOWER_LIBS)
+
++PKG_CHECK_MODULES(SET_SESSION,
++ dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION
++ gobject-2.0 >= $GLIB_REQUIRED_VERSION
++)
++AC_SUBST(SET_SESSION_CFLAGS)
++AC_SUBST(SET_SESSION_LIBS)
++
+ PKG_CHECK_MODULES(SIMPLE_GREETER,
+ dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION
+ gtk+-3.0 >= $GTK_REQUIRED_VERSION
+Index: gdm-3.0.4/daemon/gdm-session-direct.c
+===================================================================
+--- gdm-3.0.4.orig/daemon/gdm-session-direct.c 2011-08-10 18:29:07.673952489 +0200
++++ gdm-3.0.4/daemon/gdm-session-direct.c 2011-08-10 18:29:19.522011234 +0200
+@@ -63,6 +63,10 @@
+ #define GDM_SESSION_DBUS_INTERFACE "org.gnome.DisplayManager.Session"
+ #define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel"
+
++#define GDM_SETTINGS_DBUS_NAME "org.gnome.DisplayManager"
++#define GDM_SETTINGS_DBUS_PATH "/org/gnome/DisplayManager/Settings"
++#define GDM_SETTINGS_DBUS_INTERFACE "org.gnome.DisplayManager.Settings"
++
+ #ifndef GDM_SESSION_DEFAULT_PATH
+ #define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin"
+ #endif
+@@ -682,6 +686,26 @@
+ char *name;
+ GSequence *sessions;
+ GSequenceIter *session;
++ DBusGProxy *proxy = NULL;
++ GError *error = NULL;
++
++ proxy = dbus_g_proxy_new_for_name (session_direct->priv->connection,
++ GDM_SETTINGS_DBUS_NAME,
++ GDM_SETTINGS_DBUS_PATH,
++ GDM_SETTINGS_DBUS_INTERFACE);
++ if (dbus_g_proxy_call (proxy, "GetValue", &error,
++ G_TYPE_STRING, "daemon/DefaultSession", G_TYPE_INVALID,
++ G_TYPE_STRING, &name, G_TYPE_INVALID)) {
++ if (get_session_command_for_name (name, NULL)) {
++ return name;
++ }
++ }
++ else {
++ g_debug ("No DefaultSession: %s", error->message);
++ g_error_free (error);
++ }
++ if (proxy)
++ g_object_unref (proxy);
+
+ if (session_direct->priv->fallback_session_name != NULL) {
+ /* verify that the cached version still exists */
+@@ -690,7 +714,7 @@
+ }
+ }
+
+- name = g_strdup ("gnome");
++ name = g_strdup ("ubuntu");
+ if (get_session_command_for_name (name, NULL)) {
+ g_free (session_direct->priv->fallback_session_name);
+ session_direct->priv->fallback_session_name = name;
+Index: gdm-3.0.4/utils/Makefile.am
+===================================================================
+--- gdm-3.0.4.orig/utils/Makefile.am 2011-02-18 04:27:53.000000000 +0100
++++ gdm-3.0.4/utils/Makefile.am 2011-08-10 18:29:07.753952884 +0200
+@@ -6,11 +6,13 @@
+ -DLOCALSTATEDIR=\""$(localstatedir)"\" \
+ -DGDM_SCREENSHOT_DIR=\""$(GDM_SCREENSHOT_DIR)"\"\
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
++ -DGDMCONFDIR=\"$(gdmconfdir)\" \
+ $(UTILS_CFLAGS) \
+ $(CANBERRA_GTK_CFLAGS) \
+ $(GTK_CFLAGS) \
+ $(XLIB_CFLAGS) \
+ $(COMMON_CFLAGS) \
++ $(SET_SESSION_CFLAGS) \
+ $(NULL)
+
+ edit = sed \
+@@ -24,6 +26,10 @@
+ gdm-screenshot \
+ $(NULL)
+
++libexec_PROGRAMS = \
++ gdm-set-default-session \
++ $(NULL)
++
+ gdmflexiserver_SOURCES = \
+ gdmflexiserver.c \
+ $(NULL)
+@@ -44,6 +50,15 @@
+ $(COMMON_LIBS) \
+ $(NULL)
+
++gdm_set_default_session_SOURCES = \
++ gdm-set-default-session.c \
++ $(NULL)
++
++gdm_set_default_session_LDADD = \
++ $(SET_SESSION_LIBS) \
++ $(COMMON_LIBS) \
++ $(NULL)
++
+ CLEANFILES = \
+ $(NULL)
+
+Index: gdm-3.0.4/utils/gdm-set-default-session.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ gdm-3.0.4/utils/gdm-set-default-session.c 2011-08-10 18:29:07.753952884 +0200
+@@ -0,0 +1,271 @@
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <stdlib.h>
++#include <unistd.h>
++
++#include <glib.h>
++#include <glib/gi18n.h>
++#include <dbus/dbus-glib-bindings.h>
++
++#define GDM_SETTINGS_DBUS_NAME "org.gnome.DisplayManager"
++#define GDM_SETTINGS_DBUS_PATH "/org/gnome/DisplayManager/Settings"
++#define GDM_SETTINGS_DBUS_INTERFACE "org.gnome.DisplayManager.Settings"
++
++#define SESSION_KEY_GROUP "daemon"
++#define SESSION_KEY_NAME "DefaultSession"
++
++typedef enum {
++ CONNEXIONSUCCEED,
++ CONNEXIONFAILED,
++ ALREADYHASVALUE,
++ HASNOVALUE,
++ VALUEFOUND
++} DBusState;
++
++static gboolean debug = FALSE;
++static gboolean keepold = FALSE;
++static gboolean remove = FALSE;
++
++static GOptionEntry entries[] =
++{
++ { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Enable debugging", NULL },
++ { "keep-old", 'k', 0, G_OPTION_ARG_NONE, &keepold, "Only update if no default already set", NULL },
++ { "remove", 'r', 0, G_OPTION_ARG_NONE, &remove, "Remove default session if it's this one", NULL },
++ { NULL }
++};
++
++void
++show_nothing(const gchar *log_domain,
++ GLogLevelFlags log_level,
++ const gchar *message,
++ gpointer unused_data) {};
++
++int
++init_dbus_connection(DBusGProxy **proxy) {
++ DBusGConnection *connection;
++ GError *error = NULL;
++
++ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
++ if (connection == NULL) {
++ g_debug ("Can't connect to system bus: %s", error->message);
++ g_error_free (error);
++ return(CONNEXIONFAILED);
++ }
++
++ *proxy = dbus_g_proxy_new_for_name_owner (connection,
++ GDM_SETTINGS_DBUS_NAME,
++ GDM_SETTINGS_DBUS_PATH,
++ GDM_SETTINGS_DBUS_INTERFACE,
++ &error);
++ if(!*proxy) {
++ g_debug ("No object on the bus: %s", error->message);
++ g_error_free (error);
++ return(CONNEXIONFAILED);
++ }
++
++ return(CONNEXIONSUCCEED);
++}
++
++int
++get_default_session_name_with_dbus(DBusGProxy *proxy, gchar **name)
++{
++ GError *error = NULL;
++
++ if (!dbus_g_proxy_call (proxy, "GetValue", &error,
++ G_TYPE_STRING, SESSION_KEY_GROUP "/" SESSION_KEY_NAME, G_TYPE_INVALID,
++ G_TYPE_STRING, name, G_TYPE_INVALID)) {
++ // This probably (_owner used previously) means that the value doesn't exist in config file
++ if(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) {
++ g_debug ("Probably no value registered: %s. %s", dbus_g_error_get_name (error), error->message);
++ g_error_free (error);
++ return(HASNOVALUE);
++ }
++ // possible if GDM_SETTINGS_DBUS_PATH or GDM_SETTINGS_DBUS_INTERFACE aren't exposed by the
++ // existing GDM_SETTINGS_DBUS_NAME (shouldn't happen)
++ else {
++ g_debug ("No GDM_SETTINGS_DBUS_PATH or GDM_SETTINGS_DBUS_INTERFACE on the bus: %s", error->message);
++ g_error_free (error);
++ return(CONNEXIONFAILED);
++ }
++ }
++ return(VALUEFOUND);
++
++}
++
++int
++set_default_session_name_with_dbus(DBusGProxy *proxy, gchar *sessionname)
++{
++ GError *error = NULL;
++
++ dbus_g_proxy_call (proxy, "SetValue", &error,
++ G_TYPE_STRING, SESSION_KEY_GROUP "/" SESSION_KEY_NAME,
++ G_TYPE_STRING, sessionname, G_TYPE_INVALID, G_TYPE_INVALID);
++ if (error) {
++ g_debug ("Error changing default session value to '%s': %s\nNo update will be done", sessionname, error->message);
++ g_error_free (error);
++ return FALSE;
++ }
++
++ return TRUE;
++}
++
++int
++update_session_if_needed(gchar *default_session, gchar *proposed_session, gboolean dbusupdate, gpointer *parameter)
++{
++ DBusGProxy *proxy = NULL;
++ GKeyFile *keyfile = NULL;
++ gboolean success = FALSE;
++
++ if (dbusupdate)
++ proxy = (DBusGProxy *) parameter;
++ else {
++ keyfile = (GKeyFile *) parameter;
++ success = TRUE; // by default, the function succeed (return void)
++ }
++
++ if (!(default_session)) {
++ g_debug("No value previously set. Update to %s", proposed_session);
++ if (dbusupdate)
++ success = set_default_session_name_with_dbus(proxy, proposed_session);
++ else
++ g_key_file_set_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, proposed_session);
++ }
++ else {
++ if (remove) {
++ if (g_strcmp0(proposed_session, default_session) == 0) {
++ g_debug("Remove %s as default session", proposed_session);
++ if (dbusupdate)
++ success = set_default_session_name_with_dbus(proxy, "");
++ else
++ g_key_file_set_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, "");
++ if (!success)
++ return(2);
++ return(0);
++ }
++ g_debug("Don't remove: %s not default session", proposed_session);
++ return(4);
++ }
++ if (strlen(default_session) < 1) {
++ g_debug("Empty value set as gdm default session. Set to %s", proposed_session);
++ if (dbusupdate)
++ success = set_default_session_name_with_dbus(proxy, proposed_session);
++ else
++ g_key_file_set_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, proposed_session);
++ }
++ else {
++ g_debug("Found existing default session: %s", default_session);
++ if(keepold)
++ g_debug("keep-old mode: keep previous default session");
++ else {
++ g_debug("Update to %s", proposed_session);
++ if (dbusupdate)
++ success = set_default_session_name_with_dbus(proxy, proposed_session);
++ else
++ g_key_file_set_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, proposed_session);
++ }
++ }
++ }
++ if (!success)
++ return(2);
++ return(0);
++}
++
++int
++main (int argc, char *argv[])
++{
++ GOptionContext *context = NULL;
++ GError *error = NULL;
++
++ DBusGProxy *proxy = NULL;
++ DBusState return_dbus_code = CONNEXIONFAILED;
++ gboolean dbus_connexion_ok = FALSE;
++
++ GKeyFile *keyfile;
++ GKeyFileFlags flags;
++ gchar *s_data;
++ gsize size;
++ const gchar *gdm_conf_file = GDMCONFDIR "/custom.conf";
++
++ gchar *default_session = NULL;
++ gchar *proposed_session = NULL;
++ gint return_code;
++
++ g_type_init ();
++
++ context = g_option_context_new (_("- set gdm default session"));
++ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
++ if (!g_option_context_parse (context, &argc, &argv, &error)) {
++ g_printerr (_("option parsing failed: %s\n"), error->message);
++ g_option_context_free(context);
++ g_error_free (error);
++ exit (1);
++ }
++ if (argc!=2) {
++ g_printerr(_("Wrong usage of the command\n%s"), g_option_context_get_help (context, FALSE, NULL));
++ g_option_context_free(context);
++ exit(1);
++ }
++ if (context)
++ g_option_context_free(context);
++ if (!debug)
++ g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, show_nothing, NULL);
++ proposed_session = argv[1];
++
++
++ if (init_dbus_connection(&proxy) == CONNEXIONSUCCEED) {
++ return_dbus_code = get_default_session_name_with_dbus(proxy, &default_session);
++ if (return_dbus_code == CONNEXIONFAILED)
++ dbus_connexion_ok = FALSE; // dbus and service connexion ok, but can't access proxy
++ else {
++ dbus_connexion_ok = TRUE;
++ if (return_dbus_code == HASNOVALUE)
++ default_session = NULL;
++ return_code = update_session_if_needed (default_session, proposed_session, TRUE, (gpointer *) proxy);
++ }
++ }
++ if (proxy)
++ g_object_unref (proxy);
++
++ if (!dbus_connexion_ok) {
++ g_debug ("Can't change value by dbus, failback in %s direct modification", gdm_conf_file);
++ if (geteuid() != 0) {
++ g_printerr ("Updating directly %s requires root permission\n", gdm_conf_file);
++ exit(1);
++ }
++ keyfile = g_key_file_new ();
++ flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
++ if (!(g_key_file_load_from_file (keyfile, gdm_conf_file, flags, &error))) {
++ g_debug ("File doesn't seem to exist or can't be read: create one (%s)", error->message);
++ g_error_free (error);
++ error = NULL;
++ }
++ // try to get the right key
++ default_session = g_key_file_get_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, NULL);
++ return_code = update_session_if_needed (default_session, proposed_session, FALSE, (gpointer *) keyfile);
++ if(return_code == 0) {
++ s_data = g_key_file_to_data (keyfile, &size, &error);
++ if (!s_data) {
++ g_debug ("Can't convert data to string: %s", error->message);
++ g_error_free (error);
++ return_code = 1;
++ }
++ else {
++ if(!g_file_set_contents (gdm_conf_file, s_data, size, &error)) {
++ g_printerr ("Can't update: %s\n", error->message);
++ g_error_free (error);
++ return_code = 1;
++ }
++ g_free(s_data);
++ }
++ }
++ g_key_file_free(keyfile);
++ }
++
++ if(default_session)
++ g_free(default_session);
++
++ exit(return_code);
++
++}
diff --git a/gdm/patch/disable-fatal-criticals.patch b/gdm/patch/disable-fatal-criticals.patch
new file mode 100644
index 0000000..8af6636
--- /dev/null
+++ b/gdm/patch/disable-fatal-criticals.patch
@@ -0,0 +1,182 @@
+From fc6ee4aa6d71d2c448a9b62aca24ba318163c590 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode@redhat.com>
+Date: Tue, 28 Jun 2011 12:51:51 -0400
+Subject: [PATCH] common: don't tank on criticals
+
+Tiny (or not so tiny) bugs in components below GDM in the stack
+can lead to critical warnings.
+
+In development releases, GDM by default will crash when encountering
+a critical warning.
+
+Losing the login screen is a big deal. We shouldn't automatically subject
+our users to "can't log in" in order to highlight bugs in development
+releases.
+
+This commit removes fatal criticals by default.
+---
+ common/gdm-common.c | 9 ---------
+ common/gdm-common.h | 1 -
+ daemon/factory-slave-main.c | 2 --
+ daemon/main.c | 2 --
+ daemon/product-slave-main.c | 2 --
+ daemon/session-worker-main.c | 2 --
+ daemon/simple-slave-main.c | 2 --
+ daemon/xdmcp-chooser-slave-main.c | 2 --
+ gui/simple-chooser/chooser-main.c | 2 --
+ gui/simple-chooser/gdm-host-chooser.c | 2 --
+ gui/simple-greeter/greeter-main.c | 2 --
+ 11 files changed, 0 insertions(+), 28 deletions(-)
+
+diff --git a/common/gdm-common.c b/common/gdm-common.c
+index 7a4e26d..865341a 100644
+--- a/common/gdm-common.c
++++ b/common/gdm-common.c
+@@ -65,15 +65,6 @@ gdm_is_version_unstable (void)
+ return unstable;
+ }
+
+-void
+-gdm_set_fatal_warnings_if_unstable (void)
+-{
+- if (gdm_is_version_unstable ()) {
+- g_setenv ("G_DEBUG", "fatal_criticals", FALSE);
+- g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
+- }
+-}
+-
+ gboolean
+ gdm_get_pwent_for_name (const char *name,
+ struct passwd **pwentp)
+diff --git a/common/gdm-common.h b/common/gdm-common.h
+index 06300c8..41ddf1c 100644
+--- a/common/gdm-common.h
++++ b/common/gdm-common.h
+@@ -31,7 +31,6 @@
+ G_BEGIN_DECLS
+
+ gboolean gdm_is_version_unstable (void);
+-void gdm_set_fatal_warnings_if_unstable (void);
+
+ int gdm_wait_on_pid (int pid);
+ int gdm_wait_on_and_kill_pid (int pid,
+diff --git a/daemon/factory-slave-main.c b/daemon/factory-slave-main.c
+index 9caab1c..2441260 100644
+--- a/daemon/factory-slave-main.c
++++ b/daemon/factory-slave-main.c
+@@ -183,8 +183,6 @@ main (int argc,
+ textdomain (GETTEXT_PACKAGE);
+ setlocale (LC_ALL, "");
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ g_type_init ();
+
+ context = g_option_context_new (_("GNOME Display Manager Slave"));
+diff --git a/daemon/main.c b/daemon/main.c
+index 5b8d66b..2ffb779 100644
+--- a/daemon/main.c
++++ b/daemon/main.c
+@@ -543,8 +543,6 @@ main (int argc,
+
+ ret = 1;
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ g_type_init ();
+
+ context = g_option_context_new (_("GNOME Display Manager"));
+diff --git a/daemon/product-slave-main.c b/daemon/product-slave-main.c
+index b0ab03f..b8e4755 100644
+--- a/daemon/product-slave-main.c
++++ b/daemon/product-slave-main.c
+@@ -187,8 +187,6 @@ main (int argc,
+ textdomain (GETTEXT_PACKAGE);
+ setlocale (LC_ALL, "");
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ g_type_init ();
+
+ context = g_option_context_new (_("GNOME Display Manager Slave"));
+diff --git a/daemon/session-worker-main.c b/daemon/session-worker-main.c
+index 35b4463..9d40b8d 100644
+--- a/daemon/session-worker-main.c
++++ b/daemon/session-worker-main.c
+@@ -151,8 +151,6 @@ main (int argc,
+
+ g_type_init ();
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ /* Translators: worker is a helper process that does the work
+ of starting up a session */
+ context = g_option_context_new (_("GNOME Display Manager Session Worker"));
+diff --git a/daemon/simple-slave-main.c b/daemon/simple-slave-main.c
+index 7751b61..057492b 100644
+--- a/daemon/simple-slave-main.c
++++ b/daemon/simple-slave-main.c
+@@ -187,8 +187,6 @@ main (int argc,
+ textdomain (GETTEXT_PACKAGE);
+ setlocale (LC_ALL, "");
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ g_type_init ();
+
+ context = g_option_context_new (_("GNOME Display Manager Slave"));
+diff --git a/daemon/xdmcp-chooser-slave-main.c b/daemon/xdmcp-chooser-slave-main.c
+index f86ea89..ea54210 100644
+--- a/daemon/xdmcp-chooser-slave-main.c
++++ b/daemon/xdmcp-chooser-slave-main.c
+@@ -189,8 +189,6 @@ main (int argc,
+ textdomain (GETTEXT_PACKAGE);
+ setlocale (LC_ALL, "");
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ g_type_init ();
+
+ context = g_option_context_new (_("GNOME Display Manager Slave"));
+diff --git a/gui/simple-chooser/chooser-main.c b/gui/simple-chooser/chooser-main.c
+index ac1edd6..2978a23 100644
+--- a/gui/simple-chooser/chooser-main.c
++++ b/gui/simple-chooser/chooser-main.c
+@@ -233,8 +233,6 @@ main (int argc, char *argv[])
+
+ setlocale (LC_ALL, "");
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ g_type_init ();
+
+ gdm_log_init ();
+diff --git a/gui/simple-chooser/gdm-host-chooser.c b/gui/simple-chooser/gdm-host-chooser.c
+index 371ba28..1f5f9c6 100644
+--- a/gui/simple-chooser/gdm-host-chooser.c
++++ b/gui/simple-chooser/gdm-host-chooser.c
+@@ -232,8 +232,6 @@ main (int argc, char *argv[])
+
+ setlocale (LC_ALL, "");
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ g_type_init ();
+
+ gdm_log_init ();
+diff --git a/gui/simple-greeter/greeter-main.c b/gui/simple-greeter/greeter-main.c
+index aa165fa..a2c533e 100644
+--- a/gui/simple-greeter/greeter-main.c
++++ b/gui/simple-greeter/greeter-main.c
+@@ -252,8 +252,6 @@ main (int argc, char *argv[])
+
+ setlocale (LC_ALL, "");
+
+- gdm_set_fatal_warnings_if_unstable ();
+-
+ g_type_init ();
+
+ gdm_profile_start ("Initializing settings client");
+--
+1.7.5.4
+
diff --git a/gdm/patch/fix_external_program_paths.patch b/gdm/patch/fix_external_program_paths.patch
new file mode 100644
index 0000000..143e03a
--- /dev/null
+++ b/gdm/patch/fix_external_program_paths.patch
@@ -0,0 +1,24 @@
+diff -Nur gdm-2.91.91.orig/daemon/gdm-server.c gdm-2.91.91/daemon/gdm-server.c
+--- gdm-2.91.91.orig/daemon/gdm-server.c 2011-02-17 19:27:53.000000000 -0800
++++ gdm-2.91.91/daemon/gdm-server.c 2011-02-27 16:56:51.283347074 -0800
+@@ -131,7 +131,7 @@
+ g_return_val_if_fail (GDM_IS_SERVER (server), NULL);
+
+ error = NULL;
+- command = g_strdup_printf (LIBEXECDIR "/ck-get-x11-display-device --display %s",
++ command = g_strdup_printf ("/usr/lib/ConsoleKit/ck-get-x11-display-device --display %s",
+ server->priv->display_name);
+
+ g_debug ("GdmServer: Running helper %s", command);
+diff -Nur gdm-2.91.91.orig/gui/simple-chooser/gdm-chooser-session.c gdm-2.91.91/gui/simple-chooser/gdm-chooser-session.c
+--- gdm-2.91.91.orig/gui/simple-chooser/gdm-chooser-session.c 2011-02-17 19:27:53.000000000 -0800
++++ gdm-2.91.91/gui/simple-chooser/gdm-chooser-session.c 2011-02-26 08:45:01.946675918 -0800
+@@ -131,7 +131,7 @@
+ ret = FALSE;
+
+ error = NULL;
+- g_spawn_command_line_async (LIBEXECDIR "/gnome-settings-daemon", &error);
++ g_spawn_command_line_async ("/usr/bin/gnome-settings-daemon", &error);
+ if (error != NULL) {
+ g_warning ("Error starting settings daemon: %s", error->message);
+ g_error_free (error);
diff --git a/gdm/patch/switch_user.patch b/gdm/patch/switch_user.patch
new file mode 100644
index 0000000..e9485dd
--- /dev/null
+++ b/gdm/patch/switch_user.patch
@@ -0,0 +1,617 @@
+diff -r -u gdm-3.1.90.old//daemon/gdm-display.c gdm-3.1.90/daemon/gdm-display.c
+--- gdm-3.1.90.old//daemon/gdm-display.c 2011-09-02 17:35:54.663697535 +0200
++++ gdm-3.1.90/daemon/gdm-display.c 2011-09-02 17:41:27.506682115 +0200
+@@ -60,6 +60,7 @@
+ time_t creation_time;
+ GTimer *slave_timer;
+ char *slave_command;
++ char *username;
+
+ char *x11_cookie;
+ gsize x11_cookie_size;
+@@ -85,6 +86,7 @@
+ PROP_X11_AUTHORITY_FILE,
+ PROP_IS_LOCAL,
+ PROP_SLAVE_COMMAND,
++ PROP_USERNAME,
+ };
+
+ static void gdm_display_class_init (GdmDisplayClass *klass);
+@@ -574,9 +576,17 @@
+ gdm_slave_proxy_set_log_path (display->priv->slave_proxy, log_path);
+ g_free (log_path);
+
+- command = g_strdup_printf ("%s --display-id %s",
+- display->priv->slave_command,
+- display->priv->id);
++ if (display->priv->username) {
++ command = g_strdup_printf ("%s --display-id %s --username %s",
++ display->priv->slave_command,
++ display->priv->id,
++ display->priv->username);
++ } else {
++ command = g_strdup_printf ("%s --display-id %s",
++ display->priv->slave_command,
++ display->priv->id);
++ }
++
+ gdm_slave_proxy_set_command (display->priv->slave_proxy, command);
+ g_free (command);
+
+@@ -832,6 +842,14 @@
+ }
+
+ static void
++_gdm_display_set_username (GdmDisplay *display,
++ const char *username)
++{
++ g_free (display->priv->username);
++ display->priv->username = g_strdup (username);
++}
++
++static void
+ gdm_display_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+@@ -869,6 +887,9 @@
+ case PROP_SLAVE_COMMAND:
+ _gdm_display_set_slave_command (self, g_value_get_string (value));
+ break;
++ case PROP_USERNAME:
++ _gdm_display_set_username (self, g_value_get_string (value));
++ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -917,6 +938,9 @@
+ case PROP_SLAVE_COMMAND:
+ g_value_set_string (value, self->priv->slave_command);
+ break;
++ case PROP_USERNAME:
++ g_value_set_string (value, self->priv->username);
++ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -1092,6 +1116,14 @@
+ "slave command",
+ DEFAULT_SLAVE_COMMAND,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
++
++ g_object_class_install_property (object_class,
++ PROP_USERNAME,
++ g_param_spec_string ("username",
++ "username",
++ "username",
++ NULL,
++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+ g_object_class_install_property (object_class,
+ PROP_STATUS,
+ g_param_spec_int ("status",
+diff -r -u gdm-3.1.90.old//daemon/gdm-greeter-server.c gdm-3.1.90/daemon/gdm-greeter-server.c
+--- gdm-3.1.90.old//daemon/gdm-greeter-server.c 2011-09-02 17:35:54.665697535 +0200
++++ gdm-3.1.90/daemon/gdm-greeter-server.c 2011-09-02 17:44:04.614674842 +0200
+@@ -344,6 +344,14 @@
+ }
+
+ void
++gdm_greeter_server_select_user(GdmGreeterServer *greeter_server,
++ const char *username)
++{
++ g_debug ("SelectUser(%s)", username);
++ send_dbus_string_signal (greeter_server, "SelectUser", username);
++}
++
++void
+ gdm_greeter_server_request_timed_login (GdmGreeterServer *greeter_server,
+ const char *username,
+ int delay)
+@@ -848,6 +856,9 @@
+ " <signal name=\"DefaultSessionNameChanged\">\n"
+ " <arg name=\"session_name\" type=\"s\"/>\n"
+ " </signal>\n"
++ " <signal name=\"SelectUser\">\n"
++ " <arg name=\"username\" type=\"s\"/>\n"
++ " </signal>\n"
+ " <signal name=\"TimedLoginRequested\">\n"
+ " <arg name=\"username\" type=\"s\"/>\n"
+ " <arg name=\"delay\" type=\"i\"/>\n"
+@@ -1200,7 +1211,7 @@
+ "display id",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+- g_object_class_install_property (object_class,
++ g_object_class_install_property (object_class,
+ PROP_USER_NAME,
+ g_param_spec_string ("user-name",
+ "user name",
+diff -r -u gdm-3.1.90.old//daemon/gdm-greeter-server.h gdm-3.1.90/daemon/gdm-greeter-server.h
+--- gdm-3.1.90.old//daemon/gdm-greeter-server.h 2011-09-02 17:35:54.665697535 +0200
++++ gdm-3.1.90/daemon/gdm-greeter-server.h 2011-09-02 17:45:01.832672189 +0200
+@@ -107,6 +107,8 @@
+ void gdm_greeter_server_default_session_name_changed (GdmGreeterServer *greeter_server,
+ const char *text);
+
++void gdm_greeter_server_select_user (GdmGreeterServer *greeter_server,
++ const char *username);
+ void gdm_greeter_server_request_timed_login (GdmGreeterServer *greeter_server,
+ const char *username,
+ int delay);
+diff -r -u gdm-3.1.90.old//daemon/gdm-local-display-factory.c gdm-3.1.90/daemon/gdm-local-display-factory.c
+--- gdm-3.1.90.old//daemon/gdm-local-display-factory.c 2011-09-02 17:35:54.664697535 +0200
++++ gdm-3.1.90/daemon/gdm-local-display-factory.c 2011-09-02 17:47:37.620664940 +0200
+@@ -27,6 +27,8 @@
+ #include <glib/gi18n.h>
+ #include <glib-object.h>
+
++#include "gdm-common.h"
++
+ #include "gdm-display-factory.h"
+ #include "gdm-local-display-factory.h"
+ #include "gdm-local-display-factory-glue.h"
+@@ -227,6 +227,121 @@
+ return ret;
+ }
+
++static gboolean
++switch_to_user_display (GdmLocalDisplayFactory *factory, char *username)
++{
++ struct passwd *password;
++ DBusGProxy *proxy;
++ GPtrArray *sessions = NULL;
++ GError *error = NULL;
++ gboolean result = FALSE;
++
++ gdm_get_pwent_for_name (username, &password);
++ if (!password) {
++ return FALSE;
++ }
++
++ proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
++ "org.freedesktop.ConsoleKit",
++ "/org/freedesktop/ConsoleKit/Manager",
++ "org.freedesktop.ConsoleKit.Manager");
++
++ dbus_g_proxy_call (proxy, "GetSessionsForUnixUser", &error,
++ G_TYPE_UINT, password->pw_uid, G_TYPE_INVALID,
++ dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions, G_TYPE_INVALID);
++ g_object_unref(proxy);
++ if (error != NULL) {
++ g_warning ("Error getting sessions for user %s: %s", username, error->message);
++ g_error_free (error);
++ }
++
++ if (sessions && sessions->len > 0) {
++ gchar *session_id = sessions->pdata[0];
++
++ g_debug ("GdmLocalDisplayFactory: Switching to session %s (user %s)", session_id, username);
++
++ proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
++ "org.freedesktop.ConsoleKit",
++ session_id,
++ "org.freedesktop.ConsoleKit.Session");
++ result = dbus_g_proxy_call (proxy, "Activate", &error, G_TYPE_INVALID, G_TYPE_INVALID);
++ g_object_unref (proxy);
++ if (error != NULL)
++ {
++ g_warning ("Error activating session for user %s: %s", username, error->message);
++ g_error_free (error);
++ }
++ }
++
++ if (sessions != NULL) {
++ gint i;
++ for (i = 0; i < sessions->len; i++) {
++ g_free (sessions->pdata[i]);
++ }
++ g_ptr_array_free (sessions, TRUE);
++ }
++
++ return result;
++}
++
++gboolean
++gdm_local_display_factory_switch_to_user (GdmLocalDisplayFactory *factory,
++ char *username,
++ char **id,
++ GError **error)
++{
++ gboolean ret;
++ GdmDisplay *display;
++ guint32 num;
++
++ g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
++
++ /* Switch to existing user display */
++ if (switch_to_user_display (factory, username)) {
++ /* FIXME: How to return the ID of the user display? It should
++ * be easy but I can't find how to get it */
++ /*if (id != NULL) {
++ *id = g_strdup ("FIXME");
++ }*/
++
++ /* FIXME: We should return TRUE here but this causes GDM to go
++ * crazy. Luckily we can return FALSE as we don't need
++ * any values returned from this call */
++ return FALSE;
++ }
++
++ ret = FALSE;
++
++ num = take_next_display_number (factory);
++
++ g_debug ("GdmLocalDisplayFactory: Switching to user %s on display %d", username, num);
++
++ display = gdm_transient_display_new (num);
++
++ /* FIXME: don't hardcode seat1? */
++ g_object_set (display, "seat-id", CK_SEAT1_PATH, NULL);
++ g_object_set (display, "username", username, NULL);
++
++ store_display (factory, num, display);
++
++ if (! gdm_display_manage (display)) {
++ display = NULL;
++ goto out;
++ }
++
++ if (! gdm_display_get_id (display, id, NULL)) {
++ display = NULL;
++ goto out;
++ }
++
++ ret = TRUE;
++ out:
++ /* ref either held by store or not at all */
++ g_object_unref (display);
++
++ return ret;
++}
++
+ gboolean
+ gdm_local_display_factory_create_product_display (GdmLocalDisplayFactory *factory,
+ const char *parent_display_id,
+diff -r -u gdm-3.1.90.old//daemon/gdm-local-display-factory.h gdm-3.1.90/daemon/gdm-local-display-factory.h
+--- gdm-3.1.90.old//daemon/gdm-local-display-factory.h 2011-09-02 17:35:54.665697535 +0200
++++ gdm-3.1.90/daemon/gdm-local-display-factory.h 2011-09-02 17:48:38.078662173 +0200
+@@ -64,6 +64,10 @@
+ gboolean gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory,
+ char **id,
+ GError **error);
++gboolean gdm_local_display_factory_switch_to_user (GdmLocalDisplayFactory *factory,
++ char *username,
++ char **id,
++ GError **error);
+
+ gboolean gdm_local_display_factory_create_product_display (GdmLocalDisplayFactory *factory,
+ const char *parent_display_id,
+diff -r -u gdm-3.1.90.old//daemon/gdm-local-display-factory.xml gdm-3.1.90/daemon/gdm-local-display-factory.xml
+--- gdm-3.1.90.old//daemon/gdm-local-display-factory.xml 2011-09-02 17:35:54.664697535 +0200
++++ gdm-3.1.90/daemon/gdm-local-display-factory.xml 2011-09-02 17:49:05.999660840 +0200
+@@ -9,5 +9,9 @@
+ <method name="CreateTransientDisplay">
+ <arg name="id" direction="out" type="o"/>
+ </method>
++ <method name="SwitchToUser">
++ <arg name="username" direction="in" type="s"/>
++ <arg name="id" direction="out" type="o"/>
++ </method>
+ </interface>
+ </node>
+diff -r -u gdm-3.1.90.old//daemon/gdm-simple-slave.c gdm-3.1.90/daemon/gdm-simple-slave.c
+--- gdm-3.1.90.old//daemon/gdm-simple-slave.c 2011-09-02 17:35:54.664697535 +0200
++++ gdm-3.1.90/daemon/gdm-simple-slave.c 2011-09-02 18:04:47.420617214 +0200
+@@ -93,10 +93,12 @@
+ #ifdef HAVE_LOGINDEVPERM
+ gboolean use_logindevperm;
+ #endif
++ gchar *username;
+ };
+
+ enum {
+ PROP_0,
++ PROP_USERNAME,
+ };
+
+ static void gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass);
+@@ -622,6 +624,16 @@
+ }
+
+ static void
++gdm_simple_slave_set_username (GdmSimpleSlave *slave,
++ const char *username)
++{
++ g_return_if_fail (GDM_IS_SIMPLE_SLAVE (slave));
++
++ g_free (slave->priv->username);
++ slave->priv->username = g_strdup (username);
++}
++
++static void
+ on_session_conversation_started (GdmSession *session,
+ const char *service_name,
+ GdmSimpleSlave *slave)
+@@ -640,6 +652,19 @@
+ }
+ }
+
++ g_object_get (slave, "username", &username, NULL);
++ if (username) {
++ g_debug ("GdmSimpleSlave: **user '%s'", username);
++ if (slave->priv->greeter_server != NULL) {
++ g_debug ("GdmSimpleSlave: begin login for user '%s'", username);
++ gdm_simple_slave_set_username (slave, NULL);
++ gdm_greeter_server_select_user (slave->priv->greeter_server, username);
++ }
++ g_free (username);
++ return;
++ }
++ g_debug ("GdmSimpleSlave: **nouser");
++
+ enabled = FALSE;
+ gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, &username, &delay);
+ if (! enabled) {
+@@ -1523,7 +1548,14 @@
+ const GValue *value,
+ GParamSpec *pspec)
+ {
++ GdmSimpleSlave *self;
++
++ self = GDM_SIMPLE_SLAVE (object);
++
+ switch (prop_id) {
++ case PROP_USERNAME:
++ gdm_simple_slave_set_username (self, g_value_get_string (value));
++ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -1536,7 +1568,15 @@
+ GValue *value,
+ GParamSpec *pspec)
+ {
++ GdmSimpleSlave *self;
++
++ self = GDM_SIMPLE_SLAVE (object);
++
+ switch (prop_id) {
++ case PROP_USERNAME:
++ g_value_set_string (value, self->priv->username);
++ break;
++
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -1573,6 +1613,14 @@
+
+ g_type_class_add_private (klass, sizeof (GdmSimpleSlavePrivate));
+
++ g_object_class_install_property (object_class,
++ PROP_USERNAME,
++ g_param_spec_string ("username",
++ "id",
++ "id",
++ NULL,
++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
++
+ dbus_g_object_type_install_info (GDM_TYPE_SIMPLE_SLAVE, &dbus_glib_gdm_simple_slave_object_info);
+ }
+
+@@ -1608,12 +1656,13 @@
+ }
+
+ GdmSlave *
+-gdm_simple_slave_new (const char *id)
++gdm_simple_slave_new (const char *id, const char *username)
+ {
+ GObject *object;
+
+ object = g_object_new (GDM_TYPE_SIMPLE_SLAVE,
+ "display-id", id,
++ "username", username,
+ NULL);
+
+ return GDM_SLAVE (object);
+diff -r -u gdm-3.1.90.old//daemon/gdm-simple-slave.h gdm-3.1.90/daemon/gdm-simple-slave.h
+--- gdm-3.1.90.old//daemon/gdm-simple-slave.h 2011-09-02 17:35:54.664697535 +0200
++++ gdm-3.1.90/daemon/gdm-simple-slave.h 2011-09-02 18:05:15.763615898 +0200
+@@ -48,7 +48,8 @@
+ } GdmSimpleSlaveClass;
+
+ GType gdm_simple_slave_get_type (void);
+-GdmSlave * gdm_simple_slave_new (const char *id);
++GdmSlave * gdm_simple_slave_new (const char *id,
++ const char *username);
+
+ G_END_DECLS
+
+diff -r -u gdm-3.1.90.old//daemon/simple-slave-main.c gdm-3.1.90/daemon/simple-slave-main.c
+--- gdm-3.1.90.old//daemon/simple-slave-main.c 2011-09-02 17:35:54.663697535 +0200
++++ gdm-3.1.90/daemon/simple-slave-main.c 2011-09-02 18:07:12.536610486 +0200
+@@ -177,9 +177,11 @@
+ DBusGConnection *connection;
+ GdmSlave *slave;
+ static char *display_id = NULL;
++ static char *username = NULL;
+ GdmSignalHandler *signal_handler;
+ static GOptionEntry entries [] = {
+ { "display-id", 0, 0, G_OPTION_ARG_STRING, &display_id, N_("Display ID"), N_("ID") },
++ { "username", 0, 0, G_OPTION_ARG_STRING, &username, N_("Username"), N_("name") },
+ { NULL }
+ };
+
+@@ -246,7 +248,7 @@
+ gdm_signal_handler_add (signal_handler, SIGUSR1, signal_cb, NULL);
+ gdm_signal_handler_add (signal_handler, SIGUSR2, signal_cb, NULL);
+
+- slave = gdm_simple_slave_new (display_id);
++ slave = gdm_simple_slave_new (display_id, username);
+ if (slave == NULL) {
+ goto out;
+ }
+diff -r -u gdm-3.1.90.old//data/gdm.conf.in gdm-3.1.90/data/gdm.conf.in
+--- gdm-3.1.90.old//data/gdm.conf.in 2011-09-02 17:35:54.662697535 +0200
++++ gdm-3.1.90/data/gdm.conf.in 2011-09-02 18:07:54.638608550 +0200
+@@ -66,6 +66,9 @@
+ <allow send_destination="org.gnome.DisplayManager"
+ send_interface="org.gnome.DisplayManager.LocalDisplayFactory"
+ send_member="CreateTransientDisplay"/>
++ <allow send_destination="org.gnome.DisplayManager"
++ send_interface="org.gnome.DisplayManager.LocalDisplayFactory"
++ send_member="SwitchToUser"/>
+
+ <allow send_destination="org.gnome.DisplayManager"
+ send_interface="org.gnome.DisplayManager.Manager"
+diff -r -u gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-client.c gdm-3.1.90/gui/simple-greeter/gdm-greeter-client.c
+--- gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-client.c 2011-09-02 17:35:54.660697538 +0200
++++ gdm-3.1.90/gui/simple-greeter/gdm-greeter-client.c 2011-09-02 18:11:23.425598857 +0200
+@@ -70,6 +70,7 @@
+ SELECTED_USER_CHANGED,
+ DEFAULT_LANGUAGE_NAME_CHANGED,
+ DEFAULT_SESSION_NAME_CHANGED,
++ SELECT_USER,
+ TIMED_LOGIN_REQUESTED,
+ SESSION_OPENED,
+ LAST_SIGNAL
+@@ -215,6 +216,14 @@
+ }
+
+ static void
++on_select_user (GdmGreeterClient *client,
++ DBusMessage *message)
++{
++ g_debug("GdmGreeterClient: SelectUser");
++ emit_string_signal_for_message (client, "SelectUser", message, SELECT_USER);
++}
++
++static void
+ on_timed_login_requested (GdmGreeterClient *client,
+ DBusMessage *message)
+ {
+@@ -761,6 +770,8 @@
+ on_default_language_name_changed (client, message);
+ } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "DefaultSessionNameChanged")) {
+ on_default_session_name_changed (client, message);
++ } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "SelectUser")) {
++ on_select_user (client, message);
+ } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "TimedLoginRequested")) {
+ on_timed_login_requested (client, message);
+ } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "SessionOpened")) {
+@@ -1060,6 +1071,17 @@
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
++ G_TYPE_NONE,
++ 1, G_TYPE_STRING);
++
++ gdm_greeter_client_signals[SELECT_USER] =
++ g_signal_new ("select-user",
++ G_OBJECT_CLASS_TYPE (object_class),
++ G_SIGNAL_RUN_FIRST,
++ G_STRUCT_OFFSET (GdmGreeterClientClass, select_user),
++ NULL,
++ NULL,
++ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+
+diff -r -u gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-client.h gdm-3.1.90/gui/simple-greeter/gdm-greeter-client.h
+--- gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-client.h 2011-09-02 17:35:54.660697538 +0200
++++ gdm-3.1.90/gui/simple-greeter/gdm-greeter-client.h 2011-09-02 18:11:52.696597498 +0200
+@@ -74,6 +74,8 @@
+ const char *session_name);
+ void (* default_language_name_changed) (GdmGreeterClient *client,
+ const char *language_name);
++ void (* select_user) (GdmGreeterClient *client,
++ const char *username);
+ void (* timed_login_requested) (GdmGreeterClient *client,
+ const char *username,
+ int delay);
+diff -r -u gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-login-window.c gdm-3.1.90/gui/simple-greeter/gdm-greeter-login-window.c
+--- gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-login-window.c 2011-09-02 17:35:54.661697536 +0200
++++ gdm-3.1.90/gui/simple-greeter/gdm-greeter-login-window.c 2011-09-02 18:16:16.861585254 +0200
+@@ -148,6 +148,8 @@
+ guint login_button_handler_id;
+ guint start_session_handler_id;
+
++ char *username;
++
+ char *service_name_of_session_ready_to_start;
+ };
+
+@@ -1194,6 +1196,22 @@
+ }
+
+ void
++gdm_greeter_login_window_select_user (GdmGreeterLoginWindow *login_window,
++ const char *username)
++{
++ g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window));
++
++ g_debug ("GdmGreeterLoginWindow: selecting user '%s'", username);
++
++ g_free (login_window->priv->username);
++ login_window->priv->username = g_strdup (username);
++ if (login_window->priv->user_chooser_loaded) {
++ g_debug ("GdmGreeterLoginWindow: activating user '%s'", login_window->priv->username);
++ gdm_chooser_widget_set_active_item (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser), username);
++ }
++}
++
++void
+ gdm_greeter_login_window_request_timed_login (GdmGreeterLoginWindow *login_window,
+ const char *username,
+ int delay)
+@@ -1437,6 +1455,10 @@
+
+ if (!login_window->priv->user_list_disabled) {
+ gtk_widget_show (login_window->priv->user_chooser);
++ if (login_window->priv->username) {
++ g_debug ("GdmGreeterLoginWindow: activating user '%s'", login_window->priv->username);
++ gdm_chooser_widget_set_active_item (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser), login_window->priv->username);
++ }
+ }
+
+ enable_waiting_extensions (login_window);
+diff -r -u gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-login-window.h gdm-3.1.90/gui/simple-greeter/gdm-greeter-login-window.h
+--- gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-login-window.h 2011-09-02 17:35:54.659697539 +0200
++++ gdm-3.1.90/gui/simple-greeter/gdm-greeter-login-window.h 2011-09-02 18:16:55.629583456 +0200
+@@ -95,6 +95,8 @@
+ gboolean gdm_greeter_login_window_service_unavailable (GdmGreeterLoginWindow *login_window,
+ const char *service_name);
+
++void gdm_greeter_login_window_select_user (GdmGreeterLoginWindow *login_window,
++ const char *username);
+ void gdm_greeter_login_window_request_timed_login (GdmGreeterLoginWindow *login_window,
+ const char *username,
+ int delay);
+diff -r -u gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-session.c gdm-3.1.90/gui/simple-greeter/gdm-greeter-session.c
+--- gdm-3.1.90.old//gui/simple-greeter/gdm-greeter-session.c 2011-09-02 17:35:54.660697538 +0200
++++ gdm-3.1.90/gui/simple-greeter/gdm-greeter-session.c 2011-09-02 18:18:15.207579768 +0200
+@@ -170,6 +170,15 @@
+ }
+
+ static void
++on_server_select_user (GdmGreeterClient *client,
++ const char *username,
++ GdmGreeterSession *session)
++{
++ g_debug ("GdmGreeterSession: selecting user %s", username);
++ gdm_greeter_login_window_select_user (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), username);
++}
++
++static void
+ on_timed_login_requested (GdmGreeterClient *client,
+ const char *text,
+ int delay,
+@@ -600,6 +609,10 @@
+ G_CALLBACK (on_default_session_name_changed),
+ session);
+ g_signal_connect (session->priv->client,
++ "select-user",
++ G_CALLBACK (on_server_select_user),
++ session);
++ g_signal_connect (session->priv->client,
+ "timed-login-requested",
+ G_CALLBACK (on_timed_login_requested),
+ session);
diff --git a/gdm/patch/time_display_on_greeter.patch b/gdm/patch/time_display_on_greeter.patch
new file mode 100644
index 0000000..7bcad89
--- /dev/null
+++ b/gdm/patch/time_display_on_greeter.patch
@@ -0,0 +1,104 @@
+Description: Display time on the greeter in accordance with the system wide settings in Language Support.
+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=651506
+Bug-Ubuntu: https://launchpad.net/bugs/777264
+Forwarded: yes
+Author: Gunnar Hjalmarsson <ubuntu@gunnar.cc>
+
+diff -Nur -x '*.orig' -x '*~' gdm-3.0.0//gui/simple-greeter/gdm-clock-widget.c gdm-3.0.0.new//gui/simple-greeter/gdm-clock-widget.c
+--- gdm-3.0.0//gui/simple-greeter/gdm-clock-widget.c 2011-04-04 16:37:16.000000000 +0200
++++ gdm-3.0.0.new//gui/simple-greeter/gdm-clock-widget.c 2011-06-05 23:55:31.140297043 +0200
+@@ -30,6 +30,7 @@
+ #include <errno.h>
+ #include <dirent.h>
+ #include <sys/stat.h>
++#include <locale.h>
+
+ #include <glib.h>
+ #include <glib/gi18n.h>
+@@ -60,39 +61,23 @@
+ static void
+ update_time_format (GdmClockWidget *clock)
+ {
++ time_t t;
++ struct tm *tm;
++ char ampm[16];
+ char *clock_format;
+ char *tooltip_format;
+
+- if (clock->priv->should_show_date && clock->priv->should_show_seconds) {
+- /* translators: This is the time format to use when both
+- * the date and time with seconds are being shown together.
+- */
+- clock_format = _("%a %b %e, %l:%M:%S %p");
+- tooltip_format = NULL;
+- } else if (clock->priv->should_show_date && !clock->priv->should_show_seconds) {
+- /* translators: This is the time format to use when both
+- * the date and time without seconds are being shown together.
+- */
+- clock_format = _("%a %b %e, %l:%M %p");
+-
+- tooltip_format = NULL;
+- } else if (!clock->priv->should_show_date && clock->priv->should_show_seconds) {
+- /* translators: This is the time format to use when there is
+- * no date, just weekday and time with seconds.
+- */
+- clock_format = _("%a %l:%M:%S %p");
+-
+- /* translators: This is the time format to use for the date
+- */
+- tooltip_format = "%x";
++ time (&t);
++ tm = localtime (&t);
++ setlocale(LC_TIME, "");
++ strftime(ampm, sizeof(ampm), "%p", tm);
++
++ if (strlen(ampm) > 0) {
++ clock_format = "%l:%M %p";
+ } else {
+- /* translators: This is the time format to use when there is
+- * no date, just weekday and time without seconds.
+- */
+- clock_format = _("%a %l:%M %p");
+-
+- tooltip_format = "%x";
++ clock_format = "%H:%M";
+ }
++ tooltip_format = "%x";
+
+ g_free (clock->priv->time_format);
+ clock->priv->time_format = g_locale_from_utf8 (clock_format, -1, NULL, NULL, NULL);
+@@ -113,6 +98,8 @@
+ {
+ time_t t;
+ struct tm *tm;
++ char showed_time[32];
++ char weekday[32];
+ char buf[256];
+ char *utf8;
+ char *markup;
+@@ -123,10 +110,15 @@
+ g_warning ("Unable to get broken down local time");
+ return;
+ }
+- if (strftime (buf, sizeof (buf), clock_format, tm) == 0) {
++ if (strftime (showed_time, sizeof (showed_time), clock_format, tm) == 0) {
+ g_warning ("Couldn't format time: %s", clock_format);
+- strcpy (buf, "???");
++ strcpy (showed_time, "???");
+ }
++
++ setlocale( LC_TIME, getenv("LC_MESSAGES") );
++ strftime(weekday, sizeof(weekday), "%a", tm);
++ sprintf(buf, "%s %s", weekday, showed_time);
++
+ utf8 = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
+ markup = g_strdup_printf ("<b><span foreground=\"white\">%s</span></b>", utf8);
+ gtk_label_set_markup (label, markup);
+@@ -134,6 +126,7 @@
+ g_free (utf8);
+
+ if (tooltip_format != NULL) {
++ setlocale(LC_TIME, "");
+ if (strftime (buf, sizeof (buf), tooltip_format, tm) == 0) {
+ g_warning ("Couldn't format tooltip date: %s", tooltip_format);
+ strcpy (buf, "???");
diff --git a/gdm/patch/vt-allocation-hack.patch b/gdm/patch/vt-allocation-hack.patch
new file mode 100644
index 0000000..be0bcd2
--- /dev/null
+++ b/gdm/patch/vt-allocation-hack.patch
@@ -0,0 +1,118 @@
+diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
+index 39def47..03488fd 100644
+--- a/daemon/gdm-server.c
++++ b/daemon/gdm-server.c
+@@ -33,6 +33,8 @@
+ #include <grp.h>
+ #include <signal.h>
+ #include <sys/resource.h>
++#include <sys/ioctl.h>
++#include <sys/vt.h>
+
+ #ifdef HAVE_SYS_PRCTL_H
+ #include <sys/prctl.h>
+@@ -154,6 +158,92 @@ _gdm_server_query_ck_for_display_device (GdmServer *server)
+ return out;
+ }
+
++#ifndef O_NOCTTY
++# define O_NOCTTY 0
++#endif
++
++static int
++open_vt (int vtno)
++{
++ char *vtname;
++ int fd;
++
++ vtname = g_strdup_printf ("/dev/tty%d", vtno);
++
++ do {
++ errno = 0;
++ fd = open (vtname, O_RDWR | O_NOCTTY, 0);
++ } while (errno == EINTR);
++
++ g_free (vtname);
++ return fd;
++}
++
++static gint
++find_first_probably_free_vt (void)
++{
++ int fd, fdv;
++ int vtno;
++ unsigned short vtmask;
++ struct vt_stat vtstat;
++ guint v_state;
++
++ fdv = -1;
++
++ do {
++ errno = 0;
++ fd = open ("/dev/console", O_WRONLY | O_NOCTTY, 0);
++ } while (errno == EINTR);
++
++ if (fd >= 0) {
++ if (ioctl (fd, VT_GETSTATE, &vtstat) >= 0) {
++ v_state = vtstat.v_state;
++ } else {
++ close (fd);
++ v_state = 0;
++ fd = -1;
++ }
++ } else {
++ v_state = 0;
++ }
++
++ if (fd < 0) {
++ do {
++ errno = 0;
++ fd = open ("/dev/console", O_RDONLY | O_NOCTTY, 0);
++ } while (errno == EINTR);
++
++ if (fd >= 0) {
++ if (ioctl (fd, VT_GETSTATE, &vtstat) >= 0)
++ v_state = vtstat.v_state;
++ }
++ }
++
++ for (vtno = 7, vtmask = 1 << vtno; vtmask; vtno++, vtmask <<= 1) {
++ /* Is this console in use? */
++ if (v_state & vtmask)
++ continue;
++
++ /* No, try to open it */
++ fdv = open_vt (vtno);
++ if (fdv >= 0)
++ break;
++
++ /* If we're here, kernel indicated that the console was free,
++ * but we failed to open it. Just go on to higher VTs. */
++ }
++
++ if (fdv >= 0)
++ close (fdv);
++ else
++ vtno = -1;
++
++ if (fd >= 0)
++ close (fd);
++
++ return vtno;
++}
++
+ char *
+ gdm_server_get_display_device (GdmServer *server)
+ {
+@@ -314,6 +402,11 @@ gdm_server_resolve_command_line (GdmServer *server,
+
+ if (vtarg != NULL && ! gotvtarg) {
+ argv[len++] = g_strdup (vtarg);
++ } else if (!query_in_arglist && !gotvtarg) {
++ gint vtnum = find_first_probably_free_vt ();
++
++ if (vtnum > 0)
++ argv [len++] = g_strdup_printf ("vt%d", vtnum);
+ }
+
+ argv[len++] = NULL;