diff options
author | Dan Winship <danw@gnome.org> | 2012-01-20 07:52:17 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2012-02-03 10:33:43 -0600 |
commit | 2e48cc092c133ed3e10efcc00cf36b29c9d3efc8 (patch) | |
tree | 4cc6f765d30b63a9eff0d171bc6083c114b906f0 /libnm-glib/nm-object.c | |
parent | 38382770aa36b2690fbb366a649f91e38f449e7c (diff) | |
download | NetworkManager-2e48cc092c133ed3e10efcc00cf36b29c9d3efc8.tar.gz |
libnm-glib: simplify and genericize property declaration
Rename _nm_object_handle_properties_changed(), etc, to be about
properties in general, rather than just property changes.
Interpret func==NULL in NMPropertiesInfo as meaning "use
_nm_object_demarshal_generic", and then reorder the fields so that you
can just leave that field out in the declarations when it's NULL.
Add a way to register properties that exist in D-Bus but aren't
tracked by the NMObjects, and use that for NMDevice's D-Bus Ip4Address
property, replacing the existing hack.
Also add a few other missing properties noticed along the way.
Diffstat (limited to 'libnm-glib/nm-object.c')
-rw-r--r-- | libnm-glib/nm-object.c | 159 |
1 files changed, 85 insertions, 74 deletions
diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c index 9a8a60f759..e60665041c 100644 --- a/libnm-glib/nm-object.c +++ b/libnm-glib/nm-object.c @@ -22,6 +22,7 @@ */ #include <string.h> +#include <gio/gio.h> #include <nm-utils.h> #include "NetworkManager.h" #include "nm-object.h" @@ -37,15 +38,16 @@ G_DEFINE_ABSTRACT_TYPE (NMObject, nm_object, G_TYPE_OBJECT) #define NM_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_OBJECT, NMObjectPrivate)) typedef struct { - PropChangedMarshalFunc func; + PropertyMarshalFunc func; gpointer field; -} PropChangedInfo; +} PropertyInfo; typedef struct { DBusGConnection *connection; char *path; DBusGProxy *properties_proxy; - GSList *pcs; + GSList *property_interfaces; + GSList *property_tables; NMObject *parent; GSList *notify_props; @@ -118,6 +120,9 @@ dispose (GObject *object) g_slist_foreach (priv->notify_props, (GFunc) g_free, NULL); g_slist_free (priv->notify_props); + g_slist_foreach (priv->property_interfaces, (GFunc) g_free, NULL); + g_slist_free (priv->property_interfaces); + g_object_unref (priv->properties_proxy); dbus_g_connection_unref (priv->connection); @@ -129,8 +134,8 @@ finalize (GObject *object) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - g_slist_foreach (priv->pcs, (GFunc) g_hash_table_destroy, NULL); - g_slist_free (priv->pcs); + g_slist_foreach (priv->property_tables, (GFunc) g_hash_table_destroy, NULL); + g_slist_free (priv->property_tables); g_free (priv->path); G_OBJECT_CLASS (nm_object_parent_class)->finalize (object); @@ -334,37 +339,25 @@ handle_property_changed (gpointer key, gpointer data, gpointer user_data) NMObject *self = NM_OBJECT (user_data); NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); char *prop_name; - PropChangedInfo *pci; + PropertyInfo *pi; GParamSpec *pspec; gboolean success = FALSE, found = FALSE; GSList *iter; GValue *value = data; prop_name = wincaps_to_dash ((char *) key); - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (self)), prop_name); - if (!pspec) { - g_warning ("%s: property '%s' changed but wasn't defined by object type %s.", - __func__, - prop_name, - G_OBJECT_TYPE_NAME (self)); - goto out; - } /* Iterate through the object and its parents to find the property */ - for (iter = priv->pcs; iter; iter = g_slist_next (iter)) { - pci = g_hash_table_lookup ((GHashTable *) iter->data, prop_name); - if (pci) { - found = TRUE; - - /* Handle NULL object paths */ - if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) { - if (g_strcmp0 (g_value_get_boxed (value), "/") == 0) - value = NULL; + for (iter = priv->property_tables; iter; iter = g_slist_next (iter)) { + pi = g_hash_table_lookup ((GHashTable *) iter->data, prop_name); + if (pi) { + if (!pi->field) { + /* We know about this property but aren't tracking changes on it. */ + goto out; } - success = (*(pci->func)) (self, pspec, value, pci->field); - if (success) - break; + found = TRUE; + break; } } @@ -372,7 +365,26 @@ handle_property_changed (gpointer key, gpointer data, gpointer user_data) #if DEBUG g_warning ("Property '%s' unhandled.", prop_name); #endif - } else if (!success) { + goto out; + } + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (self)), prop_name); + if (!pspec) { + g_warning ("%s: property '%s' changed but wasn't defined by object type %s.", + __func__, + prop_name, + G_OBJECT_TYPE_NAME (self)); + goto out; + } + + /* Handle NULL object paths */ + if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) { + if (g_strcmp0 (g_value_get_boxed (value), "/") == 0) + value = NULL; + } + + success = (*(pi->func)) (self, pspec, value, pi->field); + if (!success) { g_warning ("%s: failed to update property '%s' of object type %s.", __func__, prop_name, @@ -397,48 +409,6 @@ properties_changed_proxy (DBusGProxy *proxy, _nm_object_process_properties_changed (NM_OBJECT (user_data), properties); } -void -_nm_object_handle_properties_changed (NMObject *object, - DBusGProxy *proxy, - const NMPropertiesChangedInfo *info) -{ - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - NMPropertiesChangedInfo *tmp; - GHashTable *instance; - - g_return_if_fail (NM_IS_OBJECT (object)); - g_return_if_fail (proxy != NULL); - g_return_if_fail (info != NULL); - - dbus_g_proxy_add_signal (proxy, "PropertiesChanged", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (proxy, - "PropertiesChanged", - G_CALLBACK (properties_changed_proxy), - object, - NULL); - - instance = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->pcs = g_slist_prepend (priv->pcs, instance); - - for (tmp = (NMPropertiesChangedInfo *) info; tmp->name; tmp++) { - PropChangedInfo *pci; - - if (!tmp->name || !tmp->func || !tmp->field) { - g_warning ("%s: missing field in NMPropertiesChangedInfo", __func__); - continue; - } - - pci = g_malloc0 (sizeof (PropChangedInfo)); - if (!pci) { - g_warning ("%s: not enough memory for PropChangedInfo", __func__); - continue; - } - pci->func = tmp->func; - pci->field = tmp->field; - g_hash_table_insert (instance, g_strdup (tmp->name), pci); - } -} - #define HANDLE_TYPE(ucase, lcase, getter) \ } else if (pspec->value_type == G_TYPE_##ucase) { \ if (G_VALUE_HOLDS_##ucase (value)) { \ @@ -449,11 +419,11 @@ _nm_object_handle_properties_changed (NMObject *object, goto done; \ } -gboolean -_nm_object_demarshal_generic (NMObject *object, - GParamSpec *pspec, - GValue *value, - gpointer field) +static gboolean +demarshal_generic (NMObject *object, + GParamSpec *pspec, + GValue *value, + gpointer field) { gboolean success = TRUE; @@ -503,6 +473,47 @@ done: return success; } +void +_nm_object_register_properties (NMObject *object, + DBusGProxy *proxy, + const NMPropertiesInfo *info) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + NMPropertiesInfo *tmp; + GHashTable *instance; + + g_return_if_fail (NM_IS_OBJECT (object)); + g_return_if_fail (proxy != NULL); + g_return_if_fail (info != NULL); + + priv->property_interfaces = g_slist_prepend (priv->property_interfaces, + g_strdup (dbus_g_proxy_get_interface (proxy))); + + dbus_g_proxy_add_signal (proxy, "PropertiesChanged", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxy, + "PropertiesChanged", + G_CALLBACK (properties_changed_proxy), + object, + NULL); + + instance = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->property_tables = g_slist_prepend (priv->property_tables, instance); + + for (tmp = (NMPropertiesInfo *) info; tmp->name; tmp++) { + PropertyInfo *pi; + + if (!tmp->name || (tmp->func && !tmp->field)) { + g_warning ("%s: missing field in NMPropertiesInfo", __func__); + continue; + } + + pi = g_malloc0 (sizeof (PropertyInfo)); + pi->func = tmp->func ? tmp->func : demarshal_generic; + pi->field = tmp->field; + g_hash_table_insert (instance, g_strdup (tmp->name), pi); + } +} + gboolean _nm_object_get_property (NMObject *object, const char *interface, |