Exemple #1
0
static gboolean
megaphone_applet_button_press_event_cb (GtkWidget       *widget,
					GdkEventButton  *event, 
					MegaphoneApplet *applet)
{
	MegaphoneAppletPriv *priv = GET_PRIV (applet);

	/* Only react on left-clicks */
	if (event->button != 1 || event->type != GDK_BUTTON_PRESS) {
		return FALSE;
	}

	/* If the contact is unavailable we display the preferences dialog */
	if (priv->contact == NULL) {
		megaphone_applet_show_preferences (applet);
		return TRUE;
	}
	
	DEBUG ("Requesting text channel for contact %s (%d)",
		empathy_contact_get_id (priv->contact),
		empathy_contact_get_handle (priv->contact));

	empathy_dispatcher_chat_with_contact (priv->contact, NULL, NULL);

	return TRUE;
}
static void
tp_streamed_media_request_streams_for_capabilities (EmpathyTpStreamedMedia *call,
                                          EmpathyCapabilities capabilities)
{
  EmpathyTpStreamedMediaPriv *priv = GET_PRIV (call);
  GArray *stream_types;
  guint handle;
  guint stream_type;

  if (capabilities == EMPATHY_CAPABILITIES_UNKNOWN)
      capabilities = EMPATHY_CAPABILITIES_AUDIO | EMPATHY_CAPABILITIES_VIDEO;

  DEBUG ("Requesting new stream for capabilities %d",
      capabilities);

  stream_types = g_array_new (FALSE, FALSE, sizeof (guint));
  handle = empathy_contact_get_handle (priv->contact);

  if (capabilities & EMPATHY_CAPABILITIES_AUDIO)
    {
      stream_type = TP_MEDIA_STREAM_TYPE_AUDIO;
      g_array_append_val (stream_types, stream_type);
    }
  if (capabilities & EMPATHY_CAPABILITIES_VIDEO)
    {
      stream_type = TP_MEDIA_STREAM_TYPE_VIDEO;
      g_array_append_val (stream_types, stream_type);
    }

  tp_cli_channel_type_streamed_media_call_request_streams (priv->channel, -1,
      handle, stream_types, tp_streamed_media_request_streams_cb, NULL, NULL,
      G_OBJECT (call));

  g_array_unref (stream_types);
}
static void
contact_list_view_drag_got_contact (EmpathyTpContactFactory *factory,
				    EmpathyContact          *contact,
				    const GError            *error,
				    gpointer                 user_data,
				    GObject                 *view)
{
	EmpathyContactListViewPriv *priv = GET_PRIV (view);
	DndGetContactData          *data = user_data;
	EmpathyContactList         *list;

	if (error != NULL) {
		DEBUG ("Error: %s", error->message);
		return;
	}

	DEBUG ("contact %s (%d) dragged from '%s' to '%s'",
		empathy_contact_get_id (contact),
		empathy_contact_get_handle (contact),
		data->old_group, data->new_group);

	list = empathy_contact_list_store_get_list_iface (priv->store);
	if (data->new_group) {
		empathy_contact_list_add_to_group (list, contact, data->new_group);
	}
	if (data->old_group && data->action == GDK_ACTION_MOVE) {
		empathy_contact_list_remove_from_group (list, contact, data->old_group);
	}
}
static void
update_contact_capabilities (EmpathyTpContactFactory *self,
			     GHashTable *caps)
{
	GHashTableIter iter;
	gpointer key, value;

	g_hash_table_iter_init (&iter, caps);
	while (g_hash_table_iter_next (&iter, &key, &value)) {
		TpHandle handle = GPOINTER_TO_UINT (key);
		GPtrArray *classes = value;
		EmpathyContact *contact;
		EmpathyCapabilities  capabilities;

		contact = tp_contact_factory_find_by_handle (self, handle);
		if (contact == NULL)
			continue;

		capabilities = empathy_contact_get_capabilities (contact);
		capabilities &= ~EMPATHY_CAPABILITIES_UNKNOWN;

		capabilities |= channel_classes_to_capabilities (classes, TRUE);

		DEBUG ("Changing capabilities for contact %s (%d) to %d",
			empathy_contact_get_id (contact),
			empathy_contact_get_handle (contact),
			capabilities);

		empathy_contact_set_capabilities (contact, capabilities);
	}
}
static void
tp_contact_list_add (EmpathyContactList *list,
		     EmpathyContact     *contact,
		     const gchar        *message)
{
	EmpathyTpContactListPriv *priv = GET_PRIV (list);
	TpHandle handle;
	GArray handles = {(gchar *) &handle, 1};

	handle = empathy_contact_get_handle (contact);

	if (priv->subscribe) {
		tp_cli_channel_interface_group_call_add_members (priv->subscribe,
			-1, &handles, message, NULL, NULL, NULL, NULL);
	}

	if (priv->publish) {
		TpChannelGroupFlags flags = tp_channel_group_get_flags (priv->subscribe);
		if (flags & TP_CHANNEL_GROUP_FLAG_CAN_ADD ||
		    g_hash_table_lookup (priv->pendings, GUINT_TO_POINTER (handle))) {
			tp_cli_channel_interface_group_call_add_members (priv->publish,
				-1, &handles, message, NULL, NULL, NULL, NULL);
		}
	}

	/* We want to unblock the contact */
	if (tp_proxy_has_interface_by_id (priv->connection,
		TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_BLOCKING)) {
		TpContact *tp_contact = empathy_contact_get_tp_contact (contact);

		if (tp_contact != NULL)
			tp_contact_unblock_async (tp_contact, NULL, NULL);
	}
}
static void
got_added_members_cb (TpConnection            *connection,
		      guint                    n_contacts,
		      EmpathyContact * const * contacts,
		      guint                    n_failed,
		      const TpHandle          *failed,
		      const GError            *error,
		      gpointer                 user_data,
		      GObject                 *list)
{
	EmpathyTpContactListPriv *priv = GET_PRIV (list);
	guint i;

	if (error) {
		DEBUG ("Error: %s", error->message);
		return;
	}

	for (i = 0; i < n_contacts; i++) {
		EmpathyContact *contact = contacts[i];
		TpHandle handle = empathy_contact_get_handle (contact);

		if (g_hash_table_lookup (priv->members, GUINT_TO_POINTER (handle)))
			continue;

		/* Add to the list and emit signal */
		g_hash_table_insert (priv->members, GUINT_TO_POINTER (handle),
				     g_object_ref (contact));
		g_signal_emit_by_name (list, "members-changed", contact,
				       0, 0, NULL, TRUE);
	}
}
Exemple #7
0
static EmpathyContact *
chat_lookup_contact (EmpathyTpChat *chat,
		     TpHandle       handle,
		     gboolean       remove)
{
	EmpathyTpChatPriv *priv = GET_PRIV (chat);
	GList *l;

	for (l = priv->members; l; l = l->next) {
		EmpathyContact *c = l->data;

		if (empathy_contact_get_handle (c) != handle) {
			continue;
		}

		if (remove) {
			/* Caller takes the reference. */
			priv->members = g_list_delete_link (priv->members, l);
		} else {
			g_object_ref (c);
		}

		return c;
	}

	return NULL;
}
static void
ft_handler_populate_outgoing_request (EmpathyFTHandler *handler)
{
  guint contact_handle;
  EmpathyFTHandlerPriv *priv = GET_PRIV (handler);
  gchar *uri;

  contact_handle = empathy_contact_get_handle (priv->contact);
  uri = g_file_get_uri (priv->gfile);

  priv->request = tp_asv_new (
      TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
        TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER,
      TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
        TP_HANDLE_TYPE_CONTACT,
      TP_PROP_CHANNEL_TARGET_HANDLE, G_TYPE_UINT,
        contact_handle,
      TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_TYPE, G_TYPE_STRING,
        priv->content_type,
      TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_FILENAME, G_TYPE_STRING,
        priv->filename,
      TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_SIZE, G_TYPE_UINT64,
        priv->total_bytes,
      TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_DATE, G_TYPE_UINT64,
        priv->mtime,
      TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_URI, G_TYPE_STRING, uri,
      NULL);

  g_free (uri);
}
static void
contact_list_store_groups_changed_cb (EmpathyContactList      *list_iface,
				      EmpathyContact          *contact,
				      gchar                   *group,
				      gboolean                 is_member,
				      EmpathyContactListStore *store)
{
	EmpathyContactListStorePriv *priv;
	gboolean                     show_active;

	priv = GET_PRIV (store);

	DEBUG ("Updating groups for contact %s (%d)",
		empathy_contact_get_id (contact),
		empathy_contact_get_handle (contact));

	/* We do this to make sure the groups are correct, if not, we
	 * would have to check the groups already set up for each
	 * contact and then see what has been updated.
	 */
	show_active = priv->show_active;
	priv->show_active = FALSE;
	contact_list_store_remove_contact (store, contact);
	contact_list_store_add_contact (store, contact);
	priv->show_active = show_active;
}
static void
tp_contact_list_remove (EmpathyContactList *list,
			EmpathyContact     *contact,
			const gchar        *message)
{
	EmpathyTpContactListPriv *priv = GET_PRIV (list);
	TpHandle handle;
	GArray handles = {(gchar *) &handle, 1};

	handle = empathy_contact_get_handle (contact);

	/* FIXME: this is racy if tp_contact_list_remove is called before the
	 * 'stored' list has been retrieved. */
	if (priv->stored != NULL) {
		tp_cli_channel_interface_group_call_remove_members (priv->stored,
			-1, &handles, message, NULL, NULL, NULL, NULL);
	}

	if (priv->subscribe) {
		tp_cli_channel_interface_group_call_remove_members (priv->subscribe,
			-1, &handles, message, NULL, NULL, NULL, NULL);
	}
	if (priv->publish) {
		tp_cli_channel_interface_group_call_remove_members (priv->publish,
			-1, &handles, message, NULL, NULL, NULL, NULL);
	}
}
void
empathy_call_handler_start_call (EmpathyCallHandler *handler)
{

  EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
  EmpathyDispatcher *dispatcher;
  TpConnection *connection;
  GList *classes;
  GValue *value;
  GHashTable *request;

  if (priv->call != NULL)
    {
      empathy_call_handler_start_tpfs (handler);
      empathy_tp_call_accept_incoming_call (priv->call);
      return;
    }

  g_assert (priv->contact != NULL);

  dispatcher = empathy_dispatcher_dup_singleton ();
  connection = empathy_contact_get_connection (priv->contact);
  classes = empathy_dispatcher_find_requestable_channel_classes
    (dispatcher, connection, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
     TP_HANDLE_TYPE_CONTACT, NULL);

  if (classes == NULL)
    return;

  g_list_free (classes);

  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, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
  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.TargetHandle*/
  value = tp_g_value_slice_new (G_TYPE_UINT);
  g_value_set_uint (value, empathy_contact_get_handle (priv->contact));
  g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value);

  empathy_dispatcher_create_channel (dispatcher, connection,
    request, empathy_call_handler_request_cb, handler);

  g_object_unref (dispatcher);
}
static gboolean
find_window_for_handle (gpointer key,
    gpointer value,
    gpointer user_data)
{
  EmpathyContact *contact = key;
  guint handle = GPOINTER_TO_UINT (user_data);

  if (handle == empathy_contact_get_handle (contact))
    return TRUE;

  return FALSE;
}
static void
tp_contact_list_got_local_pending_cb (TpConnection            *connection,
				      guint                    n_contacts,
				      EmpathyContact * const * contacts,
				      guint                    n_failed,
				      const TpHandle          *failed,
				      const GError            *error,
				      gpointer                 user_data,
				      GObject                 *list)
{
	EmpathyTpContactListPriv *priv = GET_PRIV (list);
	guint i;

	if (error) {
		DEBUG ("Error: %s", error->message);
		return;
	}

	for (i = 0; i < n_contacts; i++) {
		EmpathyContact *contact = contacts[i];
		TpHandle handle;
		const gchar *message;
		TpChannelGroupChangeReason reason;
		const TpIntSet *members, *remote_pending;

		handle = empathy_contact_get_handle (contact);
		members = tp_channel_group_get_members (priv->subscribe);
		remote_pending = tp_channel_group_get_remote_pending (priv->subscribe);

		if (tp_intset_is_member (members, handle) ||
		    tp_intset_is_member (remote_pending, handle)) {
			GArray handles = {(gchar *) &handle, 1};

			/* This contact is already subscribed, or user requested
			 * to subscribe, auto accept. */
			tp_cli_channel_interface_group_call_add_members (priv->publish,
				-1, &handles, NULL, NULL, NULL, NULL, NULL);
		}
		else if (tp_channel_group_get_local_pending_info (priv->publish,
								  handle,
								  NULL,
								  &reason,
								  &message)) {
			/* Add contact to pendings */
			g_hash_table_insert (priv->pendings, GUINT_TO_POINTER (handle),
					     g_object_ref (contact));
			g_signal_emit_by_name (list, "pendings-changed", contact,
					       contact, reason, message, TRUE);
		}
	}
}
Exemple #14
0
static void
tp_chat_update_remote_contact (EmpathyTpChat *chat)
{
	EmpathyTpChatPriv *priv = GET_PRIV (chat);
	EmpathyContact *contact = NULL;
	TpHandle self_handle;
	TpHandleType handle_type;
	GList *l;

	/* If this is a named chatroom, never pretend it is a private chat */
	tp_channel_get_handle (priv->channel, &handle_type);
	if (handle_type == TP_HANDLE_TYPE_ROOM) {
		return;
	}

	/* This is an MSN-like chat where anyone can join the chat at anytime.
	 * If there is only one non-self contact member, we are in a private
	 * chat and we set the "remote-contact" property to that contact. If
	 * there are more, set the "remote-contact" property to NULL and the
	 * UI will display a contact list. */
	self_handle = tp_channel_group_get_self_handle (priv->channel);
	for (l = priv->members; l; l = l->next) {
		/* Skip self contact if member */
		if (empathy_contact_get_handle (l->data) == self_handle) {
			continue;
		}

		/* We have more than one remote contact, break */
		if (contact != NULL) {
			contact = NULL;
			break;
		}

		/* If we didn't find yet a remote contact, keep this one */
		contact = l->data;
	}

	if (priv->remote_contact == contact) {
		return;
	}

	DEBUG ("Changing remote contact from %p to %p",
		priv->remote_contact, contact);

	if (priv->remote_contact) {
		g_object_unref (priv->remote_contact);
	}

	priv->remote_contact = contact ? g_object_ref (contact) : NULL;
	g_object_notify (G_OBJECT (chat), "remote-contact");
}
static void
tp_contact_list_add_to_group (EmpathyContactList *list,
			      EmpathyContact     *contact,
			      const gchar        *group_name)
{
	TpHandle handle;
	GArray *handles;

	handle = empathy_contact_get_handle (contact);
	handles = g_array_sized_new (FALSE, FALSE, sizeof (TpHandle), 1);
	g_array_append_val (handles, handle);
	tp_contact_list_group_add (EMPATHY_TP_CONTACT_LIST (list),
				   group_name, handles);
}
static EmpathyContact *
tp_contact_factory_find_by_handle (EmpathyTpContactFactory *tp_factory,
				   guint                    handle)
{
	EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
	GList                       *l;

	for (l = priv->contacts; l; l = l->next) {
		if (empathy_contact_get_handle (l->data) == handle) {
			return l->data;
		}
	}

	return NULL;
}
Exemple #17
0
static void
tp_chat_remove (EmpathyContactList *list,
		EmpathyContact     *contact,
		const gchar        *message)
{
	EmpathyTpChatPriv *priv = GET_PRIV (list);
	TpHandle           handle;
	GArray             handles = {(gchar *) &handle, 1};

	g_return_if_fail (EMPATHY_IS_TP_CHAT (list));
	g_return_if_fail (EMPATHY_IS_CONTACT (contact));

	handle = empathy_contact_get_handle (contact);
	tp_cli_channel_interface_group_call_remove_members (priv->channel, -1,
							    &handles, NULL,
							    NULL, NULL, NULL,
							    NULL);
}
static void
contact_list_store_members_changed_cb (EmpathyContactList      *list_iface,
				       EmpathyContact          *contact,
				       EmpathyContact          *actor,
				       guint                    reason,
				       gchar                   *message,
				       gboolean                 is_member,
				       EmpathyContactListStore *store)
{
	EmpathyContactListStorePriv *priv;

	priv = GET_PRIV (store);

	DEBUG ("Contact %s (%d) %s",
		empathy_contact_get_id (contact),
		empathy_contact_get_handle (contact),
		is_member ? "added" : "removed");

	if (is_member) {
		g_signal_connect (contact, "notify::presence",
				  G_CALLBACK (contact_list_store_contact_updated_cb),
				  store);
		g_signal_connect (contact, "notify::presence-message",
				  G_CALLBACK (contact_list_store_contact_updated_cb),
				  store);
		g_signal_connect (contact, "notify::name",
				  G_CALLBACK (contact_list_store_contact_updated_cb),
				  store);
		g_signal_connect (contact, "notify::avatar",
				  G_CALLBACK (contact_list_store_contact_updated_cb),
				  store);
		g_signal_connect (contact, "notify::capabilities",
				  G_CALLBACK (contact_list_store_contact_updated_cb),
				  store);

		contact_list_store_add_contact (store, contact);
	} else {
		g_signal_handlers_disconnect_by_func (contact,
						      G_CALLBACK (contact_list_store_contact_updated_cb),
						      store);

		contact_list_store_remove_contact (store, contact);
	}
}
Exemple #19
0
static void
tp_chat_state_changed_got_contact_cb (EmpathyTpContactFactory *factory,
				      EmpathyContact          *contact,
				      const GError            *error,
				      gpointer                 user_data,
				      GObject                 *chat)
{
	TpChannelChatState state;

	if (error) {
		DEBUG ("Error: %s", error->message);
		return;
	}

	state = GPOINTER_TO_UINT (user_data);
	DEBUG ("Chat state changed for %s (%d): %d",
		empathy_contact_get_name (contact),
		empathy_contact_get_handle (contact), state);

	g_signal_emit (chat, signals[CHAT_STATE_CHANGED], 0, contact, state);
}
static void
tp_contact_list_remove_from_group (EmpathyContactList *list,
				   EmpathyContact     *contact,
				   const gchar        *group_name)
{
	EmpathyTpContactListPriv *priv = GET_PRIV (list);
	TpChannel                *channel;
	TpHandle                  handle;
	GArray                    handles = {(gchar *) &handle, 1};

	channel = g_hash_table_lookup (priv->groups, group_name);
	if (channel == NULL) {
		return;
	}

	handle = empathy_contact_get_handle (contact);
	DEBUG ("remove contact %s (%d) from group %s",
		empathy_contact_get_id (contact), handle, group_name);

	tp_cli_channel_interface_group_call_remove_members (channel, -1,
		&handles, NULL, NULL, NULL, NULL, NULL);
}
Exemple #21
0
static void
tp_chat_got_added_contacts_cb (EmpathyTpContactFactory *factory,
			       guint                    n_contacts,
			       EmpathyContact * const * contacts,
			       guint                    n_failed,
			       const TpHandle          *failed,
			       const GError            *error,
			       gpointer                 user_data,
			       GObject                 *chat)
{
	EmpathyTpChatPriv *priv = GET_PRIV (chat);
	guint i;
	const TpIntSet *members;
	TpHandle handle;
	EmpathyContact *contact;

	if (error) {
		DEBUG ("Error: %s", error->message);
		return;
	}

	members = tp_channel_group_get_members (priv->channel);
	for (i = 0; i < n_contacts; i++) {
		contact = contacts[i];
		handle = empathy_contact_get_handle (contact);

		/* Make sure the contact is still member */
		if (tp_intset_is_member (members, handle)) {
			priv->members = g_list_prepend (priv->members,
				g_object_ref (contact));
			g_signal_emit_by_name (chat, "members-changed",
					       contact, NULL, 0, NULL, TRUE);
		}
	}

	tp_chat_update_remote_contact (EMPATHY_TP_CHAT (chat));
	tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat));
}
void
empathy_tp_contact_factory_set_alias (EmpathyTpContactFactory *tp_factory,
				      EmpathyContact          *contact,
				      const gchar             *alias)
{
	EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
	GHashTable                  *new_alias;
	guint                        handle;

	g_return_if_fail (EMPATHY_IS_TP_CONTACT_FACTORY (tp_factory));
	g_return_if_fail (EMPATHY_IS_CONTACT (contact));

	handle = empathy_contact_get_handle (contact);

	DEBUG ("Setting alias for contact %s (%d) to %s",
		empathy_contact_get_id (contact),
		handle, alias);

	new_alias = g_hash_table_new_full (g_direct_hash,
					   g_direct_equal,
					   NULL,
					   g_free);

	g_hash_table_insert (new_alias,
			     GUINT_TO_POINTER (handle),
			     g_strdup (alias));

	tp_cli_connection_interface_aliasing_call_set_aliases (priv->connection,
							       -1,
							       new_alias,
							       tp_contact_factory_set_aliases_cb,
							       NULL, NULL,
							       G_OBJECT (tp_factory));

	g_hash_table_destroy (new_alias);
}
static void
tp_contact_factory_update_capabilities (EmpathyTpContactFactory *tp_factory,
					guint                    handle,
					const gchar             *channel_type,
					guint                    generic,
					guint                    specific)
{
	EmpathyContact      *contact;
	EmpathyCapabilities  capabilities;

	contact = tp_contact_factory_find_by_handle (tp_factory, handle);
	if (!contact) {
		return;
	}

	capabilities = empathy_contact_get_capabilities (contact);
	capabilities &= ~EMPATHY_CAPABILITIES_UNKNOWN;

	if (strcmp (channel_type, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA) == 0) {
		capabilities &= ~EMPATHY_CAPABILITIES_AUDIO;
		capabilities &= ~EMPATHY_CAPABILITIES_VIDEO;
		if (specific & TP_CHANNEL_MEDIA_CAPABILITY_AUDIO) {
			capabilities |= EMPATHY_CAPABILITIES_AUDIO;
		}
		if (specific & TP_CHANNEL_MEDIA_CAPABILITY_VIDEO) {
			capabilities |= EMPATHY_CAPABILITIES_VIDEO;
		}
	}

	DEBUG ("Changing capabilities for contact %s (%d) to %d",
		empathy_contact_get_id (contact),
		empathy_contact_get_handle (contact),
		capabilities);

	empathy_contact_set_capabilities (contact, capabilities);
}
static GList *
tp_contact_list_get_groups (EmpathyContactList *list,
			    EmpathyContact     *contact)
{
	EmpathyTpContactListPriv  *priv = GET_PRIV (list);
	GList                     *ret = NULL;
	GHashTableIter             iter;
	gpointer                   group_name;
	gpointer                   channel;
	TpHandle                   handle;

	handle = empathy_contact_get_handle (contact);
	g_hash_table_iter_init (&iter, priv->groups);
	while (g_hash_table_iter_next (&iter, &group_name, &channel)) {
		const TpIntSet *members;

		members = tp_channel_group_get_members (channel);
		if (tp_intset_is_member (members, handle)) {
			ret = g_list_prepend (ret, g_strdup (group_name));
		}
	}

	return ret;
}
Exemple #25
0
EmpathyTpTube *
empathy_tp_tube_new_stream_tube (EmpathyContact *contact,
                                 TpSocketAddressType type,
                                 const gchar *hostname,
                                 guint port,
                                 const gchar *service,
                                 GHashTable *parameters)
{
  MissionControl *mc;
  McAccount *account;
  TpConnection *connection;
  TpChannel *channel;
  gchar *object_path;
  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_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);

  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);
      g_object_unref (connection);
      return NULL;
    }

  DEBUG ("Offering a new stream tube");

  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)
  params = g_hash_table_new (g_str_hash, g_str_equal);
  address = tp_g_value_slice_new (ADDRESS_TYPE);
  g_value_take_boxed (address, dbus_g_type_specialized_construct (ADDRESS_TYPE));
  dbus_g_type_struct_set (address, 0, hostname, 1, port, G_MAXUINT);
  control_param = tp_g_value_slice_new (G_TYPE_STRING);

  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 offered");

  tube = empathy_tp_tube_new (channel);

