[evolution-data-server/eclient] Calendar's getFreeBusy notifies about components with a signal



commit 507a774695ac82968aa3eb3c263c78a582136490
Author: Milan Crha <mcrha redhat com>
Date:   Tue Apr 26 16:34:08 2011 +0200

    Calendar's getFreeBusy notifies about components with a signal

 addressbook/libebook/e-book-client.c             |    3 -
 calendar/libecal/e-cal-client.c                  |  147 +++++++++++-----------
 calendar/libecal/e-cal-client.h                  |    7 +-
 calendar/libecal/e-cal.c                         |  118 +++++++++++-------
 calendar/libedata-cal/e-cal-backend-sync.c       |    4 +-
 calendar/libedata-cal/e-data-cal.c               |   28 +++--
 calendar/libedata-cal/e-data-cal.h               |    3 +-
 calendar/libegdbus/e-gdbus-cal.c                 |   25 +++-
 calendar/libegdbus/e-gdbus-cal.h                 |   11 +-
 libedataserver/e-client.c                        |   50 ++++++++
 libedataserver/e-client.h                        |    2 +
 tests/libecal/client/test-client-get-free-busy.c |   37 ++++--
 tests/libecal/ecal-test-utils.c                  |    1 -
 tests/libecal/test-ecal-get-free-busy.c          |    3 +-
 14 files changed, 280 insertions(+), 159 deletions(-)
---
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index 7cf6cc7..a78de81 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -2433,14 +2433,11 @@ static void
 book_client_finalize (GObject *object)
 {
 	EBookClient *client;
-	EBookClientPrivate *priv;
 
 	client = E_BOOK_CLIENT (object);
 	g_return_if_fail (client != NULL);
 	g_return_if_fail (client->priv != NULL);
 
-	priv = client->priv;
-
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (e_book_client_parent_class)->finalize (object);
 
diff --git a/calendar/libecal/e-cal-client.c b/calendar/libecal/e-cal-client.c
index 5fe0ec4..280cd0e 100644
--- a/calendar/libecal/e-cal-client.c
+++ b/calendar/libecal/e-cal-client.c
@@ -55,6 +55,13 @@ struct _ECalClientPrivate
 	GHashTable *zone_cache;
 };
 
+enum {
+	FREE_BUSY_DATA,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
 G_DEFINE_TYPE (ECalClient, e_cal_client, E_TYPE_CLIENT)
 
 /**
@@ -460,6 +467,48 @@ auth_required_cb (EGdbusCal *object, const gchar * const *credentials_strv, ECal
 	e_credentials_free (credentials);
 }
 
+static void
+free_busy_data_cb (EGdbusCal *object, const gchar * const *free_busy_strv, ECalClient *client)
+{
+	GSList *ecalcomps = NULL;
+	gint ii;
+
+	g_return_if_fail (client != NULL);
+	g_return_if_fail (E_IS_CAL_CLIENT (client));
+	g_return_if_fail (free_busy_strv != NULL);
+
+
+	for (ii = 0; free_busy_strv[ii]; ii++) {
+		ECalComponent *comp;
+		icalcomponent *icalcomp;
+		icalcomponent_kind kind;
+
+		icalcomp = icalcomponent_new_from_string (free_busy_strv[ii]);
+		if (!icalcomp)
+			continue;
+
+		kind = icalcomponent_isa (icalcomp);
+		if (kind == ICAL_VFREEBUSY_COMPONENT) {
+			comp = e_cal_component_new ();
+			if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+				icalcomponent_free (icalcomp);
+				g_object_unref (G_OBJECT (comp));
+				continue;
+			}
+
+			ecalcomps = g_slist_prepend (ecalcomps, comp);
+		} else {
+			icalcomponent_free (icalcomp);
+		}
+	}
+
+	ecalcomps = g_slist_reverse (ecalcomps);
+
+	g_signal_emit (client, signals[FREE_BUSY_DATA], 0, ecalcomps);
+
+	e_client_util_free_object_slist (ecalcomps);
+}
+
 static EDataCalObjType
 convert_type (ECalClientSourceType type)
 {
@@ -586,6 +635,7 @@ e_cal_client_new (ESource *source, ECalClientSourceType source_type, GError **er
 	g_signal_connect (client->priv->gdbus_cal, "readonly", G_CALLBACK (readonly_cb), client);
 	g_signal_connect (client->priv->gdbus_cal, "online", G_CALLBACK (online_cb), client);
 	g_signal_connect (client->priv->gdbus_cal, "auth-required", G_CALLBACK (auth_required_cb), client);
+	g_signal_connect (client->priv->gdbus_cal, "free-busy-data", G_CALLBACK (free_busy_data_cb), client);
 
 	return client;
 }
@@ -1629,14 +1679,11 @@ static void
 foreach_tzid_callback (icalparameter *param, gpointer cbdata)
 {
 	ForeachTZIDCallbackData *data = cbdata;
-	ECalClientPrivate *priv;
 	const gchar *tzid;
 	icaltimezone *zone = NULL;
 	icalcomponent *vtimezone_comp;
 	gchar *vtimezone_as_string;
 
-	priv = data->client->priv;
-
 	/* Get the TZID string from the parameter. */
 	tzid = icalparameter_get_tzid (param);
 	if (!tzid)
@@ -2848,8 +2895,9 @@ e_cal_client_get_object_list_as_comps_sync (ECalClient *client, const gchar *sex
  * @callback: callback to call when a result is ready
  * @user_data: user data for the @callback
  *
- * Gets free/busy information from the calendar server
- * as a list of #ECalComponent-s.
+ * Begins retrieval of free/busy information from the calendar server
+ * as a list of #ECalComponent-s. Connect to "free-busy-data" signal
+ * to receive chunks of free/busy components.
  * The call is finished by e_cal_client_get_free_busy_finish() from
  * the @callback.
  *
@@ -2872,84 +2920,30 @@ e_cal_client_get_free_busy (ECalClient *client, time_t start, time_t end, const
 
 	opid = e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) strv, cancellable, callback, user_data, e_cal_client_get_free_busy,
 			e_gdbus_cal_call_get_free_busy,
-			NULL, NULL, NULL, e_gdbus_cal_call_get_free_busy_finish, NULL);
+			e_gdbus_cal_call_get_free_busy_finish, NULL, NULL, NULL, NULL);
 
 	g_strfreev (strv);
 
 	return opid;
 }
 
