[gdm/display-configuration: 2/20] Second pass at display configuration



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

    Second pass at display configuration
    
    See http://bugzilla.gnome.org/show_bug.cgi?id=536355

 configure.ac                         |    2 +-
 daemon/gdm-display.c                 |  129 ---------
 daemon/gdm-display.h                 |    9 -
 daemon/gdm-display.xml               |    9 -
 daemon/gdm-local-display-factory.c   |  473 +++++++++++++++++++++++-----------
 daemon/gdm-local-display-factory.h   |   17 --
 daemon/gdm-local-display-factory.xml |   74 ------
 daemon/gdm-server.c                  |  253 ++++++++++---------
 8 files changed, 459 insertions(+), 507 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4470557..a3512e7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -268,7 +268,7 @@ AC_CHECK_TYPE(socklen_t,,
 #endif
 )
 AC_CHECK_HEADERS(sys/sockio.h)
-AC_CHECK_FUNCS([setresuid setenv unsetenv clearenv])
+AC_CHECK_FUNCS([setresuid setenv unsetenv clearenv strrep])
 
 dnl checks needed for Darwin compatibility to linux **environ.
 AC_CHECK_HEADERS(crt_externs.h)
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 4370261..45521ad 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -48,17 +48,6 @@ 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;
@@ -66,9 +55,6 @@ struct GdmDisplayPrivate
 
         char                 *remote_hostname;
         char                 *x11_command;
-        char                 *x11_arguments;
-        char                 *tty_device;
-        int                   priority;
         int                   x11_display_number;
         char                 *x11_display_name;
         int                   status;
@@ -96,9 +82,6 @@ enum {
         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,
@@ -782,46 +765,6 @@ gdm_display_get_x11_command (GdmDisplay *display,
 }
 
 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)
