[gdm/display-configuration: 1/2] Add start of display configuration



commit 15b783fb68e53c98d283f565eca305a3f919322d
Author: Halton Huo <halton huo sun com>
Date:   Sun May 10 22:43:06 2009 -0400

    Add start of display configuration
    
    See http://bugzilla.gnome.org/show_bug.cgi?id=536355

 daemon/Makefile.am                   |    2 +
 daemon/ck-connector.c                |    2 +
 daemon/gdm-display.c                 |  251 ++++++++++++++++++++-
 daemon/gdm-display.h                 |   18 ++
 daemon/gdm-display.xml               |   22 ++-
 daemon/gdm-dynamic-display.c         |  210 +++++++++++++++++
 daemon/gdm-dynamic-display.h         |   59 +++++
 daemon/gdm-factory-slave.c           |   22 ++-
 daemon/gdm-greeter-session.c         |    6 +-
 daemon/gdm-greeter-session.h         |    4 +-
 daemon/gdm-local-display-factory.c   |  225 ++++++++++++++++++-
 daemon/gdm-local-display-factory.h   |   17 ++
 daemon/gdm-local-display-factory.xml |   74 ++++++
 daemon/gdm-product-slave.c           |   11 +-
 daemon/gdm-server.c                  |  416 +++++++++++++++++++++-------------
 daemon/gdm-server.h                  |    3 +-
 daemon/gdm-simple-slave.c            |   22 ++-
 daemon/gdm-slave.c                   |   40 ++++
 daemon/gdm-static-display.c          |    1 +
 daemon/gdm-welcome-session.c         |   59 +++++-
 daemon/gdm-xdmcp-chooser-display.c   |    2 +-
 21 files changed, 1269 insertions(+), 197 deletions(-)
---
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 3daf924..0a00016 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -296,6 +296,8 @@ gdm_binary_SOURCES = 			\
 	gdm-static-display.h		\
 	gdm-transient-display.c		\
 	gdm-transient-display.h		\
+	gdm-dynamic-display.c		\
+	gdm-dynamic-display.h		\
 	gdm-static-factory-display.c	\
 	gdm-static-factory-display.h	\
 	gdm-product-display.c		\
diff --git a/daemon/ck-connector.c b/daemon/ck-connector.c
index 0117eb9..6f96613 100644
--- a/daemon/ck-connector.c
+++ b/daemon/ck-connector.c
@@ -76,9 +76,11 @@ static struct {
         { "display-device",     DBUS_TYPE_STRING },
         { "x11-display-device", DBUS_TYPE_STRING },
         { "x11-display",        DBUS_TYPE_STRING },
+        { "seat-id",            DBUS_TYPE_STRING },
         { "remote-host-name",   DBUS_TYPE_STRING },
         { "session-type",       DBUS_TYPE_STRING },
         { "is-local",           DBUS_TYPE_BOOLEAN },
+        { "is-dynamic",         DBUS_TYPE_BOOLEAN },
         { "unix-user",          DBUS_TYPE_INT32 },
 };
 
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 53f48f9..4370261 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -48,12 +48,27 @@ static guint32 display_serial = 1;
 
 #define DEFAULT_SLAVE_COMMAND LIBEXECDIR "/gdm-simple-slave"
 