-static gboolean
-complete_get_free_busy (gboolean res, gchar **out_strv, GSList **ecalcomps, GError **error)
-{
-	g_return_val_if_fail (ecalcomps != NULL, FALSE);
-
-	*ecalcomps = NULL;
-
-	if (res && out_strv) {
-		gint ii;
-
-		for (ii = 0; out_strv[ii]; ii++) {
-			ECalComponent *comp;
-			icalcomponent *icalcomp;
-			icalcomponent_kind kind;
-
-			icalcomp = icalcomponent_new_from_string (out_strv[ii]);
-			if (!icalcomp)
-				continue;
-
-			kind = icalcomponent_isa (icalcomp);
-			if (kind == ICAL_VFREEBUSY_COMPONENT) {
-				comp = e_cal_component_new ();
-				if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
-					icalcomponent_free (icalcomp);
-					g_object_unref (G_OBJECT (comp));
-					continue;
-				}
-
-				*ecalcomps = g_slist_prepend (*ecalcomps, comp);
-			} else {
-				icalcomponent_free (icalcomp);
-			}
-		}
-
-		*ecalcomps = g_slist_reverse (*ecalcomps);
-	} else {
-		res = FALSE;
-	}
-
-	g_strfreev (out_strv);
-
-	return res;
-}
-
 /**
  * e_cal_client_get_free_busy_finish:
  * @client: an #ECalClient
  * @result: a #GAsyncResult
- * @ecalcomps: (out): Return value for VFREEBUSY #ECalComponent objects.
  * @error: (out): a #GError to set an error, if any
  *
- * Finishes previous call of e_cal_client_get_free_busy() and sets @ecalcomps
- * with fetched free/busy information from the calendar server.
- * The @ecalcomps is a list of #ECalComponent.
- * This list should be freed with #e_cal_client_free_ecalcomp_slist().
+ * Finishes previous call of e_cal_client_get_free_busy().
+ * All VFREEBUSY #ECalComponent-s were received by "free-busy-data" signal.
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
  * Since: 3.2
  **/
 gboolean
-e_cal_client_get_free_busy_finish (ECalClient *client, GAsyncResult *result, GSList **ecalcomps, GError **error)
+e_cal_client_get_free_busy_finish (ECalClient *client, GAsyncResult *result, GError **error)
 {
-	gboolean res;
-	gchar **out_strv = NULL;
-
-	g_return_val_if_fail (ecalcomps != NULL, FALSE);
-
-	res = e_client_proxy_call_finish_strv (E_CLIENT (client), result, &out_strv, error, e_cal_client_get_free_busy);
-
-	return complete_get_free_busy (res, out_strv, ecalcomps, error);
+	return e_client_proxy_call_finish_void (E_CLIENT (client), result, error, e_cal_client_get_free_busy);
 }
 
 /**
@@ -2958,29 +2952,26 @@ e_cal_client_get_free_busy_finish (ECalClient *client, GAsyncResult *result, GSL
  * @start: Start time for query
  * @end: End time for query
  * @users: List of users to retrieve free/busy information for
- * @ecalcomps: (out): Return value for VFREEBUSY #ECalComponent objects.
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
- * Gets free/busy information from the calendar server. The objects will
- * be returned in the @ecalcomps argument, which is a list of #ECalComponent.
- * This list should be freed with #e_cal_client_free_ecalcomp_slist().
+ * Gets free/busy information from the calendar server.
+ * All VFREEBUSY #ECalComponent-s were received by "free-busy-data" signal.
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  *
  * Since: 3.2
  **/
 gboolean
-e_cal_client_get_free_busy_sync (ECalClient *client, time_t start, time_t end, const GSList *users, GSList **ecalcomps, GCancellable *cancellable, GError **error)
+e_cal_client_get_free_busy_sync (ECalClient *client, time_t start, time_t end, const GSList *users, GCancellable *cancellable, GError **error)
 {
 	gboolean res;
-	gchar **strv, **out_strv = NULL;
+	gchar **strv;
 
 	g_return_val_if_fail (client != NULL, FALSE);
 	g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
 	g_return_val_if_fail (client->priv != NULL, FALSE);
 	g_return_val_if_fail (users != NULL, FALSE);
-	g_return_val_if_fail (ecalcomps != NULL, FALSE);
 
 	if (!client->priv->gdbus_cal) {
 		g_set_error_literal (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_DBUS_ERROR, _("D-Bus calendar proxy gone"));
@@ -2988,10 +2979,10 @@ e_cal_client_get_free_busy_sync (ECalClient *client, time_t start, time_t end, c
 	}
 
 	strv = e_gdbus_cal_encode_get_free_busy (start, end, users);
-	res = e_client_proxy_call_sync_strv__strv (E_CLIENT (client), (const gchar * const *) strv, &out_strv, cancellable, error, e_gdbus_cal_call_get_free_busy_sync);
+	res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) strv, cancellable, error, e_gdbus_cal_call_get_free_busy_sync);
 	g_strfreev (strv);
 
-	return complete_get_free_busy (res, out_strv, ecalcomps, error);
+	return res;
 }
 
 /**
@@ -4390,4 +4381,14 @@ e_cal_client_class_init (ECalClientClass *klass)
 	client_class->remove = cal_client_remove;
 	client_class->remove_finish = cal_client_remove_finish;
 	client_class->remove_sync = cal_client_remove_sync;
+
+	signals[FREE_BUSY_DATA] = g_signal_new (
+		"free-busy-data",
+		G_OBJECT_CLASS_TYPE (klass),
+		G_SIGNAL_RUN_FIRST,
+		G_STRUCT_OFFSET (ECalClientClass, free_busy_data),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__POINTER,
+		G_TYPE_NONE, 1,
+		G_TYPE_POINTER);
 }
diff --git a/calendar/libecal/e-cal-client.h b/calendar/libecal/e-cal-client.h
index 479d977..2802add 100644
--- a/calendar/libecal/e-cal-client.h
+++ b/calendar/libecal/e-cal-client.h
@@ -91,6 +91,9 @@ struct _ECalClient {
 
 struct _ECalClientClass {
 	EClientClass parent;
+
+	/* Signals */
+	void (* free_busy_data) (ECalClient *client, const GSList *free_busy_ecalcomps);
 };
 
 GType			e_cal_client_get_type			(void);