@@ -894,35 +837,6 @@ _gdm_display_set_x11_command (GdmDisplay     *display,
 }
 
 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)
 {
@@ -1007,15 +921,6 @@ gdm_display_set_property (GObject        *object,
         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;
@@ -1069,15 +974,6 @@ gdm_display_get_property (GObject        *object,
         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;
@@ -1235,29 +1131,6 @@ gdm_display_class_init (GdmDisplayClass *klass)
                                                               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",
@@ -1369,8 +1242,6 @@ 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 5df9c65..6f240bb 100644
--- a/daemon/gdm-display.h
+++ b/daemon/gdm-display.h
@@ -105,15 +105,6 @@ gboolean            gdm_display_get_id                         (GdmDisplay *disp
 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);
diff --git a/daemon/gdm-display.xml b/daemon/gdm-display.xml
index a7e1f5a..894d5c0 100644
--- a/daemon/gdm-display.xml
+++ b/daemon/gdm-display.xml
@@ -7,15 +7,6 @@
     <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>
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 53f18fb..72d2816 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -40,6 +40,13 @@
 
 #define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate))
 
+#define CK_NAME              "org.freedesktop.ConsoleKit"
+#define CK_PATH              "/org/freedesktop/ConsoleKit"
+#define CK_INTERFACE         "org.freedesktop.ConsoleKit"
+#define CK_MANAGER_PATH      "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+#define CK_SEAT_INTERFACE    "org.freedesktop.ConsoleKit.Seat"
+
 #define CK_SEAT1_PATH                       "/org/freedesktop/ConsoleKit/Seat1"
 
 #define GDM_DBUS_PATH                       "/org/gnome/DisplayManager"
@@ -59,8 +66,10 @@
 struct GdmLocalDisplayFactoryPrivate
 {
         DBusGConnection *connection;
-        DBusGProxy      *proxy;
+        DBusGProxy      *proxy_hal;
+        DBusGProxy      *proxy_ck;
         GHashTable      *displays;
+        GSList          *lst_proxy;
 
         /* FIXME: this needs to be per seat? */
         guint            num_failures;
@@ -251,130 +260,6 @@ gdm_local_display_lookup_by_number (GdmLocalDisplayFactory *factory,
   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 \
-  --type=method_call --print-reply --reply-timeout=2000 \
   /org/gnome/DisplayManager/Manager \
   org.gnome.DisplayManager.Manager.GetDisplays
 */
@@ -558,31 +443,287 @@ create_display (GdmLocalDisplayFactory *factory)
         return display;
 }
 
+#ifndef HAVE_STRREP
+static void
+strrep (char* in, char** out, char* old, char* new)
+{
+        char* temp;
+        char* orig = strdup(in);
+        char* found = strstr(orig, old);
+        if(!found) {
+                *out = malloc(strlen(orig) + 1);
+                strcpy(*out, orig);
+                return;
+        }
+        
+        int idx = found - orig;
+        
+        *out = realloc(*out, strlen(orig) - strlen(old) + strlen(new) + 1);
+        strncpy(*out, orig, idx);
+        strcpy(*out + idx, new);
+        strcpy(*out + idx + strlen(new), orig + idx + strlen(old));
+        
+
+        temp = malloc(idx+strlen(new)+1);
+        strncpy(temp,*out,idx+strlen(new)); 
+        temp[idx + strlen(new)] = '\0';
+
+        strrep(found + strlen(old), out, old, new);
+        temp = realloc(temp, strlen(temp) + strlen(*out) + 1);
+        strcat(temp,*out);
+        free(*out);
+        *out = temp;
+}
+#endif
+
+static void
+seat_session_to_add (DBusGProxy             *seat_proxy,
+                     gboolean                is_dynamic,
+                     const char             *xserver_command,
+                     GdmLocalDisplayFactory *factory)
+{
+        GdmDisplay *display;
+        gint        argc;
+        gchar     **argv;
+        GError     *error;
+        char       *comm = NULL;
+        const char *sid = NULL;
+        gint32      display_number;
+        gboolean    is_chooser;
+        gboolean    use_auth;
+        int         i;
+        gboolean    res;
+
+        g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory));
+        g_return_if_fail (IS_STR_SET (xserver_command));
+
+        if (! g_shell_parse_argv (xserver_command, &argc, &argv, &error)) {
+                g_warning ("Could not parse command %s: %s", xserver_command, error->message);
+                g_error_free (error);
+                return;
+        }
+
+        comm = g_strdup (xserver_command);
+        for (i = 0; i < argc; i++) {
+                /* replase $display in case of not specified */
+                if (g_str_equal (argv[i], "$display")) {
+                        display_number = take_next_display_number (factory);
+                        strrep (comm, &comm, "$display", "");
+                        break;
+                }
+
+                /* get display_number in case of specified */
+                if (g_str_has_prefix (argv[i], ":")) {
+                        display_number = atoi (argv[i]+1);
+                        strrep (comm, &comm, argv[i], "");
+                        break;
+                }
+        }
+        g_strfreev (argv);
+
+        is_chooser = FALSE;
+        if (strstr (comm, "-indirect")) {
+                is_chooser = TRUE;
+        }
+
+        use_auth = FALSE;
+        if (strstr (comm, "-auth $auth")) {
+                use_auth = TRUE;
+                strrep (comm, &comm, "-auth $auth", "");
+        }
+
+        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);
+                g_free (comm);
+                return;
+        }
+
+        sid = dbus_g_proxy_get_path (seat_proxy);
+        if (IS_STR_SET (sid))
+                g_object_set (display, "seat-id", sid, NULL);
+        if (IS_STR_SET (comm))
+                g_object_set (display, "x11-command", comm, NULL);
+        g_free (comm);
+        g_object_set (display, "use-auth", use_auth, NULL);
+
+        store_display (factory, display_number, display);
+
+        g_object_unref (display);
+
+        if (! gdm_display_manage (display)) {
+                gdm_display_unmanage (display);
+        }
+}
+
+static void
+seat_session_to_remove (DBusGProxy             *seat_proxy,
+                        int                     display_number,
+                        GdmLocalDisplayFactory *factory)
+{
+        GdmDisplay      *display;
+
+        g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory));
+
+        /* 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");
+                return;
+        }
+
+        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;
+                return;
+        }
+
+        store_remove_display (factory, display_number, display);
+}
+
+static void                                                        
+marshal_VOID__BOOLEAN_STRING (GClosure     *closure,
+                              GValue       *return_value,
+                              guint         n_param_values,
+                              const GValue *param_values,
+                              gpointer      invocation_hint,
+                              gpointer      marshal_data)
+{
+  typedef void (*GMarshalFunc_VOID__BOOLEAN_STRING) (gpointer     data1,
+                                                     guint        arg_1,
+                                                     gpointer     arg_2,
+                                                     gpointer     data2);
+  register GMarshalFunc_VOID__BOOLEAN_STRING callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+
+  g_return_if_fail (n_param_values == 3);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_VOID__BOOLEAN_STRING) (marshal_data ? marshal_data : cc->callback);
+
+  callback (data1,
+            g_marshal_value_peek_boolean (param_values + 1),
+            g_marshal_value_peek_string (param_values + 2),
+            data2);
+}
+
+static void
+manage_static_sessions_per_seat (GdmLocalDisplayFactory *factory,
+                                 const char             *sid)
+{
+        DBusGProxy *proxy;
+
+        proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
+                                           CK_NAME,
+                                           sid,
+                                           CK_SEAT_INTERFACE);
+
+        if (proxy == NULL) {
+                g_warning ("Failed to connect to the ConsoleKit seat object");
+                return;
+        }
+
+        dbus_g_object_register_marshaller (marshal_VOID__BOOLEAN_STRING,
+                                           G_TYPE_NONE,
+                                           G_TYPE_BOOLEAN,
+                                           G_TYPE_STRING,
+                                           G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (proxy,
+                                 "SessionToAdd",
+                                 G_TYPE_BOOLEAN,
+                                 G_TYPE_STRING,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_add_signal (proxy,
+                                 "SessionToRemove",
+                                 G_TYPE_INT,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_connect_signal (proxy,
+                                     "SessionToAdd",
+                                     G_CALLBACK (seat_session_to_add),
+                                     factory,
+                                     NULL);
+        dbus_g_proxy_connect_signal (proxy,
+                                     "SessionToRemove",
+                                     G_CALLBACK (seat_session_to_remove),
+                                     factory,
+                                     NULL);
+
+        dbus_g_proxy_call_no_reply (proxy,
+                                    "ManageSeat",
+                                    G_TYPE_INVALID,
+                                    G_TYPE_INVALID);
+
+        factory->priv->lst_proxy = g_slist_append (factory->priv->lst_proxy, proxy);
+
+}
+
+static void
+seat_added (DBusGProxy             *mgr_proxy,
+            const char             *sid,
+            GdmLocalDisplayFactory *factory)
+{
+        manage_static_sessions_per_seat (factory, sid);
+}
 
 static gboolean
 create_static_displays (GdmLocalDisplayFactory *factory)
 {
-        DBusGProxy      *proxy;
-        GError          *error = NULL;
+        GError     *error;
+        gboolean    res;
+        GPtrArray  *seats;
+        int         i;
 
-        proxy = dbus_g_proxy_new_for_name_owner (factory->priv->connection,
-                                                 "org.freedesktop.ConsoleKit",
-                                                 "/org/freedesktop/ConsoleKit/Manager",
-                                                 "org.freedesktop.ConsoleKit.Manager",
-                                                 &error);
+        seats = NULL;
 
-        if (proxy == NULL) {
-                g_warning ("Failed to create a new proxy, %s", error->message);
+        error = NULL;
+        res = dbus_g_proxy_call (factory->priv->proxy_ck,
+                                 "GetUnmanagedSeats",
+                                 &error,
+                                 G_TYPE_INVALID,
+                                 dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
+                                 &seats,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                g_warning ("Failed to get list of unmanaged seats: %s", error->message);
                 g_error_free (error);
                 return FALSE;
         }
 
-        dbus_g_proxy_call_no_reply (proxy, 
-                                   "CreateStaticSessions", 
-                                   G_TYPE_INVALID,
-                                   G_TYPE_INVALID);
+        for (i = 0; i < seats->len; i++) {
+                char *sid;
+
+                sid = g_ptr_array_index (seats, i);
+
+                manage_static_sessions_per_seat (factory, sid);
+
+                g_free (sid);
+        }
 
-        g_object_unref (proxy);
         return TRUE;
 
 }
@@ -743,11 +884,11 @@ register_factory (GdmLocalDisplayFactory *factory)
 static gboolean
 connect_to_hal (GdmLocalDisplayFactory *factory)
 {
-        factory->priv->proxy = dbus_g_proxy_new_for_name (factory->priv->connection,
-                                                          HAL_DBUS_NAME,
-                                                          HAL_DBUS_MANAGER_PATH,
-                                                          HAL_DBUS_MANAGER_INTERFACE);
-        if (factory->priv->proxy == NULL) {
+        factory->priv->proxy_hal = dbus_g_proxy_new_for_name (factory->priv->connection,
+                                                              HAL_DBUS_NAME,
+                                                              HAL_DBUS_MANAGER_PATH,
+                                                              HAL_DBUS_MANAGER_INTERFACE);
+        if (factory->priv->proxy_hal == NULL) {
                 g_warning ("Couldn't create proxy for HAL Manager");
                 return FALSE;
         }
@@ -758,8 +899,44 @@ connect_to_hal (GdmLocalDisplayFactory *factory)
 static void
 disconnect_from_hal (GdmLocalDisplayFactory *factory)
 {
-        if (factory->priv->proxy == NULL) {
-                g_object_unref (factory->priv->proxy);
+        if (factory->priv->proxy_hal == NULL) {
+                g_object_unref (factory->priv->proxy_hal);
+        }
+}
+
+static gboolean
+connect_to_ck (GdmLocalDisplayFactory *factory)
+{
+        GdmLocalDisplayFactoryPrivate *priv;
+
+        priv = factory->priv;
+
+        priv->proxy_ck = dbus_g_proxy_new_for_name (priv->connection,
+                                                    CK_NAME,
+                                                    CK_MANAGER_PATH,
+                                                    CK_MANAGER_INTERFACE);
+
+        if (priv->proxy_ck == NULL) {
+                g_warning ("Couldn't create proxy for ConsoleKit Manager");
+                return FALSE;
+        }
+
+        dbus_g_proxy_add_signal (priv->proxy_ck,
+                                 "SeatAdded",
+                                 DBUS_TYPE_G_OBJECT_PATH,
+                                 G_TYPE_INVALID);
+        dbus_g_proxy_connect_signal (priv->proxy_ck,
+                                     "SeatAdded",
+                                     G_CALLBACK (seat_added),
+                                     factory,
+                                     NULL);
+}
+
+static void
+disconnect_from_ck (GdmLocalDisplayFactory *factory)
+{
+        if (factory->priv->proxy_hal == NULL) {
+                g_object_unref (factory->priv->proxy_hal);
         }
 }
 
@@ -781,6 +958,7 @@ gdm_local_display_factory_constructor (GType                  type,
         }
 
         connect_to_hal (factory);
+        connect_to_ck (factory);
 
         return G_OBJECT (factory);
 }
@@ -826,7 +1004,10 @@ gdm_local_display_factory_finalize (GObject *object)
 
         g_hash_table_destroy (factory->priv->displays);
 
+        g_slist_foreach (factory->priv->lst_proxy, g_object_unref, NULL);
+
         disconnect_from_hal (factory);
+        disconnect_from_ck (factory);
 
         G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object);
 }
diff --git a/daemon/gdm-local-display-factory.h b/daemon/gdm-local-display-factory.h
index 8c43b35..2abb053 100644
--- a/daemon/gdm-local-display-factory.h
+++ b/daemon/gdm-local-display-factory.h
@@ -71,23 +71,6 @@ 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 0920b85..51f5153 100644
--- a/daemon/gdm-local-display-factory.xml
+++ b/daemon/gdm-local-display-factory.xml
@@ -1,85 +1,11 @@
 <!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-server.c b/daemon/gdm-server.c
index bedf038..8289a8e 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -67,37 +67,44 @@ extern char **environ;
 
 struct GdmServerPrivate
 {
+        char    *command;
         GPid     pid;
 
-        char    *user_name;
-        char    *log_dir;
         gboolean disable_tcp;
+        int      priority;
+        char    *user_name;
+        char    *session_args;
 
-        /* cached display values */
+        char    *log_dir;
         char    *display_id;
