diff options
-rw-r--r-- | daemon/gdm-display.c | 316 | ||||
-rw-r--r-- | daemon/gdm-launch-environment.c | 106 | ||||
-rw-r--r-- | daemon/gdm-launch-environment.h | 12 | ||||
-rw-r--r-- | daemon/gdm-local-display.c | 40 | ||||
-rw-r--r-- | daemon/gdm-simple-slave.c | 429 | ||||
-rw-r--r-- | daemon/gdm-slave.c | 19 | ||||
-rw-r--r-- | daemon/gdm-slave.h | 10 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-chooser-display.c | 37 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-chooser-slave.c | 283 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-display-factory.c | 36 | ||||
-rw-r--r-- | daemon/gdm-xdmcp-display.c | 37 |
11 files changed, 564 insertions, 761 deletions
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c index 97f0e7da..a205839a 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c @@ -42,9 +42,14 @@ #include "gdm-settings-direct.h" #include "gdm-settings-keys.h" +#include "gdm-launch-environment.h" #include "gdm-simple-slave.h" +#include "gdm-xdmcp-chooser-slave.h" #include "gdm-dbus-util.h" +#define INITIAL_SETUP_USERNAME "gnome-initial-setup" +#define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions" + #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate)) struct GdmDisplayPrivate @@ -83,6 +88,7 @@ struct GdmDisplayPrivate guint is_initial : 1; guint allow_timed_login : 1; guint have_existing_user_accounts : 1; + guint doing_initial_setup : 1; }; enum { @@ -101,7 +107,8 @@ enum { PROP_LAUNCH_ENVIRONMENT, PROP_IS_INITIAL, PROP_ALLOW_TIMED_LOGIN, - PROP_HAVE_EXISTING_USER_ACCOUNTS + PROP_HAVE_EXISTING_USER_ACCOUNTS, + PROP_DOING_INITIAL_SETUP, }; static void gdm_display_class_init (GdmDisplayClass *klass); @@ -110,9 +117,79 @@ static void gdm_display_finalize (GObject *object); static void queue_finish (GdmDisplay *self); static void _gdm_display_set_status (GdmDisplay *self, int status); - G_DEFINE_ABSTRACT_TYPE (GdmDisplay, gdm_display, G_TYPE_OBJECT) +static gboolean +chown_file (GFile *file, + uid_t uid, + gid_t gid, + GError **error) +{ + if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, error)) { + return FALSE; + } + if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, error)) { + return FALSE; + } + return TRUE; +} + +static gboolean +chown_recursively (GFile *dir, + uid_t uid, + gid_t gid, + GError **error) +{ + GFile *file = NULL; + GFileInfo *info = NULL; + GFileEnumerator *enumerator = NULL; + gboolean retval = FALSE; + + if (chown_file (dir, uid, gid, error) == FALSE) { + goto out; + } + + enumerator = g_file_enumerate_children (dir, + G_FILE_ATTRIBUTE_STANDARD_TYPE"," + G_FILE_ATTRIBUTE_STANDARD_NAME, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, error); + if (!enumerator) { + goto out; + } + + while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) { + file = g_file_get_child (dir, g_file_info_get_name (info)); + + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { + if (chown_recursively (file, uid, gid, error) == FALSE) { + goto out; + } + } else if (chown_file (file, uid, gid, error) == FALSE) { + goto out; + } + + g_clear_object (&file); + g_clear_object (&info); + } + + if (*error) { + goto out; + } + + retval = TRUE; +out: + g_clear_object (&file); + g_clear_object (&info); + g_clear_object (&enumerator); + + return retval; +} + GQuark gdm_display_error_quark (void) { @@ -523,11 +600,6 @@ gdm_display_real_prepare (GdmDisplay *self) G_CALLBACK (on_slave_stopped), self, 0); - g_object_bind_property (G_OBJECT (self->priv->slave), - "session-id", - G_OBJECT (self), - "session-id", - G_BINDING_DEFAULT); return TRUE; } @@ -627,6 +699,11 @@ gdm_display_finish (GdmDisplay *self) { g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); + if (self->priv->finish_idle_id != 0) { + g_source_remove (self->priv->finish_idle_id); + self->priv->finish_idle_id = 0; + } + _gdm_display_set_status (self, GDM_DISPLAY_FINISHED); g_debug ("GdmDisplay: finish display"); @@ -796,6 +873,12 @@ _gdm_display_set_launch_environment (GdmDisplay *self, g_clear_object (&self->priv->launch_environment); self->priv->launch_environment = g_object_ref (launch_environment); + + g_object_bind_property (launch_environment, + "session-id", + self, + "session-id", + G_BINDING_SYNC_CREATE); } static void @@ -922,6 +1005,9 @@ gdm_display_get_property (GObject *object, case PROP_HAVE_EXISTING_USER_ACCOUNTS: g_value_set_boolean (value, self->priv->have_existing_user_accounts); break; + case PROP_DOING_INITIAL_SETUP: + g_value_set_boolean (value, self->priv->doing_initial_setup); + break; case PROP_ALLOW_TIMED_LOGIN: g_value_set_boolean (value, self->priv->allow_timed_login); break; @@ -1225,6 +1311,10 @@ gdm_display_dispose (GObject *object) g_debug ("GdmDisplay: Disposing display"); + if (self->priv->finish_idle_id != 0) { + g_source_remove (self->priv->finish_idle_id); + self->priv->finish_idle_id = 0; + } g_clear_object (&self->priv->launch_environment); g_assert (self->priv->status == GDM_DISPLAY_FINISHED || @@ -1337,6 +1427,13 @@ gdm_display_class_init (GdmDisplayClass *klass) FALSE, G_PARAM_READABLE)); g_object_class_install_property (object_class, + PROP_DOING_INITIAL_SETUP, + g_param_spec_boolean ("doing-initial-setup", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_LAUNCH_ENVIRONMENT, g_param_spec_object ("launch-environment", NULL, @@ -1418,23 +1515,222 @@ gdm_display_get_object_skeleton (GdmDisplay *self) return self->priv->object_skeleton; } +static void +on_launch_environment_session_opened (GdmLaunchEnvironment *launch_environment, + GdmDisplay *self) +{ + char *session_id; + + g_debug ("GdmDisplay: Greeter session opened"); + session_id = gdm_launch_environment_get_session_id (launch_environment); + + g_object_set (GDM_SLAVE (self), "session-id", session_id, NULL); + g_free (session_id); +} + +static void +on_launch_environment_session_started (GdmLaunchEnvironment *launch_environment, + GdmDisplay *self) +{ + g_debug ("GdmDisplay: Greeter started"); +} + +static void +on_launch_environment_session_stopped (GdmLaunchEnvironment *launch_environment, + GdmDisplay *self) +{ + g_debug ("GdmDisplay: Greeter stopped"); + gdm_slave_stop (self->priv->slave); + + g_clear_object (&self->priv->launch_environment); +} + +static void +on_launch_environment_session_exited (GdmLaunchEnvironment *launch_environment, + int code, + GdmDisplay *self) +{ + g_debug ("GdmDisplay: Greeter exited: %d", code); + gdm_slave_stop (self->priv->slave); +} + +static void +on_launch_environment_session_died (GdmLaunchEnvironment *launch_environment, + int signal, + GdmDisplay *self) +{ + g_debug ("GdmDisplay: Greeter died: %d", signal); + gdm_slave_stop (self->priv->slave); +} + +static gboolean +can_create_environment (const char *session_id) +{ + char *path; + gboolean session_exists; + + path = g_strdup_printf (GNOME_SESSION_SESSIONS_PATH "/%s.session", session_id); + session_exists = g_file_test (path, G_FILE_TEST_EXISTS); + + g_free (path); + + return session_exists; +} + +static gboolean +wants_initial_setup (GdmDisplay *self) +{ + gboolean enabled = FALSE; + + /* don't run initial-setup on remote displays + */ + if (!self->priv->is_local) { + return FALSE; + } + + /* don't run if the system has existing users */ + if (self->priv->have_existing_user_accounts) { + return FALSE; + } + + /* don't run if initial-setup is unavailable */ + if (!can_create_environment ("gnome-initial-setup")) { + return FALSE; + } + + if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) { + return FALSE; + } + + return enabled; +} + void gdm_display_set_up_greeter_session (GdmDisplay *self, char **username) { - gdm_slave_set_up_greeter_session (self->priv->slave, username); + self->priv->doing_initial_setup = wants_initial_setup (self); + + if (self->priv->doing_initial_setup) { + *username = g_strdup (INITIAL_SETUP_USERNAME); + } else { + *username = g_strdup (GDM_USERNAME); + } } void gdm_display_start_greeter_session (GdmDisplay *self) { - gdm_slave_start_greeter_session (self->priv->slave); + char *display_name; + char *seat_id; + char *hostname; + char *auth_file; + + g_debug ("GdmDisplay: Running greeter"); + + display_name = NULL; + seat_id = NULL; + hostname = NULL; + + g_object_get (self, + "x11-display-name", &display_name, + "seat-id", &seat_id, + "remote-hostname", &hostname, + NULL); + auth_file = gdm_display_access_file_get_path (self->priv->access_file); + + g_debug ("GdmDisplay: Creating greeter for %s %s", display_name, hostname); + + g_signal_connect_object (self->priv->launch_environment, + "opened", + G_CALLBACK (on_launch_environment_session_opened), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "started", + G_CALLBACK (on_launch_environment_session_started), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "stopped", + G_CALLBACK (on_launch_environment_session_stopped), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "exited", + G_CALLBACK (on_launch_environment_session_exited), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "died", + G_CALLBACK (on_launch_environment_session_died), + self, 0); + + g_object_set (self->priv->launch_environment, + "x11-authority-file", auth_file, + NULL); + + gdm_launch_environment_start (self->priv->launch_environment); + + g_free (display_name); + g_free (seat_id); + g_free (hostname); + g_free (auth_file); +} + +static void +chown_initial_setup_home_dir (void) +{ + GFile *dir; + GError *error; + char *gis_dir_path; + char *gis_uid_path; + char *gis_uid_contents; + struct passwd *pwe; + uid_t uid; + + if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) { + g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME); + return; + } + + gis_dir_path = g_strdup (pwe->pw_dir); + + gis_uid_path = g_build_filename (gis_dir_path, + "gnome-initial-setup-uid", + NULL); + if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) { + g_warning ("Unable to read %s", gis_uid_path); + goto out; + } + + uid = (uid_t) atoi (gis_uid_contents); + pwe = getpwuid (uid); + if (uid == 0 || pwe == NULL) { + g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path); + goto out; + } + + error = NULL; + dir = g_file_new_for_path (gis_dir_path); + if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) { + g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message); + g_error_free (error); + } + g_object_unref (dir); +out: + g_free (gis_uid_contents); + g_free (gis_uid_path); + g_free (gis_dir_path); } void gdm_display_stop_greeter_session (GdmDisplay *self) { - gdm_slave_stop_greeter_session (self->priv->slave); + if (self->priv->launch_environment != NULL) { + gdm_launch_environment_stop (self->priv->launch_environment); + g_clear_object (&self->priv->launch_environment); + } + + if (self->priv->doing_initial_setup) { + chown_initial_setup_home_dir (); + } } GdmSlave * diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c index 07a60262..c572a41f 100644 --- a/daemon/gdm-launch-environment.c +++ b/daemon/gdm-launch-environment.c @@ -47,8 +47,12 @@ #include "gdm-session-enum-types.h" #include "gdm-launch-environment.h" +#include "gdm-settings-direct.h" +#include "gdm-settings-keys.h" #define DBUS_LAUNCH_COMMAND BINDIR "/dbus-launch --exit-with-session" +#define INITIAL_SETUP_USERNAME "gnome-initial-setup" +#define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions" extern char **environ; @@ -890,3 +894,105 @@ gdm_launch_environment_finalize (GObject *object) G_OBJECT_CLASS (gdm_launch_environment_parent_class)->finalize (object); } + +static GdmLaunchEnvironment * +create_gnome_session_environment (const char *session_id, + const char *user_name, + const char *display_name, + const char *seat_id, + const char *display_hostname, + gboolean display_is_local) +{ + gboolean debug = FALSE; + char *command; + GdmLaunchEnvironment *launch_environment; + char **argv; + GPtrArray *args; + + gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); + + args = g_ptr_array_new (); + g_ptr_array_add (args, BINDIR "/gnome-session"); + + g_ptr_array_add (args, "--autostart"); + g_ptr_array_add (args, DATADIR "/gdm/greeter/autostart"); + + if (debug) { + g_ptr_array_add (args, "--debug"); + } + + if (session_id != NULL) { + g_ptr_array_add (args, " --session"); + g_ptr_array_add (args, (char *) session_id); + } + + g_ptr_array_add (args, NULL); + + argv = (char **) g_ptr_array_free (args, FALSE); + command = g_strjoinv (" ", argv); + g_free (argv); + + launch_environment = g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT, + "command", command, + "user-name", user_name, + "x11-display-name", display_name, + "x11-display-seat-id", seat_id, + "x11-display-hostname", display_hostname, + "x11-display-is-local", display_is_local, + "runtime-dir", GDM_SCREENSHOT_DIR, + NULL); + + g_free (command); + return launch_environment; +} + +GdmLaunchEnvironment * +gdm_create_greeter_launch_environment (const char *display_name, + const char *seat_id, + const char *display_hostname, + gboolean display_is_local) +{ + return create_gnome_session_environment (NULL, + GDM_USERNAME, + display_name, + seat_id, + display_hostname, + display_is_local); +} + +GdmLaunchEnvironment * +gdm_create_initial_setup_launch_environment (const char *display_name, + const char *seat_id, + const char *display_hostname, + gboolean display_is_local) +{ + return create_gnome_session_environment ("gnome-initial-setup", + INITIAL_SETUP_USERNAME, + display_name, + seat_id, + display_hostname, + display_is_local); +} + +GdmLaunchEnvironment * +gdm_create_chooser_launch_environment (const char *display_name, + const char *seat_id, + const char *display_hostname) + +{ + GdmLaunchEnvironment *launch_environment; + + launch_environment = g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT, + "command", LIBEXECDIR "/gdm-simple-chooser", + "verification-mode", GDM_SESSION_VERIFICATION_MODE_CHOOSER, + "user-name", GDM_USERNAME, + "x11-display-name", display_name, + "x11-display-seat-id", seat_id, + "x11-display-hostname", display_hostname, + "x11-display-is-local", FALSE, + "runtime-dir", GDM_SCREENSHOT_DIR, + NULL); + + return launch_environment; +} + diff --git a/daemon/gdm-launch-environment.h b/daemon/gdm-launch-environment.h index 8f276432..34070b98 100644 --- a/daemon/gdm-launch-environment.h +++ b/daemon/gdm-launch-environment.h @@ -68,6 +68,18 @@ gboolean gdm_launch_environment_stop (GdmLaunchEnviro GdmSession * gdm_launch_environment_get_session (GdmLaunchEnvironment *launch_environment); char * gdm_launch_environment_get_session_id (GdmLaunchEnvironment *launch_environment); +GdmLaunchEnvironment *gdm_create_greeter_launch_environment (const char *display_name, + const char *seat_id, + const char *display_hostname, + gboolean display_is_local); +GdmLaunchEnvironment *gdm_create_initial_setup_launch_environment (const char *display_name, + const char *seat_id, + const char *display_hostname, + gboolean display_is_local); +GdmLaunchEnvironment *gdm_create_chooser_launch_environment (const char *display_name, + const char *seat_id, + const char *display_hostname); + G_END_DECLS #endif /* __GDM_LAUNCH_ENVIRONMENT_H */ diff --git a/daemon/gdm-local-display.c b/daemon/gdm-local-display.c index caaf3041..112a7cd2 100644 --- a/daemon/gdm-local-display.c +++ b/daemon/gdm-local-display.c @@ -38,6 +38,7 @@ #include "gdm-common.h" #include "gdm-display.h" +#include "gdm-launch-environment.h" #include "gdm-local-display.h" #include "gdm-local-display-glue.h" @@ -82,14 +83,53 @@ gdm_local_display_finalize (GObject *object) G_OBJECT_CLASS (gdm_local_display_parent_class)->finalize (object); } +static gboolean +gdm_local_display_prepare (GdmDisplay *display) +{ + GdmLocalDisplay *self = GDM_LOCAL_DISPLAY (display); + GdmLaunchEnvironment *launch_environment; + char *display_name; + char *seat_id; + gboolean doing_initial_setup = FALSE; + + display_name = NULL; + seat_id = NULL; + + g_object_get (self, + "x11-display-name", &display_name, + "seat-id", &seat_id, + "doing-initial-setup", &doing_initial_setup, + NULL); + + if (!doing_initial_setup) { + launch_environment = gdm_create_greeter_launch_environment (display_name, + seat_id, + NULL, + TRUE); + } else { + launch_environment = gdm_create_initial_setup_launch_environment (display_name, + seat_id, + NULL, + TRUE); + } + + g_object_set (self, "launch-environment", launch_environment, NULL); + g_object_unref (launch_environment); + + return GDM_DISPLAY_CLASS (gdm_local_display_parent_class)->prepare (display); +} + static void gdm_local_display_class_init (GdmLocalDisplayClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdmDisplayClass *display_class = GDM_DISPLAY_CLASS (klass); object_class->constructor = gdm_local_display_constructor; object_class->finalize = gdm_local_display_finalize; + display_class->prepare = gdm_local_display_prepare; + g_type_class_add_private (klass, sizeof (GdmLocalDisplayPrivate)); } diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c index 691b14c9..1263da4a 100644 --- a/daemon/gdm-simple-slave.c +++ b/daemon/gdm-simple-slave.c @@ -76,9 +76,6 @@ struct GdmSimpleSlavePrivate GdmServer *server; - /* this spawns and controls the greeter session */ - GdmLaunchEnvironment *greeter_environment; - GDBusProxy *accountsservice_proxy; guint have_existing_user_accounts : 1; guint accountsservice_ready : 1; @@ -98,126 +95,8 @@ static void gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass); static void gdm_simple_slave_init (GdmSimpleSlave *simple_slave); static void gdm_simple_slave_finalize (GObject *object); -static gboolean wants_initial_setup (GdmSimpleSlave *slave); G_DEFINE_TYPE (GdmSimpleSlave, gdm_simple_slave, GDM_TYPE_SLAVE) -static gboolean -chown_file (GFile *file, - uid_t uid, - gid_t gid, - GError **error) -{ - if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, error)) { - return FALSE; - } - if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, error)) { - return FALSE; - } - return TRUE; -} - -static gboolean -chown_recursively (GFile *dir, - uid_t uid, - gid_t gid, - GError **error) -{ - GFile *file = NULL; - GFileInfo *info = NULL; - GFileEnumerator *enumerator = NULL; - gboolean retval = FALSE; - - if (chown_file (dir, uid, gid, error) == FALSE) { - goto out; - } - - enumerator = g_file_enumerate_children (dir, - G_FILE_ATTRIBUTE_STANDARD_TYPE"," - G_FILE_ATTRIBUTE_STANDARD_NAME, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, error); - if (!enumerator) { - goto out; - } - - while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) { - file = g_file_get_child (dir, g_file_info_get_name (info)); - - if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { - if (chown_recursively (file, uid, gid, error) == FALSE) { - goto out; - } - } else if (chown_file (file, uid, gid, error) == FALSE) { - goto out; - } - - g_clear_object (&file); - g_clear_object (&info); - } - - if (*error) { - goto out; - } - - retval = TRUE; -out: - g_clear_object (&file); - g_clear_object (&info); - g_clear_object (&enumerator); - - return retval; -} - -static void -chown_initial_setup_home_dir (void) -{ - GFile *dir; - GError *error; - char *gis_dir_path; - char *gis_uid_path; - char *gis_uid_contents; - struct passwd *pwe; - uid_t uid; - - if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) { - g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME); - return; - } - - gis_dir_path = g_strdup (pwe->pw_dir); - - gis_uid_path = g_build_filename (gis_dir_path, - "gnome-initial-setup-uid", - NULL); - if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) { - g_warning ("Unable to read %s", gis_uid_path); - goto out; - } - - uid = (uid_t) atoi (gis_uid_contents); - pwe = getpwuid (uid); - if (uid == 0 || pwe == NULL) { - g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path); - goto out; - } - - error = NULL; - dir = g_file_new_for_path (gis_dir_path); - if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) { - g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message); - g_error_free (error); - } - g_object_unref (dir); -out: - g_free (gis_uid_contents); - g_free (gis_uid_path); - g_free (gis_dir_path); -} - #ifdef HAVE_LOGINDEVPERM static void gdm_simple_slave_grant_console_permissions (GdmSimpleSlave *slave) @@ -286,314 +165,11 @@ gdm_simple_slave_revoke_console_permissions (GdmSimpleSlave *slave) #endif /* HAVE_LOGINDEVPERM */ static void -on_greeter_environment_session_opened (GdmLaunchEnvironment *greeter_environment, - GdmSimpleSlave *slave) -{ - char *session_id; - - g_debug ("GdmSimpleSlave: Greeter session opened"); - session_id = gdm_launch_environment_get_session_id (GDM_LAUNCH_ENVIRONMENT (greeter_environment)); - - g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL); - g_free (session_id); -} - -static void -on_greeter_environment_session_started (GdmLaunchEnvironment *greeter_environment, - GdmSimpleSlave *slave) -{ - g_debug ("GdmSimpleSlave: Greeter started"); -} - -static void -on_greeter_environment_session_stopped (GdmLaunchEnvironment *greeter_environment, - GdmSimpleSlave *slave) -{ - g_debug ("GdmSimpleSlave: Greeter stopped"); - gdm_slave_stop (GDM_SLAVE (slave)); - - g_object_unref (slave->priv->greeter_environment); - slave->priv->greeter_environment = NULL; -} - -static void -on_greeter_environment_session_exited (GdmLaunchEnvironment *greeter_environment, - int code, - GdmSimpleSlave *slave) -{ - g_debug ("GdmSimpleSlave: Greeter exited: %d", code); - gdm_slave_stop (GDM_SLAVE (slave)); -} - -static void -on_greeter_environment_session_died (GdmLaunchEnvironment *greeter_environment, - int signal, - GdmSimpleSlave *slave) -{ - g_debug ("GdmSimpleSlave: Greeter died: %d", signal); - gdm_slave_stop (GDM_SLAVE (slave)); -} - -static void setup_server (GdmSimpleSlave *slave) { } static gboolean -can_create_environment (const char *session_id) -{ - char *path; - gboolean session_exists; - - path = g_strdup_printf (GNOME_SESSION_SESSIONS_PATH "/%s.session", session_id); - session_exists = g_file_test (path, G_FILE_TEST_EXISTS); - - g_free (path); - - return session_exists; -} - -static GdmLaunchEnvironment * -create_environment (const char *session_id, - const char *user_name, - const char *display_name, - const char *seat_id, - const char *display_device, - const char *display_hostname, - gboolean display_is_local) -{ - gboolean debug = FALSE; - char *command; - GdmLaunchEnvironment *launch_environment; - char **argv; - GPtrArray *args; - - gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); - - args = g_ptr_array_new (); - g_ptr_array_add (args, BINDIR "/gnome-session"); - - g_ptr_array_add (args, "--autostart"); - g_ptr_array_add (args, DATADIR "/gdm/greeter/autostart"); - - if (debug) { - g_ptr_array_add (args, "--debug"); - } - - if (session_id != NULL) { - g_ptr_array_add (args, " --session"); - g_ptr_array_add (args, (char *) session_id); - } - - g_ptr_array_add (args, NULL); - - argv = (char **) g_ptr_array_free (args, FALSE); - command = g_strjoinv (" ", argv); - g_free (argv); - - launch_environment = g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT, - "command", command, - "user-name", user_name, - "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, - "runtime-dir", GDM_SCREENSHOT_DIR, - NULL); - - g_free (command); - return launch_environment; -} - -static void -start_launch_environment (GdmSimpleSlave *slave, - char *username, - char *session_id) -{ - gboolean display_is_local; - char *display_name; - char *seat_id; - char *display_device; - char *display_hostname; - char *auth_file; - gboolean res; - - g_debug ("GdmSimpleSlave: Running greeter"); - - display_is_local = FALSE; - 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-name", &display_name, - "display-seat-id", &seat_id, - "display-hostname", &display_hostname, - "display-x11-authority-file", &auth_file, - NULL); - - g_debug ("GdmSimpleSlave: Creating greeter for %s %s", display_name, display_hostname); - - if (slave->priv->server != NULL) { - display_device = gdm_server_get_display_device (slave->priv->server); - } - - /* FIXME: send a signal back to the master */ - - /* If XDMCP setup pinging */ - slave->priv->ping_interval = DEFAULT_PING_INTERVAL; - res = gdm_settings_direct_get_int (GDM_KEY_PING_INTERVAL, - &(slave->priv->ping_interval)); - - if ( ! display_is_local && res && slave->priv->ping_interval > 0) { - alarm (slave->priv->ping_interval); - } - - g_debug ("GdmSimpleSlave: Creating greeter on %s %s %s", display_name, display_device, display_hostname); - slave->priv->greeter_environment = create_environment (session_id, - username, - display_name, - seat_id, - display_device, - display_hostname, - display_is_local); - g_signal_connect (slave->priv->greeter_environment, - "opened", - G_CALLBACK (on_greeter_environment_session_opened), - slave); - g_signal_connect (slave->priv->greeter_environment, - "started", - G_CALLBACK (on_greeter_environment_session_started), - slave); - g_signal_connect (slave->priv->greeter_environment, - "stopped", - G_CALLBACK (on_greeter_environment_session_stopped), - slave); - g_signal_connect (slave->priv->greeter_environment, - "exited", - G_CALLBACK (on_greeter_environment_session_exited), - slave); - g_signal_connect (slave->priv->greeter_environment, - "died", - G_CALLBACK (on_greeter_environment_session_died), - slave); - g_object_set (slave->priv->greeter_environment, - "x11-authority-file", auth_file, - NULL); - - gdm_launch_environment_start (GDM_LAUNCH_ENVIRONMENT (slave->priv->greeter_environment)); - - g_free (display_name); - g_free (seat_id); - g_free (display_device); - g_free (display_hostname); - g_free (auth_file); -} - -static void -start_greeter (GdmSimpleSlave *slave) -{ - start_launch_environment (slave, GDM_USERNAME, NULL); -} - -static void -start_initial_setup (GdmSimpleSlave *slave) -{ - slave->priv->doing_initial_setup = TRUE; - start_launch_environment (slave, INITIAL_SETUP_USERNAME, "gnome-initial-setup"); -} - -static gboolean -wants_initial_setup (GdmSimpleSlave *slave) -{ - gboolean enabled = FALSE; - gboolean display_is_local = FALSE; - - g_object_get (G_OBJECT (slave), - "display-is-local", &display_is_local, - NULL); - - /* don't run initial-setup on remote displays - */ - if (!display_is_local) { - return FALSE; - } - - /* don't run if the system has existing users */ - if (slave->priv->have_existing_user_accounts) { - return FALSE; - } - - /* don't run if initial-setup is unavailable */ - if (!can_create_environment ("gnome-initial-setup")) { - return FALSE; - } - - if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) { - return FALSE; - } - - return enabled; -} - -static void -gdm_simple_slave_set_up_greeter_session (GdmSlave *slave, - char **username) -{ - GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave); - - if (wants_initial_setup (self)) { - *username = g_strdup (INITIAL_SETUP_USERNAME); - } else { - *username = g_strdup (GDM_USERNAME); - } -} - -static void -gdm_simple_slave_stop_greeter_session (GdmSlave *slave) -{ - GdmSimpleSlave *self = GDM_SIMPLE_SLAVE (slave); - - if (self->priv->greeter_environment != NULL) { - g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, - G_CALLBACK (on_greeter_environment_session_opened), - self); - g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, - G_CALLBACK (on_greeter_environment_session_started), - self); - g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, - G_CALLBACK (on_greeter_environment_session_stopped), - self); - g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, - G_CALLBACK (on_greeter_environment_session_exited), - self); - g_signal_handlers_disconnect_by_func (self->priv->greeter_environment, - G_CALLBACK (on_greeter_environment_session_died), - self); - gdm_launch_environment_stop (GDM_LAUNCH_ENVIRONMENT (self->priv->greeter_environment)); - g_clear_object (&self->priv->greeter_environment); - } - - if (GDM_SIMPLE_SLAVE (slave)->priv->doing_initial_setup) { - chown_initial_setup_home_dir (); - } -} - -static void -gdm_simple_slave_start_greeter_session (GdmSlave *slave) -{ - if (wants_initial_setup (GDM_SIMPLE_SLAVE (slave))) { - start_initial_setup (GDM_SIMPLE_SLAVE (slave)); - } else { - start_greeter (GDM_SIMPLE_SLAVE (slave)); - } -} - -static gboolean idle_connect_to_display (GdmSimpleSlave *slave) { gboolean res; @@ -793,8 +369,6 @@ gdm_simple_slave_stop (GdmSlave *slave) GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->stop (slave); - gdm_simple_slave_stop_greeter_session (slave); - if (self->priv->server != NULL) { gdm_server_stop (self->priv->server); g_clear_object (&self->priv->server); @@ -815,9 +389,6 @@ gdm_simple_slave_class_init (GdmSimpleSlaveClass *klass) slave_class->start = gdm_simple_slave_start; slave_class->stop = gdm_simple_slave_stop; - slave_class->set_up_greeter_session = gdm_simple_slave_set_up_greeter_session; - slave_class->start_greeter_session = gdm_simple_slave_start_greeter_session; - slave_class->stop_greeter_session = gdm_simple_slave_stop_greeter_session; g_type_class_add_private (klass, sizeof (GdmSimpleSlavePrivate)); } diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c index 84954f8b..a16b5630 100644 --- a/daemon/gdm-slave.c +++ b/daemon/gdm-slave.c @@ -697,25 +697,6 @@ gdm_slave_get_property (GObject *object, } } -void -gdm_slave_set_up_greeter_session (GdmSlave *slave, - char **username) -{ - GDM_SLAVE_GET_CLASS (slave)->set_up_greeter_session (slave, username); -} - -void -gdm_slave_start_greeter_session (GdmSlave *slave) -{ - GDM_SLAVE_GET_CLASS (slave)->start_greeter_session (slave); -} - -void -gdm_slave_stop_greeter_session (GdmSlave *slave) -{ - GDM_SLAVE_GET_CLASS (slave)->stop_greeter_session (slave); -} - static void gdm_slave_class_init (GdmSlaveClass *klass) { diff --git a/daemon/gdm-slave.h b/daemon/gdm-slave.h index 20b1cf32..e0033191 100644 --- a/daemon/gdm-slave.h +++ b/daemon/gdm-slave.h @@ -50,11 +50,6 @@ typedef struct gboolean (*start) (GdmSlave *slave); gboolean (*stop) (GdmSlave *slave); - void (* set_up_greeter_session) (GdmSlave *slave, - char **username); - void (* start_greeter_session) (GdmSlave *slave); - void (* stop_greeter_session) (GdmSlave *slave); - /* signals */ void (*stopped) (GdmSlave *slave); } GdmSlaveClass; @@ -83,11 +78,6 @@ gboolean gdm_slave_add_user_authorization (GdmSlave *slave, gboolean gdm_slave_connect_to_x11_display (GdmSlave *slave); -void gdm_slave_set_up_greeter_session (GdmSlave *slave, - char **username); -void gdm_slave_start_greeter_session (GdmSlave *slave); -void gdm_slave_stop_greeter_session (GdmSlave *slave); - G_END_DECLS #endif /* __GDM_SLAVE_H */ diff --git a/daemon/gdm-xdmcp-chooser-display.c b/daemon/gdm-xdmcp-chooser-display.c index 371c2b0a..711751bb 100644 --- a/daemon/gdm-xdmcp-chooser-display.c +++ b/daemon/gdm-xdmcp-chooser-display.c @@ -36,6 +36,7 @@ #include <glib-object.h> #include "gdm-display.h" +#include "gdm-launch-environment.h" #include "gdm-xdmcp-chooser-display.h" #include "gdm-xdmcp-chooser-slave.h" @@ -56,7 +57,7 @@ static gboolean gdm_xdmcp_chooser_display_prepare (GdmDisplay *display); G_DEFINE_TYPE (GdmXdmcpChooserDisplay, gdm_xdmcp_chooser_display, GDM_TYPE_XDMCP_DISPLAY) static void -on_hostname_selected (GdmXdmcpChooserSlave *slave, +on_hostname_selected (GdmLaunchEnvironment *launch_environment, const char *hostname, GdmXdmcpChooserDisplay *display) { @@ -93,17 +94,33 @@ gdm_xdmcp_chooser_display_init (GdmXdmcpChooserDisplay *xdmcp_chooser_display) static gboolean gdm_xdmcp_chooser_display_prepare (GdmDisplay *display) { - GdmXdmcpChooserSlave *slave; - - if (!GDM_DISPLAY_CLASS (gdm_xdmcp_chooser_display_parent_class)->prepare (display)) - return FALSE; - - slave = GDM_XDMCP_CHOOSER_SLAVE (gdm_display_get_slave (display)); - - g_signal_connect (slave, "hostname-selected", + GdmXdmcpDisplay *self = GDM_XDMCP_DISPLAY (display); + GdmLaunchEnvironment *launch_environment; + char *display_name; + char *seat_id; + char *hostname; + + launch_environment = NULL; + display_name = NULL; + seat_id = NULL; + hostname = NULL; + + g_object_get (self, + "x11-display-name", &display_name, + "seat-id", &seat_id, + "remote-hostname", &hostname, + NULL); + + launch_environment = gdm_create_chooser_launch_environment (display_name, + seat_id, + hostname); + g_object_set (self, "launch-environment", launch_environment, NULL); + g_object_unref (launch_environment); + + g_signal_connect (launch_environment, "hostname-selected", G_CALLBACK (on_hostname_selected), display); - return TRUE; + return GDM_DISPLAY_CLASS (gdm_xdmcp_chooser_display_parent_class)->prepare (display); } GdmDisplay * diff --git a/daemon/gdm-xdmcp-chooser-slave.c b/daemon/gdm-xdmcp-chooser-slave.c index df92424d..bec5deb0 100644 --- a/daemon/gdm-xdmcp-chooser-slave.c +++ b/daemon/gdm-xdmcp-chooser-slave.c @@ -62,12 +62,9 @@ struct GdmXdmcpChooserSlavePrivate int ping_interval; guint connection_attempts; - - GdmLaunchEnvironment *chooser_environment; }; enum { - HOSTNAME_SELECTED, LAST_SIGNAL }; @@ -80,293 +77,13 @@ static void gdm_xdmcp_chooser_slave_finalize (GObject G_DEFINE_TYPE (GdmXdmcpChooserSlave, gdm_xdmcp_chooser_slave, GDM_TYPE_SLAVE) static void -on_chooser_session_opened (GdmLaunchEnvironment *chooser, - GdmXdmcpChooserSlave *slave) -{ - char *session_id; - - g_debug ("GdmSimpleSlave: Chooser session opened"); - session_id = gdm_launch_environment_get_session_id (GDM_LAUNCH_ENVIRONMENT (chooser)); - - g_object_set (GDM_SLAVE (slave), "session-id", session_id, NULL); - g_free (session_id); -} - -static void -on_chooser_session_start (GdmLaunchEnvironment *chooser, - GdmXdmcpChooserSlave *slave) -{ - g_debug ("GdmXdmcpChooserSlave: Chooser started"); -} - -static void -on_chooser_session_stop (GdmLaunchEnvironment *chooser, - GdmXdmcpChooserSlave *slave) -{ - g_debug ("GdmXdmcpChooserSlave: Chooser stopped"); - gdm_slave_stop (GDM_SLAVE (slave)); - - g_object_unref (GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser_environment); - GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser_environment = NULL; -} - -static void -on_chooser_session_exited (GdmLaunchEnvironment *chooser, - int code, - GdmXdmcpChooserSlave *slave) -{ - g_debug ("GdmXdmcpChooserSlave: Chooser exited: %d", code); - - g_object_set (GDM_SLAVE (slave), "session-id", NULL, NULL); - - gdm_slave_stop (GDM_SLAVE (slave)); -} - -static void -on_chooser_session_died (GdmLaunchEnvironment *chooser, - int signal, - GdmXdmcpChooserSlave *slave) -{ - g_debug ("GdmXdmcpChooserSlave: Chooser died: %d", signal); - - g_object_set (GDM_SLAVE (slave), "session-id", NULL, NULL); - - gdm_slave_stop (GDM_SLAVE (slave)); -} - -static void -on_chooser_hostname_selected (GdmSession *session, - const char *name, - GdmXdmcpChooserSlave *slave) -{ - g_debug ("GdmXdmcpChooserSlave: connecting to host %s", name); - g_signal_emit (slave, signals [HOSTNAME_SELECTED], 0, name); -} - -static void -on_chooser_disconnected (GdmSession *session, - GdmXdmcpChooserSlave *slave) -{ - g_debug ("GdmXdmcpChooserSlave: Chooser disconnected"); - - /* stop pinging */ - alarm (0); - - gdm_slave_stop (GDM_SLAVE (slave)); -} - -static void -on_chooser_connected (GdmSession *session, - GCredentials *credentials, - GPid pid_of_client, - GdmXdmcpChooserSlave *slave) -{ - g_debug ("GdmXdmcpChooserSlave: Chooser connected"); -} - -static void -setup_server (GdmXdmcpChooserSlave *slave) -{ -} - -static GdmLaunchEnvironment * -create_chooser_session (const char *display_name, - const char *display_hostname) -{ - return g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT, - "command", LIBEXECDIR "/gdm-simple-chooser", - "verification-mode", GDM_SESSION_VERIFICATION_MODE_CHOOSER, - "x11-display-name", display_name, - "x11-display-hostname", display_hostname, - NULL); -} - -static void -run_chooser (GdmXdmcpChooserSlave *slave) -{ - char *display_name; - char *display_hostname; - char *auth_file; - gboolean res; - GdmSession *session; - - g_debug ("GdmXdmcpChooserSlave: Running chooser"); - - display_name = NULL; - auth_file = NULL; - display_hostname = NULL; - - g_object_get (slave, - "display-name", &display_name, - "display-hostname", &display_hostname, - "display-x11-authority-file", &auth_file, - NULL); - - g_debug ("GdmXdmcpChooserSlave: Creating chooser for %s %s", display_name, display_hostname); - - /* FIXME: send a signal back to the master */ - - /* If XDMCP setup pinging */ - slave->priv->ping_interval = DEFAULT_PING_INTERVAL; - res = gdm_settings_direct_get_int (GDM_KEY_PING_INTERVAL, - &(slave->priv->ping_interval)); - - if (res && slave->priv->ping_interval > 0) { - alarm (slave->priv->ping_interval); - } - - /* Run the init script. gdmslave suspends until script has terminated */ - gdm_run_script (GDMCONFDIR "/Init", GDM_USERNAME, - display_name, - display_hostname, - auth_file); - - g_debug ("GdmXdmcpChooserSlave: Creating chooser on %s %s", display_name, display_hostname); - slave->priv->chooser_environment = create_chooser_session (display_name, - display_hostname); - g_signal_connect (slave->priv->chooser_environment, - "opened", - G_CALLBACK (on_chooser_session_opened), - slave); - g_signal_connect (slave->priv->chooser_environment, - "started", - G_CALLBACK (on_chooser_session_start), - slave); - g_signal_connect (slave->priv->chooser_environment, - "stopped", - G_CALLBACK (on_chooser_session_stop), - slave); - g_signal_connect (slave->priv->chooser_environment, - "exited", - G_CALLBACK (on_chooser_session_exited), - slave); - g_signal_connect (slave->priv->chooser_environment, - "died", - G_CALLBACK (on_chooser_session_died), - slave); - g_object_set (slave->priv->chooser_environment, - "x11-authority-file", auth_file, - NULL); - - gdm_launch_environment_start (GDM_LAUNCH_ENVIRONMENT (slave->priv->chooser_environment)); - - session = gdm_launch_environment_get_session (GDM_LAUNCH_ENVIRONMENT (slave->priv->chooser_environment)); - - g_signal_connect (session, - "hostname-selected", - G_CALLBACK (on_chooser_hostname_selected), - slave); - g_signal_connect (session, - "client-disconnected", - G_CALLBACK (on_chooser_disconnected), - slave); - g_signal_connect (session, - "disconnected", - G_CALLBACK (on_chooser_disconnected), - slave); - g_signal_connect (session, - "client-connected", - G_CALLBACK (on_chooser_connected), - slave); - g_free (display_name); - g_free (display_hostname); - g_free (auth_file); -} - -static gboolean -idle_connect_to_display (GdmXdmcpChooserSlave *slave) -{ - gboolean res; - - slave->priv->connection_attempts++; - - res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave)); - if (res) { - /* FIXME: handle wait-for-go */ - - setup_server (slave); - run_chooser (slave); - } else { - if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) { - g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts); - exit (1); - } - return TRUE; - } - - return FALSE; -} - -static gboolean -gdm_xdmcp_chooser_slave_run (GdmXdmcpChooserSlave *slave) -{ - char *display_name; - char *auth_file; - - g_object_get (slave, - "display-name", &display_name, - "display-x11-authority-file", &auth_file, - NULL); - - g_timeout_add (500, (GSourceFunc)idle_connect_to_display, slave); - - g_free (display_name); - g_free (auth_file); - - return TRUE; -} - -static gboolean -gdm_xdmcp_chooser_slave_start (GdmSlave *slave) -{ - GDM_SLAVE_CLASS (gdm_xdmcp_chooser_slave_parent_class)->start (slave); - - gdm_xdmcp_chooser_slave_run (GDM_XDMCP_CHOOSER_SLAVE (slave)); - - return TRUE; -} - -static gboolean -gdm_xdmcp_chooser_slave_stop (GdmSlave *slave) -{ - GdmXdmcpChooserSlave *self = GDM_XDMCP_CHOOSER_SLAVE (slave); - - g_debug ("GdmXdmcpChooserSlave: Stopping xdmcp_chooser_slave"); - - GDM_SLAVE_CLASS (gdm_xdmcp_chooser_slave_parent_class)->stop (slave); - - if (self->priv->chooser_environment != NULL) { - gdm_launch_environment_stop (GDM_LAUNCH_ENVIRONMENT (self->priv->chooser_environment)); - g_object_unref (self->priv->chooser_environment); - self->priv->chooser_environment = NULL; - } - - return TRUE; -} - -static void gdm_xdmcp_chooser_slave_class_init (GdmXdmcpChooserSlaveClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - GdmSlaveClass *slave_class = GDM_SLAVE_CLASS (klass); object_class->finalize = gdm_xdmcp_chooser_slave_finalize; - slave_class->start = gdm_xdmcp_chooser_slave_start; - slave_class->stop = gdm_xdmcp_chooser_slave_stop; - g_type_class_add_private (klass, sizeof (GdmXdmcpChooserSlavePrivate)); - - signals [HOSTNAME_SELECTED] = - g_signal_new ("hostname-selected", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 1, G_TYPE_STRING); } static void diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c index dfd825ae..328ec37b 100644 --- a/daemon/gdm-xdmcp-display-factory.c +++ b/daemon/gdm-xdmcp-display-factory.c @@ -55,6 +55,7 @@ #include "gdm-common.h" #include "gdm-xdmcp-chooser-display.h" #include "gdm-display-factory.h" +#include "gdm-launch-environment.h" #include "gdm-xdmcp-display-factory.h" #include "gdm-display-store.h" #include "gdm-settings-direct.h" @@ -2046,15 +2047,35 @@ on_hostname_selected (GdmXdmcpChooserDisplay *display, } static void +on_client_disconnected (GdmDisplay *display) +{ + if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) + return; + + gdm_display_unmanage (display); + gdm_display_finish (display); +} + +static void on_display_status_changed (GdmDisplay *display, GParamSpec *arg1, GdmXdmcpDisplayFactory *factory) { int status; GdmDisplayStore *store; + GdmLaunchEnvironment *launch_environment; + GdmSession *session; store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + launch_environment = NULL; + g_object_get (display, "launch-environment", &launch_environment, NULL); + + session = NULL; + if (launch_environment != NULL) { + session = gdm_launch_environment_get_session (launch_environment); + } + status = gdm_display_get_status (display); g_debug ("GdmXdmcpDisplayFactory: xdmcp display status changed: %d", status); @@ -2066,10 +2087,25 @@ on_display_status_changed (GdmDisplay *display, gdm_display_store_remove (store, display); break; case GDM_DISPLAY_UNMANAGED: + if (session != NULL) { + g_signal_handlers_disconnect_by_func (G_OBJECT (session), + G_CALLBACK (on_client_disconnected), + display); + } break; case GDM_DISPLAY_PREPARED: break; case GDM_DISPLAY_MANAGED: + if (session != NULL) { + g_signal_connect_object (G_OBJECT (session), + "client-disconnected", + G_CALLBACK (on_client_disconnected), + display, 0); + g_signal_connect_object (G_OBJECT (session), + "disconnected", + G_CALLBACK (on_client_disconnected), + display, 0); + } break; default: g_assert_not_reached (); diff --git a/daemon/gdm-xdmcp-display.c b/daemon/gdm-xdmcp-display.c index e09a2fdf..27f7ee5e 100644 --- a/daemon/gdm-xdmcp-display.c +++ b/daemon/gdm-xdmcp-display.c @@ -36,6 +36,7 @@ #include <glib-object.h> #include "gdm-display.h" +#include "gdm-launch-environment.h" #include "gdm-xdmcp-display.h" #include "gdm-common.h" @@ -140,14 +141,50 @@ gdm_xdmcp_display_get_property (GObject *object, } } +static gboolean +gdm_xdmcp_display_prepare (GdmDisplay *display) +{ + GdmXdmcpDisplay *self = GDM_XDMCP_DISPLAY (display); + GdmLaunchEnvironment *launch_environment; + char *display_name; + char *seat_id; + char *hostname; + + launch_environment = NULL; + display_name = NULL; + seat_id = NULL; + hostname = NULL; + + g_object_get (self, + "x11-display-name", &display_name, + "seat-id", &seat_id, + "remote-hostname", &hostname, + "launch-environment", &launch_environment, + NULL); + + if (launch_environment == NULL) { + launch_environment = gdm_create_greeter_launch_environment (display_name, + seat_id, + hostname, + FALSE); + g_object_set (self, "launch-environment", launch_environment, NULL); + g_object_unref (launch_environment); + } + + return GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->prepare (display); +} + static void gdm_xdmcp_display_class_init (GdmXdmcpDisplayClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdmDisplayClass *display_class = GDM_DISPLAY_CLASS (klass); object_class->get_property = gdm_xdmcp_display_get_property; object_class->set_property = gdm_xdmcp_display_set_property; + display_class->prepare = gdm_xdmcp_display_prepare; + g_type_class_add_private (klass, sizeof (GdmXdmcpDisplayPrivate)); g_object_class_install_property (object_class, |