@@ -167,8 +170,8 @@ gboolean	e_cal_client_get_object_list_as_comps_finish	(ECalClient *client, GAsyn
 gboolean	e_cal_client_get_object_list_as_comps_sync	(ECalClient *client, const gchar *sexp, GSList **ecalcomps, GCancellable *cancellable, GError **error);
 
 guint32		e_cal_client_get_free_busy			(ECalClient *client, time_t start, time_t end, const GSList *users, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean	e_cal_client_get_free_busy_finish		(ECalClient *client, GAsyncResult *result, GSList **ecalcomps, GError **error);
-gboolean	e_cal_client_get_free_busy_sync			(ECalClient *client, time_t start, time_t end, const GSList *users, GSList **ecalcomps, GCancellable *cancellable, GError **error);
+gboolean	e_cal_client_get_free_busy_finish		(ECalClient *client, GAsyncResult *result, GError **error);
+gboolean	e_cal_client_get_free_busy_sync			(ECalClient *client, time_t start, time_t end, const GSList *users, GCancellable *cancellable, GError **error);
 
 guint32		e_cal_client_create_object			(ECalClient *client, const icalcomponent *icalcomp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
 gboolean	e_cal_client_create_object_finish		(ECalClient *client, GAsyncResult *result, gchar **uid, GError **error);
diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c
index 90127b8..9b1a942 100644
--- a/calendar/libecal/e-cal.c
+++ b/calendar/libecal/e-cal.c
@@ -123,6 +123,9 @@ struct _ECalPrivate {
 	/* For locking the operation while localling cache values like 
 	   static capabilities, cal address etc. */
 	GStaticRecMutex cache_lock;
+
+	GList **free_busy_data;
+	GMutex *free_busy_data_lock;
 };
 
 
@@ -435,6 +438,7 @@ e_cal_init (ECal *ecal)
 	priv->gdbus_cal = NULL;
 	priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
 	priv->default_zone = icaltimezone_get_utc_timezone ();
+	priv->free_busy_data_lock = g_mutex_new ();
 	g_static_rec_mutex_init (&priv->cache_lock);
 }
 
@@ -570,10 +574,20 @@ e_cal_finalize (GObject *object)
 		priv->capabilities = NULL;
 	}
 
+	if (priv->free_busy_data) {
+		g_mutex_lock (priv->free_busy_data_lock);
+		g_list_foreach (*priv->free_busy_data, (GFunc) g_object_unref, NULL);
+		g_list_free (*priv->free_busy_data);
+		*priv->free_busy_data = NULL;
+		priv->free_busy_data = NULL;
+		g_mutex_unlock (priv->free_busy_data_lock);
+	}
+
 	g_hash_table_foreach (priv->timezones, free_timezone, NULL);
 	g_hash_table_destroy (priv->timezones);
 	priv->timezones = NULL;
 	g_static_rec_mutex_free (&priv->cache_lock);
+	g_mutex_free (priv->free_busy_data_lock);
 
 	(* G_OBJECT_CLASS (parent_class)->finalize) (object);
 
@@ -931,7 +945,7 @@ reopen_with_auth (gpointer data)
 }
 
 static void
-auth_required_cb (EGdbusCal *gdbus_cal, const ECredentials *credentials, ECal *cal)
+auth_required_cb (EGdbusCal *gdbus_cal, const gchar * const *credentials_strv, ECal *cal)
 {
 	ECalPrivate *priv;
 	g_return_if_fail (E_IS_CAL (cal));
@@ -944,6 +958,51 @@ auth_required_cb (EGdbusCal *gdbus_cal, const ECredentials *credentials, ECal *c
 		g_idle_add (reopen_with_auth, (gpointer) cal);
 }
 
+static void
+free_busy_data_cb (EGdbusCal *gdbus_cal, const gchar * const *free_busy_strv, ECal *cal)
+{
+	ECalPrivate *priv;
+
+	g_return_if_fail (E_IS_CAL (cal));
+
+	priv = cal->priv;
+
+	g_mutex_lock (priv->free_busy_data_lock);
+
+	if (priv->free_busy_data) {
+		gint ii;
+		GList *list = *priv->free_busy_data;
+
+		for (ii = 0; free_busy_strv[ii]; ii++) {
+			ECalComponent *comp;
+			icalcomponent *icalcomp;
+			icalcomponent_kind kind;
+
+			icalcomp = icalcomponent_new_from_string (free_busy_strv[ii]);
+			if (!icalcomp)
+				continue;
+
+			kind = icalcomponent_isa (icalcomp);
+			if (kind == ICAL_VFREEBUSY_COMPONENT) {
+				comp = e_cal_component_new ();
+				if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+					icalcomponent_free (icalcomp);
+					g_object_unref (G_OBJECT (comp));
+					continue;
+				}
+
+				list = g_list_append (list, comp);
+			} else {
+				icalcomponent_free (icalcomp);
+			}
+		}
+
+		*priv->free_busy_data = list;
+	}
+
+	g_mutex_unlock (priv->free_busy_data_lock);
+}
+
 typedef struct
 {
 	ECal *ecal;
@@ -1117,6 +1176,7 @@ e_cal_new (ESource *source, ECalSourceType type)
 	g_signal_connect (priv->gdbus_cal, "backend-error", G_CALLBACK (backend_error_cb), ecal);
 	g_signal_connect (priv->gdbus_cal, "readonly", G_CALLBACK (readonly_cb), ecal);
 	g_signal_connect (priv->gdbus_cal, "online", G_CALLBACK (online_cb), ecal);
+	g_signal_connect (priv->gdbus_cal, "free-busy-data", G_CALLBACK (free_busy_data_cb), ecal);
 
 	/* Set the local attachment store path for the calendar */
 	set_local_attachment_store (ecal);
@@ -2748,40 +2808,6 @@ e_cal_free_object_list (GList *objects)
 	g_list_free (objects);
 }
 