-        char    *command;
-        char    *session_args;
-        char    *tty_device;
         char    *display_name;
-        char    *auth_file;
-        int      priority;
-
         char    *display_device;
+        char    *auth_file;
 
         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,48 +259,67 @@ connect_to_parent (GdmServer *server)
 
 static gboolean
 gdm_server_resolve_command_line (GdmServer  *server,
+                                 const char *vtarg,
                                  int        *argcp,
                                  char     ***argvp)
 {
-        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);
+        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];
         }
 
+        /* server number is the FIRST argument, before any others */
+        argv[1] = g_strdup (server->priv->display_name);
+        len++;
+
         if (server->priv->auth_file != NULL) {
-                tmp = g_strdup (command);
-                g_free (command);
-                command = g_strdup_printf ("%s -auth %s ",
-                                           tmp, server->priv->auth_file);
-                g_free (tmp);
+                argv[len++] = g_strdup ("-auth");
+                argv[len++] = g_strdup (server->priv->auth_file);
         }
-#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);
+
+        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;
         }
-#endif
 
-        ret = g_shell_parse_argv (command, argcp, argvp, NULL);
-        g_free (command);
+        if (vtarg != NULL && ! gotvtarg) {
+                argv[len++] = g_strdup (vtarg);
+        }
 
-        return ret;
+        argv[len++] = NULL;
+
+        *argvp = argv;
+        *argcp = len;
+
+        return TRUE;
 }
 
 static void
