[gdm/wip/slave-connection: 21/33] daemon: Fix added/remove signal emission in display code
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdm/wip/slave-connection: 21/33] daemon: Fix added/remove signal emission in display code
- Date: Wed, 11 Jul 2012 07:07:12 +0000 (UTC)
commit ddde2202cdb3f07ad98397aa9ac888fd4bc74c2e
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 | 120 ++++++++++++++++++++++++++++++------
daemon/gdm-display-store.h | 3 +
daemon/gdm-local-display-factory.c | 1 +
daemon/gdm-manager.c | 45 +++++++++++++
4 files changed, 150 insertions(+), 19 deletions(-)
---
diff --git a/daemon/gdm-display-store.c b/daemon/gdm-display-store.c
index 62d7e93..364dcc8 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,52 @@ 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);
+ return stored_display->display;
}
GdmDisplay *
@@ -114,14 +188,18 @@ gdm_display_store_find (GdmDisplayStore *store,
GdmDisplayStoreFunc predicate,
gpointer user_data)
{
- GdmDisplay *display;
+ GdmDisplay *display;
+ FindClosure closure;
g_return_val_if_fail (store != NULL, NULL);
g_return_val_if_fail (predicate != NULL, NULL);
+ closure.predicate = predicate;
+ closure.user_data = user_data;
+
display = g_hash_table_find (store->priv->displays,
- (GHRFunc)predicate,
- user_data);
+ (GHRFunc) find_func,
+ &closure);
return display;
}
@@ -130,15 +208,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 +227,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 +237,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 +280,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 +288,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]