[gdm/display-configuration: 11/20] Rework SessionToAdd/Remove in factory
- From: Ray Strode <halfline src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gdm/display-configuration: 11/20] Rework SessionToAdd/Remove in factory
- Date: Tue, 4 Aug 2009 18:32:05 +0000 (UTC)
commit 0eb4e739f38f8e3351aed556ef27e2f6debc1799
Author: Ray Strode <rstrode redhat com>
Date: Tue Jun 23 23:14:26 2009 -0400
Rework SessionToAdd/Remove in factory
Now we:
- keep a map of sessions to displays, so we can easily access which
display a session is associated with.
- If a display is blocked we now queue add requests dealing with it until
it is unblocked.
- Only create dynamic displays. Creating static displays dynamically
based on events from ConsoleKit doesn't really make much sense.
daemon/gdm-local-display-factory.c | 272 ++++++++++++++++++++++++++----------
1 files changed, 197 insertions(+), 75 deletions(-)
---
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 8ebc966..6807103 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -72,6 +72,7 @@ struct GdmLocalDisplayFactoryPrivate
DBusGProxy *proxy_hal;
DBusGProxy *proxy_ck;
GHashTable *displays;
+ GHashTable *displays_by_session;
GSList *lst_proxy;
/* FIXME: this needs to be per seat? */
@@ -90,6 +91,9 @@ static gboolean create_static_displays (GdmLocalDisplayFactory
static void on_display_status_changed (GdmDisplay *display,
GParamSpec *arg1,
GdmLocalDisplayFactory *factory);
+static void on_block_console_session_requests_changed (GdmDisplay *display,
+ GParamSpec *arg1,
+ GdmLocalDisplayFactory *factory);
static gpointer local_display_factory_object = NULL;
@@ -217,47 +221,6 @@ store_remove_display (GdmLocalDisplayFactory *factory,
g_hash_table_remove (factory->priv->displays, GUINT_TO_POINTER (num));
}
-static gboolean
-lookup_by_display_number (const char *id,
- GdmDisplay *display,
- gpointer data)
-{
- gint32 number;
- gint32 display_number = -1;
-
- number = GPOINTER_TO_INT (data);
-
- if (! GDM_IS_DISPLAY (display)) {
- return FALSE;
- }
-
- gdm_display_get_x11_display_number (display, &display_number, NULL);
-
- if (display_number == number) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-static GdmDisplay *
-gdm_local_display_lookup_by_number (GdmLocalDisplayFactory *factory,
- gint32 number)
-{
- GdmDisplay *display;
- GdmDisplayStore *store;
-
- if (number < 0)
- return NULL;
-
- store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
- display = gdm_display_store_find (store,
- (GdmDisplayStoreFunc)lookup_by_display_number,
- GINT_TO_POINTER (number));
-
- return display;
-}
-
/*
Example:
dbus-send --system --dest=org.gnome.DisplayManager \
@@ -354,6 +317,102 @@ gdm_local_display_factory_create_product_display (GdmLocalDisplayFactory *factor
return ret;
}
+static gboolean
+display_has_pending_sessions (GdmLocalDisplayFactory *factory,
+ GdmDisplay *display)
+{
+ return g_object_get_data (G_OBJECT (display),
+ "gdm-local-display-factory-console-session-requests") != NULL;
+}
+
+static void
+manage_next_pending_session_on_display (GdmLocalDisplayFactory *factory,
+ GdmDisplay *display)
+{
+ GList *pending_sessions;
+ GList *next_session;
+ char *ssid;
+
+
+ pending_sessions = g_object_get_data (G_OBJECT (display),
+ "gdm-local-display-factory-console-session-requests");
+ next_session = g_list_last (pending_sessions);
+
+ if (next_session == NULL) {
+ return;
+ }
+
+ ssid = next_session->data;
+ pending_sessions = g_list_delete_link (pending_sessions, next_session);
+ g_object_set_data (G_OBJECT (display),
+ "gdm-local-display-factory-console-session-requests",
+ pending_sessions);
+
+ g_object_set (display, "session-id", ssid, NULL);
+ g_hash_table_insert (factory->priv->displays_by_session, g_strdup (ssid), g_object_ref (display));
+ g_free (ssid);
+
+ gdm_display_manage (display);
+}
+
+static void
+discard_pending_session_on_display (GdmLocalDisplayFactory *factory,
+ GdmDisplay *display,
+ const char *ssid)
+{
+ GList *pending_sessions;
+ GList *node;
+
+ pending_sessions = g_object_get_data (G_OBJECT (display),
+ "gdm-local-display-factory-console-session-requests");
+ node = g_list_last (pending_sessions);
+
+ while (node != NULL) {
+ GList *prev_node;
+ char *node_ssid;
+
+ prev_node = node->prev;
+ node_ssid = node->data;
+
+ if (strcmp (node_ssid, ssid) == 0) {
+ pending_sessions = g_list_delete_link (pending_sessions, node);
+ break;
+ }
+
+ node = prev_node;
+ }
+
+ g_object_set_data (G_OBJECT (display),
+ "gdm-local-display-factory-console-session-requests",
+ pending_sessions);
+}
+
+static void
+on_block_console_session_requests_changed (GdmDisplay *display,
+ GParamSpec *arg1,
+ GdmLocalDisplayFactory *factory)
+{
+ gboolean display_is_blocked;
+ int status;
+
+ g_object_get (G_OBJECT (display),
+ "status", &status,
+ "block-console-session-requests",
+ &display_is_blocked, NULL);
+
+ if (display_is_blocked) {
+ int number;
+
+ gdm_display_get_x11_display_number (display, &number, NULL);
+ g_debug ("GdmLocalDisplayFactory: display :%d is blocked", number);
+ return;
+ }
+
+ if (status == GDM_DISPLAY_UNMANAGED) {
+ manage_next_pending_session_on_display (factory, display);
+ }
+}
+
static void
on_display_status_changed (GdmDisplay *display,
GParamSpec *arg1,
@@ -362,6 +421,7 @@ on_display_status_changed (GdmDisplay *display,
int status;
GdmDisplayStore *store;
int num;
+ gboolean display_is_blocked;
num = -1;
gdm_display_get_x11_display_number (display, &num, NULL);
@@ -371,6 +431,10 @@ on_display_status_changed (GdmDisplay *display,
status = gdm_display_get_status (display);
+ g_object_get (G_OBJECT (display),
+ "block-console-session-requests",
+ &display_is_blocked, NULL);
+
g_debug ("GdmLocalDisplayFactory: static display status changed: %d", status);
switch (status) {
case GDM_DISPLAY_FINISHED:
@@ -393,6 +457,10 @@ on_display_status_changed (GdmDisplay *display,
}
break;
case GDM_DISPLAY_UNMANAGED:
+ if (display_has_pending_sessions (factory, display) && !display_is_blocked) {
+ store_display (factory, num, display);
+ manage_next_pending_session_on_display (factory, display);
+ }
break;
case GDM_DISPLAY_PREPARED:
break;
@@ -457,11 +525,22 @@ seat_session_to_add (DBusGProxy *seat_proxy,
gboolean is_chooser;
gboolean use_auth;
int i;
- gboolean res;
char *xserver_command;
+ gboolean display_is_blocked;
+ GList *pending_sessions;
g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory));
+ display_is_blocked = FALSE;
+
+ display = g_hash_table_lookup (factory->priv->displays_by_session, ssid);
+
+ if (display != NULL) {
+ g_object_get (G_OBJECT (display),
+ "block-console-session-requests",
+ &display_is_blocked, NULL);
+ }
+
if (strcmp (display_type, "X11") != 0) {
g_warning ("Unknown display type '%s' requested", display_type);
return;
@@ -504,69 +583,108 @@ seat_session_to_add (DBusGProxy *seat_proxy,
strrep (comm, &comm, "-auth $auth", "");
}
- if (is_chooser) {
- /* TODO: Start a xdmcp chooser as request */
+ if (display == NULL) {
+ if (is_chooser) {
+ /* TODO: Start a xdmcp chooser as request */
- /* display = gdm_xdmcp_chooser_display_new (display_number); */
- } else {
- if (is_dynamic)
+ /* display = gdm_xdmcp_chooser_display_new (display_number); */
+ } else {
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);
+ if (display == NULL) {
+ g_warning ("Unable to create display: %d", display_number);
+ g_free (comm);
+ return;
+ }
+
+ g_object_set (display, "session-id", ssid, NULL);
+ g_hash_table_insert (factory->priv->displays_by_session, g_strdup (ssid), g_object_ref (display));
+
+ 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);
- return;
- }
+ g_object_set (display, "use-auth", use_auth, NULL);
- g_object_set (display, "session-id", ssid, NULL);
+ g_signal_connect (display,
+ "notify::status",
+ G_CALLBACK (on_display_status_changed),
+ factory);
- 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);
+ g_signal_connect (display,
+ "notify::block-console-session-requests",
+ G_CALLBACK (on_block_console_session_requests_changed),
+ factory);
- store_display (factory, display_number, display);
+ store_display (factory, display_number, display);
- g_object_unref (display);
+ g_object_unref (display);
- if (! gdm_display_manage (display)) {
- gdm_display_unmanage (display);
+ if (! gdm_display_manage (display)) {
+ gdm_display_unmanage (display);
+ }
+
+ return;
+ }
+
+ /* FIXME: Make sure the display returned is compatible
+ */
+
+ if (!display_is_blocked) {
+ /* FIXME: What do we do here?
+ */
+ g_warning ("Got console request to add display for session that "
+ "already has a display, and display is already in "
+ "use");
+ return;
}
+
+ pending_sessions = g_object_get_data (G_OBJECT (display),
+ "gdm-local-display-factory-console-session-requests");
+ pending_sessions = g_list_prepend (pending_sessions, g_strdup (ssid));
+
+ g_object_set_data (G_OBJECT (display),
+ "gdm-local-display-factory-console-session-requests",
+ pending_sessions);
}
static void
seat_session_to_remove (DBusGProxy *seat_proxy,
- int display_number,
+ const char *ssid,
GdmLocalDisplayFactory *factory)
{
GdmDisplay *display;
+ int display_number;
+ char *display_ssid;
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");
+ display = g_hash_table_lookup (factory->priv->displays_by_session, ssid);
+
+ if (display == NULL) {
+ g_debug ("GdmLocalDisplayFactory: display for session '%s' doesn't exists", ssid);
return;
}
- g_debug ("GdmLocalDisplayFactory: Removing dynamic display %d", display_number);
+ g_object_get (G_OBJECT (display), "session-id", &display_ssid, NULL);
- display = gdm_local_display_lookup_by_number (factory, display_number);
+ if (display_ssid == NULL || strcmp (ssid, display_ssid) != 0) {
+ g_free (display_ssid);
+ discard_pending_session_on_display (factory, display, ssid);
+ return;
+ }
+ g_free (display_ssid);
+ g_hash_table_remove (factory->priv->displays_by_session, ssid);
if (! gdm_display_unmanage (display)) {
display = NULL;
return;
}
+ gdm_display_get_x11_display_number (display, &display_number, NULL);
store_remove_display (factory, display_number, display);
}
@@ -932,6 +1050,9 @@ gdm_local_display_factory_init (GdmLocalDisplayFactory *factory)
factory->priv = GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE (factory);
factory->priv->displays = g_hash_table_new (NULL, NULL);
+ factory->priv->displays_by_session = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
}
static void
@@ -947,6 +1068,7 @@ gdm_local_display_factory_finalize (GObject *object)
g_return_if_fail (factory->priv != NULL);
g_hash_table_destroy (factory->priv->displays);
+ g_hash_table_destroy (factory->priv->displays_by_session);
g_slist_foreach (factory->priv->lst_proxy, g_object_unref, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]