-static GList *
-build_free_busy_list (const gchar **seq)
-{
-	GList *list = NULL;
-	gint i;
-
-	/* Create the list in reverse order */
-	for (i = 0; seq[i]; i++) {
-		ECalComponent *comp;
-		icalcomponent *icalcomp;
-		icalcomponent_kind kind;
-
-		icalcomp = icalcomponent_new_from_string ((gchar *)seq[i]);
-		if (!icalcomp)
-			continue;
-
-		kind = icalcomponent_isa (icalcomp);
-		if (kind == ICAL_VFREEBUSY_COMPONENT) {
-			comp = e_cal_component_new ();
-			if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
-				icalcomponent_free (icalcomp);
-				g_object_unref (G_OBJECT (comp));
-				continue;
-			}
-
-			list = g_list_append (list, comp);
-		} else {
-			icalcomponent_free (icalcomp);
-		}
-	}
-
-	return list;
-}
-
 /**
  * e_cal_get_free_busy
  * @ecal: A calendar client.
@@ -2803,7 +2829,6 @@ e_cal_get_free_busy (ECal *ecal, GList *users, time_t start, time_t end,
 {
 	ECalPrivate *priv;
 	gchar **strv;
-	gchar **freebusy_array = NULL;
 	GSList *susers;
 	GList *l;
 
@@ -2826,18 +2851,25 @@ e_cal_get_free_busy (ECal *ecal, GList *users, time_t start, time_t end,
 	strv = e_gdbus_cal_encode_get_free_busy (start, end, susers);
 	g_slist_free (susers);
 
-	if (!e_gdbus_cal_call_get_free_busy_sync (priv->gdbus_cal, (const gchar * const *) strv, &freebusy_array, NULL, error)) {
+	g_mutex_lock (priv->free_busy_data_lock);
+	priv->free_busy_data = freebusy;
+	g_mutex_unlock (priv->free_busy_data_lock);
+
+	if (!e_gdbus_cal_call_get_free_busy_sync (priv->gdbus_cal, (const gchar * const *) strv, NULL, error)) {
 		g_strfreev (strv);
+		g_mutex_lock (priv->free_busy_data_lock);
+		priv->free_busy_data = NULL;
+		g_mutex_unlock (priv->free_busy_data_lock);
+
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_DBUS_EXCEPTION, error);
 	}
 	g_strfreev (strv);
 
-	if (freebusy_array) {
-		*freebusy = build_free_busy_list ((const gchar **) freebusy_array);
-		g_strfreev (freebusy_array);
-		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
-	} else
-		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OTHER_ERROR, error);
+	g_mutex_lock (priv->free_busy_data_lock);
+	priv->free_busy_data = NULL;
+	g_mutex_unlock (priv->free_busy_data_lock);
+
+	E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
 }
 
 struct comp_instance {
diff --git a/calendar/libedata-cal/e-cal-backend-sync.c b/calendar/libedata-cal/e-cal-backend-sync.c
index 1a9639d..52264bf 100644
--- a/calendar/libedata-cal/e-cal-backend-sync.c
+++ b/calendar/libedata-cal/e-cal-backend-sync.c
@@ -596,7 +596,9 @@ cal_backend_get_free_busy (ECalBackend *backend, EDataCal *cal, guint32 opid, GC
 
 	e_cal_backend_sync_get_free_busy (E_CAL_BACKEND_SYNC (backend), cal, cancellable, users, start, end, &freebusyobjs, &error);
 
-	e_data_cal_respond_get_free_busy (cal, opid, error, freebusyobjs);
+	if (freebusyobjs)
+		e_data_cal_report_free_busy_data (cal, freebusyobjs);
+	e_data_cal_respond_get_free_busy (cal, opid, error);
 
 	g_slist_foreach (freebusyobjs, (GFunc) g_free, NULL);
 	g_slist_free (freebusyobjs);
diff --git a/calendar/libedata-cal/e-data-cal.c b/calendar/libedata-cal/e-data-cal.c
index 7aeddf6..9cab4d1 100644
--- a/calendar/libedata-cal/e-data-cal.c
+++ b/calendar/libedata-cal/e-data-cal.c
@@ -1150,25 +1150,20 @@ e_data_cal_respond_get_object_list (EDataCal *cal, guint32 opid, GError *error,
  * e_data_cal_respond_get_free_busy:
  * @cal: A calendar client interface.
  * @error: Operation error, if any, automatically freed if passed it.
- * @freebusy: List of free/busy objects.
  *
  * Notifies listeners of the completion of the get_free_busy method call.
+ * To pass actual free/busy objects to the client use e_data_cal_report_free_busy_data().
  */
 void
-e_data_cal_respond_get_free_busy (EDataCal *cal, guint32 opid, GError *error, const GSList *freebusy)
+e_data_cal_respond_get_free_busy (EDataCal *cal, guint32 opid, GError *error)
 {
-	gchar **strv_freebusy;
-
 	op_complete (cal, opid);
 
 	/* Translators: This is prefix to a detailed error message */
 	g_prefix_error (&error, "%s", _("Cannot retrieve calendar free/busy list: "));
 
-	strv_freebusy = gslist_to_strv (freebusy);
+	e_gdbus_cal_emit_get_free_busy_done (cal->priv->gdbus_object, opid, error);
 
-	e_gdbus_cal_emit_get_free_busy_done (cal->priv->gdbus_object, opid, error, (const gchar * const *) strv_freebusy);
-
-	g_strfreev (strv_freebusy);
 	if (error)
 		g_error_free (error);
 }
