GDBusObjectManager *object_manager;
GMainContext *context;
+
+ GSource *changed_timeout_source;
};
typedef struct
PROP_MANAGER
};
+enum
+{
+ CHANGED_SIGNAL,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
static void initable_iface_init (GInitableIface *initable_iface);
static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
+static void on_object_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data);
+
+static void on_object_removed (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data);
+
+static void on_interface_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface,
+ gpointer user_data);
+
+static void on_interface_removed (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface,
+ gpointer user_data);
+
+static void on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager,
+ GDBusObjectProxy *object_proxy,
+ GDBusProxy *interface_proxy,
+ GVariant *changed_properties,
+ const gchar *const *invalidated_properties,
+ gpointer user_data);
+
G_DEFINE_TYPE_WITH_CODE (UDisksClient, udisks_client, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
{
UDisksClient *client = UDISKS_CLIENT (object);
+ if (client->changed_timeout_source != NULL)
+ g_source_destroy (client->changed_timeout_source);
+
if (client->initialization_error != NULL)
g_error_free (client->initialization_error);
+ g_signal_handlers_disconnect_by_func (client->object_manager,
+ G_CALLBACK (on_object_added),
+ client);
+ g_signal_handlers_disconnect_by_func (client->object_manager,
+ G_CALLBACK (on_object_removed),
+ client);
+ g_signal_handlers_disconnect_by_func (client->object_manager,
+ G_CALLBACK (on_interface_added),
+ client);
+ g_signal_handlers_disconnect_by_func (client->object_manager,
+ G_CALLBACK (on_interface_removed),
+ client);
+ g_signal_handlers_disconnect_by_func (client->object_manager,
+ G_CALLBACK (on_interface_proxy_properties_changed),
+ client);
g_object_unref (client->object_manager);
if (client->context != NULL)
UDISKS_TYPE_MANAGER,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
+
+ /**
+ * UDisksClient::changed:
+ * @client: A #UDisksClient.
+ *
+ * This signal is emitted either when an object or interface is
+ * added or removed a when property has changed. Additionally,
+ * multiple received signals are coalesced into a single signal that
+ * is rate-limited to fire at most every 100ms.
+ *
+ * For greater detail, connect to the
+ * #GDBusObjectManager::object-added,
+ * #GDBusObjectManager::object-removed,
+ * #GDBusObjectManager::interface-added,
+ * #GDBusObjectManager::interface-removed,
+ * #GDBusObjectManagerClient::interface-proxy-properties-changed and
+ * signals on the #UDisksClient:object-manager object.
+ */
+ signals[CHANGED_SIGNAL] = g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* G_STRUCT_OFFSET */
+ NULL, /* accu */
+ NULL, /* accu data */
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE,
+ 0);
+
}
/**
if (client->object_manager == NULL)
goto out;
+ g_signal_connect (client->object_manager,
+ "object-added",
+ G_CALLBACK (on_object_added),
+ client);
+ g_signal_connect (client->object_manager,
+ "object-removed",
+ G_CALLBACK (on_object_removed),
+ client);
+ g_signal_connect (client->object_manager,
+ "interface-added",
+ G_CALLBACK (on_interface_added),
+ client);
+ g_signal_connect (client->object_manager,
+ "interface-removed",
+ G_CALLBACK (on_interface_removed),
+ client);
+ g_signal_connect (client->object_manager,
+ "interface-proxy-properties-changed",
+ G_CALLBACK (on_interface_proxy_properties_changed),
+ client);
+
ret = TRUE;
out:
g_list_free (objects);
return ret;
}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+on_changed_timeout (gpointer user_data)
+{
+ UDisksClient *client = UDISKS_CLIENT (user_data);
+ client->changed_timeout_source = NULL;
+ g_signal_emit (client, signals[CHANGED_SIGNAL], 0);
+ return FALSE; /* remove source */
+}
+
+static void
+queue_changed (UDisksClient *client)
+{
+ if (client->changed_timeout_source != NULL)
+ goto out;
+
+ client->changed_timeout_source = g_timeout_source_new (100);
+ g_source_set_callback (client->changed_timeout_source,
+ (GSourceFunc) on_changed_timeout,
+ client,
+ NULL); /* destroy notify */
+ g_source_attach (client->changed_timeout_source, client->context);
+ g_source_unref (client->changed_timeout_source);
+
+ out:
+ ;
+}
+
+static void
+on_object_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data)
+{
+ UDisksClient *client = UDISKS_CLIENT (user_data);
+ queue_changed (client);
+}
+
+static void
+on_object_removed (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data)
+{
+ UDisksClient *client = UDISKS_CLIENT (user_data);
+ queue_changed (client);
+}
+
+static void
+on_interface_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface,
+ gpointer user_data)
+{
+ UDisksClient *client = UDISKS_CLIENT (user_data);
+ queue_changed (client);
+}
+
+static void
+on_interface_removed (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface,
+ gpointer user_data)
+{
+ UDisksClient *client = UDISKS_CLIENT (user_data);
+ queue_changed (client);
+}
+
+static void
+on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager,
+ GDBusObjectProxy *object_proxy,
+ GDBusProxy *interface_proxy,
+ GVariant *changed_properties,
+ const gchar *const *invalidated_properties,
+ gpointer user_data)
+{
+ UDisksClient *client = UDISKS_CLIENT (user_data);
+ queue_changed (client);
+}