From 4e392e230d0ea8531c1ea387fca2a6273568efdb Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sat, 7 Jul 2012 16:10:56 -0400 Subject: daemon: Fix added/remove signal emission in display code The display store is a small container object meant to track currently known about displays. It has two signals, "display-added" and "display-removed" that are supposed to get emitted any time a display gets added or removed from the store. Likewise, the GdmManager object has two similar signals that are supposed to be emitted under similar circumstances. These signals in GdmDisplayStore and GdmManager were never actually hooked up to fire at the appropriate times. This commit changes GdmDisplayStore and GdmManager to properly fire these signals. --- daemon/gdm-display-store.c | 133 ++++++++++++++++++++++++++++++++++++++------- daemon/gdm-display-store.h | 3 + daemon/gdm-manager.c | 45 +++++++++++++++ 3 files changed, 160 insertions(+), 21 deletions(-) (limited to 'daemon') diff --git a/daemon/gdm-display-store.c b/daemon/gdm-display-store.c index 62d7e93f..4abe7018 100644 --- a/daemon/gdm-display-store.c +++ b/daemon/gdm-display-store.c @@ -40,6 +40,12 @@ struct GdmDisplayStorePrivate GHashTable *displays; }; +typedef struct +{ + GdmDisplayStore *store; + GdmDisplay *display; +} StoredDisplay; + enum { DISPLAY_ADDED, DISPLAY_REMOVED, @@ -54,6 +60,39 @@ static void gdm_display_store_finalize (GObject *object); G_DEFINE_TYPE (GdmDisplayStore, gdm_display_store, G_TYPE_OBJECT) +static StoredDisplay * +stored_display_new (GdmDisplayStore *store, + GdmDisplay *display) +{ + StoredDisplay *stored_display; + + stored_display = g_slice_new (StoredDisplay); + stored_display->store = store; + stored_display->display = g_object_ref (display); + + return stored_display; +} + +static void +stored_display_free (StoredDisplay *stored_display) +{ + char *id; + + gdm_display_get_id (stored_display->display, &id, NULL); + + g_signal_emit (G_OBJECT (stored_display->store), + signals[DISPLAY_REMOVED], + 0, + id); + g_free (id); + + g_debug ("GdmDisplayStore: Unreffing display: %p", + stored_display->display); + g_object_unref (stored_display->display); + + g_slice_free (StoredDisplay, stored_display); +} + GQuark gdm_display_store_error_quark (void) { @@ -96,17 +135,56 @@ gdm_display_store_remove (GdmDisplayStore *store, return FALSE; } +typedef struct +{ + GdmDisplayStoreFunc predicate; + gpointer user_data; +} FindClosure; + +static gboolean +find_func (const char *id, + StoredDisplay *stored_display, + FindClosure *closure) +{ + return closure->predicate (id, + stored_display->display, + closure->user_data); +} + void gdm_display_store_foreach (GdmDisplayStore *store, GdmDisplayStoreFunc func, gpointer user_data) { + FindClosure closure; + g_return_if_fail (store != NULL); g_return_if_fail (func != NULL); + closure.predicate = func; + closure.user_data = user_data; + g_hash_table_find (store->priv->displays, - (GHRFunc)func, - user_data); + (GHRFunc) find_func, + &closure); +} + +GdmDisplay * +gdm_display_store_lookup (GdmDisplayStore *store, + const char *id) +{ + StoredDisplay *stored_display; + + g_return_val_if_fail (store != NULL, NULL); + g_return_val_if_fail (id != NULL, NULL); + + stored_display = g_hash_table_lookup (store->priv->displays, + id); + if (stored_display == NULL) { + return NULL; + } + + return stored_display->display; } GdmDisplay * @@ -114,15 +192,24 @@ gdm_display_store_find (GdmDisplayStore *store, GdmDisplayStoreFunc predicate, gpointer user_data) { - GdmDisplay *display; + StoredDisplay *stored_display; + FindClosure closure; g_return_val_if_fail (store != NULL, NULL); g_return_val_if_fail (predicate != NULL, NULL); - display = g_hash_table_find (store->priv->displays, - (GHRFunc)predicate, - user_data); - return display; + closure.predicate = predicate; + closure.user_data = user_data; + + stored_display = g_hash_table_find (store->priv->displays, + (GHRFunc) find_func, + &closure); + + if (stored_display == NULL) { + return NULL; + } + + return stored_display->display; } guint @@ -130,15 +217,18 @@ gdm_display_store_foreach_remove (GdmDisplayStore *store, GdmDisplayStoreFunc func, gpointer user_data) { - guint ret; + FindClosure closure; + guint ret; g_return_val_if_fail (store != NULL, 0); g_return_val_if_fail (func != NULL, 0); - ret = g_hash_table_foreach_remove (store->priv->displays, - (GHRFunc)func, - user_data); + closure.predicate = func; + closure.user_data = user_data; + ret = g_hash_table_foreach_remove (store->priv->displays, + (GHRFunc) find_func, + &closure); return ret; } @@ -146,7 +236,8 @@ void gdm_display_store_add (GdmDisplayStore *store, GdmDisplay *display) { - char *id; + char *id; + StoredDisplay *stored_display; g_return_if_fail (store != NULL); g_return_if_fail (display != NULL); @@ -155,9 +246,15 @@ gdm_display_store_add (GdmDisplayStore *store, g_debug ("GdmDisplayStore: Adding display %s to store", id); + stored_display = stored_display_new (store, display); g_hash_table_insert (store->priv->displays, id, - g_object_ref (display)); + stored_display); + + g_signal_emit (G_OBJECT (store), + signals[DISPLAY_ADDED], + 0, + id); } static void @@ -191,13 +288,6 @@ gdm_display_store_class_init (GdmDisplayStoreClass *klass) g_type_class_add_private (klass, sizeof (GdmDisplayStorePrivate)); } -static void -display_unref (GdmDisplay *display) -{ - g_debug ("GdmDisplayStore: Unreffing display: %p", display); - g_object_unref (display); -} - static void gdm_display_store_init (GdmDisplayStore *store) { @@ -207,7 +297,8 @@ gdm_display_store_init (GdmDisplayStore *store) store->priv->displays = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, - (GDestroyNotify) display_unref); + (GDestroyNotify) + stored_display_free); } static void diff --git a/daemon/gdm-display-store.h b/daemon/gdm-display-store.h index dcd88149..ccebd3f1 100644 --- a/daemon/gdm-display-store.h +++ b/daemon/gdm-display-store.h @@ -79,6 +79,9 @@ void gdm_display_store_foreach (GdmDisplayStore guint gdm_display_store_foreach_remove (GdmDisplayStore *store, GdmDisplayStoreFunc func, gpointer user_data); +GdmDisplay * gdm_display_store_lookup (GdmDisplayStore *store, + const char *id); + GdmDisplay * gdm_display_store_find (GdmDisplayStore *store, GdmDisplayStoreFunc predicate, gpointer user_data); diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c index 59495e49..6cc38e47 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -89,6 +89,34 @@ static gpointer manager_object = NULL; G_DEFINE_TYPE (GdmManager, gdm_manager, G_TYPE_OBJECT) +static void +on_display_removed (GdmDisplayStore *display_store, + const char *id, + GdmManager *manager) +{ + GdmDisplay *display; + + display = gdm_display_store_lookup (display_store, id); + + if (display != NULL) { + g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, id); + } +} + +static void +on_display_added (GdmDisplayStore *display_store, + const char *id, + GdmManager *manager) +{ + GdmDisplay *display; + + display = gdm_display_store_lookup (display_store, id); + + if (display != NULL) { + g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id); + } +} + GQuark gdm_manager_error_quark (void) { @@ -358,6 +386,16 @@ gdm_manager_init (GdmManager *manager) manager->priv = GDM_MANAGER_GET_PRIVATE (manager); manager->priv->display_store = gdm_display_store_new (); + + g_signal_connect (G_OBJECT (manager->priv->display_store), + "display-added", + G_CALLBACK (on_display_added), + manager); + + g_signal_connect (G_OBJECT (manager->priv->display_store), + "display-removed", + G_CALLBACK (on_display_removed), + manager); } static void @@ -379,6 +417,13 @@ gdm_manager_finalize (GObject *object) g_clear_object (&manager->priv->connection); gdm_display_store_clear (manager->priv->display_store); + + g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), + G_CALLBACK (on_display_added), + manager); + g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), + G_CALLBACK (on_display_removed), + manager); g_object_unref (manager->priv->display_store); G_OBJECT_CLASS (gdm_manager_parent_class)->finalize (object); -- cgit v1.2.1