@@ -1181,7 +1176,8 @@ e_data_cal_respond_get_free_busy (EDataCal *cal, guint32 opid, GError *error, co
  * @object: The object created as an iCalendar string.
  *
  * Notifies listeners of the completion of the create_object method call.
- */void
+ */
+void
 e_data_cal_respond_create_object (EDataCal *cal, guint32 opid, GError *error,
 				  const gchar *uid, const gchar *object)
 {
@@ -1448,6 +1444,20 @@ e_data_cal_report_auth_required (EDataCal *cal, const ECredentials *credentials)
 	g_strfreev (strv);
 }
 
+void
+e_data_cal_report_free_busy_data (EDataCal *cal, const GSList *freebusy)
+{
+	gchar **strv_freebusy;
+
+	g_return_if_fail (cal != NULL);
+
+	strv_freebusy = gslist_to_strv (freebusy);
+
+	e_gdbus_cal_emit_free_busy_data (cal->priv->gdbus_object, (const gchar * const *) strv_freebusy);
+
+	g_strfreev (strv_freebusy);
+}
+
 /* Instance init */
 static void
 e_data_cal_init (EDataCal *ecal)
diff --git a/calendar/libedata-cal/e-data-cal.h b/calendar/libedata-cal/e-data-cal.h
index b962fc5..14923f7 100644
--- a/calendar/libedata-cal/e-data-cal.h
+++ b/calendar/libedata-cal/e-data-cal.h
@@ -118,7 +118,7 @@ void		e_data_cal_respond_get_alarm_email_address	(EDataCal *cal, guint32 opid, G
 void		e_data_cal_respond_get_default_object		(EDataCal *cal, guint32 opid, GError *error, const gchar *object);
 void		e_data_cal_respond_get_object			(EDataCal *cal, guint32 opid, GError *error, const gchar *object);
 void		e_data_cal_respond_get_object_list		(EDataCal *cal, guint32 opid, GError *error, const GSList *objects);
-void		e_data_cal_respond_get_free_busy		(EDataCal *cal, guint32 opid, GError *error, const GSList *freebusy);
+void		e_data_cal_respond_get_free_busy		(EDataCal *cal, guint32 opid, GError *error);
 void		e_data_cal_respond_create_object		(EDataCal *cal, guint32 opid, GError *error, const gchar *uid, const gchar *object);
 void		e_data_cal_respond_modify_object		(EDataCal *cal, guint32 opid, GError *error, const gchar *old_object, const gchar *object);
 void		e_data_cal_respond_remove_object		(EDataCal *cal, guint32 opid, GError *error, const ECalComponentId *id, const gchar *old_object, const gchar *object);
@@ -133,6 +133,7 @@ void		e_data_cal_report_error				(EDataCal *cal, const gchar *message);
 void		e_data_cal_report_readonly			(EDataCal *cal, gboolean is_readonly);
 void		e_data_cal_report_online			(EDataCal *cal, gboolean is_online);
 void		e_data_cal_report_auth_required			(EDataCal *cal, const ECredentials *credentials);
+void		e_data_cal_report_free_busy_data		(EDataCal *cal, const GSList *freebusy);
 
 G_END_DECLS
 
diff --git a/calendar/libegdbus/e-gdbus-cal.c b/calendar/libegdbus/e-gdbus-cal.c
index 12c20ad..6d0b6d1 100644
--- a/calendar/libegdbus/e-gdbus-cal.c
+++ b/calendar/libegdbus/e-gdbus-cal.c
@@ -40,6 +40,7 @@ enum
 	__READONLY_SIGNAL,
 	__ONLINE_SIGNAL,
 	__AUTH_REQUIRED_SIGNAL,
+	__FREE_BUSY_DATA_SIGNAL,
 	__OPEN_METHOD,
 	__OPEN_DONE_SIGNAL,
 	__AUTHENTICATE_USER_METHOD,
@@ -134,6 +135,7 @@ E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRING  (GDBUS_CAL_INTERFACE_NAME, backend_
 E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_BOOLEAN (GDBUS_CAL_INTERFACE_NAME, readonly)
 E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_BOOLEAN (GDBUS_CAL_INTERFACE_NAME, online)
 E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV    (GDBUS_CAL_INTERFACE_NAME, auth_required)
+E_DECLARE_GDBUS_SIGNAL_EMISSION_HOOK_STRV    (GDBUS_CAL_INTERFACE_NAME, free_busy_data)
 
 E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID	(GDBUS_CAL_INTERFACE_NAME, open)
 E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID	(GDBUS_CAL_INTERFACE_NAME, authenticate_user)
@@ -146,7 +148,7 @@ E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING	(GDBUS_CAL_INTERFACE_NAME
 E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING	(GDBUS_CAL_INTERFACE_NAME, get_default_object)
 E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING	(GDBUS_CAL_INTERFACE_NAME, get_object)
 E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV	(GDBUS_CAL_INTERFACE_NAME, get_object_list)
-E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV	(GDBUS_CAL_INTERFACE_NAME, get_free_busy)
+E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID	(GDBUS_CAL_INTERFACE_NAME, get_free_busy)
 E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING	(GDBUS_CAL_INTERFACE_NAME, create_object)
 E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID	(GDBUS_CAL_INTERFACE_NAME, modify_object)
 E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID	(GDBUS_CAL_INTERFACE_NAME, remove_object)
@@ -171,6 +173,7 @@ e_gdbus_cal_default_init (EGdbusCalIface *iface)
 	E_INIT_GDBUS_SIGNAL_BOOLEAN		(EGdbusCalIface, "readonly",		readonly,	__READONLY_SIGNAL)
 	E_INIT_GDBUS_SIGNAL_BOOLEAN		(EGdbusCalIface, "online",		online,		__ONLINE_SIGNAL)
 	E_INIT_GDBUS_SIGNAL_STRV   		(EGdbusCalIface, "auth_required", 	auth_required,	__AUTH_REQUIRED_SIGNAL)
+	E_INIT_GDBUS_SIGNAL_STRV   		(EGdbusCalIface, "free_busy_data", 	free_busy_data,	__FREE_BUSY_DATA_SIGNAL)
 
 	/* GObject signals definitions for D-Bus methods: */
 	E_INIT_GDBUS_METHOD_ASYNC_BOOLEAN__VOID	(EGdbusCalIface, "open",			open, __OPEN_METHOD, __OPEN_DONE_SIGNAL)
@@ -184,7 +187,7 @@ e_gdbus_cal_default_init (EGdbusCalIface *iface)
 	E_INIT_GDBUS_METHOD_ASYNC_VOID__STRING	(EGdbusCalIface, "getDefaultObject",		get_default_object, __GET_DEFAULT_OBJECT_METHOD, __GET_DEFAULT_OBJECT_DONE_SIGNAL)
 	E_INIT_GDBUS_METHOD_ASYNC_STRV__STRING	(EGdbusCalIface, "getObject",			get_object, __GET_OBJECT_METHOD, __GET_OBJECT_DONE_SIGNAL)
 	E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV	(EGdbusCalIface, "getObjectList",		get_object_list, __GET_OBJECT_LIST_METHOD, __GET_OBJECT_LIST_DONE_SIGNAL)
-	E_INIT_GDBUS_METHOD_ASYNC_STRV__STRV	(EGdbusCalIface, "getFreeBusy",			get_free_busy, __GET_FREE_BUSY_METHOD, __GET_FREE_BUSY_DONE_SIGNAL)
+	E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID	(EGdbusCalIface, "getFreeBusy",			get_free_busy, __GET_FREE_BUSY_METHOD, __GET_FREE_BUSY_DONE_SIGNAL)
 	E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusCalIface, "createObject",		create_object, __CREATE_OBJECT_METHOD, __CREATE_OBJECT_DONE_SIGNAL)
 	E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID	(EGdbusCalIface, "modifyObject",		modify_object, __MODIFY_OBJECT_METHOD, __MODIFY_OBJECT_DONE_SIGNAL)
 	E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID	(EGdbusCalIface, "removeObject",		remove_object, __REMOVE_OBJECT_METHOD, __REMOVE_OBJECT_DONE_SIGNAL)
@@ -517,15 +520,15 @@ e_gdbus_cal_call_get_free_busy (GDBusProxy *proxy, const gchar * const *in_start
 }
 
 gboolean
-e_gdbus_cal_call_get_free_busy_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_freebusy, GError **error)
+e_gdbus_cal_call_get_free_busy_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error)
 {
-	return e_gdbus_proxy_finish_call_strv (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_freebusy, error, e_gdbus_cal_call_get_free_busy);
+	return e_gdbus_proxy_finish_call_void (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, error, e_gdbus_cal_call_get_free_busy);
 }
 
 gboolean
-e_gdbus_cal_call_get_free_busy_sync (GDBusProxy *proxy, const gchar * const *in_start_end_userlist, gchar ***out_freebusy, GCancellable *cancellable, GError **error)
+e_gdbus_cal_call_get_free_busy_sync (GDBusProxy *proxy, const gchar * const *in_start_end_userlist, GCancellable *cancellable, GError **error)
 {
-	return e_gdbus_proxy_call_sync_strv__strv (proxy, in_start_end_userlist, out_freebusy, cancellable, error,
+	return e_gdbus_proxy_call_sync_strv__void (proxy, in_start_end_userlist, cancellable, error,
 		e_gdbus_cal_call_get_free_busy,
 		e_gdbus_cal_call_get_free_busy_finish);
 }
@@ -915,7 +918,7 @@ DECLARE_EMIT_DONE_SIGNAL_1 (get_alarm_email_address,	__GET_ALARM_EMAIL_ADDRESS_D
 DECLARE_EMIT_DONE_SIGNAL_1 (get_default_object,		__GET_DEFAULT_OBJECT_DONE_SIGNAL, const gchar *)
 DECLARE_EMIT_DONE_SIGNAL_1 (get_object,			__GET_OBJECT_DONE_SIGNAL, const gchar *)
 DECLARE_EMIT_DONE_SIGNAL_1 (get_object_list,		__GET_OBJECT_LIST_DONE_SIGNAL, const gchar * const *)
-DECLARE_EMIT_DONE_SIGNAL_1 (get_free_busy,		__GET_FREE_BUSY_DONE_SIGNAL, const gchar * const *)
+DECLARE_EMIT_DONE_SIGNAL_0 (get_free_busy,		__GET_FREE_BUSY_DONE_SIGNAL)
 DECLARE_EMIT_DONE_SIGNAL_1 (create_object,		__CREATE_OBJECT_DONE_SIGNAL, const gchar *)
 DECLARE_EMIT_DONE_SIGNAL_0 (modify_object,		__MODIFY_OBJECT_DONE_SIGNAL)
 DECLARE_EMIT_DONE_SIGNAL_0 (remove_object,		__REMOVE_OBJECT_DONE_SIGNAL)
@@ -953,10 +956,17 @@ e_gdbus_cal_emit_auth_required (EGdbusCal *object, const gchar * const *arg_cred
 	g_signal_emit (object, signals[__AUTH_REQUIRED_SIGNAL], 0, arg_credentials);
 }
 
+void
+e_gdbus_cal_emit_free_busy_data (EGdbusCal *object, const gchar * const *arg_free_busy)
+{
+	g_signal_emit (object, signals[__FREE_BUSY_DATA_SIGNAL], 0, arg_free_busy);
+}
+
 E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, backend_error, message, "s")
 E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, readonly, is_readonly, "b")
 E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, online, is_online, "b")
 E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, auth_required, credentials, "as")
