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/>.
18
* Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
25
#include "zeitgeist-log.h"
26
#include "zeitgeist-simple-result-set.h"
27
#include "zeitgeist-eggdbusconversions.h"
28
#include "eggzeitgeistbindings.h"
31
* SECTION:zeitgeist-log
32
* @short_description: Primary access point for talking to the Zeitgeist daemon
33
* @include: zeitgeist.h
35
* #ZeitgeistLog encapsulates the low level access to the Zeitgeist daemon.
36
* You can use it to manage the log by inserting and deleting entries as well
37
* as do queries on the logged data.
39
* It's important to realize that the #ZeitgeistLog class does not expose
40
* any API that does synchronous communications with the message bus -
41
* everything is asynchronous. To ease development some of the methods have
42
* variants that are "fire and forget" ignoring the normal return value, so
43
* that callbacks does not have to be set up.
46
G_DEFINE_TYPE (ZeitgeistLog, zeitgeist_log, G_TYPE_OBJECT);
47
#define ZEITGEIST_LOG_GET_PRIVATE(obj) \
48
(G_TYPE_INSTANCE_GET_PRIVATE(obj, ZEITGEIST_TYPE_LOG, ZeitgeistLogPrivate))
52
/* The connection to the ZG daemon
53
* Note: The EggZeitgeistLog is owned by the EggDBusObjectProxy! */
54
EggDBusObjectProxy *log_proxy;
57
/* Hash set of ZeitgeistMonitors we've installed. We actually store
58
* a map of (monitor, log) because this is most convenient for use with
59
* _zeitgeist_monitor_weak_unref() casted to a GHFunc */
61
} ZeitgeistLogPrivate;
71
static void _zeitgeist_log_on_name_owner_changed (ZeitgeistLog *self);
73
static void _zeitgeist_log_on_monitor_destroyed (ZeitgeistLog *self,
74
ZeitgeistMonitor *monitor);
76
static void _zeitgeist_monitor_weak_unref (ZeitgeistMonitor *monitor,
79
/* Signature of egg_zeitgeist variants of find_events() and find_event_ids() */
80
typedef guint (*FindEventsFunc) (EggZeitgeistLog *instance,
81
EggDBusCallFlags call_flags,
82
EggZeitgeistTimeRange *time_range,
83
EggDBusArraySeq *event_templates,
84
EggZeitgeistStorageState storage_state,
86
EggZeitgeistResultType result_type,
87
GCancellable *cancellable,
88
GAsyncReadyCallback callback,
91
/* Signature for egg_zeitgeist_log functions that send an array of event ids */
92
typedef guint (*SendEventIdsFunc) (EggZeitgeistLog *instance,
93
EggDBusCallFlags call_flags,
94
EggDBusArraySeq *event_ids,
95
GCancellable *cancellable,
96
GAsyncReadyCallback callback,
99
/* Signature for egg_zeitgeist_log functions that does not have arguments */
100
typedef guint (*SendVoidFunc) (EggZeitgeistLog *instance,
101
EggDBusCallFlags call_flags,
102
GCancellable *cancellable,
103
GAsyncReadyCallback callback,
106
typedef gboolean (*CollectEventsFunc) (EggZeitgeistLog *instance,
107
EggDBusArraySeq **out_events,
111
typedef gboolean (*CollectIdsFunc) (EggZeitgeistLog *instance,
112
EggDBusArraySeq **out_event_ids,
116
typedef gboolean (*CollectVoidFunc) (EggZeitgeistLog *instance,
121
zeitgeist_log_init (ZeitgeistLog *self)
123
ZeitgeistLogPrivate *priv;
124
EggDBusConnection *conn;
126
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
128
/* Reset hash set of monitors */
129
priv->monitors = g_hash_table_new (g_direct_hash, g_direct_equal);
131
/* Set up the connection to the ZG daemon */
132
conn = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SESSION);
134
egg_dbus_connection_get_object_proxy (conn,
135
"org.gnome.zeitgeist.Engine",
136
"/org/gnome/zeitgeist/log/activity");
138
priv->log = EGG_ZEITGEIST_QUERY_INTERFACE_LOG (priv->log_proxy);
139
g_object_unref (conn);
141
/* We need to detect if the Zeitgeist daemon leaves/enters the bus */
142
g_signal_connect_swapped (priv->log_proxy, "notify::name-owner",
143
G_CALLBACK (_zeitgeist_log_on_name_owner_changed),
148
zeitgeist_log_finalize (GObject *object)
150
ZeitgeistLog *log = ZEITGEIST_LOG (object);
151
ZeitgeistLogPrivate *priv;
153
priv = ZEITGEIST_LOG_GET_PRIVATE (log);
155
/* Note: priv->log is owned by priv->log_proxy */
158
g_object_unref (priv->log_proxy);
161
/* Out list of monitors only holds weak refs to the monitors */
164
g_hash_table_foreach (priv->monitors,
165
(GHFunc) _zeitgeist_monitor_weak_unref,
167
g_hash_table_unref (priv->monitors);
170
G_OBJECT_CLASS (zeitgeist_log_parent_class)->finalize (object);
174
zeitgeist_log_get_property (GObject *object,
179
ZeitgeistLogPrivate *priv = ZEITGEIST_LOG_GET_PRIVATE (object);
184
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
191
zeitgeist_log_set_property (GObject *object,
196
ZeitgeistLogPrivate *priv = ZEITGEIST_LOG_GET_PRIVATE (object);
201
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
209
zeitgeist_log_class_init (ZeitgeistLogClass *klass)
211
GObjectClass *object_class = G_OBJECT_CLASS (klass);
214
object_class->finalize = zeitgeist_log_finalize;
215
object_class->get_property = zeitgeist_log_get_property;
216
object_class->set_property = zeitgeist_log_set_property;
218
g_type_class_add_private (object_class, sizeof (ZeitgeistLogPrivate));
221
/* Used to marshal the async callbacks from EggDBus into ones
222
* coming from this Log instance */
224
dispatch_async_callback (GObject *source_object,
228
gpointer *data = (gpointer*) user_data;
229
ZeitgeistLog *self = ZEITGEIST_LOG (data[0]);
230
GAsyncReadyCallback callback = (GAsyncReadyCallback) data[1];
231
gpointer _user_data = data[2];
233
if (callback != NULL)
235
callback (G_OBJECT (self), res, _user_data);
238
g_object_unref (self);
248
* Create a new log that interfaces with the default event log of the Zeitgeist
251
* Log instances are not overly expensive for neither client or the Zeitgeist
252
* daemon so there's no need to go to lenghts to keep singleton instances
255
* Returns: A reference to a newly allocated log.
258
zeitgeist_log_new (void)
262
log = (ZeitgeistLog*) g_object_new (ZEITGEIST_TYPE_LOG,
268
/* Helper for _finish() functions that returns a GArray of event ids */
270
_zeitgeist_log_collect_event_ids (CollectIdsFunc collect_ids_func,
272
GArray **out_event_ids,
276
ZeitgeistLogPrivate *priv;
277
EggDBusArraySeq *event_ids;
282
g_return_val_if_fail (ZEITGEIST_IS_LOG (self), FALSE);
283
g_return_val_if_fail (out_event_ids != NULL, FALSE);
284
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
285
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
287
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
289
result = collect_ids_func (priv->log,
299
len = egg_dbus_array_seq_get_size (event_ids);
300
*out_event_ids = g_array_sized_new (FALSE, FALSE, sizeof (guint32), len);
301
for (i = 0; i < len; i++)
303
event_id = egg_dbus_array_seq_get_fixed (event_ids, i);
304
g_array_append_val (*out_event_ids, event_id);
308
g_object_unref (event_ids);
312
/* Helper for _finish() functions returning an array of events.
313
* Set the free_func on @out_events to g_object_unref() */
315
_zeitgeist_log_collect_events (CollectEventsFunc collect_events_func,
317
GPtrArray **out_events,
321
ZeitgeistLogPrivate *priv;
322
EggDBusArraySeq *events;
325
g_return_val_if_fail (ZEITGEIST_IS_LOG (self), FALSE);
326
g_return_val_if_fail (out_events != NULL, FALSE);
327
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
328
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
330
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
332
result = collect_events_func (priv->log,
342
*out_events = _egg_zeitgeist_events_to_zeitgeist_events (events);
343
g_ptr_array_set_free_func (*out_events, (GDestroyNotify) g_object_unref);
345
g_object_unref (events);
349
/* Helper for _finish() functions without a return value */
351
_zeitgeist_log_collect_void (CollectVoidFunc collect_void,
356
ZeitgeistLogPrivate *priv;
357
EggDBusArraySeq *events;
360
g_return_val_if_fail (ZEITGEIST_IS_LOG (self), FALSE);
361
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
362
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
364
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
366
return collect_void (priv->log, res, error);
370
* zeitgeist_log_insert_events:
371
* @self: The log logging the events
372
* @cancellable: To cancel the operation or %NULL
373
* @callback: #GAsyncReadyCallback to invoke once the logging operation has
374
* completed. Set to %NULL to ignore the result. In this callback
375
* you can invoke zeitgeist_log_insert_events_finish() to collect
376
* the event ids of the inserted events
377
* @user_data: Any user data to pass back to @callback
378
* @VarArgs: A list of #ZeitgeistEvent<!-- -->s terminated by a %NULL
380
* Asynchrnously send a set of events to the Zeitgeist daemon, requesting they
381
* be inserted into the log.
384
zeitgeist_log_insert_events (ZeitgeistLog *self,
385
GCancellable *cancellable,
386
GAsyncReadyCallback callback,
392
va_start (events, user_data);
393
zeitgeist_log_insert_events_valist (self, cancellable,
394
callback, user_data, events);
399
* zeitgeist_log_insert_events_no_reply:
400
* @self: The log logging the events
401
* @VarArgs: A list of #ZeitgeistEvent<!-- -->s terminated by a %NULL
403
* Asynchrnously send a set of events to the Zeitgeist daemon, requesting they
404
* be inserted into the log. This method is "fire and forget" and the
405
* caller will never know whether the events was succesfully inserted or not.
407
* This method is exactly equivalent to calling zeitgeist_log_insert_events()
408
* with %NULL set as @cancellable, @callback, and @user_data.
411
zeitgeist_log_insert_events_no_reply (ZeitgeistLog *self,
416
va_start (events, self);
417
zeitgeist_log_insert_events_valist (self, NULL, NULL, NULL, events);
422
* zeitgeist_log_insert_events_valist:
423
* @self: The log logging the events
424
* @cancellable: To cancel the operation or %NULL
425
* @callback: #GAsyncReadyCallback to invoke once the logging operation has
426
* completed. Set to %NULL to ignore the result. In this callback
427
* you can invoke zeitgeist_log_insert_events_finish() to collect
428
* the event ids of the inserted events
429
* @user_data: Any user data to pass back to @callback
430
* @events: A #GPtrArray of #ZeitgeistEvent<!-- -->s to insert. This method
431
* steals the reference to @events and consumes all floating refs
432
* on the event members. It is assumed that the free_func on @events
433
* is set to g_object_unref().
435
* This method is intended for language bindings. If calling this function
436
* from C code it's generally more handy to use zeitgeist_log_insert_events()
437
* or zeitgeist_log_insert_events_from_ptrarray().
439
* Asynchrnously send a set of events to the Zeitgeist daemon, requesting they
440
* be inserted into the log.
443
zeitgeist_log_insert_events_valist (ZeitgeistLog *self,
444
GCancellable *cancellable,
445
GAsyncReadyCallback callback,
451
_events = _zeitgeist_events_from_valist (events);
452
zeitgeist_log_insert_events_from_ptrarray (self, _events, cancellable,
453
callback, user_data);
457
* zeitgeist_log_insert_events_from_ptrarray:
458
* @self: The log logging the events
459
* @events: A #GPtrArray of #ZeitgeistEvent<!-- -->s to insert. This method
460
* steals the reference to @events and consumes all floating refs
461
* on the event members. It is assumed that the free_func on @events
462
* is set to g_object_unref().
463
* @cancellable: To cancel the operation or %NULL
464
* @callback: #GAsyncReadyCallback to invoke once the logging operation has
465
* completed. Set to %NULL to ignore the result. In this callback
466
* you can invoke zeitgeist_log_insert_events_finish() to collect
467
* the event ids of the inserted events
468
* @user_data: Any user data to pass back to @callback
470
* Asynchrnously send a set of events to the Zeitgeist daemon, requesting they
471
* be inserted into the log.
474
zeitgeist_log_insert_events_from_ptrarray (ZeitgeistLog *self,
476
GCancellable *cancellable,
477
GAsyncReadyCallback callback,
480
ZeitgeistLogPrivate *priv;
481
EggDBusArraySeq *_events;
482
gpointer *dispatch_data;
484
g_return_if_fail (ZEITGEIST_IS_LOG (self));
485
g_return_if_fail (events != NULL);
486
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE(cancellable));
488
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
490
/* Own all floating refs on the events */
491
g_ptr_array_foreach (events, (GFunc) g_object_ref_sink, NULL);
493
_events = _zeitgeist_events_to_egg_zeitgeist_events (events);
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_log_insert_events (priv->log,
501
EGG_DBUS_CALL_FLAGS_NONE,
504
dispatch_async_callback,
507
/* Release the events */
508
g_ptr_array_unref (events);
509
g_object_unref (_events);
514
zeitgeist_log_insert_events_finish (ZeitgeistLog *self,
520
_zeitgeist_log_collect_event_ids (egg_zeitgeist_log_insert_events_finish,
521
self, &event_ids, res, error);
525
/* Shared helper for dispatching find_events() and find_event_ids() */
527
_zeitgeist_log_find_events_with_func (FindEventsFunc find_events_func,
529
ZeitgeistTimeRange *time_range,
530
GPtrArray *event_templates,
531
ZeitgeistStorageState storage_state,
533
ZeitgeistResultType result_type,
534
GCancellable *cancellable,
535
GAsyncReadyCallback callback,
538
ZeitgeistLogPrivate *priv;
539
EggZeitgeistTimeRange *_time_range;
540
EggDBusArraySeq *_event_templates;
541
gpointer *dispatch_data;
543
g_return_if_fail (ZEITGEIST_IS_LOG (self));
544
g_return_if_fail (ZEITGEIST_IS_TIME_RANGE (time_range));
545
g_return_if_fail (event_templates != NULL);
546
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE(cancellable));
548
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
550
/* Own all floating refs on the events and the time_range */
551
g_ptr_array_foreach (event_templates, (GFunc) g_object_ref_sink, NULL);
552
g_object_ref_sink (time_range);
554
_time_range = _zeitgeist_time_range_to_egg_zeitgeist_time_range (time_range);
555
_event_templates = _zeitgeist_events_to_egg_zeitgeist_events (event_templates);
557
dispatch_data = g_new (gpointer, 3);
558
dispatch_data[0] = g_object_ref (self);
559
dispatch_data[1] = callback;
560
dispatch_data[2] = user_data;
562
find_events_func (priv->log,
563
EGG_DBUS_CALL_FLAGS_NONE,
566
(EggZeitgeistStorageState) storage_state,
568
(EggZeitgeistResultType) result_type,
570
dispatch_async_callback,
573
/* Release the event templates */
574
g_ptr_array_foreach (event_templates, (GFunc) g_object_unref, NULL);
575
g_ptr_array_unref (event_templates);
576
g_object_unref (time_range);
577
g_object_unref (_event_templates);
578
g_object_unref (_time_range);
582
zeitgeist_log_find_events (ZeitgeistLog *self,
583
ZeitgeistTimeRange *time_range,
584
GPtrArray *event_templates,
585
ZeitgeistStorageState storage_state,
587
ZeitgeistResultType result_type,
588
GCancellable *cancellable,
589
GAsyncReadyCallback callback,
592
_zeitgeist_log_find_events_with_func (egg_zeitgeist_log_find_events,
605
* zeitgeist_log_find_events_finish:
610
* Retrieve the result from an asynchronous query started with
611
* zeitgeist_log_find_events().
613
* Returns: (transfer-full): A newly allocated #ZeitgeistResultSet containing
614
* the #ZeitgeistEvent<!-- -->s
615
* matching the query. You must free the result set with
616
* g_object_unref(). The events held in the result set will
617
* automatically be unreffed when the result set is finalized.
620
zeitgeist_log_find_events_finish (ZeitgeistLog *self,
626
_zeitgeist_log_collect_events (egg_zeitgeist_log_find_events_finish,
627
self, &events, res, error);
628
return _zeitgeist_simple_result_set_new (events, events->len);
632
zeitgeist_log_find_event_ids (ZeitgeistLog *self,
633
ZeitgeistTimeRange *time_range,
634
GPtrArray *event_templates,
635
ZeitgeistStorageState storage_state,
637
ZeitgeistResultType result_type,
638
GCancellable *cancellable,
639
GAsyncReadyCallback callback,
642
_zeitgeist_log_find_events_with_func (egg_zeitgeist_log_find_event_ids,
655
zeitgeist_log_find_event_ids_finish (ZeitgeistLog *self,
661
_zeitgeist_log_collect_event_ids (egg_zeitgeist_log_find_event_ids_finish,
662
self, &event_ids, res, error);
667
_zeitgeist_log_send_event_ids (SendEventIdsFunc send_event_ids,
670
GCancellable *cancellable,
671
GAsyncReadyCallback callback,
674
ZeitgeistLogPrivate *priv;
675
EggDBusArraySeq *_event_ids;
676
gpointer *dispatch_data;
679
g_return_if_fail (ZEITGEIST_IS_LOG (self));
680
g_return_if_fail (event_ids != NULL);
681
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE(cancellable));
683
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
685
/* Convert GArray<guint32> to EggDBusArraySeq<guint> */
686
_event_ids = egg_dbus_array_seq_new (G_TYPE_UINT, NULL, NULL, NULL);
687
for (i = 0; i < event_ids->len; i++)
689
egg_dbus_array_seq_add_fixed (_event_ids,
690
g_array_index (event_ids, guint32, i));
693
dispatch_data = g_new (gpointer, 3);
694
dispatch_data[0] = g_object_ref (self);
695
dispatch_data[1] = callback;
696
dispatch_data[2] = user_data;
698
send_event_ids (priv->log,
699
EGG_DBUS_CALL_FLAGS_NONE,
702
dispatch_async_callback,
705
/* Release the event ids */
706
g_array_unref (event_ids);
707
g_object_unref (_event_ids);
711
zeitgeist_log_get_events (ZeitgeistLog *self,
713
GCancellable *cancellable,
714
GAsyncReadyCallback callback,
717
_zeitgeist_log_send_event_ids (egg_zeitgeist_log_get_events,
718
self, event_ids, cancellable,
719
callback, user_data);
723
zeitgeist_log_get_events_finish (ZeitgeistLog *self,
729
_zeitgeist_log_collect_events (egg_zeitgeist_log_get_events_finish,
730
self, &events, res, error);
731
return _zeitgeist_simple_result_set_new (events, events->len);
735
zeitgeist_log_delete_events (ZeitgeistLog *self,
737
GCancellable *cancellable,
738
GAsyncReadyCallback callback,
741
_zeitgeist_log_send_event_ids (egg_zeitgeist_log_delete_events,
742
self, event_ids, cancellable,
743
callback, user_data);
747
zeitgeist_log_delete_events_finish (ZeitgeistLog *self,
751
return _zeitgeist_log_collect_void (egg_zeitgeist_log_delete_events_finish,
756
zeitgeist_log_find_related_uris (ZeitgeistLog *self,
757
ZeitgeistTimeRange *time_range,
758
GPtrArray *event_templates,
759
GPtrArray *result_event_templates,
760
ZeitgeistStorageState storage_state,
762
ZeitgeistResultType result_type,
763
GCancellable *cancellable,
764
GAsyncReadyCallback callback,
767
ZeitgeistLogPrivate *priv;
768
EggZeitgeistTimeRange *_time_range;
769
EggDBusArraySeq *_event_templates, *_result_event_templates;
770
gpointer *dispatch_data;
772
g_return_if_fail (ZEITGEIST_IS_LOG (self));
773
g_return_if_fail (ZEITGEIST_IS_TIME_RANGE (time_range));
774
g_return_if_fail (event_templates != NULL);
775
g_return_if_fail (result_event_templates != NULL);
776
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE(cancellable));
778
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
780
/* Own all floating refs on the events and the time_range */
781
g_ptr_array_foreach (event_templates, (GFunc) g_object_ref_sink, NULL);
782
g_ptr_array_foreach (result_event_templates, (GFunc) g_object_ref_sink, NULL);
783
g_object_ref_sink (time_range);
785
_time_range = _zeitgeist_time_range_to_egg_zeitgeist_time_range (time_range);
786
_event_templates = _zeitgeist_events_to_egg_zeitgeist_events (event_templates);
787
_result_event_templates = _zeitgeist_events_to_egg_zeitgeist_events (event_templates);
789
dispatch_data = g_new (gpointer, 3);
790
dispatch_data[0] = g_object_ref (self);
791
dispatch_data[1] = callback;
792
dispatch_data[2] = user_data;
794
egg_zeitgeist_log_find_related_uris (priv->log,
795
EGG_DBUS_CALL_FLAGS_NONE,
798
_result_event_templates,
799
(EggZeitgeistStorageState) storage_state,
801
(EggZeitgeistResultType) result_type,
803
dispatch_async_callback,
806
/* Release the event templates */
807
g_ptr_array_foreach (event_templates, (GFunc) g_object_unref, NULL);
808
g_ptr_array_foreach (result_event_templates, (GFunc) g_object_unref, NULL);
809
g_ptr_array_unref (event_templates);
810
g_ptr_array_unref (result_event_templates);
811
g_object_unref (time_range);
812
g_object_unref (_event_templates);
813
g_object_unref (_result_event_templates);
814
g_object_unref (_time_range);
818
zeitgeist_log_find_related_uris_finish (ZeitgeistLog *self,
822
ZeitgeistLogPrivate *priv;
826
g_return_val_if_fail (ZEITGEIST_IS_LOG (self), FALSE);
827
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
828
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
830
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
832
egg_zeitgeist_log_find_related_uris_finish (priv->log,
841
_zeitgeist_log_send_void (SendVoidFunc send_void,
843
GCancellable *cancellable,
844
GAsyncReadyCallback callback,
847
ZeitgeistLogPrivate *priv;
848
gpointer *dispatch_data;
850
g_return_if_fail (ZEITGEIST_IS_LOG (self));
851
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE(cancellable));
853
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
855
dispatch_data = g_new (gpointer, 3);
856
dispatch_data[0] = g_object_ref (self);
857
dispatch_data[1] = callback;
858
dispatch_data[2] = user_data;
860
send_void (priv->log,
861
EGG_DBUS_CALL_FLAGS_NONE,
863
dispatch_async_callback,
868
zeitgeist_log_delete_log (ZeitgeistLog *self,
869
GCancellable *cancellable,
870
GAsyncReadyCallback callback,
873
_zeitgeist_log_send_void (egg_zeitgeist_log_delete_log,
874
self, cancellable, callback, user_data);
878
zeitgeist_log_delete_log_finish (ZeitgeistLog *self,
882
_zeitgeist_log_collect_void (egg_zeitgeist_log_delete_log_finish,
887
zeitgeist_log_quit (ZeitgeistLog *self,
888
GCancellable *cancellable,
889
GAsyncReadyCallback callback,
892
_zeitgeist_log_send_void (egg_zeitgeist_log_quit,
893
self, cancellable, callback, user_data);
897
zeitgeist_log_quit_finish (ZeitgeistLog *self,
901
_zeitgeist_log_collect_void (egg_zeitgeist_log_quit_finish,
906
_zeitgeist_log_install_monitor (ZeitgeistLog *self,
907
ZeitgeistMonitor *monitor,
908
GCancellable *cancellable,
909
GAsyncReadyCallback callback,
912
ZeitgeistLogPrivate *priv;
913
EggZeitgeistTimeRange *_time_range;
914
EggDBusArraySeq *_event_templates;
915
EggDBusConnection *connection;
916
gpointer *dispatch_data;
918
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
920
/* Export the monitor, client side, on the session bus. Once the last
921
* ref to the monitor is dropped eggdbus will automatically unregister it */
922
connection = egg_dbus_object_proxy_get_connection (priv->log_proxy);
923
egg_dbus_connection_register_interface (connection,
924
zeitgeist_monitor_get_path (monitor),
925
EGG_ZEITGEIST_TYPE_MONITOR,
929
/* Register the monitor with the ZG daemon */
930
_time_range = _zeitgeist_time_range_to_egg_zeitgeist_time_range (
931
zeitgeist_monitor_get_time_range (monitor));
932
_event_templates = _zeitgeist_events_to_egg_zeitgeist_events (
933
zeitgeist_monitor_get_templates (monitor));
935
dispatch_data = g_new (gpointer, 3);
936
dispatch_data[0] = g_object_ref (self);
937
dispatch_data[1] = callback;
938
dispatch_data[2] = user_data;
940
egg_zeitgeist_log_install_monitor (priv->log,
941
EGG_DBUS_CALL_FLAGS_NONE,
942
zeitgeist_monitor_get_path (monitor),
946
dispatch_async_callback,
949
/* Release the event templates */
950
g_object_unref (_event_templates);
951
g_object_unref (_time_range);
955
zeitgeist_log_install_monitor (ZeitgeistLog *self,
956
ZeitgeistMonitor *monitor,
957
GCancellable *cancellable,
958
GAsyncReadyCallback callback,
961
ZeitgeistLogPrivate *priv;
963
g_return_if_fail (ZEITGEIST_IS_LOG (self));
964
g_return_if_fail (ZEITGEIST_IS_MONITOR (monitor));
965
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE(cancellable));
967
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
969
/* Track the monitor so we can reinstate it if the Zeitgeist daemon
970
* leaves and reappears on the bus */
971
g_object_weak_ref (G_OBJECT (monitor),
972
(GWeakNotify) _zeitgeist_log_on_monitor_destroyed,
974
g_hash_table_insert (priv->monitors, monitor, monitor);
976
_zeitgeist_log_install_monitor (self, monitor,
977
cancellable, callback, user_data);
981
zeitgeist_log_install_monitor_finish (ZeitgeistLog *self,
985
return _zeitgeist_log_collect_void (egg_zeitgeist_log_install_monitor_finish,
990
zeitgeist_log_remove_monitor (ZeitgeistLog *self,
991
ZeitgeistMonitor *monitor,
992
GCancellable *cancellable,
993
GAsyncReadyCallback callback,
996
ZeitgeistLogPrivate *priv;
997
EggDBusConnection *connection;
998
gpointer *dispatch_data;
1000
g_return_if_fail (ZEITGEIST_IS_LOG (self));
1001
g_return_if_fail (ZEITGEIST_IS_MONITOR (monitor));
1002
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE(cancellable));
1004
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
1006
/* Retract the monitor from the session bus */
1007
connection = egg_dbus_object_proxy_get_connection (priv->log_proxy);
1008
egg_dbus_connection_unregister_interface (connection,
1009
zeitgeist_monitor_get_path (monitor),
1010
EGG_ZEITGEIST_TYPE_MONITOR,
1013
dispatch_data = g_new (gpointer, 3);
1014
dispatch_data[0] = g_object_ref (self);
1015
dispatch_data[1] = callback;
1016
dispatch_data[2] = user_data;
1018
egg_zeitgeist_log_remove_monitor (priv->log,
1019
EGG_DBUS_CALL_FLAGS_NONE,
1020
zeitgeist_monitor_get_path (monitor),
1022
dispatch_async_callback,
1027
zeitgeist_log_remove_monitor_finish (ZeitgeistLog *self,
1031
return _zeitgeist_log_collect_void (egg_zeitgeist_log_remove_monitor_finish,
1035
/* Helper for dropping a weak ref from a log on a monitor. The method
1036
* signature makes it suitable for casting to a GHFunc */
1038
_zeitgeist_monitor_weak_unref (ZeitgeistMonitor *monitor,
1041
g_object_weak_unref (G_OBJECT (monitor),
1042
(GWeakNotify) _zeitgeist_log_on_monitor_destroyed,
1046
/* Called when a monitor is finalized, by virtue of our weak ref */
1048
_zeitgeist_log_on_monitor_destroyed (ZeitgeistLog *self,
1049
ZeitgeistMonitor *monitor)
1051
ZeitgeistLogPrivate *priv;
1053
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
1054
g_hash_table_remove (priv->monitors, monitor);
1057
/* Called when the Zeitgeist daemon enters/leaves the bus */
1059
_zeitgeist_log_on_name_owner_changed (ZeitgeistLog *self)
1061
ZeitgeistLogPrivate *priv;
1064
priv = ZEITGEIST_LOG_GET_PRIVATE (self);
1065
g_object_get (priv->log_proxy, "name-owner", &name_owner, NULL);
1067
if (name_owner == NULL)
1069
/* The Zeitgeist daemon disconnected. Do nothing */
1073
/* The Zeitgeist daemon entered the bus. Reinstate all active monitors */
1074
GHashTableIter iter;
1075
gpointer monitor, dummy;
1077
g_hash_table_iter_init (&iter, priv->monitors);
1078
while (g_hash_table_iter_next (&iter, &monitor, &dummy))
1080
_zeitgeist_log_install_monitor (self, ZEITGEIST_MONITOR (monitor),
1083
g_free (name_owner);
b'\\ No newline at end of file'