commit 2e36b2c15552a98485efa63cc4534c3308fff35b Author: mccann Date: Wed Dec 3 01:49:35 2008 +0000 2008-12-02 William Jon McCann * daemon/gdm-display.c (gdm_display_real_prepare), (gdm_display_prepare), (gdm_display_real_manage), (gdm_display_class_init): * daemon/gdm-display.h: * daemon/gdm-local-display-factory.c (on_static_display_status_changed): * daemon/gdm-manager.c (gdm_manager_stop), (gdm_manager_start), (gdm_manager_set_xdmcp_enabled): * daemon/gdm-manager.h: * daemon/gdm-xdmcp-display-factory.c (gdm_xdmcp_display_create), (gdm_xdmcp_handle_manage): Correctly handle changes in the xdmcp enabled property. Add a display state called prepared that sets up the display before actually managing (starting) it. This is required for the XDMCP Request phase to work. Fixes #561396 git-svn-id: svn+ssh://svn.gnome.org/svn/gdm/trunk@6610 267140dd-db25-0410-8347-d580a0480a36 diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c index d1c0580..1bca58d 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c @@ -542,7 +542,7 @@ _gdm_display_set_status (GdmDisplay *display, } static gboolean -gdm_display_real_manage (GdmDisplay *display) +gdm_display_real_prepare (GdmDisplay *display) { char *command; char *log_file; @@ -550,7 +550,7 @@ gdm_display_real_manage (GdmDisplay *display) g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); - g_debug ("GdmDisplay: manage display"); + g_debug ("GdmDisplay: prepare display"); g_assert (display->priv->slave_proxy == NULL); @@ -560,7 +560,7 @@ gdm_display_real_manage (GdmDisplay *display) return FALSE; } - _gdm_display_set_status (display, GDM_DISPLAY_MANAGED); + _gdm_display_set_status (display, GDM_DISPLAY_PREPARED); display->priv->slave_proxy = gdm_slave_proxy_new (); g_signal_connect (display->priv->slave_proxy, @@ -584,6 +584,48 @@ gdm_display_real_manage (GdmDisplay *display) gdm_slave_proxy_set_command (display->priv->slave_proxy, command); g_free (command); + return TRUE; +} + +gboolean +gdm_display_prepare (GdmDisplay *display) +{ + gboolean ret; + + g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); + + g_debug ("GdmDisplay: Preparing display: %s", display->priv->id); + + g_object_ref (display); + ret = GDM_DISPLAY_GET_CLASS (display)->prepare (display); + g_object_unref (display); + + return ret; +} + + +static gboolean +gdm_display_real_manage (GdmDisplay *display) +{ + char *command; + char *log_file; + char *log_path; + gboolean res; + + g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); + + g_debug ("GdmDisplay: manage display"); + + /* If not explicitly prepared, do it now */ + if (display->priv->status == GDM_DISPLAY_UNMANAGED) { + res = gdm_display_prepare (display); + if (! res) { + return FALSE; + } + } + + g_assert (display->priv->slave_proxy != NULL); + g_timer_start (display->priv->slave_timer); gdm_slave_proxy_start (display->priv->slave_proxy); @@ -985,6 +1027,7 @@ gdm_display_class_init (GdmDisplayClass *klass) klass->remove_user_authorization = gdm_display_real_remove_user_authorization; klass->set_slave_bus_name = gdm_display_real_set_slave_bus_name; klass->get_timed_login_details = gdm_display_real_get_timed_login_details; + klass->prepare = gdm_display_real_prepare; klass->manage = gdm_display_real_manage; klass->finish = gdm_display_real_finish; klass->unmanage = gdm_display_real_unmanage; diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h index 7e64012..2914c81 100644 --- a/daemon/gdm-display.h +++ b/daemon/gdm-display.h @@ -38,6 +38,7 @@ typedef struct GdmDisplayPrivate GdmDisplayPrivate; typedef enum { GDM_DISPLAY_UNMANAGED = 0, + GDM_DISPLAY_PREPARED, GDM_DISPLAY_MANAGED, GDM_DISPLAY_FINISHED, GDM_DISPLAY_FAILED, @@ -65,6 +66,7 @@ typedef struct gboolean (*set_slave_bus_name) (GdmDisplay *display, const char *name, GError **error); + gboolean (*prepare) (GdmDisplay *display); gboolean (*manage) (GdmDisplay *display); gboolean (*finish) (GdmDisplay *display); gboolean (*unmanage) (GdmDisplay *display); @@ -90,6 +92,7 @@ time_t gdm_display_get_creation_time (GdmDisplay *disp char * gdm_display_get_user_auth (GdmDisplay *display); gboolean gdm_display_create_authority (GdmDisplay *display); +gboolean gdm_display_prepare (GdmDisplay *display); gboolean gdm_display_manage (GdmDisplay *display); gboolean gdm_display_finish (GdmDisplay *display); gboolean gdm_display_unmanage (GdmDisplay *display); diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c index 72a2f4a..3984ada 100644 --- a/daemon/gdm-local-display-factory.c +++ b/daemon/gdm-local-display-factory.c @@ -324,6 +324,8 @@ on_static_display_status_changed (GdmDisplay *display, break; case GDM_DISPLAY_UNMANAGED: break; + case GDM_DISPLAY_PREPARED: + break; case GDM_DISPLAY_MANAGED: break; default: diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c index d87e82e..4def8b6 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -61,6 +61,7 @@ struct GdmManagerPrivate #endif gboolean xdmcp_enabled; + gboolean started; gboolean wait_for_go; gboolean no_console; @@ -138,9 +139,27 @@ gdm_manager_get_displays (GdmManager *manager, } void +gdm_manager_stop (GdmManager *manager) +{ + g_debug ("GdmManager: GDM stopping"); + + if (manager->priv->local_factory != NULL) { + gdm_display_factory_stop (GDM_DISPLAY_FACTORY (manager->priv->local_factory)); + } + +#ifdef HAVE_LIBXDMCP + if (manager->priv->xdmcp_factory != NULL) { + gdm_display_factory_stop (GDM_DISPLAY_FACTORY (manager->priv->xdmcp_factory)); + } +#endif + + manager->priv->started = FALSE; +} + +void gdm_manager_start (GdmManager *manager) { - g_debug ("GdmManager: GDM starting to manage"); + g_debug ("GdmManager: GDM starting to manage displays"); if (! manager->priv->wait_for_go) { gdm_display_factory_start (GDM_DISPLAY_FACTORY (manager->priv->local_factory)); @@ -155,6 +174,8 @@ gdm_manager_start (GdmManager *manager) } } #endif + + manager->priv->started = TRUE; } void @@ -271,7 +292,24 @@ gdm_manager_set_xdmcp_enabled (GdmManager *manager, { g_return_if_fail (GDM_IS_MANAGER (manager)); - manager->priv->xdmcp_enabled = enabled; + if (manager->priv->xdmcp_enabled != enabled) { + manager->priv->xdmcp_enabled = enabled; + + if (manager->priv->xdmcp_enabled) { + manager->priv->xdmcp_factory = gdm_xdmcp_display_factory_new (manager->priv->display_store); + if (manager->priv->started) { + gdm_display_factory_start (GDM_DISPLAY_FACTORY (manager->priv->xdmcp_factory)); + } + } else { + if (manager->priv->started) { + gdm_display_factory_stop (GDM_DISPLAY_FACTORY (manager->priv->xdmcp_factory)); + } + + g_object_unref (manager->priv->xdmcp_factory); + manager->priv->xdmcp_factory = NULL; + } + } + } static void diff --git a/daemon/gdm-manager.h b/daemon/gdm-manager.h index 0b2a04e..c479d93 100644 --- a/daemon/gdm-manager.h +++ b/daemon/gdm-manager.h @@ -63,6 +63,7 @@ GType gdm_manager_get_type (void); GdmManager * gdm_manager_new (void); void gdm_manager_start (GdmManager *manager); +void gdm_manager_stop (GdmManager *manager); void gdm_manager_set_wait_for_go (GdmManager *manager, gboolean wait_for_go); diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c index 57695a1..58cdf59 100644 --- a/daemon/gdm-xdmcp-display-factory.c +++ b/daemon/gdm-xdmcp-display-factory.c @@ -2041,6 +2041,13 @@ gdm_xdmcp_display_create (GdmXdmcpDisplayFactory *factory, goto out; } + if (! gdm_display_prepare (display)) { + gdm_display_unmanage (display); + g_object_unref (display); + display = NULL; + goto out; + } + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); gdm_display_store_add (store, display); @@ -2507,7 +2514,7 @@ gdm_xdmcp_handle_manage (GdmXdmcpDisplayFactory *factory, display = gdm_xdmcp_display_lookup (factory, clnt_sessid); if (display != NULL && - gdm_display_get_status (display) == GDM_DISPLAY_UNMANAGED) { + gdm_display_get_status (display) == GDM_DISPLAY_PREPARED) { char *name; name = NULL;