(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_CAL_CLIENT_VIEW, ECalClientViewPrivate))
+typedef struct _SignalClosure SignalClosure;
+
struct _ECalClientViewPrivate {
ECalClient *client;
GDBusProxy *dbus_proxy;
gulong complete_handler_id;
};
+struct _SignalClosure {
+ ECalClientView *client_view;
+ GSList *component_list;
+ GSList *component_id_list;
+ gchar *message;
+ guint percent;
+ GError *error;
+};
+
enum {
PROP_0,
PROP_CLIENT,
G_TYPE_INITABLE,
e_cal_client_view_initable_init))
+static void
+signal_closure_free (SignalClosure *signal_closure)
+{
+ g_object_unref (signal_closure->client_view);
+
+ g_slist_free_full (
+ signal_closure->component_list,
+ (GDestroyNotify) icalcomponent_free);
+
+ g_slist_free_full (
+ signal_closure->component_id_list,
+ (GDestroyNotify) e_cal_component_free_id);
+
+ g_free (signal_closure->message);
+
+ if (signal_closure->error != NULL)
+ g_error_free (signal_closure->error);
+
+ g_slice_free (SignalClosure, signal_closure);
+}
+
static GSList *
build_object_list (const gchar * const *seq)
{
return g_slist_reverse (list);
}
+static gboolean
+cal_client_view_emit_objects_added_idle_cb (gpointer user_data)
+{
+ SignalClosure *signal_closure = user_data;
+
+ g_signal_emit (
+ signal_closure->client_view,
+ signals[OBJECTS_ADDED], 0,
+ signal_closure->component_list);
+
+ return FALSE;
+}
+
+static gboolean
+cal_client_view_emit_objects_modified_idle_cb (gpointer user_data)
+{
+ SignalClosure *signal_closure = user_data;
+
+ g_signal_emit (
+ signal_closure->client_view,
+ signals[OBJECTS_MODIFIED], 0,
+ signal_closure->component_list);
+
+ return FALSE;
+}
+
+static gboolean
+cal_client_view_emit_objects_removed_idle_cb (gpointer user_data)
+{
+ SignalClosure *signal_closure = user_data;
+
+ g_signal_emit (
+ signal_closure->client_view,
+ signals[OBJECTS_REMOVED], 0,
+ signal_closure->component_id_list);
+
+ return FALSE;
+}
+
+static gboolean
+cal_client_view_emit_progress_idle_cb (gpointer user_data)
+{
+ SignalClosure *signal_closure = user_data;
+
+ g_signal_emit (
+ signal_closure->client_view,
+ signals[PROGRESS], 0,
+ signal_closure->percent,
+ signal_closure->message);
+
+ return FALSE;
+}
+
+static gboolean
+cal_client_view_emit_complete_idle_cb (gpointer user_data)
+{
+ SignalClosure *signal_closure = user_data;
+
+ g_signal_emit (
+ signal_closure->client_view,
+ signals[COMPLETE], 0,
+ signal_closure->error);
+
+ return FALSE;
+}
+
static void
cal_client_view_objects_added_cb (EGdbusCalView *dbus_proxy,
const gchar * const *objects,
- ECalClientView *view)
+ ECalClientView *client_view)
{
- GSList *list;
+ ECalClient *client;
+ GSource *idle_source;
+ GMainContext *main_context;
+ SignalClosure *signal_closure;
- if (!view->priv->running)
+ if (!client_view->priv->running)
return;
- g_object_ref (view);
+ signal_closure = g_slice_new0 (SignalClosure);
+ signal_closure->client_view = g_object_ref (client_view);
+ signal_closure->component_list = build_object_list (objects);
- list = build_object_list (objects);
+ client = e_cal_client_view_get_client (client_view);
+ main_context = e_client_ref_main_context (E_CLIENT (client));
- g_signal_emit (view, signals[OBJECTS_ADDED], 0, list);
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ cal_client_view_emit_objects_added_idle_cb,
+ signal_closure,
+ (GDestroyNotify) signal_closure_free);
+ g_source_attach (idle_source, main_context);
+ g_source_unref (idle_source);
- g_slist_free_full (list, (GDestroyNotify) icalcomponent_free);
-
- g_object_unref (view);
+ g_main_context_unref (main_context);
}
static void
cal_client_view_objects_modified_cb (EGdbusCalView *dbus_proxy,
const gchar * const *objects,
- ECalClientView *view)
+ ECalClientView *client_view)
{
- GSList *list;
+ ECalClient *client;
+ GSource *idle_source;
+ GMainContext *main_context;
+ SignalClosure *signal_closure;
- if (!view->priv->running)
+ if (!client_view->priv->running)
return;
- g_object_ref (view);
-
- list = build_object_list (objects);
+ signal_closure = g_slice_new0 (SignalClosure);
+ signal_closure->client_view = g_object_ref (client_view);
+ signal_closure->component_list = build_object_list (objects);
- g_signal_emit (view, signals[OBJECTS_MODIFIED], 0, list);
+ client = e_cal_client_view_get_client (client_view);
+ main_context = e_client_ref_main_context (E_CLIENT (client));
- g_slist_free_full (list, (GDestroyNotify) icalcomponent_free);
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ cal_client_view_emit_objects_modified_idle_cb,
+ signal_closure,
+ (GDestroyNotify) signal_closure_free);
+ g_source_attach (idle_source, main_context);
+ g_source_unref (idle_source);
- g_object_unref (view);
+ g_main_context_unref (main_context);
}
static void
cal_client_view_objects_removed_cb (EGdbusCalView *dbus_proxy,
const gchar * const *uids,
- ECalClientView *view)
+ ECalClientView *client_view)
{
- GSList *list;
+ ECalClient *client;
+ GSource *idle_source;
+ GMainContext *main_context;
+ SignalClosure *signal_closure;
- if (!view->priv->running)
+ if (!client_view->priv->running)
return;
- g_object_ref (view);
-
- list = build_id_list (uids);
+ signal_closure = g_slice_new0 (SignalClosure);
+ signal_closure->client_view = g_object_ref (client_view);
+ signal_closure->component_id_list = build_id_list (uids);
- g_signal_emit (view, signals[OBJECTS_REMOVED], 0, list);
+ client = e_cal_client_view_get_client (client_view);
+ main_context = e_client_ref_main_context (E_CLIENT (client));
- g_slist_free_full (list, (GDestroyNotify) e_cal_component_free_id);
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ cal_client_view_emit_objects_removed_idle_cb,
+ signal_closure,
+ (GDestroyNotify) signal_closure_free);
+ g_source_attach (idle_source, main_context);
+ g_source_unref (idle_source);
- g_object_unref (view);
+ g_main_context_unref (main_context);
}
static void
cal_client_view_progress_cb (EGdbusCalView *dbus_proxy,
guint percent,
const gchar *message,
- ECalClientView *view)
+ ECalClientView *client_view)
{
- if (!view->priv->running)
+ ECalClient *client;
+ GSource *idle_source;
+ GMainContext *main_context;
+ SignalClosure *signal_closure;
+
+ if (!client_view->priv->running)
return;
- g_signal_emit (G_OBJECT (view), signals[PROGRESS], 0, percent, message);
+ signal_closure = g_slice_new0 (SignalClosure);
+ signal_closure->client_view = g_object_ref (client_view);
+ signal_closure->message = g_strdup (message);
+ signal_closure->percent = percent;
+
+ client = e_cal_client_view_get_client (client_view);
+ main_context = e_client_ref_main_context (E_CLIENT (client));
+
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ cal_client_view_emit_progress_idle_cb,
+ signal_closure,
+ (GDestroyNotify) signal_closure_free);
+ g_source_attach (idle_source, main_context);
+ g_source_unref (idle_source);
+
+ g_main_context_unref (main_context);
}
static void
cal_client_view_complete_cb (EGdbusCalView *dbus_proxy,
const gchar * const *arg_error,
- ECalClientView *view)
+ ECalClientView *client_view)
{
- GError *error = NULL;
+ ECalClient *client;
+ GSource *idle_source;
+ GMainContext *main_context;
+ SignalClosure *signal_closure;
- if (!view->priv->running)
+ if (!client_view->priv->running)
return;
- g_return_if_fail (e_gdbus_templates_decode_error (arg_error, &error));
+ signal_closure = g_slice_new0 (SignalClosure);
+ signal_closure->client_view = g_object_ref (client_view);
+ e_gdbus_templates_decode_error (arg_error, &signal_closure->error);
+
+ client = e_cal_client_view_get_client (client_view);
+ main_context = e_client_ref_main_context (E_CLIENT (client));
- g_signal_emit (G_OBJECT (view), signals[COMPLETE], 0, error);
+ idle_source = g_idle_source_new ();
+ g_source_set_callback (
+ idle_source,
+ cal_client_view_emit_complete_idle_cb,
+ signal_closure,
+ (GDestroyNotify) signal_closure_free);
+ g_source_attach (idle_source, main_context);
+ g_source_unref (idle_source);
- if (error != NULL)
- g_error_free (error);
+ g_main_context_unref (main_context);
}
static void
/* Helper for e_cal_client_get_view() */
static void
-cal_client_get_view_thread (GSimpleAsyncResult *simple,
- GObject *source_object,
- GCancellable *cancellable)
+cal_client_get_view_in_dbus_thread (GSimpleAsyncResult *simple,
+ GObject *source_object,
+ GCancellable *cancellable)
{
+ ECalClient *client = E_CAL_CLIENT (source_object);
AsyncContext *async_context;
+ gchar *utf8_sexp;
+ gchar *object_path = NULL;
GError *error = NULL;
async_context = g_simple_async_result_get_op_res_gpointer (simple);
- e_cal_client_get_view_sync (
- E_CAL_CLIENT (source_object),
- async_context->sexp,
- &async_context->client_view,
- cancellable, &error);
+ utf8_sexp = e_util_utf8_make_valid (async_context->sexp);
+
+ e_dbus_calendar_call_get_view_sync (
+ client->priv->dbus_proxy, utf8_sexp,
+ &object_path, cancellable, &error);
+
+ g_free (utf8_sexp);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((object_path != NULL) && (error == NULL)) ||
+ ((object_path == NULL) && (error != NULL)));
+
+ if (object_path != NULL) {
+ GDBusConnection *connection;
+ ECalClientView *client_view;
+
+ connection = g_dbus_proxy_get_connection (
+ G_DBUS_PROXY (client->priv->dbus_proxy));
+
+ client_view = g_initable_new (
+ E_TYPE_CAL_CLIENT_VIEW,
+ cancellable, &error,
+ "client", client,
+ "connection", connection,
+ "object-path", object_path,
+ NULL);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client_view != NULL) && (error == NULL)) ||
+ ((client_view == NULL) && (error != NULL)));
+
+ async_context->client_view = client_view;
+
+ g_free (object_path);
+ }
if (error != NULL)
g_simple_async_result_take_error (simple, error);
g_simple_async_result_set_op_res_gpointer (
simple, async_context, (GDestroyNotify) async_context_free);
- g_simple_async_result_run_in_thread (
- simple, cal_client_get_view_thread,
+ cal_client_run_in_dbus_thread (
+ simple, cal_client_get_view_in_dbus_thread,
G_PRIORITY_DEFAULT, cancellable);
g_object_unref (simple);
GCancellable *cancellable,
GError **error)
{
- gchar *utf8_sexp;
- gchar *object_path = NULL;
+ EAsyncClosure *closure;
+ GAsyncResult *result;
gboolean success;
g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
g_return_val_if_fail (sexp != NULL, FALSE);
g_return_val_if_fail (out_view != NULL, FALSE);
- utf8_sexp = e_util_utf8_make_valid (sexp);
-
- success = e_dbus_calendar_call_get_view_sync (
- client->priv->dbus_proxy, utf8_sexp,
- &object_path, cancellable, error);
-
- g_free (utf8_sexp);
-
- /* Sanity check. */
- g_return_val_if_fail (
- (success && (object_path != NULL)) ||
- (!success && (object_path == NULL)), FALSE);
-
- if (object_path != NULL) {
- GDBusConnection *connection;
- ECalClientView *client_view;
+ closure = e_async_closure_new ();
- connection = g_dbus_proxy_get_connection (
- G_DBUS_PROXY (client->priv->dbus_proxy));
+ e_cal_client_get_view (
+ client, sexp, cancellable,
+ e_async_closure_callback, closure);
- client_view = g_initable_new (
- E_TYPE_CAL_CLIENT_VIEW,
- cancellable, error,
- "client", client,
- "connection", connection,
- "object-path", object_path,
- NULL);
+ result = e_async_closure_wait (closure);
- /* XXX Would have been easier to return the
- * EBookClientView directly rather than
- * through an "out" parameter. */
- if (client_view != NULL)
- *out_view = client_view;
- else
- success = FALSE;
+ success = e_cal_client_get_view_finish (
+ client, result, out_view, error);
- g_free (object_path);
- }
+ e_async_closure_free (closure);
return success;
}