@@ -440,14 +466,7 @@ server_child_setup (GdmServer *server)
         sigemptyset (&mask);
         sigprocmask (SIG_SETMASK, &mask, NULL);
 
-#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 (server->priv->priority != 0) {
                 if (setpriority (PRIO_PROCESS, 0, server->priv->priority)) {
                         g_warning (_("%s: Server priority couldn't be set to %d: %s"),
                                    "gdm_server_spawn",
@@ -526,6 +545,30 @@ 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)
@@ -552,7 +595,8 @@ server_child_watch (GPid       pid,
 }
 
 static gboolean
-gdm_server_spawn (GdmServer  *server)
+gdm_server_spawn (GdmServer  *server,
+                  const char *vtarg)
 {
         int              argc;
         gchar          **argv = NULL;
@@ -567,9 +611,14 @@ 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",
@@ -629,7 +678,7 @@ gdm_server_start (GdmServer *server)
         gboolean res;
 
         /* fork X server process */
-        res = gdm_server_spawn (server);
+        res = gdm_server_spawn (server, NULL);
 
         return res;
 }
@@ -695,6 +744,14 @@ _gdm_server_set_display_id (GdmServer  *server,
 }
 
 static void
+_gdm_server_set_auth_file (GdmServer  *server,
+                           const char *auth_file)
+{
+        g_free (server->priv->auth_file);
+        server->priv->auth_file = g_strdup (auth_file);
+}
+
+static void
 _gdm_server_set_user_name (GdmServer  *server,
                            const char *name)
 {
@@ -723,6 +780,9 @@ gdm_server_set_property (GObject      *object,
         case PROP_DISPLAY_ID:
                 _gdm_server_set_display_id (self, g_value_get_string (value));
                 break;
+        case PROP_AUTH_FILE:
+                _gdm_server_set_auth_file (self, g_value_get_string (value));
+                break;
         case PROP_USER_NAME:
                 _gdm_server_set_user_name (self, g_value_get_string (value));
                 break;
@@ -753,6 +813,9 @@ gdm_server_get_property (GObject    *object,
                 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;
@@ -838,6 +901,14 @@ 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",
@@ -852,13 +923,19 @@ 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
@@ -985,72 +1062,6 @@ gdm_server_new (const char *display_id)
 
         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,
@@ -1067,13 +1078,11 @@ gdm_server_new (const char *display_id)
                 exit (1);   
         }
 
-        /* If tty_device is not set, set it NULL */
+        /* If auth_file 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;
 }



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