OUT:
  g_object_unref (channel);
  g_free (object_path);
  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);

  return tube;
}
static void
tp_contact_factory_add_contact (EmpathyTpContactFactory *tp_factory,
				EmpathyContact          *contact)
{
	EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
	TpHandle self_handle;
	TpHandle handle;
	GArray handles = {(gchar *) &handle, 1};
	EmpathyCapabilities caps;

	/* Keep a weak ref to that contact */
	g_object_weak_ref (G_OBJECT (contact),
			   tp_contact_factory_weak_notify,
			   tp_factory);
	priv->contacts = g_list_prepend (priv->contacts, contact);

	/* The contact keeps a ref to its factory */
	g_object_set_data_full (G_OBJECT (contact), "empathy-factory",
				g_object_ref (tp_factory),
				g_object_unref);

	caps = empathy_contact_get_capabilities (contact);

	/* Set the FT capability */
	if (!priv->contact_caps_supported) {
		/* ContactCapabilities is not supported; assume all contacts can do file
		 * transfer if it's implemented in the CM */
		if (priv->can_request_ft) {
			caps |= EMPATHY_CAPABILITIES_FT;
		}

		/* Set the Stream Tube capability */
		if (priv->can_request_st) {
			caps |= EMPATHY_CAPABILITIES_STREAM_TUBE;
		}
	}

	empathy_contact_set_capabilities (contact, caps);

	/* Set is-user property. Note that it could still be the handle is
	 * different from the connection's self handle, in the case the handle
	 * comes from a group interface. */
	self_handle = tp_connection_get_self_handle (priv->connection);
	handle = empathy_contact_get_handle (contact);
	empathy_contact_set_is_user (contact, self_handle == handle);

	/* FIXME: This should be done by TpContact */
	if (tp_proxy_has_interface_by_id (priv->connection,
			TP_IFACE_QUARK_CONNECTION_INTERFACE_AVATARS)) {
		tp_cli_connection_interface_avatars_call_get_known_avatar_tokens (
			priv->connection, -1, &handles,
			tp_contact_factory_got_known_avatar_tokens, NULL, NULL,
			G_OBJECT (tp_factory));
	}

	if (priv->contact_caps_supported) {
		tp_cli_connection_interface_contact_capabilities_call_get_contact_capabilities (
			priv->connection, -1, &handles,
			tp_contact_factory_got_contact_capabilities, NULL, NULL,
			G_OBJECT (tp_factory));
	}
	else if (tp_proxy_has_interface_by_id (priv->connection,
			TP_IFACE_QUARK_CONNECTION_INTERFACE_CAPABILITIES)) {
		tp_cli_connection_interface_capabilities_call_get_capabilities (
			priv->connection, -1, &handles,
			tp_contact_factory_got_capabilities, NULL, NULL,
			G_OBJECT (tp_factory));
	}

	DEBUG ("Contact added: %s (%d)",
		empathy_contact_get_id (contact),
		empathy_contact_get_handle (contact));
}
static void
contact_list_view_drag_data_received (GtkWidget         *widget,
				      GdkDragContext    *context,
				      gint               x,
				      gint               y,
				      GtkSelectionData  *selection,
				      guint              info,
				      guint              time)
{
	EmpathyContactListViewPriv *priv;
	EmpathyContactList         *list;
	EmpathyContactFactory      *factory;
	McAccount                  *account;
	GtkTreeModel               *model;
	GtkTreePath                *path;
	GtkTreeViewDropPosition     position;
	EmpathyContact             *contact = NULL;
	const gchar                *id;
	gchar                     **strv;
	gchar                      *new_group = NULL;
	gchar                      *old_group = NULL;
	gboolean                    is_row;

	priv = GET_PRIV (widget);

	id = (const gchar*) selection->data;
	DEBUG ("Received %s%s drag & drop contact from roster with id:'%s'",
		context->action == GDK_ACTION_MOVE ? "move" : "",
		context->action == GDK_ACTION_COPY ? "copy" : "",
		id);

	strv = g_strsplit (id, "/", 2);
	factory = empathy_contact_factory_new ();
	account = mc_account_lookup (strv[0]);
	if (account) {
		contact = empathy_contact_factory_get_from_id (factory,
							       account,
							       strv[1]);
		g_object_unref (account);
	}
	g_object_unref (factory);
	g_strfreev (strv);

	if (!contact) {
		DEBUG ("No contact found associated with drag & drop");
		return;
	}

	empathy_contact_run_until_ready (contact,
					 EMPATHY_CONTACT_READY_HANDLE,
					 NULL);

	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));

	/* Get source group information. */
	if (priv->drag_row) {
		path = gtk_tree_row_reference_get_path (priv->drag_row);
		if (path) {
			old_group = empathy_contact_list_store_get_parent_group (model, path, NULL);
			gtk_tree_path_free (path);
		}
	}

	/* Get destination group information. */
	is_row = gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
						    x,
						    y,
						    &path,
						    &position);

	if (is_row) {
		new_group = empathy_contact_list_store_get_parent_group (model, path, NULL);
		gtk_tree_path_free (path);
	}

	DEBUG ("contact %s (%d) dragged from '%s' to '%s'",
		empathy_contact_get_id (contact),
		empathy_contact_get_handle (contact),
		old_group, new_group);

	list = empathy_contact_list_store_get_list_iface (priv->store);
	if (new_group) {
		empathy_contact_list_add_to_group (list, contact, new_group);
	}
	if (old_group && context->action == GDK_ACTION_MOVE) {	
		empathy_contact_list_remove_from_group (list, contact, old_group);
	}

	g_free (old_group);
	g_free (new_group);

	gtk_drag_finish (context, TRUE, FALSE, GDK_CURRENT_TIME);
}