[gdm/wip/slave-connection: 21/34] daemon: Fix added/remove signal emission in display code



commit a995382f32181a27bf15f123af620ab25eef3b8f
Author: Ray Strode <rstrode redhat com>
Date:   Sat Jul 7 16:10:56 2012 -0400

    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-local-display-factory.c |    1 +
 daemon/gdm-manager.c               |   45 ++++++++++++
 4 files changed, 161 insertions(+), 21 deletions(-)
---
diff --git a/daemon/gdm-display-store.c b/daemon/gdm-display-store.c
index 62d7e93..4abe701 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
@@ -192,13 +289,6 @@ gdm_display_store_class_init (GdmDisplayStoreClass *klass)
 }
 
 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 dcd8814..ccebd3f 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-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 6360287..be5620c 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -183,6 +183,7 @@ store_display (GdmLocalDisplayFactory *factory,
         g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory);
 
         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+
         gdm_display_store_add (store, display);
 
         /* now fill our reserved spot */
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 65f1318..322fc17 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -90,6 +90,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)
 {
@@ -426,6 +454,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
@@ -447,6 +485,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);



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