2
* Copyright (C) 2010 Canonical, Ltd.
4
* This library is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU Lesser General Public License
6
* version 3.0 as published by the Free Software Foundation.
8
* This library is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Lesser General Public License version 3.0 for more details.
13
* You should have received a copy of the GNU Lesser General Public
14
* License along with this library. If not, see
15
* <http://www.gnu.org/licenses/>.
17
* Authored by: Michal Hruby <michal.mhr@gmail.com>
24
#include "zeitgeist-data-source-registry.h"
25
#include "zeitgeist-eggdbusconversions.h"
26
#include "zeitgeist-marshal.h"
27
#include "eggzeitgeistbindings.h"
30
* SECTION:zeitgeist-data-source-registry
31
* @short_description: Query the Zeitgeist Data Source Registry extension
32
* @include: zeitgeist.h
34
* The Zeitgeist engine maintains a publicly available list of recognized
35
* data-sources (components inserting information into Zeitgeist).
36
* #ZeitgeistDataSourceRegistry is used to register new data sources,
37
* get information about them and gives the ability to enable or disable
41
G_DEFINE_TYPE (ZeitgeistDataSourceRegistry,
42
zeitgeist_data_source_registry,
44
#define ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE(obj) \
45
(G_TYPE_INSTANCE_GET_PRIVATE(obj, ZEITGEIST_TYPE_DATA_SOURCE_REGISTRY, \
46
ZeitgeistDataSourceRegistryPrivate))
50
/* The connection to the ZG daemon
51
* Note: The EggZeitgeistDataSourceRegistry is owned by
52
* the EggDBusObjectProxy!
54
EggDBusObjectProxy *registry_proxy;
55
EggZeitgeistDataSourceRegistry *registry;
57
gulong src_registered_id;
58
gulong src_disconnected_id;
59
gulong src_enabled_id;
61
} ZeitgeistDataSourceRegistryPrivate;
79
static guint _registry_signals[LAST_SIGNAL] = { 0 };
82
zeitgeist_data_source_registry_init (ZeitgeistDataSourceRegistry *self)
84
ZeitgeistDataSourceRegistryPrivate *priv;
85
EggDBusConnection *conn;
87
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (self);
89
/* Set up the connection to the ZG daemon */
90
conn = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SESSION);
91
priv->registry_proxy =
92
egg_dbus_connection_get_object_proxy (conn,
93
"org.gnome.zeitgeist.Engine",
94
"/org/gnome/zeitgeist/data_source_registry");
97
EGG_ZEITGEIST_QUERY_INTERFACE_DATA_SOURCE_REGISTRY (priv->registry_proxy);
98
g_object_unref (conn);
102
zeitgeist_data_source_registry_finalize (GObject *object)
104
ZeitgeistDataSourceRegistry *registry;
105
ZeitgeistDataSourceRegistryPrivate *priv;
107
registry = ZEITGEIST_DATA_SOURCE_REGISTRY (object);
108
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (registry);
110
if (priv->src_registered_id)
112
g_signal_handler_disconnect (priv->registry, priv->src_registered_id);
115
if (priv->src_disconnected_id)
117
g_signal_handler_disconnect (priv->registry, priv->src_disconnected_id);
120
if (priv->src_enabled_id)
122
g_signal_handler_disconnect (priv->registry, priv->src_enabled_id);
125
/* Note: priv->registry is owned by priv->registry_proxy */
126
if (priv->registry_proxy)
128
g_object_unref (priv->registry_proxy);
131
G_OBJECT_CLASS (zeitgeist_data_source_registry_parent_class)->finalize (object);
135
zeitgeist_data_source_registry_get_property (GObject *object,
140
ZeitgeistDataSourceRegistryPrivate *priv;
142
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (object);
147
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
154
zeitgeist_data_source_registry_set_property (GObject *object,
159
ZeitgeistDataSourceRegistryPrivate *priv;
161
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (object);
166
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
173
zeitgeist_data_source_registry_src_registered (
174
ZeitgeistDataSourceRegistry *registry,
175
EggZeitgeistDataSource *source)
177
ZeitgeistDataSource *data_source;
179
data_source = _egg_zeitgeist_data_source_to_zeitgeist_data_source (source);
181
g_signal_emit (registry, _registry_signals[SOURCE_REGISTERED],
184
g_object_unref (data_source);
188
zeitgeist_data_source_registry_src_disconnected (
189
ZeitgeistDataSourceRegistry *registry,
190
EggZeitgeistDataSource *source)
192
ZeitgeistDataSource *data_source;
194
data_source = _egg_zeitgeist_data_source_to_zeitgeist_data_source (source);
196
g_signal_emit (registry, _registry_signals[SOURCE_DISCONNECTED],
199
g_object_unref (data_source);
203
zeitgeist_data_source_registry_src_enabled (
204
ZeitgeistDataSourceRegistry *registry,
208
g_signal_emit (registry, _registry_signals[SOURCE_ENABLED],
209
0, unique_id, enabled);
213
zeitgeist_data_source_registry_constructed (GObject *object)
215
ZeitgeistDataSourceRegistryPrivate *priv;
217
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (object);
219
priv->src_registered_id = g_signal_connect_swapped (
220
priv->registry, "data-source-registered",
221
G_CALLBACK (zeitgeist_data_source_registry_src_registered),
223
priv->src_disconnected_id = g_signal_connect_swapped (
224
priv->registry, "data-source-disconnected",
225
G_CALLBACK (zeitgeist_data_source_registry_src_disconnected),
227
priv->src_enabled_id = g_signal_connect_swapped (
228
priv->registry, "data-source-enabled",
229
G_CALLBACK (zeitgeist_data_source_registry_src_enabled),
234
zeitgeist_data_source_registry_class_init (ZeitgeistDataSourceRegistryClass *klass)
236
GObjectClass *object_class = G_OBJECT_CLASS (klass);
239
object_class->finalize = zeitgeist_data_source_registry_finalize;
240
object_class->get_property = zeitgeist_data_source_registry_get_property;
241
object_class->set_property = zeitgeist_data_source_registry_set_property;
242
object_class->constructed = zeitgeist_data_source_registry_constructed;
244
_registry_signals[SOURCE_REGISTERED] =
245
g_signal_new ("source-registered",
246
G_OBJECT_CLASS_TYPE (object_class),
248
G_STRUCT_OFFSET (ZeitgeistDataSourceRegistryClass, source_registered),
250
g_cclosure_marshal_VOID__OBJECT,
251
G_TYPE_NONE, 1, ZEITGEIST_TYPE_DATA_SOURCE);
253
_registry_signals[SOURCE_DISCONNECTED] =
254
g_signal_new ("source-disconnected",
255
G_OBJECT_CLASS_TYPE (object_class),
257
G_STRUCT_OFFSET (ZeitgeistDataSourceRegistryClass, source_disconnected),
259
g_cclosure_marshal_VOID__OBJECT,
260
G_TYPE_NONE, 1, ZEITGEIST_TYPE_DATA_SOURCE);
262
_registry_signals[SOURCE_ENABLED] =
263
g_signal_new ("source-enabled",
264
G_OBJECT_CLASS_TYPE (object_class),
266
G_STRUCT_OFFSET (ZeitgeistDataSourceRegistryClass, source_enabled),
268
_zeitgeist_cclosure_marshal_VOID__STRING_BOOLEAN,
269
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN);
271
g_type_class_add_private (object_class,
272
sizeof (ZeitgeistDataSourceRegistryPrivate));
275
/* Used to marshal the async callbacks from EggDBus into ones
276
* coming from this DataSourceRegistry instance */
278
dispatch_async_callback (GObject *source_object,
282
gpointer *data = (gpointer*) user_data;
283
ZeitgeistDataSourceRegistry *self = ZEITGEIST_DATA_SOURCE_REGISTRY (data[0]);
284
GAsyncReadyCallback callback = (GAsyncReadyCallback) data[1];
285
gpointer _user_data = data[2];
287
if (callback != NULL)
289
callback (G_OBJECT (self), res, _user_data);
292
g_object_unref (self);
301
* zeitgeist_data_source_registry_new:
303
* Create a new data source registry instance.
305
* DataSourceRegistry instances are not overly expensive for neither
306
* client or the Zeitgeist daemon so there's no need to go to lengths
307
* to keep singleton instances around.
309
* Returns: A reference to a newly allocated registry.
311
ZeitgeistDataSourceRegistry*
312
zeitgeist_data_source_registry_new (void)
314
ZeitgeistDataSourceRegistry *registry;
316
registry = (ZeitgeistDataSourceRegistry*)
317
g_object_new (ZEITGEIST_TYPE_DATA_SOURCE_REGISTRY, NULL);
323
zeitgeist_data_source_registry_get_data_sources (
324
ZeitgeistDataSourceRegistry *self,
325
GCancellable *cancellable,
326
GAsyncReadyCallback callback,
329
ZeitgeistDataSourceRegistryPrivate *priv;
330
gpointer *dispatch_data;
332
g_return_if_fail (ZEITGEIST_IS_DATA_SOURCE_REGISTRY (self));
333
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
335
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (self);
337
dispatch_data = g_new (gpointer, 3);
338
dispatch_data[0] = g_object_ref (self);
339
dispatch_data[1] = callback;
340
dispatch_data[2] = user_data;
342
egg_zeitgeist_data_source_registry_get_data_sources (
344
EGG_DBUS_CALL_FLAGS_NONE,
346
dispatch_async_callback,
351
* zeitgeist_data_source_registry_get_data_sources_finish:
352
* @self: Instance of #ZeitgeistDataSourceRegistry.
353
* @res: a #GAsyncResult.
354
* @error: a #GError or #NULL.
356
* Returns: Newly created #GPtrArray containing #ZeitgeistDataSource<!-- -->(s)
357
* registered in Zeitgeist. Free using g_ptr_array_unref() once
358
* you're done using it.
361
zeitgeist_data_source_registry_get_data_sources_finish (
362
ZeitgeistDataSourceRegistry *self,
366
ZeitgeistDataSourceRegistryPrivate *priv;
367
EggDBusArraySeq *array_seq;
368
gboolean call_result;
369
GPtrArray *data_sources = NULL;
371
g_return_val_if_fail (ZEITGEIST_IS_DATA_SOURCE_REGISTRY (self), NULL);
373
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (self);
375
call_result = egg_zeitgeist_data_source_registry_get_data_sources_finish (
382
_egg_zeitgeist_data_sources_to_zeitgeist_data_sources (array_seq);
383
g_ptr_array_set_free_func (data_sources, g_object_unref);
385
g_object_unref (array_seq);
391
* zeitgeist_data_source_registry_register_data_source:
392
* @self: Instance of #ZeitgeistDataSourceRegistry.
393
* @source: Data source to register.
394
* @cancellable: a #GCancellable or #NULL.
395
* @callback: a GAsyncReadyCallback to call when the request is finished.
396
* @user_data: the data to pass to callback function.
398
* Registers new data source in the registry, the @source parameter needs to
399
* have unique-id, name, description and optionally event_templates set,
400
* therefore it is useful to pass #ZeitgeistDataSource instance created using
401
* zeitgeist_data_source_new_full(). The registry will assume its ownership.
404
zeitgeist_data_source_registry_register_data_source (
405
ZeitgeistDataSourceRegistry *self,
406
ZeitgeistDataSource *source,
407
GCancellable *cancellable,
408
GAsyncReadyCallback callback,
411
ZeitgeistDataSourceRegistryPrivate *priv;
412
gpointer *dispatch_data;
413
EggDBusArraySeq *templates;
415
g_return_if_fail (ZEITGEIST_IS_DATA_SOURCE_REGISTRY (self));
416
g_return_if_fail (ZEITGEIST_IS_DATA_SOURCE (source));
417
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
419
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (self);
421
g_object_ref_sink (G_OBJECT (source));
423
dispatch_data = g_new (gpointer, 3);
424
dispatch_data[0] = g_object_ref (self);
425
dispatch_data[1] = callback;
426
dispatch_data[2] = user_data;
428
templates = _zeitgeist_events_to_egg_zeitgeist_events (
429
zeitgeist_data_source_get_event_templates (source)
432
egg_zeitgeist_data_source_registry_register_data_source (
434
EGG_DBUS_CALL_FLAGS_NONE,
435
zeitgeist_data_source_get_unique_id (source),
436
zeitgeist_data_source_get_name (source),
437
zeitgeist_data_source_get_description (source),
440
dispatch_async_callback,
443
g_object_unref (templates);
444
g_object_unref (source);
448
* zeitgeist_data_source_registry_register_data_source_finish:
449
* @self: Instance of #ZeitgeistDataSourceRegistry.
450
* @res: Result of the asynchronous operation.
451
* @error: a #GError or NULL.
453
* Returns: If error is unset, returns whether this data source is enabled.
456
zeitgeist_data_source_registry_register_data_source_finish (
457
ZeitgeistDataSourceRegistry *self,
461
ZeitgeistDataSourceRegistryPrivate *priv;
462
gboolean result = FALSE;
464
g_return_val_if_fail (ZEITGEIST_IS_DATA_SOURCE_REGISTRY (self), FALSE);
466
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (self);
468
egg_zeitgeist_data_source_registry_register_data_source_finish (
478
zeitgeist_data_source_registry_set_data_source_enabled (
479
ZeitgeistDataSourceRegistry *self,
480
const gchar *unique_id,
482
GCancellable *cancellable,
483
GAsyncReadyCallback callback,
486
ZeitgeistDataSourceRegistryPrivate *priv;
487
gpointer *dispatch_data;
489
g_return_if_fail (ZEITGEIST_IS_DATA_SOURCE_REGISTRY (self));
490
g_return_if_fail (unique_id != NULL);
491
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
493
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (self);
495
dispatch_data = g_new (gpointer, 3);
496
dispatch_data[0] = g_object_ref (self);
497
dispatch_data[1] = callback;
498
dispatch_data[2] = user_data;
500
egg_zeitgeist_data_source_registry_set_data_source_enabled (
502
EGG_DBUS_CALL_FLAGS_NONE,
506
dispatch_async_callback,
511
zeitgeist_data_source_registry_set_data_source_enabled_finish (
512
ZeitgeistDataSourceRegistry *self,
516
ZeitgeistDataSourceRegistryPrivate *priv;
518
g_return_if_fail (ZEITGEIST_IS_DATA_SOURCE_REGISTRY (self));
520
priv = ZEITGEIST_DATA_SOURCE_REGISTRY_GET_PRIVATE (self);
522
egg_zeitgeist_data_source_registry_set_data_source_enabled_finish (