+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+async_initable_init_first (GAsyncInitable *initable)
+{
+ GDBusProxy *proxy = G_DBUS_PROXY (initable);
+
+ if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES))
+ {
+ /* subscribe to PropertiesChanged() */
+ proxy->priv->properties_changed_subscription_id =
+ g_dbus_connection_signal_subscribe (proxy->priv->connection,
+ proxy->priv->name,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ proxy->priv->object_path,
+ proxy->priv->interface_name,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_properties_changed,
+ signal_subscription_ref (proxy->priv->signal_subscription_data),
+ (GDestroyNotify) signal_subscription_unref);
+ }
+
+ if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS))
+ {
+ /* subscribe to all signals for the object */
+ proxy->priv->signals_subscription_id =
+ g_dbus_connection_signal_subscribe (proxy->priv->connection,
+ proxy->priv->name,
+ proxy->priv->interface_name,
+ NULL, /* member */
+ proxy->priv->object_path,
+ NULL, /* arg0 */
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_signal_received,
+ signal_subscription_ref (proxy->priv->signal_subscription_data),
+ (GDestroyNotify) signal_subscription_unref);
+ }
+
+ if (proxy->priv->name != NULL && !g_dbus_is_unique_name (proxy->priv->name))
+ {
+ proxy->priv->name_owner_changed_subscription_id =
+ g_dbus_connection_signal_subscribe (proxy->priv->connection,
+ "org.freedesktop.DBus", /* name */
+ "org.freedesktop.DBus", /* interface */
+ "NameOwnerChanged", /* signal name */
+ "/org/freedesktop/DBus", /* path */
+ proxy->priv->name, /* arg0 */
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_name_owner_changed,
+ signal_subscription_ref (proxy->priv->signal_subscription_data),
+ (GDestroyNotify) signal_subscription_unref);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/* initialization is split into two parts - the first is the
+ * non-blocing part that requires the callers GMainContext - the
+ * second is a blocking part async part that doesn't require the
+ * callers GMainContext.. we do this split so the code can be reused
+ * in the GInitable implementation below.
+ *
+ * Note that obtaining a GDBusConnection is not shared between the two
+ * paths.
+ */
+
+typedef struct
+{
+ GDBusProxy *proxy;
+ gint io_priority;
+ GCancellable *cancellable;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+} GetConnectionData;
+
+static void
+get_connection_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GetConnectionData *data = user_data;
+ GError *error;
+
+ error = NULL;
+ data->proxy->priv->connection = g_bus_get_finish (res, &error);
+ if (data->proxy->priv->connection == NULL)
+ {
+ GSimpleAsyncResult *simple;
+ simple = g_simple_async_result_new (G_OBJECT (data->proxy),
+ data->callback,
+ data->user_data,
+ NULL);
+ g_simple_async_result_set_check_cancellable (simple, data->cancellable);
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ }
+ else
+ {
+ async_initable_init_first (G_ASYNC_INITABLE (data->proxy));
+ async_initable_init_second_async (G_ASYNC_INITABLE (data->proxy),
+ data->io_priority,
+ data->cancellable,
+ data->callback,
+ data->user_data);
+ }
+
+ if (data->cancellable != NULL)
+ g_object_unref (data->cancellable);
+
+ g_object_unref (data->proxy);
+ g_free (data);
+}
+
+static void
+async_initable_init_async (GAsyncInitable *initable,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GDBusProxy *proxy = G_DBUS_PROXY (initable);
+
+ if (proxy->priv->bus_type != G_BUS_TYPE_NONE)
+ {
+ GetConnectionData *data;
+
+ g_assert (proxy->priv->connection == NULL);
+
+ data = g_new0 (GetConnectionData, 1);
+ data->proxy = g_object_ref (proxy);
+ data->io_priority = io_priority;
+ data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
+ data->callback = callback;
+ data->user_data = user_data;
+ g_bus_get (proxy->priv->bus_type,
+ cancellable,
+ get_connection_cb,
+ data);
+ }
+ else
+ {
+ async_initable_init_first (initable);
+ async_initable_init_second_async (initable, io_priority, cancellable, callback, user_data);
+ }
+}
+
+static gboolean
+async_initable_init_finish (GAsyncInitable *initable,
+ GAsyncResult *res,
+ GError **error)
+{
+ return async_initable_init_second_finish (initable, res, error);
+}
+