#include <config.h>
#include <telepathy-glib/connection.h>
+#include <telepathy-glib/proxy.h>
#include <telepathy-glib/util.h>
+#include <extensions/extensions.h>
-#include "empathy-contact-factory.h"
#include "empathy-enum-types.h"
#include "empathy-tp-tube.h"
#include "empathy-utils.h"
#define DEBUG_FLAG EMPATHY_DEBUG_TP
#include "empathy-debug.h"
-#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_TP_TUBE, \
- EmpathyTpTubePriv))
+typedef struct {
+ TpSocketAddressType type;
+ EmpatyTpTubeAcceptStreamTubeCb *callback;
+ gpointer user_data;
+} EmpathyTpTubeAcceptData;
-typedef struct _EmpathyTpTubePriv EmpathyTpTubePriv;
+static EmpathyTpTubeAcceptData *
+new_empathy_tp_tube_accept_data (TpSocketAddressType type,
+ EmpatyTpTubeAcceptStreamTubeCb *callback, gpointer user_data)
+{
+ EmpathyTpTubeAcceptData *r;
+
+ r = g_slice_new0 (EmpathyTpTubeAcceptData);
+ r->type = type;
+ r->callback = callback;
+ r->user_data = user_data;
+
+ return r;
+}
+
+static void
+free_empathy_tp_tube_accept_data (gpointer data)
+{
+ g_slice_free (EmpathyTpTubeAcceptData, data);
+}
-struct _EmpathyTpTubePriv
+
+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;
- guint id;
- guint initiator;
- guint type;
- gchar *service;
- GHashTable *parameters;
- guint state;
- EmpathyContact *initiator_contact;
- EmpathyContactFactory *factory;
-};
+ EmpTubeChannelState state;
+ gboolean ready;
+ GSList *ready_callbacks;
+} EmpathyTpTubePriv;
enum
{
PROP_0,
PROP_CHANNEL,
- PROP_TP_TUBES,
- PROP_ID,
- PROP_INITIATOR,
- PROP_TYPE,
- PROP_SERVICE,
- PROP_PARAMETERS,
PROP_STATE,
- PROP_INITIATOR_CONTACT
};
enum
G_DEFINE_TYPE (EmpathyTpTube, empathy_tp_tube, G_TYPE_OBJECT)
static void
-tp_tube_state_changed_cb (TpChannel *channel,
- guint id,
- guint state,
+tp_tube_state_changed_cb (TpProxy *proxy,
+ EmpTubeChannelState state,
gpointer user_data,
GObject *tube)
{
EmpathyTpTubePriv *priv = GET_PRIV (tube);
- if (id != priv->id)
- return;
+ if (!priv->ready)
+ /* We didn't get the state yet */
+ return;
DEBUG ("Tube state changed");
g_signal_emit (tube, signals[DESTROY], 0);
}
-static void
-tp_tube_closed_cb (TpChannel *channel,
- guint id,
- gpointer user_data,
- GObject *tube)
-{
- EmpathyTpTubePriv *priv = GET_PRIV (tube);
-
- if (id != priv->id)
- return;
-
- DEBUG ("Tube closed");
- g_signal_emit (tube, signals[DESTROY], 0);
-}
-
static void
tp_tube_async_cb (TpChannel *channel,
const GError *error,
case PROP_CHANNEL:
priv->channel = g_value_dup_object (value);
break;
- case PROP_ID:
- priv->id = g_value_get_uint (value);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_CHANNEL:
g_value_set_object (value, priv->channel);
break;
- case PROP_ID:
- g_value_set_uint (value, priv->id);
- break;
- case PROP_INITIATOR:
- g_value_set_uint (value, priv->initiator);
- break;
- case PROP_TYPE:
- g_value_set_uint (value, priv->type);
- break;
- case PROP_SERVICE:
- g_value_set_string (value, priv->service);
- break;
- case PROP_PARAMETERS:
- g_value_set_boxed (value, priv->parameters);
- break;
case PROP_STATE:
g_value_set_uint (value, priv->state);
break;
- case PROP_INITIATOR_CONTACT:
- g_value_set_object (value, priv->initiator_contact);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+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,
{
GObject *self;
EmpathyTpTubePriv *priv;
- GPtrArray *tubes;
- guint i;
- GError *error = NULL;
self = G_OBJECT_CLASS (empathy_tp_tube_parent_class)->constructor (
type, n_props, props);
g_signal_connect (priv->channel, "invalidated",
G_CALLBACK (tp_tube_invalidated_cb), self);
- tp_cli_channel_type_tubes_connect_to_tube_closed (priv->channel,
- tp_tube_closed_cb, NULL, NULL, self, NULL);
- tp_cli_channel_type_tubes_connect_to_tube_state_changed (priv->channel,
- tp_tube_state_changed_cb, NULL, NULL, self, NULL);
-
- /* FIXME: It is absolutely not opimized to list all tubes to get information
- * about our tube, but we don't really have the choice to avoid races. */
- if (!tp_cli_channel_type_tubes_run_list_tubes (priv->channel, -1, &tubes,
- &error, NULL))
- {
- DEBUG ("Couldn't list tubes: %s", error->message);
- g_clear_error (&error);
- return self;
- }
- for (i = 0; i < tubes->len; i++)
- {
- GValueArray *values;
- guint id;
-
- values = g_ptr_array_index (tubes, i);
- id = g_value_get_uint (g_value_array_get_nth (values, 0));
+ priv->ready = FALSE;
- if (id == priv->id)
- {
- TpConnection *connection;
- MissionControl *mc;
- McAccount *account;
-
- g_object_get (priv->channel, "connection", &connection, NULL);
- mc = empathy_mission_control_new ();
- account = mission_control_get_account_for_tpconnection (mc,
- connection, NULL);
-
- priv->initiator = g_value_get_uint (g_value_array_get_nth (values, 1));
- priv->type = g_value_get_uint (g_value_array_get_nth (values, 2));
- priv->service = g_value_dup_string (g_value_array_get_nth (values, 3));
- priv->parameters = g_value_dup_boxed (g_value_array_get_nth (values, 4));
- priv->state = g_value_get_uint (g_value_array_get_nth (values, 5));
- priv->initiator_contact = empathy_contact_factory_get_from_handle (
- priv->factory, account, priv->initiator);
-
- g_object_unref (connection);
- g_object_unref (mc);
- g_object_unref (account);
- }
+ emp_cli_channel_interface_tube_connect_to_tube_channel_state_changed (
+ TP_PROXY (priv->channel), tp_tube_state_changed_cb, NULL, NULL,
+ self, NULL);
- g_value_array_free (values);
- }
- g_ptr_array_free (tubes, TRUE);
+ 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);
{
g_signal_handlers_disconnect_by_func (priv->channel,
tp_tube_invalidated_cb, object);
- tp_cli_channel_type_tubes_call_close_tube (priv->channel, -1, priv->id,
- tp_tube_async_cb, "closing tube", NULL, NULL);
+ tp_cli_channel_call_close (priv->channel, -1, tp_tube_async_cb,
+ "closing tube", NULL, NULL);
g_object_unref (priv->channel);
}
- if (priv->initiator_contact)
- g_object_unref (priv->initiator_contact);
- if (priv->factory)
- g_object_unref (priv->factory);
- g_free (priv->service);
- g_hash_table_destroy (priv->parameters);
+ 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);
}
g_object_class_install_property (object_class, PROP_CHANNEL,
g_param_spec_object ("channel", "channel", "channel", TP_TYPE_CHANNEL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (object_class, PROP_ID,
- g_param_spec_uint ("id", "id", "id", 0, G_MAXUINT, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (object_class, PROP_INITIATOR,
- g_param_spec_uint ("initiator", "initiator", "initiator",
- 0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (object_class, PROP_TYPE,
- g_param_spec_uint ("type", "type", "type", 0, G_MAXUINT, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (object_class, PROP_SERVICE,
- g_param_spec_string ("service", "service", "service", NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (object_class, PROP_PARAMETERS,
- g_param_spec_boxed ("parameters", "parameters", "parameters",
- G_TYPE_HASH_TABLE, G_PARAM_READABLE | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_STATE,
- g_param_spec_uint ("state", "state", "state", 0, G_MAXUINT, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
-
- g_object_class_install_property (object_class, PROP_INITIATOR_CONTACT,
- g_param_spec_object ("initiator-contact", "initiator contact",
- "initiator contact", EMPATHY_TYPE_CONTACT, G_PARAM_READABLE |
- G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+ g_param_spec_uint ("state", "state", "state",
+ 0, NUM_EMP_TUBE_CHANNEL_STATES, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_STRINGS));
signals[DESTROY] = g_signal_new ("destroy",
G_TYPE_FROM_CLASS (klass),
static void
empathy_tp_tube_init (EmpathyTpTube *tube)
{
- EmpathyTpTubePriv *priv = GET_PRIV (tube);
+ EmpathyTpTubePriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (tube,
+ EMPATHY_TYPE_TP_TUBE, EmpathyTpTubePriv);
- priv->factory = empathy_contact_factory_new ();
+ tube->priv = priv;
}
EmpathyTpTube *
-empathy_tp_tube_new (TpChannel *channel, guint tube_id)
+empathy_tp_tube_new (TpChannel *channel)
{
g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL);
- return g_object_new (EMPATHY_TYPE_TP_TUBE,
- "channel", channel, "id", tube_id, NULL);
+ return g_object_new (EMPATHY_TYPE_TP_TUBE, "channel", channel, NULL);
}
EmpathyTpTube *
TpSocketAddressType type,
const gchar *hostname,
guint port,
- const gchar *service)
+ const gchar *service,
+ GHashTable *parameters)
{
MissionControl *mc;
McAccount *account;
TpConnection *connection;
TpChannel *channel;
gchar *object_path;
- guint id;
GHashTable *params;
GValue *address;
GValue *control_param;
EmpathyTpTube *tube = NULL;
GError *error = NULL;
+ GHashTable *request;
+ GHashTable *channel_properties;
+ GValue *value;
g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
g_return_val_if_fail (hostname != NULL, NULL);
g_return_val_if_fail (service != NULL, NULL);
- mc = empathy_mission_control_new ();
+ mc = empathy_mission_control_dup_singleton ();
account = empathy_contact_get_account (contact);
connection = mission_control_get_tpconnection (mc, account, NULL);
g_object_unref (mc);
- if (!tp_cli_connection_run_request_channel (connection, -1,
- TP_IFACE_CHANNEL_TYPE_TUBES, TP_HANDLE_TYPE_CONTACT,
- empathy_contact_get_handle (contact), FALSE, &object_path, &error, NULL))
+ tp_connection_run_until_ready (connection, FALSE, NULL, NULL);
+
+ request = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) tp_g_value_slice_free);
+
+ /* org.freedesktop.Telepathy.Channel.ChannelType */
+ value = tp_g_value_slice_new (G_TYPE_STRING);
+ g_value_set_string (value, EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".ChannelType", value);
+
+ /* org.freedesktop.Telepathy.Channel.TargetHandleType */
+ value = tp_g_value_slice_new (G_TYPE_UINT);
+ g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT);
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandleType", value);
+
+ /* org.freedesktop.Telepathy.Channel.TargetHandleType */
+ value = tp_g_value_slice_new (G_TYPE_UINT);
+ g_value_set_uint (value, empathy_contact_get_handle (contact));
+ g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value);
+
+ /* org.freedesktop.Telepathy.Channel.Type.StreamTube.Service */
+ value = tp_g_value_slice_new (G_TYPE_STRING);
+ g_value_set_string (value, service);
+ g_hash_table_insert (request,
+ EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service", value);
+
+ if (!tp_cli_connection_interface_requests_run_create_channel (connection, -1,
+ request, &object_path, &channel_properties, &error, NULL))
{
DEBUG ("Error requesting channel: %s", error->message);
g_clear_error (&error);
DEBUG ("Offering a new stream tube");
- channel = tp_channel_new (connection, object_path,
- TP_IFACE_CHANNEL_TYPE_TUBES, TP_HANDLE_TYPE_CONTACT,
- empathy_contact_get_handle (contact), NULL);
+ channel = tp_channel_new_from_properties (connection, object_path,
+ channel_properties, NULL);
+
+ tp_channel_run_until_ready (channel, NULL, NULL);
#define ADDRESS_TYPE dbus_g_type_get_struct ("GValueArray",\
G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID)
dbus_g_type_struct_set (address, 0, hostname, 1, port, G_MAXUINT);
control_param = tp_g_value_slice_new (G_TYPE_STRING);
- if (!tp_cli_channel_type_tubes_run_offer_stream_tube (channel, -1,
- service, params, type, address,
- TP_SOCKET_ACCESS_CONTROL_LOCALHOST, control_param, &id, &error, NULL))
+ if (parameters == NULL)
+ /* Pass an empty dict as parameters */
+ parameters = g_hash_table_new (g_str_hash, g_str_equal);
+ else
+ g_hash_table_ref (parameters);
+
+ if (!emp_cli_channel_type_stream_tube_run_offer_stream_tube (
+ TP_PROXY(channel), -1, type, address,
+ TP_SOCKET_ACCESS_CONTROL_LOCALHOST, control_param, parameters,
+ &error, NULL))
{
DEBUG ("Couldn't offer tube: %s", error->message);
g_clear_error (&error);
goto OUT;
}
- DEBUG ("Stream tube id=%d offered", id);
+ DEBUG ("Stream tube offered");
- tube = empathy_tp_tube_new (channel, id);
+ tube = empathy_tp_tube_new (channel);
OUT:
g_object_unref (channel);
g_free (object_path);
- g_hash_table_destroy (params);
+ g_hash_table_destroy (request);
+ g_hash_table_destroy (channel_properties);
tp_g_value_slice_free (address);
tp_g_value_slice_free (control_param);
g_object_unref (connection);
+ g_hash_table_unref (parameters);
return tube;
}
static void
-tp_tube_accept_stream_cb (TpChannel *proxy,
+tp_tube_accept_stream_cb (TpProxy *proxy,
const GValue *address,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
+ EmpathyTpTube *tube = EMPATHY_TP_TUBE (weak_object);
+ EmpathyTpTubeAcceptData *data = (EmpathyTpTubeAcceptData *)user_data;
+ EmpathyTpTubeAddress eaddress;
+
+ eaddress.type = data->type;
+
if (error)
+ {
DEBUG ("Error accepting tube: %s", error->message);
+ data->callback (tube, NULL, error, data->user_data);
+ return;
+ }
+
+ switch (eaddress.type)
+ {
+ case TP_SOCKET_ADDRESS_TYPE_UNIX:
+ case TP_SOCKET_ADDRESS_TYPE_ABSTRACT_UNIX:
+ eaddress.a.socket.path = g_value_get_boxed (address);
+ break;
+ case TP_SOCKET_ADDRESS_TYPE_IPV4:
+ case TP_SOCKET_ADDRESS_TYPE_IPV6:
+ dbus_g_type_struct_get (address,
+ 0, &eaddress.a.inet.hostname,
+ 1, &eaddress.a.inet.port, G_MAXUINT);
+ break;
+ }
+
+ data->callback (tube, &eaddress, NULL, data->user_data);
}
void
empathy_tp_tube_accept_stream_tube (EmpathyTpTube *tube,
- TpSocketAddressType type)
+ TpSocketAddressType type, EmpatyTpTubeAcceptStreamTubeCb *callback,
+ gpointer user_data)
{
EmpathyTpTubePriv *priv = GET_PRIV (tube);
GValue *control_param;
+ EmpathyTpTubeAcceptData *data;
g_return_if_fail (EMPATHY_IS_TP_TUBE (tube));
- DEBUG ("Accepting stream tube - id: %d", priv->id);
-
+ DEBUG ("Accepting stream tube");
+ /* FIXME allow other acls */
control_param = tp_g_value_slice_new (G_TYPE_STRING);
- tp_cli_channel_type_tubes_call_accept_stream_tube (priv->channel, -1, priv->id,
- type, TP_SOCKET_ACCESS_CONTROL_LOCALHOST, control_param,
- tp_tube_accept_stream_cb, NULL, NULL, G_OBJECT (tube));
+
+ data = new_empathy_tp_tube_accept_data (type, callback, user_data);
+
+ emp_cli_channel_type_stream_tube_call_accept_stream_tube (
+ TP_PROXY (priv->channel), -1, type, TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
+ control_param, tp_tube_accept_stream_cb, data,
+ free_empathy_tp_tube_accept_data, G_OBJECT (tube));
tp_g_value_slice_free (control_param);
}
void
-empathy_tp_tube_get_socket (EmpathyTpTube *tube,
- gchar **hostname,
- guint *port)
+empathy_tp_tube_call_when_ready (EmpathyTpTube *self,
+ EmpathyTpTubeReadyCb *callback,
+ gpointer user_data,
+ GDestroyNotify destroy,
+ GObject *weak_object)
{
- EmpathyTpTubePriv *priv = GET_PRIV (tube);
- GValue *address;
- guint address_type;
- GError *error = NULL;
-
- g_return_if_fail (EMPATHY_IS_TP_TUBE (tube));
+ EmpathyTpTubePriv *priv = GET_PRIV (self);
- DEBUG ("Getting stream tube socket address");
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (callback != NULL);
- address = g_slice_new0 (GValue);
- if (!tp_cli_channel_type_tubes_run_get_stream_tube_socket_address (priv->channel,
- -1, priv->id, &address_type, &address, &error, NULL))
+ if (priv->ready)
{
- DEBUG ("Couldn't get socket address: %s", error->message);
- g_clear_error (&error);
- return;
+ callback (self, NULL, user_data, weak_object);
+ if (destroy != NULL)
+ destroy (user_data);
}
-
- switch (address_type)
+ else
{
- case TP_SOCKET_ADDRESS_TYPE_UNIX:
- case TP_SOCKET_ADDRESS_TYPE_ABSTRACT_UNIX:
- dbus_g_type_struct_get (address, 0, hostname, G_MAXUINT);
- break;
- case TP_SOCKET_ADDRESS_TYPE_IPV4:
- case TP_SOCKET_ADDRESS_TYPE_IPV6:
- dbus_g_type_struct_get (address, 0, hostname, 1, port, G_MAXUINT);
- break;
+ priv->ready_callbacks = g_slist_prepend (priv->ready_callbacks,
+ ready_cb_data_new (self, callback, user_data, destroy, weak_object));
}
-
- tp_g_value_slice_free (address);
}
-