+E_DECLARE_GDBUS_NOTIFY_SIGNAL_1 (cal, free_busy_data, free_busy_data, "as")
 
 E_DECLARE_GDBUS_ASYNC_METHOD_1			(cal, open, only_if_exists, "b")
 E_DECLARE_GDBUS_ASYNC_METHOD_1			(cal, authenticateUser, credentials, "as")
@@ -1021,6 +1031,7 @@ static const GDBusSignalInfo * const e_gdbus_cal_signal_info_pointers[] =
 	&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, readonly),
 	&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, online),
 	&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, auth_required),
+	&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, free_busy_data),
 
 	&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, open_done),
 	&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (cal, authenticateUser_done),
diff --git a/calendar/libegdbus/e-gdbus-cal.h b/calendar/libegdbus/e-gdbus-cal.h
index 3292702..73b5dae 100644
--- a/calendar/libegdbus/e-gdbus-cal.h
+++ b/calendar/libegdbus/e-gdbus-cal.h
@@ -107,6 +107,7 @@ struct _EGdbusCalIface
 	void	(*readonly)				(EGdbusCal *object, gboolean arg_is_readonly);
 	void	(*online)				(EGdbusCal *object, gboolean arg_is_online);
 	void	(*auth_required)			(EGdbusCal *object, const gchar * const *arg_credentials);
+	void	(*free_busy_data)			(EGdbusCal *object, const gchar * const *arg_free_busy);
 
 	/* Signal handlers for handling D-Bus method calls: */
 	gboolean (*handle_open)				(EGdbusCal *object, GDBusMethodInvocation *invocation, gboolean in_only_if_exists);
@@ -143,7 +144,7 @@ struct _EGdbusCalIface
 	void	 (*get_object_list_done)		(EGdbusCal *object, guint arg_opid, const GError *arg_error, gchar ***out_objects);
 
 	gboolean (*handle_get_free_busy)		(EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar * const *in_start_end_userlist);
-	void	 (*get_free_busy_done)			(EGdbusCal *object, guint arg_opid, const GError *arg_error, gchar ***out_freebusy);
+	void	 (*get_free_busy_done)			(EGdbusCal *object, guint arg_opid, const GError *arg_error);
 
 	gboolean (*handle_create_object)		(EGdbusCal *object, GDBusMethodInvocation *invocation, const gchar *in_calobj);
 	void	 (*create_object_done)			(EGdbusCal *object, guint arg_opid, const GError *arg_error, gchar **out_uid);