+#if __sun
+#define GDM_PRIO_MIN 0
+#define GDM_PRIO_MAX (NZERO*2)-1
+#define GDM_PRIO_DEFAULT NZERO
+#else
+#include <sys/resource.h>
+#define GDM_PRIO_MIN PRIO_MIN
+#define GDM_PRIO_MAX PRIO_MAX
+#define GDM_PRIO_DEFAULT 0
+#endif
+
 struct GdmDisplayPrivate
 {
         char                 *id;
         char                 *seat_id;
 
         char                 *remote_hostname;
+        char                 *x11_command;
+        char                 *x11_arguments;
+        char                 *tty_device;
+        int                   priority;
         int                   x11_display_number;
         char                 *x11_display_name;
         int                   status;
@@ -66,6 +81,8 @@ struct GdmDisplayPrivate
         GdmDisplayAccessFile *access_file;
 
         gboolean              is_local;
+        gboolean              is_dynamic;
+        gboolean              use_auth;
         guint                 finish_idle_id;
 
         GdmSlaveProxy        *slave_proxy;
@@ -78,12 +95,18 @@ enum {
         PROP_ID,
         PROP_STATUS,
         PROP_SEAT_ID,
+        PROP_X11_COMMAND,
+        PROP_X11_ARGUMENTS,
+        PROP_TTY_DEVICE,
+        PROP_PRIORITY,
         PROP_REMOTE_HOSTNAME,
         PROP_X11_DISPLAY_NUMBER,
         PROP_X11_DISPLAY_NAME,
         PROP_X11_COOKIE,
         PROP_X11_AUTHORITY_FILE,
         PROP_IS_LOCAL,
+        PROP_IS_DYNAMIC,
+        PROP_USE_AUTH,
         PROP_SLAVE_COMMAND,
 };
 
@@ -551,10 +574,12 @@ gdm_display_real_prepare (GdmDisplay *display)
 
         g_assert (display->priv->slave_proxy == NULL);
 
-        if (!gdm_display_create_authority (display)) {
-                g_warning ("Unable to set up access control for display %d",
-                           display->priv->x11_display_number);
-                return FALSE;
+        if (display->priv->use_auth) {
+                if (!gdm_display_create_authority (display)) {
+                        g_warning ("Unable to set up access control for display %d",
+                                   display->priv->x11_display_number);
+                        return FALSE;
+                }
         }
 
         _gdm_display_set_status (display, GDM_DISPLAY_PREPARED);
@@ -743,6 +768,60 @@ gdm_display_get_id (GdmDisplay         *display,
 }
 
 gboolean
+gdm_display_get_x11_command (GdmDisplay *display,
+                             char      **command,
+                             GError    **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        if (command != NULL) {
+                *command = g_strdup (display->priv->x11_command);
+        }
+
+        return TRUE;
+}
+
+gboolean
+gdm_display_get_x11_arguments (GdmDisplay *display,
+                               char      **arguments,
+                               GError    **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        if (arguments != NULL) {
+                *arguments = g_strdup (display->priv->x11_arguments);
+        }
+
+        return TRUE;
+}
+
+gboolean
+gdm_display_get_tty_device (GdmDisplay *display,
+                            char      **tty_device,
+                            GError    **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        if (tty_device != NULL) {
+                *tty_device = g_strdup (display->priv->tty_device);
+        }
+
+        return TRUE;
+}
+
+gboolean
+gdm_display_get_priority (GdmDisplay *display,
+                          int        *priority,
+                          GError    **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        *priority = display->priv->priority;
+
+        return TRUE;
+}
+
+gboolean
 gdm_display_get_x11_display_name (GdmDisplay   *display,
                                   char        **x11_display,
                                   GError      **error)
@@ -770,6 +849,34 @@ gdm_display_is_local (GdmDisplay *display,
         return TRUE;
 }
 
+gboolean
+gdm_display_is_dynamic (GdmDisplay *display,
+                        gboolean   *dynamic,
+                        GError    **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        if (dynamic != NULL) {
+                *dynamic = display->priv->is_dynamic;
+        }
+
+        return TRUE;
+}
+
+gboolean
+gdm_display_use_auth (GdmDisplay *display,
+                      gboolean   *use_auth,
+                      GError    **error)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        if (use_auth != NULL) {
+                *use_auth = display->priv->use_auth;
+        }
+
+        return TRUE;
+}
+
 static void
 _gdm_display_set_id (GdmDisplay     *display,
                      const char     *id)
@@ -779,6 +886,43 @@ _gdm_display_set_id (GdmDisplay     *display,
 }
 
 static void
+_gdm_display_set_x11_command (GdmDisplay     *display,
+                              const char     *x11_command)
+{
+        g_free (display->priv->x11_command);
+        display->priv->x11_command = g_strdup (x11_command);
+}
+
+static void
+_gdm_display_set_x11_arguments (GdmDisplay     *display,
+                                const char     *x11_arguments)
+{
+        g_free (display->priv->x11_arguments);
+        display->priv->x11_arguments = g_strdup (x11_arguments);
+}
+
+static void
+_gdm_display_set_tty_device (GdmDisplay     *display,
+                             const char     *tty_device)
+{
+        g_free (display->priv->tty_device);
+        display->priv->tty_device = g_strdup (tty_device);
+}
+
+static void
+_gdm_display_set_priority (GdmDisplay     *display,
+                           int             priority)
+{
+        /* do some bounds checking */
+        if (priority < GDM_PRIO_MIN)
+                display->priv->priority = GDM_PRIO_MIN;
+        else if (priority > GDM_PRIO_MAX)
+                display->priv->priority = GDM_PRIO_MAX;
+        else
+                display->priv->priority = priority;
+}
+
+static void
 _gdm_display_set_seat_id (GdmDisplay     *display,
                           const char     *seat_id)
 {
@@ -825,6 +969,20 @@ _gdm_display_set_is_local (GdmDisplay     *display,
 }
 
 static void
+_gdm_display_set_is_dynamic (GdmDisplay     *display,
+                             gboolean        is_dynamic)
+{
+        display->priv->is_dynamic = is_dynamic;
+}
+
+static void
+_gdm_display_set_use_auth (GdmDisplay     *display,
+                           gboolean        use_auth)
+{
+        display->priv->use_auth = use_auth;
+}
+
+static void
 _gdm_display_set_slave_command (GdmDisplay     *display,
                                 const char     *command)
 {
@@ -846,6 +1004,18 @@ gdm_display_set_property (GObject        *object,
         case PROP_ID:
                 _gdm_display_set_id (self, g_value_get_string (value));
                 break;
+        case PROP_X11_COMMAND:
+                _gdm_display_set_x11_command (self, g_value_get_string (value));
+                break;
+        case PROP_X11_ARGUMENTS:
+                _gdm_display_set_x11_arguments (self, g_value_get_string (value));
+                break;
+        case PROP_TTY_DEVICE:
+                _gdm_display_set_tty_device (self, g_value_get_string (value));
+                break;
+        case PROP_PRIORITY:
+                _gdm_display_set_priority (self, g_value_get_int (value));
+                break;
         case PROP_STATUS:
                 _gdm_display_set_status (self, g_value_get_int (value));
                 break;
@@ -867,6 +1037,12 @@ gdm_display_set_property (GObject        *object,
         case PROP_IS_LOCAL:
                 _gdm_display_set_is_local (self, g_value_get_boolean (value));
                 break;
+        case PROP_IS_DYNAMIC:
+                _gdm_display_set_is_dynamic (self, g_value_get_boolean (value));
+                break;
+        case PROP_USE_AUTH:
+                _gdm_display_set_use_auth (self, g_value_get_boolean (value));
+                break;
         case PROP_SLAVE_COMMAND:
                 _gdm_display_set_slave_command (self, g_value_get_string (value));
                 break;
@@ -890,6 +1066,18 @@ gdm_display_get_property (GObject        *object,
         case PROP_ID:
                 g_value_set_string (value, self->priv->id);
                 break;
+        case PROP_X11_COMMAND:
+                g_value_set_string (value, self->priv->x11_command);
+                break;
+        case PROP_X11_ARGUMENTS:
+                g_value_set_string (value, self->priv->x11_arguments);
+                break;
+        case PROP_TTY_DEVICE:
+                g_value_set_string (value, self->priv->tty_device);
+                break;
+        case PROP_PRIORITY:
+                g_value_set_int (value, self->priv->priority);
+                break;
         case PROP_STATUS:
                 g_value_set_int (value, self->priv->status);
                 break;
@@ -915,6 +1103,12 @@ gdm_display_get_property (GObject        *object,
         case PROP_IS_LOCAL:
                 g_value_set_boolean (value, self->priv->is_local);
                 break;
+        case PROP_IS_DYNAMIC:
+                g_value_set_boolean (value, self->priv->is_dynamic);
+                break;
+        case PROP_USE_AUTH:
+                g_value_set_boolean (value, self->priv->use_auth);
+                break;
         case PROP_SLAVE_COMMAND:
                 g_value_set_string (value, self->priv->slave_command);
                 break;
@@ -1034,6 +1228,36 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
+                                         PROP_X11_COMMAND,
+                                         g_param_spec_string ("x11-command",
+                                                              "x11 command",
+                                                              "x11 command",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_X11_ARGUMENTS,
+                                         g_param_spec_string ("x11-arguments",
+                                                              "x11 arguments",
+                                                              "x11 arguments",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_TTY_DEVICE,
+                                         g_param_spec_string ("tty-device",
+                                                              "tty device",
+                                                              "tty device",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_PRIORITY,
+                                         g_param_spec_int ("priority",
+                                                           "priority",
+                                                           "priority",
+                                                           GDM_PRIO_MIN,
+                                                           GDM_PRIO_MAX,
+                                                           GDM_PRIO_DEFAULT,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
                                          PROP_REMOTE_HOSTNAME,
                                          g_param_spec_string ("remote-hostname",
                                                               "remote-hostname",
@@ -1077,7 +1301,6 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                               "authority file",
                                                               NULL,
                                                               G_PARAM_READABLE));
-
         g_object_class_install_property (object_class,
                                          PROP_IS_LOCAL,
                                          g_param_spec_boolean ("is-local",
@@ -1085,7 +1308,20 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                                NULL,
                                                                TRUE,
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
+        g_object_class_install_property (object_class,
+                                         PROP_IS_DYNAMIC,
+                                         g_param_spec_boolean ("is-dynamic",
+                                                               NULL,
+                                                               NULL,
+                                                               FALSE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_USE_AUTH,
+                                         g_param_spec_boolean ("use-auth",
+                                                               NULL,
+                                                               NULL,
+                                                               TRUE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
         g_object_class_install_property (object_class,
                                          PROP_SLAVE_COMMAND,
                                          g_param_spec_string ("slave-command",
@@ -1132,6 +1368,9 @@ gdm_display_finalize (GObject *object)
 
         g_debug ("GdmDisplay: Finalizing display: %s", display->priv->id);
         g_free (display->priv->id);
+        g_free (display->priv->x11_command);
+        g_free (display->priv->x11_arguments);
+        g_free (display->priv->tty_device);
         g_free (display->priv->seat_id);
         g_free (display->priv->remote_hostname);
         g_free (display->priv->x11_display_name);
diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h
index 607ea1d..5df9c65 100644
--- a/daemon/gdm-display.h
+++ b/daemon/gdm-display.h
@@ -102,6 +102,18 @@ gboolean            gdm_display_unmanage                       (GdmDisplay *disp
 gboolean            gdm_display_get_id                         (GdmDisplay *display,
                                                                 char      **id,
                                                                 GError    **error);
+gboolean            gdm_display_get_x11_command                (GdmDisplay *display,
+                                                                char      **command,
+                                                                GError    **error);
+gboolean            gdm_display_get_x11_arguments              (GdmDisplay *display,
+                                                                char      **arguments,
+                                                                GError    **error);
+gboolean            gdm_display_get_tty_device                 (GdmDisplay *display,
+                                                                char      **tty_device,
+                                                                GError    **error);
+gboolean            gdm_display_get_priority                   (GdmDisplay *display,
+                                                                int        *priority,
+                                                                GError    **error);
 gboolean            gdm_display_get_remote_hostname            (GdmDisplay *display,
                                                                 char      **hostname,
                                                                 GError    **error);
@@ -117,6 +129,12 @@ gboolean            gdm_display_get_seat_id                    (GdmDisplay *disp
 gboolean            gdm_display_is_local                       (GdmDisplay *display,
                                                                 gboolean   *local,
                                                                 GError    **error);
+gboolean            gdm_display_is_dynamic                     (GdmDisplay *display,
+                                                                gboolean   *dynamic,
+                                                                GError    **error);
+gboolean            gdm_display_use_auth                       (GdmDisplay *display,
+                                                                gboolean   *use_auth,
+                                                                GError    **error);
 gboolean            gdm_display_get_timed_login_details        (GdmDisplay *display,
                                                                 gboolean   *enabled,
                                                                 char      **username,
diff --git a/daemon/gdm-display.xml b/daemon/gdm-display.xml
index a92e37f..a7e1f5a 100644
--- a/daemon/gdm-display.xml
+++ b/daemon/gdm-display.xml
@@ -4,11 +4,23 @@
     <method name="GetId">
       <arg name="id" direction="out" type="o"/>
     </method>
+    <method name="GetX11Command">
+      <arg name="command" direction="out" type="s"/>
+    </method>
+    <method name="GetX11Arguments">
+      <arg name="arguments" direction="out" type="s"/>
+    </method>
+    <method name="GetTtyDevice">
+      <arg name="tty_device" direction="out" type="s"/>
+    </method>
+    <method name="GetPriority">
+      <arg name="priority" direction="out" type="i"/>
+    </method>
     <method name="GetX11DisplayName">
       <arg name="name" direction="out" type="s"/>
     </method>
     <method name="GetX11DisplayNumber">
-      <arg name="name" direction="out" type="i"/>
+      <arg name="number" direction="out" type="i"/>
     </method>
     <method name="GetX11Cookie">
       <arg name="x11_cookie" direction="out" type="ay"/>
@@ -17,7 +29,7 @@
       <arg name="filename" direction="out" type="s"/>
     </method>
     <method name="GetSeatId">
-      <arg name="filename" direction="out" type="s"/>
+      <arg name="seat_id" direction="out" type="s"/>
     </method>
     <method name="GetRemoteHostname">
       <arg name="hostname" direction="out" type="s"/>
@@ -25,6 +37,12 @@
     <method name="IsLocal">
       <arg name="local" direction="out" type="b"/>
     </method>
+    <method name="IsDynamic">
+      <arg name="dynamic" direction="out" type="b"/>
+    </method>
+    <method name="UseAuth">
+      <arg name="dynamic" direction="out" type="b"/>
+    </method>
     <method name="AddUserAuthorization">
       <arg name="username" direction="in" type="s"/>
       <arg name="filename" direction="out" type="s"/>
diff --git a/daemon/gdm-dynamic-display.c b/daemon/gdm-dynamic-display.c
new file mode 100644
index 0000000..ea07b1d
--- /dev/null
+++ b/daemon/gdm-dynamic-display.c
@@ -0,0 +1,210 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Authors: halton huo sun com
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#include "gdm-common.h"
+#include "gdm-display.h"
+#include "gdm-dynamic-display.h"
+
+#define GDM_DYNAMIC_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DYNAMIC_DISPLAY, GdmDynamicDisplayPrivate))
+
+struct _GdmDynamicDisplayPrivate
+{
+        gpointer dummy;
+};
+
+enum {
+        PROP_0,
+};
+
+static void     gdm_dynamic_display_class_init   (GdmDynamicDisplayClass *klass);
+static void     gdm_dynamic_display_init         (GdmDynamicDisplay      *display);
+static void     gdm_dynamic_display_finalize     (GObject                  *object);
+
+G_DEFINE_TYPE (GdmDynamicDisplay, gdm_dynamic_display, GDM_TYPE_DISPLAY)
+
+static gboolean
+gdm_dynamic_display_create_authority (GdmDisplay *display)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->create_authority (display);
+
+        return TRUE;
+}
+
+static gboolean
+gdm_dynamic_display_add_user_authorization (GdmDisplay *display,
+                                            const char *username,
+                                            char      **filename,
+                                            GError    **error)
+{
+        return GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->add_user_authorization (display, username, filename, error);
+}
+
+static gboolean
+gdm_dynamic_display_remove_user_authorization (GdmDisplay *display,
+                                               const char *username,
+                                               GError    **error)
+{
+        return GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->remove_user_authorization (display, username, error);
+}
+
+static gboolean
+gdm_dynamic_display_manage (GdmDisplay *display)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->manage (display);
+
+        return TRUE;
+}
+
+static gboolean
+gdm_dynamic_display_finish (GdmDisplay *display)
+{
+        int status;
+
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        /* restart dynamic display */
+        gdm_display_unmanage (display);
+
+        status = gdm_display_get_status (display);
+        if (status != GDM_DISPLAY_FAILED) {
+                gdm_display_manage (display);
+        }
+
+        return TRUE;
+}
+
+static gboolean
+gdm_dynamic_display_unmanage (GdmDisplay *display)
+{
+        g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
+
+        GDM_DISPLAY_CLASS (gdm_dynamic_display_parent_class)->unmanage (display);
+
+        return TRUE;
+}
+
+static void
+gdm_dynamic_display_set_property (GObject      *object,
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gdm_dynamic_display_get_property (GObject    *object,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gdm_dynamic_display_class_init (GdmDynamicDisplayClass *klass)
+{
+        GObjectClass    *object_class = G_OBJECT_CLASS (klass);
+        GdmDisplayClass *display_class = GDM_DISPLAY_CLASS (klass);
+
+        object_class->get_property = gdm_dynamic_display_get_property;
+        object_class->set_property = gdm_dynamic_display_set_property;
+        object_class->finalize = gdm_dynamic_display_finalize;
+
+        display_class->create_authority = gdm_dynamic_display_create_authority;
+        display_class->add_user_authorization = gdm_dynamic_display_add_user_authorization;
+        display_class->remove_user_authorization = gdm_dynamic_display_remove_user_authorization;
+        display_class->manage = gdm_dynamic_display_manage;
+        display_class->finish = gdm_dynamic_display_finish;
+        display_class->unmanage = gdm_dynamic_display_unmanage;
+
+        g_type_class_add_private (klass, sizeof (GdmDynamicDisplayPrivate));
+
+}
+
+static void
+gdm_dynamic_display_init (GdmDynamicDisplay *display)
+{
+
+        display->priv = GDM_DYNAMIC_DISPLAY_GET_PRIVATE (display);
+}
+
+static void
+gdm_dynamic_display_finalize (GObject *object)
+{
+        GdmDynamicDisplay *display;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GDM_IS_DYNAMIC_DISPLAY (object));
+
+        display = GDM_DYNAMIC_DISPLAY (object);
+
+        g_return_if_fail (display->priv != NULL);
+
+        G_OBJECT_CLASS (gdm_dynamic_display_parent_class)->finalize (object);
+}
+
+GdmDisplay *
+gdm_dynamic_display_new (int display_number)
+{
+        GObject *object;
+        char    *x11_display;
+
+        x11_display = g_strdup_printf (":%d", display_number);
+        object = g_object_new (GDM_TYPE_DYNAMIC_DISPLAY,
+                               "x11-display-number", display_number,
+                               "x11-display-name", x11_display,
+                               "is-dynamic", TRUE,
+                               NULL);
+        g_free (x11_display);
+
+        return GDM_DISPLAY (object);
+}
diff --git a/daemon/gdm-dynamic-display.h b/daemon/gdm-dynamic-display.h
new file mode 100644
index 0000000..9595a40
--- /dev/null
+++ b/daemon/gdm-dynamic-display.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Authors: halton huo sun com
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef __GDM_DYNAMIC_DISPLAY_H
+#define __GDM_DYNAMIC_DISPLAY_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include "gdm-display.h"
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_DYNAMIC_DISPLAY         (gdm_dynamic_display_get_type ())
+#define GDM_DYNAMIC_DISPLAY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_DYNAMIC_DISPLAY, GdmDynamicDisplay))
+#define GDM_DYNAMIC_DISPLAY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_DYNAMIC_DISPLAY, GdmDynamicDisplayClass))
+#define GDM_IS_DYNAMIC_DISPLAY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_DYNAMIC_DISPLAY))
+#define GDM_IS_DYNAMIC_DISPLAY_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_DYNAMIC_DISPLAY))
+#define GDM_DYNAMIC_DISPLAY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_DYNAMIC_DISPLAY, GdmDynamicDisplayClass))
+
+typedef struct _GdmDynamicDisplayPrivate GdmDynamicDisplayPrivate;
+
+typedef struct
+{
+        GdmDisplay                parent;
+        GdmDynamicDisplayPrivate *priv;
+} GdmDynamicDisplay;
+
+typedef struct
+{
+        GdmDisplayClass   parent_class;
+
+} GdmDynamicDisplayClass;
+
+GType               gdm_dynamic_display_get_type                (void);
+GdmDisplay *        gdm_dynamic_display_new                     (int display_number);
+
+
+G_END_DECLS
+
+#endif /* __GDM_DYNAMIC_DISPLAY_H */
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
index d09c913..f5fe731 100644
--- a/daemon/gdm-factory-slave.c
+++ b/daemon/gdm-factory-slave.c
@@ -458,8 +458,10 @@ static void
 run_greeter (GdmFactorySlave *slave)
 {
         gboolean       display_is_local;
+        gboolean       display_is_dynamic;
         char          *display_id;
         char          *display_name;
+        char          *seat_id;
         char          *display_device;
         char          *display_hostname;
         char          *auth_file;
@@ -468,16 +470,20 @@ run_greeter (GdmFactorySlave *slave)
         g_debug ("GdmFactorySlave: Running greeter");
 
         display_is_local = FALSE;
+        display_is_dynamic = FALSE;
         display_id = NULL;
         display_name = NULL;
+        seat_id = NULL;
         auth_file = NULL;
         display_device = NULL;
         display_hostname = NULL;
 
         g_object_get (slave,
                       "display-is-local", &display_is_local,
+                      "display-is-dynamic", &display_is_dynamic,
                       "display-id", &display_id,
                       "display-name", &display_name,
+                      "seat-id", &seat_id,
                       "display-hostname", &display_hostname,
                       "display-x11-authority-file", &auth_file,
                       NULL);
@@ -534,9 +540,11 @@ run_greeter (GdmFactorySlave *slave)
 
         g_debug ("GdmFactorySlave: Creating greeter on %s %s", display_name, display_device);
         slave->priv->greeter = gdm_greeter_session_new (display_name,
+                                                        seat_id,
                                                         display_device,
                                                         display_hostname,
-                                                        display_is_local);
+                                                        display_is_local,
+                                                        display_is_dynamic);
         g_signal_connect (slave->priv->greeter,
                           "started",
                           G_CALLBACK (on_greeter_session_start),
@@ -563,6 +571,7 @@ run_greeter (GdmFactorySlave *slave)
 
         g_free (display_id);
         g_free (display_name);
+        g_free (seat_id);
         g_free (display_device);
         g_free (display_hostname);
         g_free (auth_file);
@@ -628,14 +637,12 @@ on_server_died (GdmServer       *server,
 static gboolean
 gdm_factory_slave_run (GdmFactorySlave *slave)
 {
-        char    *display_name;
-        char    *auth_file;
+        char    *display_id;
         gboolean display_is_local;
 
         g_object_get (slave,
+                      "display-id", &display_id,
                       "display-is-local", &display_is_local,
-                      "display-name", &display_name,
-                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
@@ -643,7 +650,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_id);
                 g_signal_connect (slave->priv->server,
                                   "exited",
                                   G_CALLBACK (on_server_exited),
@@ -675,8 +682,7 @@ gdm_factory_slave_run (GdmFactorySlave *slave)
                 g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
         }
 
-        g_free (display_name);
-        g_free (auth_file);
+        g_free (display_id);
 
         return TRUE;
 }
diff --git a/daemon/gdm-greeter-session.c b/daemon/gdm-greeter-session.c
index aae1928..eaec1c9 100644
--- a/daemon/gdm-greeter-session.c
+++ b/daemon/gdm-greeter-session.c
@@ -140,9 +140,11 @@ gdm_greeter_session_finalize (GObject *object)
 
 GdmGreeterSession *
 gdm_greeter_session_new (const char *display_name,
+                         const char *seat_id,
                          const char *display_device,
                          const char *display_hostname,
-                         gboolean    display_is_local)
+                         gboolean    display_is_local,
+                         gboolean    display_is_dynamic)
 {
         GObject *object;
 
@@ -153,9 +155,11 @@ gdm_greeter_session_new (const char *display_name,
                                "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,
                                "x11-display-hostname", display_hostname,
                                "x11-display-is-local", display_is_local,
+                               "x11-display-is-dynamic", display_is_dynamic,
                                NULL);
 
         return GDM_GREETER_SESSION (object);
diff --git a/daemon/gdm-greeter-session.h b/daemon/gdm-greeter-session.h
index 0a171c9..284ae24 100644
--- a/daemon/gdm-greeter-session.h
+++ b/daemon/gdm-greeter-session.h
@@ -50,9 +50,11 @@ typedef struct
 
 GType                 gdm_greeter_session_get_type           (void);
 GdmGreeterSession *   gdm_greeter_session_new                (const char        *display_name,
+                                                              const char        *seat_id,
                                                               const char        *display_device,
                                                               const char        *display_hostname,
-                                                              gboolean           display_is_local);
+                                                              gboolean           display_is_local,
+                                                              gboolean           display_is_dynamic);
 
 G_END_DECLS
 
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 3984ada..53f18fb 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -33,6 +33,7 @@
 
 #include "gdm-display-store.h"
 #include "gdm-static-display.h"
+#include "gdm-dynamic-display.h"
 #include "gdm-transient-display.h"
 #include "gdm-static-factory-display.h"
 #include "gdm-product-display.h"
@@ -53,6 +54,8 @@
 
 #define MAX_DISPLAY_FAILURES 5
 
+#define IS_STR_SET(x) (x != NULL && x[0] != '\0')
+
 struct GdmLocalDisplayFactoryPrivate
 {
         DBusGConnection *connection;
@@ -72,6 +75,10 @@ static void     gdm_local_display_factory_init          (GdmLocalDisplayFactory
 static void     gdm_local_display_factory_finalize      (GObject                     *object);
 
 static GdmDisplay *create_display                       (GdmLocalDisplayFactory      *factory);
+static gboolean create_static_displays                  (GdmLocalDisplayFactory      *factory);
+static void     on_display_status_changed               (GdmDisplay                  *display,
+                                                         GParamSpec                  *arg1,
+                                                         GdmLocalDisplayFactory      *factory);
 
 static gpointer local_display_factory_object = NULL;
 
@@ -185,6 +192,185 @@ store_display (GdmLocalDisplayFactory *factory,
         g_hash_table_insert (factory->priv->displays, GUINT_TO_POINTER (num), NULL);
 }
 
+static void
+store_remove_display (GdmLocalDisplayFactory *factory,
+                      guint32                 num,
+                      GdmDisplay             *display)
+{
+        GdmDisplayStore *store;
+
+        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+        gdm_display_store_remove (store, display);
+
+        /* remove from our reserved spot */
+        g_hash_table_remove (factory->priv->displays, GUINT_TO_POINTER (num));
+}
+
+static gboolean
+lookup_by_display_number (const char *id,
+                          GdmDisplay *display,
+                          gpointer    data)
+{
+        gint32 number;
+        gint32 display_number = -1;
+
+        number = GPOINTER_TO_INT (data);
+
+        if (! GDM_IS_DISPLAY (display)) {
+                return FALSE;
+        }
+
+        gdm_display_get_x11_display_number (display, &display_number, NULL);
+
+        if (display_number == number) {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+static GdmDisplay *
+gdm_local_display_lookup_by_number (GdmLocalDisplayFactory *factory,
+                                    gint32                  number)
+{
+        GdmDisplay      *display;
+        GdmDisplayStore *store;
+
+        if (number < 0)
+                return NULL;
+               
+        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+        display = gdm_display_store_find (store,
+                                          (GdmDisplayStoreFunc)lookup_by_display_number,
+                                          GINT_TO_POINTER (number));
+
+        return display;
+}
+
+/*
+  Example:
+  dbus-send --system --dest=org.gnome.DisplayManager \
+  --type=method_call --print-reply --reply-timeout=2000 \
+  /org/gnome/DisplayManager/LocalDisplayFactory \
+  org.gnome.DisplayManager.LocalDisplayFactory.CreateDisplay \
+  string:"/org/freedesktop/ConsoleKit/Seat1" \
+  int32:0 string:"/usr/X11/bin/Xorg" string:"-br -verbose -nolisten tcp" \
+  boolean:true int32:0 boolean:true \
+  string:"" boolean:false
+*/
+gboolean
+gdm_local_display_factory_create_display (GdmLocalDisplayFactory *factory,
+                                          char                   *sid,
+                                          gint32                  display_number,
+                                          char                   *xserver_command,
+                                          char                   *arguments,
+                                          gboolean                is_chooser,
+                                          gboolean                use_auth,
+                                          gint32                  priority,
+                                          char                   *tty_device,
+                                          gboolean                is_dynamic,
+                                          char                  **id,
+                                          GError                **error)
+{
+        GdmDisplay *display;
+
+        g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
+
+        if (display_number == -1)
+                display_number = take_next_display_number (factory);
+        else {
+                /* Make sure number doesn't exist */
+        }
+
+        if (is_chooser) {
+                /* TODO: Start a xdmcp chooser as request */
+
+                /* display = gdm_xdmcp_chooser_display_new (display_number); */
+        } else {
+                if (is_dynamic)
+                        display = gdm_dynamic_display_new (display_number);
+                else
+                        display = gdm_static_display_new (display_number);
+        }
+
+        if (display == NULL) {
+                g_warning ("Unable to create display: %d", display_number);
+                return FALSE;
+        }
+
+        if (IS_STR_SET (sid))
+                g_object_set (display, "seat-id", sid, NULL);
+        if (IS_STR_SET (xserver_command))
+                g_object_set (display, "x11-command", xserver_command, NULL);
+        if (IS_STR_SET (arguments))
+                g_object_set (display, "x11-arguments", arguments, NULL);
+        g_object_set (display, "use-auth", use_auth, NULL);
+        g_object_set (display, "priority", priority, NULL);
+        if (IS_STR_SET (tty_device))
+                g_object_set (display, "tty-device", tty_device, NULL);
+
+        store_display (factory, display_number, display);
+
+        /* let store own the ref */
+        g_object_unref (display);
+
+        if (! gdm_display_manage (display)) {
+                gdm_display_unmanage (display);
+                return FALSE;
+        }
+
+        if (! gdm_display_get_id (display, id, NULL)) {
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
+/*
+  Example:
+  dbus-send --system --dest=org.gnome.DisplayManager \
+  --type=method_call --print-reply --reply-timeout=2000 \
+  /org/gnome/DisplayManager/LocalDisplayFactory \
+  org.gnome.DisplayManager.LocalDisplayFactory.RemoveDisplay \
+  int32:101
+*/
+gboolean
+gdm_local_display_factory_remove_display (GdmLocalDisplayFactory *factory,
+                                          gint32                  display_number,
+                                          GError                **error)
+{
+        gboolean         ret;
+        GdmDisplay      *display;
+
+        g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
+
+        ret = FALSE;
+
+        /* Make sure number already exist */
+        if (! g_hash_table_lookup_extended (factory->priv->displays,
+                                        GINT_TO_POINTER (display_number),
+                                        NULL,
+                                        NULL)) {
+                g_debug ("GdmLocalDisplayFactory: display number doesn't exists");
+                goto out;
+        }
+
+        g_debug ("GdmLocalDisplayFactory: Removing dynamic display %d", display_number);
+
+        display = gdm_local_display_lookup_by_number (factory, display_number);
+
+        if (! gdm_display_unmanage (display)) {
+                display = NULL;
+                goto out;
+        }
+
+        store_remove_display (factory, display_number, display);
+
+        ret = TRUE;
+ out:
+        return ret;
+}
+
 /*
   Example:
   dbus-send --system --dest=org.gnome.DisplayManager \
@@ -282,9 +468,9 @@ gdm_local_display_factory_create_product_display (GdmLocalDisplayFactory *factor
 }
 
 static void
-on_static_display_status_changed (GdmDisplay             *display,
-                                  GParamSpec             *arg1,
-                                  GdmLocalDisplayFactory *factory)
+on_display_status_changed (GdmDisplay             *display,
+                           GParamSpec             *arg1,
+                           GdmLocalDisplayFactory *factory)
 {
         int              status;
         GdmDisplayStore *store;
@@ -357,7 +543,7 @@ create_display (GdmLocalDisplayFactory *factory)
 
         g_signal_connect (display,
                           "notify::status",
-                          G_CALLBACK (on_static_display_status_changed),
+                          G_CALLBACK (on_display_status_changed),
                           factory);
 
         store_display (factory, num, display);
@@ -372,6 +558,35 @@ create_display (GdmLocalDisplayFactory *factory)
         return display;
 }
 
+
+static gboolean
+create_static_displays (GdmLocalDisplayFactory *factory)
+{
+        DBusGProxy      *proxy;
+        GError          *error = NULL;
+
+        proxy = dbus_g_proxy_new_for_name_owner (factory->priv->connection,
+                                                 "org.freedesktop.ConsoleKit",
+                                                 "/org/freedesktop/ConsoleKit/Manager",
+                                                 "org.freedesktop.ConsoleKit.Manager",
+                                                 &error);
+
+        if (proxy == NULL) {
+                g_warning ("Failed to create a new proxy, %s", error->message);
+                g_error_free (error);
+                return FALSE;
+        }
+
+        dbus_g_proxy_call_no_reply (proxy, 
+                                   "CreateStaticSessions", 
+                                   G_TYPE_INVALID,
+                                   G_TYPE_INVALID);
+
+        g_object_unref (proxy);
+        return TRUE;
+
+}
+
 #if 0
 static void
 create_display_for_device (GdmLocalDisplayFactory *factory,
@@ -463,7 +678,7 @@ gdm_local_display_factory_start (GdmDisplayFactory *base_factory)
 #if 0
         create_displays_for_pci_devices (factory);
 #else
-        create_display (factory);
+        create_static_displays (factory);
 #endif
 
         return ret;
diff --git a/daemon/gdm-local-display-factory.h b/daemon/gdm-local-display-factory.h
index 2abb053..8c43b35 100644
--- a/daemon/gdm-local-display-factory.h
+++ b/daemon/gdm-local-display-factory.h
@@ -71,6 +71,23 @@ gboolean                   gdm_local_display_factory_create_product_display   (G
                                                                                char                  **id,
                                                                                GError                **error);
 
+gboolean                   gdm_local_display_factory_create_display           (GdmLocalDisplayFactory *factory,
+                                                                               char                   *sid,
+                                                                               gint32                  display_number,
+                                                                               char                   *xserver_command,
+                                                                               char                   *arguments,
+                                                                               gboolean                is_chooser,
+                                                                               gboolean                use_auth,
+                                                                               gint32                  priority,
+                                                                               char                   *tty_device,
+                                                                               gboolean                is_dynamic,
+                                                                               char                  **id,
+                                                                               GError                **error);
+
+gboolean                   gdm_local_display_factory_remove_display           (GdmLocalDisplayFactory *factory,
+                                                                               gint32                  display_number,
+                                                                               GError                **error);
+
 G_END_DECLS
 
 #endif /* __GDM_LOCAL_DISPLAY_FACTORY_H */
diff --git a/daemon/gdm-local-display-factory.xml b/daemon/gdm-local-display-factory.xml
index 51f5153..0920b85 100644
--- a/daemon/gdm-local-display-factory.xml
+++ b/daemon/gdm-local-display-factory.xml
@@ -1,11 +1,85 @@
 <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
 <node name="/org/gnome/DisplayManager/LocalDisplayFactory">
   <interface name="org.gnome.DisplayManager.LocalDisplayFactory">
+    <method name="CreateDisplay">
+      <arg name="sid" direction="in" type="s">
+        <doc:doc>
+          <doc:summary>The seat id. Example: /org/freedesktop/ConsoleKit/Seat1</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="display_number" direction="in" type="i">
+        <doc:doc>
+          <doc:summary>The display number</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="xserver_command" direction="in" type="s">
+        <doc:doc>
+          <doc:summary>The xserver command</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="arguments" direction="in" type="s">
+        <doc:doc>
+          <doc:summary>The arguments of xserver command</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="is_chooser" direction="in" type="b">
+        <doc:doc>
+          <doc:summary>If this value is TRUE, start a XDMCP chooser. If FALSE, start a greeter.</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="use_auth" direction="in" type="b">
+        <doc:doc>
+          <doc:summary>If this value is TRUE, add '-auth $auth_file' argument. The auth_file is generated by GDM before spawning the X server process.</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="priority" direction="in" type="i">
+        <doc:doc>
+          <doc:summary>X server process priority. If value is 0, not change. Values can be any integer value accepted by the setpriority C library function (normally between -20 and 20) with 0 being the default.</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="tty_device" direction="in" type="s">
+        <doc:doc>
+          <doc:summary>Tty device used when create X server process.</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="is_dynamic" direction="in" type="b">
+        <doc:doc>
+          <doc:summary>Whether the session is dynamically created. Only turn this parameter to TRUE when created through ck-dynamic or gdmdynamic</doc:summary>
+        </doc:doc>
+      </arg>
+      <arg name="id" direction="out" type="o">
+        <doc:doc>
+          <doc:summary>The created display id</doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:description>
+          <doc:para>Create display with given parameters
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+
+    <method name="RemoveDisplay">
+      <arg name="display_number" direction="in" type="i">
+        <doc:doc>
+          <doc:summary>The display number</doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:description>
+          <doc:para>Remove display with given display number 
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+
     <method name="CreateProductDisplay">
       <arg name="parent_display_id" direction="in" type="o"/>
       <arg name="relay_address" direction="in" type="s"/>
       <arg name="id" direction="out" type="o"/>
     </method>
+
     <method name="CreateTransientDisplay">
       <arg name="id" direction="out" type="o"/>
     </method>
diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c
index 9adcb09..2af3a46 100644
--- a/daemon/gdm-product-slave.c
+++ b/daemon/gdm-product-slave.c
@@ -415,14 +415,12 @@ on_server_died (GdmServer       *server,
 static gboolean
 gdm_product_slave_create_server (GdmProductSlave *slave)
 {
-        char    *display_name;
-        char    *auth_file;
+        char    *display_id;
         gboolean display_is_local;
 
         g_object_get (slave,
+                      "display-id", &display_id,
                       "display-is-local", &display_is_local,
-                      "display-name", &display_name,
-                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
@@ -430,7 +428,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_id);
                 g_signal_connect (slave->priv->server,
                                   "exited",
                                   G_CALLBACK (on_server_exited),
@@ -462,8 +460,7 @@ gdm_product_slave_create_server (GdmProductSlave *slave)
                 g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
         }
 
-        g_free (display_name);
-        g_free (auth_file);
+        g_free (display_id);
 
         return TRUE;
 }
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
index ba10386..bedf038 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -39,6 +39,8 @@
 #include <glib/gstdio.h>
 #include <glib-object.h>
 
+#include <dbus/dbus-glib.h>
+
 #include <X11/Xlib.h> /* for Display */
 
 #include "gdm-common.h"
@@ -50,6 +52,9 @@ extern char **environ;
 
 #define GDM_SERVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SERVER, GdmServerPrivate))
 
+#define GDM_DBUS_NAME              "org.gnome.DisplayManager"
+#define GDM_DBUS_DISPLAY_INTERFACE "org.gnome.DisplayManager.Display"
+
 /* These are the servstat values, also used as server
  * process exit codes */
 #define SERVER_TIMEOUT 2        /* Server didn't start */
@@ -62,42 +67,37 @@ extern char **environ;
 
 struct GdmServerPrivate
 {
-        char    *command;
         GPid     pid;
 
-        gboolean disable_tcp;
-        int      priority;
         char    *user_name;
-        char    *session_args;
-
         char    *log_dir;
+        gboolean disable_tcp;
+
+        /* cached display values */
+        char    *display_id;
+        char    *command;
+        char    *session_args;
+        char    *tty_device;
         char    *display_name;
-        char    *display_device;
         char    *auth_file;
+        int      priority;
+
+        char    *display_device;
 
         gboolean is_parented;
         char    *parent_display_name;
         char    *parent_auth_file;
-        char    *chosen_hostname;
 
         guint    child_watch_id;
 };
 
 enum {
         PROP_0,
-        PROP_DISPLAY_NAME,
-        PROP_DISPLAY_DEVICE,
-        PROP_AUTH_FILE,
-        PROP_IS_PARENTED,
-        PROP_PARENT_DISPLAY_NAME,
-        PROP_PARENT_AUTH_FILE,
-        PROP_CHOSEN_HOSTNAME,
-        PROP_COMMAND,
-        PROP_PRIORITY,
         PROP_USER_NAME,
-        PROP_SESSION_ARGS,
         PROP_LOG_DIR,
         PROP_DISABLE_TCP,
+        PROP_DISPLAY_ID,
+        PROP_DISPLAY_DEVICE,
 };
 
 enum {
@@ -252,72 +252,48 @@ connect_to_parent (GdmServer *server)
 
 static gboolean
 gdm_server_resolve_command_line (GdmServer  *server,
-                                 const char *vtarg,
                                  int        *argcp,
                                  char     ***argvp)
 {
-        int      argc;
-        char   **argv;
-        int      len;
-        int      i;
-        gboolean gotvtarg = FALSE;
-        gboolean query_in_arglist = FALSE;
-
-        g_shell_parse_argv (server->priv->command, &argc, &argv, NULL);
-
-        for (len = 0; argv != NULL && argv[len] != NULL; len++) {
-                char *arg = argv[len];
-
-                /* HACK! Not to add vt argument to servers that already force
-                 * allocation.  Mostly for backwards compat only */
-                if (strncmp (arg, "vt", 2) == 0 &&
-                    isdigit (arg[2]) &&
-                    (arg[3] == '\0' ||
-                     (isdigit (arg[3]) && arg[4] == '\0')))
-                        gotvtarg = TRUE;
-                if (strcmp (arg, "-query") == 0 ||
-                    strcmp (arg, "-indirect") == 0)
-                        query_in_arglist = TRUE;
-        }
-
-        argv = g_renew (char *, argv, len + 10);
-        /* shift args down one */
-        for (i = len - 1; i >= 1; i--) {
-                argv[i+1] = argv[i];
+        gboolean  ret;
+        char     *command = NULL;
+        char     *tmp = NULL;
+
+        if (server->priv->session_args != NULL) {
+                command = g_strdup_printf ("%s %s %s",
+                                           server->priv->command,
+                                           server->priv->display_name,
+                                           server->priv->session_args);
+        } else {
+                command = g_strdup_printf ("%s %s",
+                                           server->priv->command,
+                                           server->priv->display_name);
         }
 
-        /* server number is the FIRST argument, before any others */
-        argv[1] = g_strdup (server->priv->display_name);
-        len++;
-
         if (server->priv->auth_file != NULL) {
-                argv[len++] = g_strdup ("-auth");
-                argv[len++] = g_strdup (server->priv->auth_file);
+                tmp = g_strdup (command);
+                g_free (command);
+                command = g_strdup_printf ("%s -auth %s ",
+                                           tmp, server->priv->auth_file);
+                g_free (tmp);
         }
-
-        if (server->priv->chosen_hostname) {
-                /* run just one session */
-                argv[len++] = g_strdup ("-terminate");
-                argv[len++] = g_strdup ("-query");
-                argv[len++] = g_strdup (server->priv->chosen_hostname);
-                query_in_arglist = TRUE;
-        }
-
-        if (server->priv->disable_tcp && ! query_in_arglist) {
-                argv[len++] = g_strdup ("-nolisten");
-                argv[len++] = g_strdup ("tcp");
-        }
-
-        if (vtarg != NULL && ! gotvtarg) {
-                argv[len++] = g_strdup (vtarg);
+#ifndef __sun
+        /* TODO:
+           Solaris Xorg does not accept vt argument, remove #ifndef
+           when VT part for Xorg goes into Solaris.
+         */
+        if (server->priv->tty_device != NULL) {
+                tmp = g_strdup (command);
+                g_free (command);
+                command = g_strdup_printf ("%s %s", tmp, server->priv->tty_device);
+                g_free (tmp);
         }
+#endif
 
-        argv[len++] = NULL;
-
-        *argvp = argv;
-        *argcp = len;
+        ret = g_shell_parse_argv (command, argcp, argvp, NULL);
+        g_free (command);
 
-        return TRUE;
+        return ret;
 }
 
 static void
@@ -464,7 +440,14 @@ server_child_setup (GdmServer *server)
         sigemptyset (&mask);
         sigprocmask (SIG_SETMASK, &mask, NULL);
 
-        if (server->priv->priority != 0) {
+#if __sun
+#define GDM_PRIO_DEFAULT NZERO
+#else
+#include <sys/resource.h>
+#define GDM_PRIO_DEFAULT 0
+#endif
+
+        if (server->priv->priority != GDM_PRIO_DEFAULT) {
                 if (setpriority (PRIO_PROCESS, 0, server->priv->priority)) {
                         g_warning (_("%s: Server priority couldn't be set to %d: %s"),
                                    "gdm_server_spawn",
@@ -543,30 +526,6 @@ get_server_environment (GdmServer *server)
 }
 
 static void
-server_add_xserver_args (GdmServer *server,
-                         int       *argc,
-                         char    ***argv)
-{
-        int    count;
-        char **args;
-        int    len;
-        int    i;
-
-        len = *argc;
-        g_shell_parse_argv (server->priv->session_args, &count, &args, NULL);
-        *argv = g_renew (char *, *argv, len + count + 1);
-
-        for (i=0; i < count;i++) {
-                *argv[len++] = g_strdup (args[i]);
-        }
-
-        *argc += count;
-
-        argv[len] = NULL;
-        g_strfreev (args);
-}
-
-static void
 server_child_watch (GPid       pid,
                     int        status,
                     GdmServer *server)
@@ -593,8 +552,7 @@ server_child_watch (GPid       pid,
 }
 
 static gboolean
-gdm_server_spawn (GdmServer  *server,
-                  const char *vtarg)
+gdm_server_spawn (GdmServer  *server)
 {
         int              argc;
         gchar          **argv = NULL;
@@ -609,14 +567,9 @@ gdm_server_spawn (GdmServer  *server,
         argv = NULL;
         argc = 0;
         gdm_server_resolve_command_line (server,
-                                         vtarg,
                                          &argc,
                                          &argv);
 
-        if (server->priv->session_args) {
-                server_add_xserver_args (server, &argc, &argv);
-        }
-
         if (argv[0] == NULL) {
                 g_warning (_("%s: Empty server command for display %s"),
                            "gdm_server_spawn",
@@ -676,7 +629,7 @@ gdm_server_start (GdmServer *server)
         gboolean res;
 
         /* fork X server process */
-        res = gdm_server_spawn (server, NULL);
+        res = gdm_server_spawn (server);
 
         return res;
 }
@@ -733,21 +686,12 @@ gdm_server_stop (GdmServer *server)
         return TRUE;
 }
 
-
-static void
-_gdm_server_set_display_name (GdmServer  *server,
-                              const char *name)
-{
-        g_free (server->priv->display_name);
-        server->priv->display_name = g_strdup (name);
-}
-
 static void
-_gdm_server_set_auth_file (GdmServer  *server,
-                           const char *auth_file)
+_gdm_server_set_display_id (GdmServer  *server,
+                            const char *id)
 {
-        g_free (server->priv->auth_file);
-        server->priv->auth_file = g_strdup (auth_file);
+        g_free (server->priv->display_id);
+        server->priv->display_id = g_strdup (id);
 }
 
 static void
@@ -776,11 +720,8 @@ gdm_server_set_property (GObject      *object,
         self = GDM_SERVER (object);
 
         switch (prop_id) {
-        case PROP_DISPLAY_NAME:
-                _gdm_server_set_display_name (self, g_value_get_string (value));
-                break;
-        case PROP_AUTH_FILE:
-                _gdm_server_set_auth_file (self, g_value_get_string (value));
+        case PROP_DISPLAY_ID:
+                _gdm_server_set_display_id (self, g_value_get_string (value));
                 break;
         case PROP_USER_NAME:
                 _gdm_server_set_user_name (self, g_value_get_string (value));
@@ -805,16 +746,13 @@ gdm_server_get_property (GObject    *object,
         self = GDM_SERVER (object);
 
         switch (prop_id) {
-        case PROP_DISPLAY_NAME:
-                g_value_set_string (value, self->priv->display_name);
+        case PROP_DISPLAY_ID:
+                g_value_set_string (value, self->priv->display_id);
                 break;
         case PROP_DISPLAY_DEVICE:
                 g_value_take_string (value,
                                      gdm_server_get_display_device (self));
                 break;
-        case PROP_AUTH_FILE:
-                g_value_set_string (value, self->priv->auth_file);
-                break;
         case PROP_USER_NAME:
                 g_value_set_string (value, self->priv->user_name);
                 break;
@@ -886,10 +824,10 @@ gdm_server_class_init (GdmServerClass *klass)
                               G_TYPE_INT);
 
         g_object_class_install_property (object_class,
-                                         PROP_DISPLAY_NAME,
-                                         g_param_spec_string ("display-name",
-                                                              "name",
-                                                              "name",
+                                         PROP_DISPLAY_ID,
+                                         g_param_spec_string ("display-id",
+                                                              "display id",
+                                                              "display id",
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
@@ -900,14 +838,6 @@ gdm_server_class_init (GdmServerClass *klass)
                                                               NULL,
                                                               G_PARAM_READABLE));
         g_object_class_install_property (object_class,
-                                         PROP_AUTH_FILE,
-                                         g_param_spec_string ("auth-file",
-                                                              "Authorization File",
-                                                              "Path to X authorization file",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-        g_object_class_install_property (object_class,
                                          PROP_USER_NAME,
                                          g_param_spec_string ("user-name",
                                                               "user name",
@@ -922,19 +852,13 @@ gdm_server_class_init (GdmServerClass *klass)
                                                                TRUE,
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
+
 }
 
 static void
 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");
-        server->priv->log_dir = g_strdup (LOGDIR);
-
-        add_ready_handler (server);
 }
 
 static void
@@ -953,19 +877,203 @@ gdm_server_finalize (GObject *object)
 
         gdm_server_stop (server);
 
+        g_free (server->priv->command);
+        g_free (server->priv->log_dir);
+
         G_OBJECT_CLASS (gdm_server_parent_class)->finalize (object);
 }
 
 GdmServer *
-gdm_server_new (const char *display_name,
-                const char *auth_file)
+gdm_server_new (const char *display_id)
 {
-        GObject *object;
+        GObject         *object;
+        GdmServer       *server;
+        DBusGConnection *connection;
+        DBusGProxy      *proxy;
+        GError          *error;
+        gboolean         res;
+        char            *id;
 
         object = g_object_new (GDM_TYPE_SERVER,
-                               "display-name", display_name,
-                               "auth-file", auth_file,
+                               "display-id", display_id,
                                NULL);
 
-        return GDM_SERVER (object);
+        server = GDM_SERVER (object);
+
+        server->priv->pid = -1;
+        server->priv->log_dir = g_strdup (LOGDIR);
+
+        g_assert (server->priv->display_id != NULL);
+
+        error = NULL;
+        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+        if (connection == NULL) {
+                if (error != NULL) {
+                        g_critical ("error getting system bus: %s", error->message);
+                        g_error_free (error);
+                }
+
+                exit (1);
+        }               
+
+        g_debug ("GdmServer: Creating proxy for %s", server->priv->display_id);
+        error = NULL;
+        proxy = dbus_g_proxy_new_for_name_owner (connection,
+                                                 GDM_DBUS_NAME,
+                                                 server->priv->display_id,
+                                                 GDM_DBUS_DISPLAY_INTERFACE,
+                                                 &error);
+        if (proxy == NULL) {
+                if (error != NULL) {
+                        g_warning ("Failed to create display proxy %s: %s", server->priv->display_id, error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Unable to create display proxy");
+                }
+
+                exit (1);
+        }                        
+                                 
+        /* cache some values up front */
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetX11DisplayName",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &server->priv->display_name,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+
+                exit (1);
+        }
+
+        /* If display_name is not set, quit */
+        if (! server->priv->display_name || (strlen (server->priv->display_name) == 0)) {
+                g_warning ("Wrong value of method GetX11DisplayName for %s",server->priv->display_id);
+                exit (1);
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetX11Command",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &server->priv->command,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+        
+                exit (1);
+        }
+
+        /* If command is not set, set it X_SERVER */
+        if (! server->priv->command || (strlen (server->priv->command) == 0)) {
+                g_free (server->priv->command);
+                server->priv->command = g_strdup (X_SERVER);
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetX11Arguments",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &server->priv->session_args,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+        
+                exit (1);
+        }
+
+        /* If session_args is not set, set it NULL */
+        if (server->priv->session_args && (strlen (server->priv->session_args ) == 0)) {
+                g_free (server->priv->session_args);
+                server->priv->session_args = NULL;
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetTtyDevice",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &server->priv->tty_device,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+        
+                exit (1);
+        }
+
+        /* If tty_device is not set, set it NULL */
+        if (server->priv->tty_device && (strlen (server->priv->tty_device) == 0)) {
+                g_free (server->priv->tty_device);
+                server->priv->tty_device = NULL;
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetPriority",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_INT, &server->priv->priority,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+        
+                exit (1);    
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (proxy,
+                                 "GetX11AuthorityFile",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &server->priv->auth_file,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {         
+                        g_warning ("Failed to get value");
+                }
+        
+                exit (1);   
+        }
+
+        /* If tty_device is not set, set it NULL */
+        if (server->priv->auth_file && (strlen (server->priv->auth_file) == 0)) {
+                g_free (server->priv->auth_file);
+                server->priv->auth_file = NULL;
+        }
+
+        add_ready_handler (server);
+
+        return server;
 }
diff --git a/daemon/gdm-server.h b/daemon/gdm-server.h
index 535a69a..84feb1f 100644
--- a/daemon/gdm-server.h
+++ b/daemon/gdm-server.h
@@ -53,8 +53,7 @@ typedef struct
 } GdmServerClass;
 
 GType               gdm_server_get_type  (void);
-GdmServer *         gdm_server_new       (const char *display_id,
-                                          const char *auth_file);
+GdmServer *         gdm_server_new       (const char *display_id);
 gboolean            gdm_server_start     (GdmServer   *server);
 gboolean            gdm_server_stop      (GdmServer   *server);
 char *              gdm_server_get_display_device (GdmServer *server);
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 3a2623c..fa44a98 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -859,8 +859,10 @@ static void
 start_greeter (GdmSimpleSlave *slave)
 {
         gboolean       display_is_local;
+        gboolean       display_is_dynamic;
         char          *display_id;
         char          *display_name;
+        char          *seat_id;
         char          *display_device;
         char          *display_hostname;
         char          *auth_file;
@@ -870,8 +872,10 @@ start_greeter (GdmSimpleSlave *slave)
         g_debug ("GdmSimpleSlave: Running greeter");
 
         display_is_local = FALSE;
+        display_is_dynamic = FALSE;
         display_id = NULL;
         display_name = NULL;
+        seat_id = NULL;
         auth_file = NULL;
         display_device = NULL;
         display_hostname = NULL;
@@ -879,7 +883,9 @@ start_greeter (GdmSimpleSlave *slave)
         g_object_get (slave,
                       "display-id", &display_id,
                       "display-is-local", &display_is_local,
+                      "display-is-dynamic", &display_is_dynamic,
                       "display-name", &display_name,
+                      "display-seat-id", &seat_id,
                       "display-hostname", &display_hostname,
                       "display-x11-authority-file", &auth_file,
                       NULL);
@@ -961,9 +967,11 @@ start_greeter (GdmSimpleSlave *slave)
 
         g_debug ("GdmSimpleSlave: Creating greeter on %s %s %s", display_name, display_device, display_hostname);
         slave->priv->greeter = gdm_greeter_session_new (display_name,
+                                                        seat_id,
                                                         display_device,
                                                         display_hostname,
-                                                        display_is_local);
+                                                        display_is_local,
+                                                        display_is_dynamic);
         g_signal_connect (slave->priv->greeter,
                           "started",
                           G_CALLBACK (on_greeter_session_start),
@@ -988,6 +996,7 @@ start_greeter (GdmSimpleSlave *slave)
 
         g_free (display_id);
         g_free (display_name);
+        g_free (seat_id);
         g_free (display_device);
         g_free (display_hostname);
         g_free (auth_file);
@@ -1061,14 +1070,12 @@ on_server_died (GdmServer      *server,
 static gboolean
 gdm_simple_slave_run (GdmSimpleSlave *slave)
 {
-        char    *display_name;
-        char    *auth_file;
+        char    *display_id;
         gboolean display_is_local;
 
         g_object_get (slave,
+                      "display-id", &display_id,
                       "display-is-local", &display_is_local,
-                      "display-name", &display_name,
-                      "display-x11-authority-file", &auth_file,
                       NULL);
 
         /* if this is local display start a server if one doesn't
@@ -1077,7 +1084,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_id);
 
                 disable_tcp = TRUE;
                 if (gdm_settings_client_get_boolean (GDM_KEY_DISALLOW_TCP,
@@ -1118,8 +1125,7 @@ gdm_simple_slave_run (GdmSimpleSlave *slave)
                 g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave);
         }
 
-        g_free (display_name);
-        g_free (auth_file);
+        g_free (display_id);
 
         return TRUE;
 }
diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
index 477b42d..13864b7 100644
--- a/daemon/gdm-slave.c
+++ b/daemon/gdm-slave.c
@@ -82,6 +82,7 @@ struct GdmSlavePrivate
         int              display_number;
         char            *display_hostname;
         gboolean         display_is_local;
+        gboolean         display_is_dynamic;
         gboolean         display_is_parented;
         char            *display_seat_id;
         char            *display_x11_authority_file;
@@ -101,6 +102,7 @@ enum {
         PROP_DISPLAY_NUMBER,
         PROP_DISPLAY_HOSTNAME,
         PROP_DISPLAY_IS_LOCAL,
+        PROP_DISPLAY_IS_DYNAMIC,
         PROP_DISPLAY_SEAT_ID,
         PROP_DISPLAY_X11_AUTHORITY_FILE
 };
@@ -548,6 +550,24 @@ gdm_slave_real_start (GdmSlave *slave)
 
         error = NULL;
         res = dbus_g_proxy_call (slave->priv->display_proxy,
+                                 "IsDynamic",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_BOOLEAN, &slave->priv->display_is_dynamic,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                if (error != NULL) {
+                        g_warning ("Failed to get value: %s", error->message);
+                        g_error_free (error);
+                } else {
+                        g_warning ("Failed to get value");
+                }
+
+                return FALSE;
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (slave->priv->display_proxy,
                                  "GetX11DisplayName",
                                  &error,
                                  G_TYPE_INVALID,
@@ -1218,6 +1238,13 @@ _gdm_slave_set_display_is_local (GdmSlave   *slave,
 }
 
 static void
+_gdm_slave_set_display_is_dynamic (GdmSlave   *slave,
+                                   gboolean    is)
+{
+        slave->priv->display_is_dynamic = is;
+}
+
+static void
 gdm_slave_set_property (GObject      *object,
                         guint         prop_id,
                         const GValue *value,
@@ -1249,6 +1276,9 @@ gdm_slave_set_property (GObject      *object,
         case PROP_DISPLAY_IS_LOCAL:
                 _gdm_slave_set_display_is_local (self, g_value_get_boolean (value));
                 break;
+        case PROP_DISPLAY_IS_DYNAMIC:
+                _gdm_slave_set_display_is_dynamic (self, g_value_get_boolean (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -1287,6 +1317,9 @@ gdm_slave_get_property (GObject    *object,
         case PROP_DISPLAY_IS_LOCAL:
                 g_value_set_boolean (value, self->priv->display_is_local);
                 break;
+        case PROP_DISPLAY_IS_DYNAMIC:
+                g_value_set_boolean (value, self->priv->display_is_dynamic);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -1411,6 +1444,13 @@ gdm_slave_class_init (GdmSlaveClass *klass)
                                                                "display is local",
                                                                TRUE,
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_DISPLAY_IS_DYNAMIC,
+                                         g_param_spec_boolean ("display-is-dynamic",
+                                                               "display is dynamic",
+                                                               "display is dynamic",
+                                                               FALSE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
         signals [STOPPED] =
                 g_signal_new ("stopped",
diff --git a/daemon/gdm-static-display.c b/daemon/gdm-static-display.c
index a747ee3..9e5874a 100644
--- a/daemon/gdm-static-display.c
+++ b/daemon/gdm-static-display.c
@@ -224,6 +224,7 @@ gdm_static_display_new (int display_number)
         object = g_object_new (GDM_TYPE_STATIC_DISPLAY,
                                "x11-display-number", display_number,
                                "x11-display-name", x11_display,
+                               "is-dynamic", FALSE,
                                NULL);
         g_free (x11_display);
 
diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c
index b58e855..14558c1 100644
--- a/daemon/gdm-welcome-session.c
+++ b/daemon/gdm-welcome-session.c
@@ -65,10 +65,12 @@ struct GdmWelcomeSessionPrivate
         char           *group_name;
 
         char           *x11_display_name;
+        char           *x11_display_seat_id;
         char           *x11_display_device;
         char           *x11_display_hostname;
         char           *x11_authority_file;
         gboolean        x11_display_is_local;
+        gboolean        x11_display_is_dynamic;
 
         guint           child_watch_id;
 
@@ -85,10 +87,12 @@ struct GdmWelcomeSessionPrivate
 enum {
         PROP_0,
         PROP_X11_DISPLAY_NAME,
+        PROP_X11_DISPLAY_SEAT_ID,
         PROP_X11_DISPLAY_DEVICE,
         PROP_X11_DISPLAY_HOSTNAME,
         PROP_X11_AUTHORITY_FILE,
         PROP_X11_DISPLAY_IS_LOCAL,
+        PROP_X11_DISPLAY_IS_DYNAMIC,
         PROP_USER_NAME,
         PROP_GROUP_NAME,
         PROP_SERVER_ADDRESS,
@@ -133,6 +137,7 @@ open_welcome_session (GdmWelcomeSession *welcome_session)
         const char    *session_type;
         const char    *hostname;
         const char    *x11_display_device;
+        const char    *seat_id;
         int            res;
         gboolean       ret;
         DBusError      error;
@@ -168,12 +173,19 @@ open_welcome_session (GdmWelcomeSession *welcome_session)
                 x11_display_device = "";
         }
 
-        g_debug ("GdmWelcomeSession: Opening ConsoleKit session for user:%d x11-display:'%s' x11-display-device:'%s' remote-host-name:'%s' is-local:%d",
+        if (welcome_session->priv->x11_display_seat_id != NULL) {
+                seat_id = welcome_session->priv->x11_display_seat_id;
+        } else {
+                seat_id = "";
+        }
+
+        g_debug ("GdmWelcomeSession: Opening ConsoleKit session for user:%d x11-display:'%s' x11-display-device:'%s' remote-host-name:'%s' is-local:%d is-dynamic:%d",
                  pwent->pw_uid,
                  welcome_session->priv->x11_display_name,
                  x11_display_device,
                  hostname,
-                 welcome_session->priv->x11_display_is_local);
+                 welcome_session->priv->x11_display_is_local,
+                 welcome_session->priv->x11_display_is_dynamic);
 
         dbus_error_init (&error);
         res = ck_connector_open_session_with_parameters (welcome_session->priv->ckc,
@@ -181,9 +193,11 @@ open_welcome_session (GdmWelcomeSession *welcome_session)
                                                          "unix-user", &pwent->pw_uid,
                                                          "session-type", &session_type,
                                                          "x11-display", &welcome_session->priv->x11_display_name,
+                                                         "seat-id", &seat_id,
                                                          "x11-display-device", &x11_display_device,
                                                          "remote-host-name", &hostname,
                                                          "is-local", &welcome_session->priv->x11_display_is_local,
+                                                         "is-dynamic", &welcome_session->priv->x11_display_is_dynamic,
                                                          NULL);
         if (! res) {
                 if (dbus_error_is_set (&error)) {
@@ -880,6 +894,14 @@ _gdm_welcome_session_set_x11_display_name (GdmWelcomeSession *welcome_session,
 }
 
 static void
+_gdm_welcome_session_set_x11_display_seat_id (GdmWelcomeSession *welcome_session,
+                                              const char        *sid)
+{
+        g_free (welcome_session->priv->x11_display_seat_id);
+        welcome_session->priv->x11_display_seat_id = g_strdup (sid);
+}
+
+static void
 _gdm_welcome_session_set_x11_display_hostname (GdmWelcomeSession *welcome_session,
                                                const char        *name)
 {
@@ -902,6 +924,12 @@ _gdm_welcome_session_set_x11_display_is_local (GdmWelcomeSession *welcome_sessio
         welcome_session->priv->x11_display_is_local = is_local;
 }
 
+static void
+_gdm_welcome_session_set_x11_display_is_dynamic (GdmWelcomeSession *welcome_session,
+                                                 gboolean           is_dynamic)
+{
+        welcome_session->priv->x11_display_is_dynamic = is_dynamic;
+}
 
 static void
 _gdm_welcome_session_set_x11_authority_file (GdmWelcomeSession *welcome_session,
@@ -980,6 +1008,9 @@ gdm_welcome_session_set_property (GObject      *object,
         case PROP_X11_DISPLAY_NAME:
                 _gdm_welcome_session_set_x11_display_name (self, g_value_get_string (value));
                 break;
+        case PROP_X11_DISPLAY_SEAT_ID:
+                _gdm_welcome_session_set_x11_display_seat_id (self, g_value_get_string (value));
+                break;
         case PROP_X11_DISPLAY_HOSTNAME:
                 _gdm_welcome_session_set_x11_display_hostname (self, g_value_get_string (value));
                 break;
@@ -989,6 +1020,9 @@ gdm_welcome_session_set_property (GObject      *object,
         case PROP_X11_DISPLAY_IS_LOCAL:
                 _gdm_welcome_session_set_x11_display_is_local (self, g_value_get_boolean (value));
                 break;
+        case PROP_X11_DISPLAY_IS_DYNAMIC:
+                _gdm_welcome_session_set_x11_display_is_dynamic (self, g_value_get_boolean (value));
+                break;
         case PROP_X11_AUTHORITY_FILE:
                 _gdm_welcome_session_set_x11_authority_file (self, g_value_get_string (value));
                 break;
@@ -1036,6 +1070,9 @@ gdm_welcome_session_get_property (GObject    *object,
         case PROP_X11_DISPLAY_NAME:
                 g_value_set_string (value, self->priv->x11_display_name);
                 break;
+        case PROP_X11_DISPLAY_SEAT_ID:
+                g_value_set_string (value, self->priv->x11_display_seat_id);
+                break;
         case PROP_X11_DISPLAY_HOSTNAME:
                 g_value_set_string (value, self->priv->x11_display_hostname);
                 break;
@@ -1045,6 +1082,9 @@ gdm_welcome_session_get_property (GObject    *object,
         case PROP_X11_DISPLAY_IS_LOCAL:
                 g_value_set_boolean (value, self->priv->x11_display_is_local);
                 break;
+        case PROP_X11_DISPLAY_IS_DYNAMIC:
+                g_value_set_boolean (value, self->priv->x11_display_is_dynamic);
+                break;
         case PROP_X11_AUTHORITY_FILE:
                 g_value_set_string (value, self->priv->x11_authority_file);
                 break;
@@ -1112,6 +1152,13 @@ gdm_welcome_session_class_init (GdmWelcomeSessionClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
+                                         PROP_X11_DISPLAY_SEAT_ID,
+                                         g_param_spec_string ("x11-display-seat-id",
+                                                              "seat id",
+                                                              "seat id",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
                                          PROP_X11_DISPLAY_HOSTNAME,
                                          g_param_spec_string ("x11-display-hostname",
                                                               "hostname",
@@ -1133,6 +1180,13 @@ gdm_welcome_session_class_init (GdmWelcomeSessionClass *klass)
                                                                FALSE,
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
         g_object_class_install_property (object_class,
+                                         PROP_X11_DISPLAY_IS_DYNAMIC,
+                                         g_param_spec_boolean ("x11-display-is-dynamic",
+                                                               "is dynamic",
+                                                               "is dynamic",
+                                                               FALSE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
                                          PROP_X11_AUTHORITY_FILE,
                                          g_param_spec_string ("x11-authority-file",
                                                               "authority file",
@@ -1268,6 +1322,7 @@ gdm_welcome_session_finalize (GObject *object)
         g_free (welcome_session->priv->user_name);
         g_free (welcome_session->priv->group_name);
         g_free (welcome_session->priv->x11_display_name);
+        g_free (welcome_session->priv->x11_display_seat_id);
         g_free (welcome_session->priv->x11_display_device);
         g_free (welcome_session->priv->x11_display_hostname);
         g_free (welcome_session->priv->x11_authority_file);
diff --git a/daemon/gdm-xdmcp-chooser-display.c b/daemon/gdm-xdmcp-chooser-display.c
index 85bd3b7..f7b5a0b 100644
--- a/daemon/gdm-xdmcp-chooser-display.c
+++ b/daemon/gdm-xdmcp-chooser-display.c
@@ -224,7 +224,7 @@ gdm_xdmcp_chooser_display_new (const char              *hostname,
                                "remote-hostname", hostname,
                                "x11-display-number", number,
                                "x11-display-name", x11_display,
-                               "is-local", FALSE,
+                               "is-local", TRUE,
                                "remote-address", address,
                                "session-number", session_number,
                                NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]