static gint _gvalues_compare_collection (const GValue *value1, const GValue *value2) { gint ret; guint len1; guint len2; GType value_type = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value1)); gsize element_size = 0; if (type_is_fixed_size (value_type, &element_size)) { gpointer data1 = NULL; gpointer data2 = NULL; dbus_g_type_collection_get_fixed ((GValue *) value1, &data1, &len1); dbus_g_type_collection_get_fixed ((GValue *) value2, &data2, &len2); if (len1 != len2) ret = len1 < len2 ? -1 : len1 > len2; else ret = memcmp (data1, data2, len1 * element_size); } else { GSList *list1 = NULL; GSList *list2 = NULL; dbus_g_type_collection_value_iterate (value1, iterate_collection, &list1); len1 = g_slist_length (list1); dbus_g_type_collection_value_iterate (value2, iterate_collection, &list2); len2 = g_slist_length (list2); if (len1 != len2) ret = len1 < len2 ? -1 : len1 > len2; else { GSList *iter1; GSList *iter2; for (iter1 = list1, iter2 = list2, ret = 0; ret == 0 && iter1 && iter2; iter1 = iter1->next, iter2 = iter2->next) ret = _gvalues_compare ((GValue *) iter1->data, (GValue *) iter2->data); } g_slist_foreach (list1, (GFunc) _gvalue_destroy, NULL); g_slist_free (list1); g_slist_foreach (list2, (GFunc) _gvalue_destroy, NULL); g_slist_free (list2); } return ret; }
static void find_services (void) { DBusGProxy *proxy; GHashTable *props = NULL; GError *error = NULL; GValue *value; proxy = dbus_g_proxy_new_for_name (connection, CONNMAN_SERVICE, "/", CONNMAN_MANAGER_INTERFACE); if (!net_connman_Manager_get_properties (proxy, &props, &error)) { g_printerr ("Cannot get properties for manager: %s\n", error->message); g_error_free (error); g_object_unref (proxy); return; } value = g_hash_table_lookup (props, "Services"); if (value) dbus_g_type_collection_value_iterate (value, add_service, &services); g_hash_table_unref (props); g_object_unref (proxy); }
static void manager_property_changed(DBusGProxy *proxy, const char *property, GValue *value, gpointer user_data) { if (property == NULL || value == NULL) return; if (g_str_equal(property, "Services") == TRUE) { gchar *path = NULL; dbus_g_type_collection_value_iterate(value, iterate_list, &path); update_service(proxy, path); g_free(path); } }
static void network_model_update_property (const gchar *property, GValue *value, gpointer user_data) { CarrickNetworkModel *self = user_data; CarrickNetworkModelPrivate *priv = self->priv; GtkListStore *store = GTK_LIST_STORE (self); GList *new_services = NULL; GList *old_services = NULL; GList *list_iter = NULL; GList *tmp = NULL; GtkTreeIter iter; gchar *path = NULL; DBusGProxy *service; guint index = 0; if (g_str_equal (property, "Services")) { old_services = priv->services; dbus_g_type_collection_value_iterate (value, network_model_iterate_services, &new_services); priv->services = new_services; for (list_iter = new_services; list_iter != NULL; list_iter = list_iter->next) { path = list_iter->data; /* Remove from old list, if present. * We only want stale services in old list */ tmp = g_list_find_custom (old_services, path, (GCompareFunc) g_strcmp0); if (tmp) { old_services = g_list_delete_link (old_services, tmp); } /* if we don't have the service in the model, add it*/ if (network_model_have_service_by_path (store, &iter, path) == FALSE) { service = dbus_g_proxy_new_for_name (priv->connection, CONNMAN_SERVICE, path, CONNMAN_SERVICE_INTERFACE); gtk_list_store_insert_with_values (store, &iter, -1, CARRICK_COLUMN_PROXY, service, CARRICK_COLUMN_INDEX, index, -1); dbus_g_proxy_add_signal (service, "PropertyChanged", G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); dbus_g_proxy_connect_signal (service, "PropertyChanged", G_CALLBACK (network_model_service_changed_cb), self, NULL); net_connman_Service_get_properties_async (service, network_model_service_get_properties_cb, self); g_object_unref (service); } /* else update it */ else { guint current_index; gtk_tree_model_get (GTK_TREE_MODEL (self), &iter, CARRICK_COLUMN_INDEX, ¤t_index, -1); if (current_index != index) gtk_list_store_set (store, &iter, CARRICK_COLUMN_INDEX, index, -1); } index++; } /* Old list only contains items not in new list. * Remove stale services */ for (list_iter = old_services; list_iter != NULL; list_iter = list_iter->next) { path = list_iter->data; if (network_model_have_service_by_path (store, &iter, path) == TRUE) gtk_list_store_remove (store, &iter); g_free (path); } if (old_services) { g_list_free (old_services); old_services = NULL; } } }