From: Guillaume Desmottes Date: Fri, 24 Apr 2009 15:28:22 +0000 (+0100) Subject: Merge branch 'master' into tp-tube X-Git-Url: https://git.0d.be/?p=empathy.git;a=commitdiff_plain;h=f02d96379cb7043611d093921755d699e48689bb;hp=-c Merge branch 'master' into tp-tube --- f02d96379cb7043611d093921755d699e48689bb diff --combined libempathy/empathy-tp-tube.c index 746708fc,5979615e..7d22f6b7 --- a/libempathy/empathy-tp-tube.c +++ b/libempathy/empathy-tp-tube.c @@@ -22,7 -22,6 +22,7 @@@ #include #include +#include #include #include @@@ -60,21 -59,11 +60,21 @@@ free_empathy_tp_tube_accept_data (gpoin } +typedef struct { + EmpathyTpTubeReadyCb *callback; + gpointer user_data; + GDestroyNotify destroy; + GObject *weak_object; +} ReadyCbData; + + #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpTube) typedef struct { TpChannel *channel; EmpTubeChannelState state; + gboolean ready; + GSList *ready_callbacks; } EmpathyTpTubePriv; enum @@@ -102,10 -91,6 +102,10 @@@ tp_tube_state_changed_cb (TpProxy *prox { EmpathyTpTubePriv *priv = GET_PRIV (tube); + if (!priv->ready) + /* We didn't get the state yet */ + return; + DEBUG ("Tube state changed"); priv->state = state; @@@ -174,109 -159,6 +174,109 @@@ tp_tube_get_property (GObject *object } } +static void weak_object_notify (gpointer data, + GObject *old_object); + +static ReadyCbData * +ready_cb_data_new (EmpathyTpTube *self, + EmpathyTpTubeReadyCb *callback, + gpointer user_data, + GDestroyNotify destroy, + GObject *weak_object) +{ + ReadyCbData *d = g_slice_new0 (ReadyCbData); + d->callback = callback; + d->user_data = user_data; + d->destroy = destroy; + d->weak_object = weak_object; + + if (weak_object != NULL) + g_object_weak_ref (weak_object, weak_object_notify, self); + + return d; +} + +static void +ready_cb_data_free (ReadyCbData *data, + EmpathyTpTube *self) +{ + if (data->destroy != NULL) + data->destroy (data->user_data); + + if (data->weak_object != NULL) + g_object_weak_unref (data->weak_object, + weak_object_notify, self); + + g_slice_free (ReadyCbData, data); +} + +static void +weak_object_notify (gpointer data, + GObject *old_object) +{ + EmpathyTpTube *self = EMPATHY_TP_TUBE (data); + EmpathyTpTubePriv *priv = GET_PRIV (self); + GSList *l, *ln; + + for (l = priv->ready_callbacks ; l != NULL ; l = ln ) + { + ReadyCbData *d = (ReadyCbData *) l->data; + ln = g_slist_next (l); + + if (d->weak_object == old_object) + { + ready_cb_data_free (d, self); + priv->ready_callbacks = g_slist_delete_link (priv->ready_callbacks, + l); + } + } +} + + +static void +tube_is_ready (EmpathyTpTube *self, + const GError *error) +{ + EmpathyTpTubePriv *priv = GET_PRIV (self); + GSList *l; + + priv->ready = TRUE; + + for (l = priv->ready_callbacks ; l != NULL ; l = g_slist_next (l)) + { + ReadyCbData *data = (ReadyCbData *) l->data; + + data->callback (self, error, data->user_data, data->weak_object); + ready_cb_data_free (data, self); + } + + g_slist_free (priv->ready_callbacks); + priv->ready_callbacks = NULL; +} + +static void +got_tube_state_cb (TpProxy *proxy, + const GValue *out_value, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + EmpathyTpTube *self = EMPATHY_TP_TUBE (user_data); + EmpathyTpTubePriv *priv = GET_PRIV (self); + + if (error != NULL) + { + DEBUG ("Error getting State property: %s", error->message); + } + else + { + priv->state = g_value_get_uint (out_value); + g_object_notify (G_OBJECT (self), "state"); + } + + tube_is_ready (self, error); +} + static GObject * tp_tube_constructor (GType type, guint n_props, @@@ -292,25 -174,17 +292,25 @@@ g_signal_connect (priv->channel, "invalidated", G_CALLBACK (tp_tube_invalidated_cb), self); + priv->ready = FALSE; + emp_cli_channel_interface_tube_connect_to_tube_channel_state_changed ( TP_PROXY (priv->channel), tp_tube_state_changed_cb, NULL, NULL, self, NULL); + tp_cli_dbus_properties_call_get (priv->channel, -1, + EMP_IFACE_CHANNEL_INTERFACE_TUBE, "State", got_tube_state_cb, + self, NULL, G_OBJECT (self)); + return self; } static void tp_tube_finalize (GObject *object) { + EmpathyTpTube *self = EMPATHY_TP_TUBE (object); EmpathyTpTubePriv *priv = GET_PRIV (object); + GSList *l; DEBUG ("Finalizing: %p", object); @@@ -323,16 -197,6 +323,16 @@@ g_object_unref (priv->channel); } + for (l = priv->ready_callbacks; l != NULL; l = g_slist_next (l)) + { + ReadyCbData *d = (ReadyCbData *) l->data; + + ready_cb_data_free (d, self); + } + + g_slist_free (priv->ready_callbacks); + priv->ready_callbacks = NULL; + G_OBJECT_CLASS (empathy_tp_tube_parent_class)->finalize (object); } @@@ -390,8 -254,6 +390,6 @@@ empathy_tp_tube_new_stream_tube (Empath const gchar *service, GHashTable *parameters) { - MissionControl *mc; - McAccount *account; TpConnection *connection; TpChannel *channel; gchar *object_path; @@@ -408,12 -270,7 +406,7 @@@ g_return_val_if_fail (hostname != NULL, NULL); g_return_val_if_fail (service != NULL, NULL); - mc = empathy_mission_control_dup_singleton (); - account = empathy_contact_get_account (contact); - connection = mission_control_get_tpconnection (mc, account, NULL); - g_object_unref (mc); - - tp_connection_run_until_ready (connection, FALSE, NULL, NULL); + connection = empathy_contact_get_connection (contact); request = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); @@@ -557,28 -414,3 +550,28 @@@ empathy_tp_tube_accept_stream_tube (Emp tp_g_value_slice_free (control_param); } + +void +empathy_tp_tube_call_when_ready (EmpathyTpTube *self, + EmpathyTpTubeReadyCb *callback, + gpointer user_data, + GDestroyNotify destroy, + GObject *weak_object) +{ + EmpathyTpTubePriv *priv = GET_PRIV (self); + + g_return_if_fail (self != NULL); + g_return_if_fail (callback != NULL); + + if (priv->ready) + { + callback (self, NULL, user_data, weak_object); + if (destroy != NULL) + destroy (user_data); + } + else + { + priv->ready_callbacks = g_slist_prepend (priv->ready_callbacks, + ready_cb_data_new (self, callback, user_data, destroy, weak_object)); + } +}