@@ -227,8 +228,8 @@ gboolean	e_gdbus_cal_call_get_object_list_sync		(GDBusProxy *proxy, const gchar
 gchar **	e_gdbus_cal_encode_get_free_busy		(guint in_start, guint in_end, const GSList *in_users);
 gboolean	e_gdbus_cal_decode_get_free_busy		(const gchar * const *in_strv, guint *out_start, guint *out_end, GSList **out_users);
 void		e_gdbus_cal_call_get_free_busy			(GDBusProxy *proxy, const gchar * const *in_start_end_userlist, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-gboolean	e_gdbus_cal_call_get_free_busy_finish		(GDBusProxy *proxy, GAsyncResult *result, gchar ***out_freebusy, GError **error);
-gboolean	e_gdbus_cal_call_get_free_busy_sync		(GDBusProxy *proxy, const gchar * const *in_start_end_userlist, gchar ***out_freebusy, GCancellable *cancellable, GError **error);
+gboolean	e_gdbus_cal_call_get_free_busy_finish		(GDBusProxy *proxy, GAsyncResult *result, GError **error);
+gboolean	e_gdbus_cal_call_get_free_busy_sync		(GDBusProxy *proxy, const gchar * const *in_start_end_userlist, GCancellable *cancellable, GError **error);
 
 void		e_gdbus_cal_call_create_object			(GDBusProxy *proxy, const gchar *in_calobj, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
 gboolean	e_gdbus_cal_call_create_object_finish		(GDBusProxy *proxy, GAsyncResult *result, gchar **out_uid, GError **error);
@@ -324,7 +325,8 @@ void e_gdbus_cal_emit_get_alarm_email_address_done	(EGdbusCal *object, guint arg
 void e_gdbus_cal_emit_get_default_object_done		(EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar *out_object);
 void e_gdbus_cal_emit_get_object_done			(EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar *out_object);
 void e_gdbus_cal_emit_get_object_list_done		(EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar * const *out_objects);
-void e_gdbus_cal_emit_get_free_busy_done		(EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar * const *out_freebusy);
+void e_gdbus_cal_emit_get_free_busy_done		(EGdbusCal *object, guint arg_opid, const GError *arg_error);
+void e_gdbus_cal_emit_get_free_busy_data		(EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar * const *out_freebusy);
 void e_gdbus_cal_emit_discard_alarm_done		(EGdbusCal *object, guint arg_opid, const GError *arg_error);
 void e_gdbus_cal_emit_create_object_done		(EGdbusCal *object, guint arg_opid, const GError *arg_error, const gchar *out_uid);
 void e_gdbus_cal_emit_modify_object_done		(EGdbusCal *object, guint arg_opid, const GError *arg_error);
@@ -341,6 +343,7 @@ void e_gdbus_cal_emit_backend_error	(EGdbusCal *object, const gchar *arg_message
 void e_gdbus_cal_emit_readonly		(EGdbusCal *object, gboolean arg_is_readonly);
 void e_gdbus_cal_emit_online		(EGdbusCal *object, gint arg_is_online);
 void e_gdbus_cal_emit_auth_required	(EGdbusCal *object, const gchar * const *arg_credentials);
+void e_gdbus_cal_emit_free_busy_data	(EGdbusCal *object, const gchar * const *arg_free_busy);
 
 G_END_DECLS
 
diff --git a/libedataserver/e-client.c b/libedataserver/e-client.c
index 63ee46d..3f72f05 100644
--- a/libedataserver/e-client.c
+++ b/libedataserver/e-client.c
@@ -1031,6 +1031,56 @@ e_client_util_strv_to_slist (const gchar * const *strv)
 }
 
 /**
+ * e_client_util_copy_string_slist:
+ * @copy_to: Where to copy; can be NULL
+ * @strings: GSList of strings to be copied
+ *
+ * Copies GSList of strings at the end of @copy_to.
+ *
+ * Returns: New head of @copy_to.
+ * Returned pointer can be freed with e_client_util_free_string_slist().
+ *
+ * Since: 3.2
+ **/
+GSList *
+e_client_util_copy_string_slist	(GSList *copy_to, const GSList *strings)
+{
+	GSList *res = copy_to;
+	const GSList *iter;
+
+	for (iter = strings; iter; iter = iter->next) {
+		res = g_slist_append (res, g_strdup (iter->data));
+	}
+
+	return res;
+}
+
+/**
+ * e_client_util_copy_object_slist:
+ * @copy_to: Where to copy; can be NULL
+ * @objects: GSList of GObject-s to be copied
+ *
+ * Copies GSList of GObject-s at the end of @copy_to.
+ *
+ * Returns: New head of @copy_to.
+ * Returned pointer can be freed with e_client_util_free_object_slist().
+ *
+ * Since: 3.2
+ **/
+GSList *
+e_client_util_copy_object_slist	(GSList *copy_to, const GSList *objects)
+{
+	GSList *res = copy_to;
+	const GSList *iter;
+
+	for (iter = objects; iter; iter = iter->next) {
+		res = g_slist_append (res, g_object_ref (iter->data));
+	}
+
+	return res;
+}
+
+/**
  * e_client_util_free_string_slist:
  * @strings: a #GSList of strings (gchar *)
  *
diff --git a/libedataserver/e-client.h b/libedataserver/e-client.h
index 04ece4b..1d89638 100644
--- a/libedataserver/e-client.h
+++ b/libedataserver/e-client.h
@@ -95,6 +95,8 @@ gboolean	e_client_remove_sync		(EClient *client, GCancellable *cancellable, GErr
 /* utility functions */
 gchar **	e_client_util_slist_to_strv	(const GSList *strings);
 GSList *	e_client_util_strv_to_slist	(const gchar * const *strv);
+GSList *	e_client_util_copy_string_slist	(GSList *copy_to, const GSList *strings);
+GSList *	e_client_util_copy_object_slist	(GSList *copy_to, const GSList *objects);
 void		e_client_util_free_string_slist	(GSList *strings);
 void		e_client_util_free_object_slist	(GSList *objects);
 GSList *	e_client_util_parse_capabilities(const gchar *capabilities);
diff --git a/tests/libecal/client/test-client-get-free-busy.c b/tests/libecal/client/test-client-get-free-busy.c
index 027be15..3d5943c 100644
--- a/tests/libecal/client/test-client-get-free-busy.c
+++ b/tests/libecal/client/test-client-get-free-busy.c
@@ -7,14 +7,23 @@
 
 #include "client-test-utils.h"
 
+#define USER_EMAIL "user example com"
+
+static void
+free_busy_data_cb (ECalClient *client, const GSList *free_busy, const gchar *func_name)
+{
+	g_print ("   Received %d Free/Busy components from %s\n", g_slist_length ((GSList *) free_busy), func_name);
+}
+
 static gboolean
 test_sync (void)
 {
 	ECalClient *cal_client;
 	GError *error = NULL;
 	icaltimezone *utc;
-	GSList *users = NULL, *free_busy_ecalcomps = NULL;
+	GSList *users = NULL;
 	time_t start, end;
+	gulong sig_id;
 
 	cal_client = new_temp_client (E_CAL_CLIENT_SOURCE_TYPE_EVENT, NULL);
 	g_return_val_if_fail (cal_client != NULL, FALSE);
@@ -28,18 +37,21 @@ test_sync (void)
 	utc = icaltimezone_get_utc_timezone ();
 	start = time_from_isodate ("20040212T000000Z");
 	end = time_add_day_with_zone (start, 2, utc);
-	/* XXX: create dummy list, which the file backend will ignore */
-	users = g_slist_append (users, (gpointer) "user example com");
+	users = g_slist_append (users, (gpointer) USER_EMAIL);
+
+	sig_id = g_signal_connect (cal_client, "free-busy-data", G_CALLBACK (free_busy_data_cb), (gpointer) G_STRFUNC);
 
-	if (!e_cal_client_get_free_busy_sync (cal_client, start, end, users, &free_busy_ecalcomps, NULL, &error)) {
+	if (!e_cal_client_get_free_busy_sync (cal_client, start, end, users, NULL, &error)) {
 		report_error ("get free busy sync", &error);
+		g_signal_handler_disconnect (cal_client, sig_id);
 		g_object_unref (cal_client);
 		g_slist_free (users);
 		return FALSE;
 	}
 
+	g_signal_handler_disconnect (cal_client, sig_id);
+
 	g_slist_free (users);
-	e_cal_client_free_ecalcomp_slist (free_busy_ecalcomps);
 
 	if (!e_client_remove_sync (E_CLIENT (cal_client), NULL, &error)) {
 		report_error ("client remove sync", &error);
@@ -58,19 +70,16 @@ async_get_free_busy_result_ready (GObject *source_object, GAsyncResult *result,
 {
 	ECalClient *cal_client;
 	GError *error = NULL;
-	GSList *free_busy_ecalcomps = NULL;
 
 	cal_client = E_CAL_CLIENT (source_object);
 
-	if (!e_cal_client_get_free_busy_finish (cal_client, result, &free_busy_ecalcomps, &error)) {
+	if (!e_cal_client_get_free_busy_finish (cal_client, result, &error)) {
 		report_error ("create object finish", &error);
 		g_object_unref (cal_client);
 		stop_main_loop (1);
 		return;
 	}
 
-	e_cal_client_free_ecalcomp_slist (free_busy_ecalcomps);
-
 	if (!e_client_remove_sync (E_CLIENT (cal_client), NULL, &error)) {
 		report_error ("client remove sync", &error);
 		g_object_unref (cal_client);
@@ -85,7 +94,7 @@ async_get_free_busy_result_ready (GObject *source_object, GAsyncResult *result,
 
 /* synchronously in idle with main-loop running */
 static gboolean
-test_sync_in_idle (gpointer user_data)
+test_async_in_idle (gpointer user_data)
 {
 	ECalClient *cal_client;
 	GError *error = NULL;
@@ -111,8 +120,10 @@ test_sync_in_idle (gpointer user_data)
 	utc = icaltimezone_get_utc_timezone ();
 	start = time_from_isodate ("20040212T000000Z");
 	end = time_add_day_with_zone (start, 2, utc);
-	/* XXX: create dummy list, which the file backend will ignore */
-	users = g_slist_append (users, (gpointer) "user example com");
+	users = g_slist_append (users, (gpointer) USER_EMAIL);
+
+	/* here is all Free/Busy information received */
+	g_signal_connect (cal_client, "free-busy-data", G_CALLBACK (free_busy_data_cb), (gpointer) G_STRFUNC);
 
 	if (!e_cal_client_get_free_busy (cal_client, start, end, users, NULL, async_get_free_busy_result_ready, NULL)) {
 		report_error ("get free busy", NULL);
@@ -136,7 +147,7 @@ test_sync_in_thread (gpointer user_data)
 		return NULL;
 	}
 
-	g_idle_add (test_sync_in_idle, NULL);
+	g_idle_add (test_async_in_idle, NULL);
 
 	return NULL;
 }
diff --git a/tests/libecal/ecal-test-utils.c b/tests/libecal/ecal-test-utils.c
index 7f90366..9273796 100644
--- a/tests/libecal/ecal-test-utils.c
+++ b/tests/libecal/ecal-test-utils.c
@@ -632,7 +632,6 @@ ecal_test_utils_cal_get_free_busy (ECal   *cal,
 
 			comp_string = e_cal_component_get_as_string (comp);
 			test_print ("%s\n", comp_string);
-			g_object_unref (comp);
 			g_free (comp_string);
 		}
 	} else {
diff --git a/tests/libecal/test-ecal-get-free-busy.c b/tests/libecal/test-ecal-get-free-busy.c
index 7ed04d2..796bf98 100644
--- a/tests/libecal/test-ecal-get-free-busy.c
+++ b/tests/libecal/test-ecal-get-free-busy.c
@@ -25,8 +25,7 @@ main (gint argc, gchar **argv)
 	utc = icaltimezone_get_utc_timezone ();
 	start = time_from_isodate ("20040212T000000Z");
 	end = time_add_day_with_zone (start, 2, utc);
-	/* XXX: create dummy list, which the file backend will ignore */
-	users = g_list_prepend (users, NULL);
+	users = g_list_prepend (users, (gpointer) "user example com");
 
 	free_busy = ecal_test_utils_cal_get_free_busy (cal, users, start, end);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]