Mercurial > pidgin
changeset 26474:8399b545925c
propagate from branch 'im.pidgin.pidgin' (head 58b2ba106e563fcd0984b9438aa427f1d61e25e9)
to branch 'im.pidgin.cpw.darkrain42.xmpp.iq-handlers' (head a7d6ab07b988776e830ffb6befb18179ff46e24e)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sat, 04 Apr 2009 07:08:33 +0000 |
parents | c08719989149 (diff) 50ff0162fe26 (current diff) |
children | bf9438ea308d |
files | libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/jingle/rtp.c |
diffstat | 6 files changed, 290 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog.API Sat Apr 04 07:05:23 2009 +0000 +++ b/ChangeLog.API Sat Apr 04 07:08:33 2009 +0000 @@ -22,6 +22,10 @@ * purple_global_proxy_set_info * purple_log_get_activity_score * purple_network_force_online + * purple_network_set_stun_server + * purple_network_set_turn_server + * purple_network_get_stun_ip + * purple_network_get_turn_ip * purple_prpl_get_media_caps * purple_prpl_initiate_media * purple_request_field_get_group
--- a/libpurple/media.c Sat Apr 04 07:05:23 2009 +0000 +++ b/libpurple/media.c Sat Apr 04 07:08:33 2009 +0000 @@ -655,6 +655,7 @@ GObject parent; }; +#ifdef USE_VV struct _PurpleMediaCandidatePrivate { gchar *foundation; @@ -929,6 +930,13 @@ G_DEFINE_TYPE(PurpleMediaCandidate, purple_media_candidate, G_TYPE_OBJECT); +#else +GType +purple_media_candidate_get_type() +{ + return G_TYPE_NONE; +} +#endif PurpleMediaCandidate * purple_media_candidate_new(const gchar *foundation, guint component_id, @@ -948,6 +956,7 @@ static PurpleMediaCandidate * purple_media_candidate_copy(PurpleMediaCandidate *candidate) { +#ifdef USE_VV PurpleMediaCandidatePrivate *priv; PurpleMediaCandidate *new_candidate; @@ -967,6 +976,9 @@ "password", priv->password, "ttl", priv->ttl, NULL); return new_candidate; +#else + return NULL; +#endif } #ifdef USE_VV @@ -1240,6 +1252,7 @@ GObject parent; }; +#ifdef USE_VV struct _PurpleMediaCodecPrivate { gint id; @@ -1408,6 +1421,13 @@ G_DEFINE_TYPE(PurpleMediaCodec, purple_media_codec, G_TYPE_OBJECT); +#else +GType +purple_media_codec_get_type() +{ + return G_TYPE_NONE; +} +#endif guint purple_media_codec_get_id(PurpleMediaCodec *codec) @@ -1458,6 +1478,7 @@ purple_media_codec_add_optional_parameter(PurpleMediaCodec *codec, const gchar *name, const gchar *value) { +#ifdef USE_VV PurpleMediaCodecPrivate *priv; PurpleKeyValuePair *new_param; @@ -1471,12 +1492,14 @@ new_param->value = g_strdup(value); priv->optional_params = g_list_append( priv->optional_params, new_param); +#endif } void purple_media_codec_remove_optional_parameter(PurpleMediaCodec *codec, PurpleKeyValuePair *param) { +#ifdef USE_VV PurpleMediaCodecPrivate *priv; g_return_if_fail(codec != NULL && param != NULL); @@ -1489,12 +1512,14 @@ priv->optional_params = g_list_remove(priv->optional_params, param); +#endif } PurpleKeyValuePair * purple_media_codec_get_optional_parameter(PurpleMediaCodec *codec, const gchar *name, const gchar *value) { +#ifdef USE_VV PurpleMediaCodecPrivate *priv; GList *iter; @@ -1510,6 +1535,7 @@ !g_ascii_strcasecmp(param->value, value))) return param; } +#endif return NULL; } @@ -1530,6 +1556,7 @@ static PurpleMediaCodec * purple_media_codec_copy(PurpleMediaCodec *codec) { +#ifdef USE_VV PurpleMediaCodecPrivate *priv; PurpleMediaCodec *new_codec; GList *iter; @@ -1551,6 +1578,9 @@ } return new_codec; +#else + return NULL; +#endif } #ifdef USE_VV
--- a/libpurple/mediamanager.c Sat Apr 04 07:05:23 2009 +0000 +++ b/libpurple/mediamanager.c Sat Apr 04 07:08:33 2009 +0000 @@ -67,7 +67,6 @@ gulong window_id; GstElement *sink; }; -#endif struct _PurpleMediaManagerPrivate { @@ -100,10 +99,12 @@ LAST_SIGNAL }; static guint purple_media_manager_signals[LAST_SIGNAL] = {0}; +#endif GType purple_media_manager_get_type() { +#ifdef USE_VV static GType type = 0; if (type == 0) { @@ -122,9 +123,12 @@ type = g_type_register_static(G_TYPE_OBJECT, "PurpleMediaManager", &info, 0); } return type; +#else + return G_TYPE_NONE; +#endif } - +#ifdef USE_VV static void purple_media_manager_class_init (PurpleMediaManagerClass *klass) { @@ -165,6 +169,7 @@ } parent_class->finalize(media); } +#endif PurpleMediaManager * purple_media_manager_get() @@ -837,7 +842,7 @@ PURPLE_MEDIA_CAPS_NONE); return manager->priv->ui_caps; #else - return PURPLE_CAPS_NONE; + return PURPLE_MEDIA_CAPS_NONE; #endif } @@ -909,6 +914,7 @@ GObject parent; }; +#ifdef USE_VV struct _PurpleMediaElementInfoPrivate { gchar *id; @@ -1048,6 +1054,13 @@ G_DEFINE_TYPE(PurpleMediaElementInfo, purple_media_element_info, G_TYPE_OBJECT); +#else +GType +purple_media_element_info_get_type() +{ + return G_TYPE_NONE; +} +#endif gchar * purple_media_element_info_get_id(PurpleMediaElementInfo *info)
--- a/libpurple/network.h Sat Apr 04 07:05:23 2009 +0000 +++ b/libpurple/network.h Sat Apr 04 07:08:33 2009 +0000 @@ -230,6 +230,7 @@ * Will result in a DNS query being executed asynchronous * * @param stun_server The host name of the STUN server to set + * @since 2.6.0 */ void purple_network_set_stun_server(const gchar *stun_server); @@ -237,6 +238,7 @@ * Get the IP address of the STUN server as a string representation * * @return the IP address + * @since 2.6.0 */ const gchar *purple_network_get_stun_ip(void); @@ -245,6 +247,7 @@ * Will result in a DNS query being executed asynchronous * * @param stun_server The host name of the STUN server to set + * @since 2.6.0 */ void purple_network_set_turn_server(const gchar *stun_server); @@ -252,6 +255,7 @@ * Get the IP address of the STUN server as a string representation * * @return the IP address + * @since 2.6.0 */ const gchar *purple_network_get_turn_ip(void);
--- a/libpurple/protocols/jabber/jabber.c Sat Apr 04 07:05:23 2009 +0000 +++ b/libpurple/protocols/jabber/jabber.c Sat Apr 04 07:08:33 2009 +0000 @@ -2612,6 +2612,39 @@ return TRUE; } +#ifdef USE_VV +typedef struct { + PurpleConnection *pc; + gchar *who; + PurpleMediaSessionType type; + +} JabberMediaRequest; + +static void +jabber_media_cancel_cb(JabberMediaRequest *request, + PurpleRequestFields *fields) +{ + g_free(request->who); + g_free(request); +} + +static void +jabber_media_ok_cb(JabberMediaRequest *request, PurpleRequestFields *fields) +{ + PurpleRequestField *field = + purple_request_fields_get_field(fields, "resource"); + int selected_id = purple_request_field_choice_get_value(field); + GList *labels = purple_request_field_choice_get_labels(field); + gchar *who = g_strdup_printf("%s/%s", request->who, + (gchar*)g_list_nth_data(labels, selected_id)); + jabber_initiate_media(request->pc, who, request->type); + + g_free(who); + g_free(request->who); + g_free(request); +} +#endif + gboolean jabber_initiate_media(PurpleConnection *gc, const char *who, PurpleMediaSessionType type) @@ -2619,6 +2652,8 @@ #ifdef USE_VV JabberStream *js = (JabberStream *) gc->proto_data; JabberBuddy *jb; + JabberBuddyResource *jbr = NULL; + char *resource; if (!js) { purple_debug_error("jabber", @@ -2626,23 +2661,135 @@ return FALSE; } - jb = jabber_buddy_find(js, who, FALSE); - - if (!jb) { - purple_debug_error("jabber", "Could not find buddy\n"); - return FALSE; + + if((resource = jabber_get_resource(who)) != NULL) { + /* they've specified a resource, no need to ask or + * default or anything, just do it */ + + jb = jabber_buddy_find(js, who, FALSE); + jbr = jabber_buddy_find_resource(jb, resource); + g_free(resource); + + if (type & PURPLE_MEDIA_AUDIO && + !jabber_resource_has_capability(jbr, + JINGLE_APP_RTP_SUPPORT_AUDIO) && + jabber_resource_has_capability(jbr, + GOOGLE_VOICE_CAP)) + return jabber_google_session_initiate( + gc->proto_data, who, type); + else + return jingle_rtp_initiate_media( + gc->proto_data, who, type); } - if (type & PURPLE_MEDIA_AUDIO && - !jabber_buddy_has_capability(jb, - JINGLE_APP_RTP_SUPPORT_AUDIO) && - jabber_buddy_has_capability(jb, GOOGLE_VOICE_CAP)) - return jabber_google_session_initiate(gc->proto_data, who, type); - else - return jingle_rtp_initiate_media(gc->proto_data, who, type); -#else + jb = jabber_buddy_find(js, who, FALSE); + + if(!jb || !jb->resources) { + /* no resources online, we're trying to initiate with someone + * whose presence we're not subscribed to, or + * someone who is offline. Let's inform the user */ + char *msg; + + if(!jb) { + msg = g_strdup_printf(_("Unable to initiate media with %s, invalid JID"), who); + } else if(jb->subscription & JABBER_SUB_TO) { + msg = g_strdup_printf(_("Unable to initiate media with %s, user is not online"), who); + } else { + msg = g_strdup_printf(_("Unable to initiate media with %s, not subscribed to user presence"), who); + } + + purple_notify_error(js->gc, _("Media Initiation Failed"), + _("Media Initiation Failed"), msg); + g_free(msg); + return FALSE; + } else if(!jb->resources->next) { + /* only 1 resource online (probably our most common case) + * so no need to ask who to initiate with */ + gchar *name; + gboolean result; + jbr = jb->resources->data; + name = g_strdup_printf("%s/%s", who, jbr->name); + result = jabber_initiate_media(gc, name, type); + g_free(name); + return result; + } else { + /* we've got multiple resources, + * we need to pick one to initiate with */ + GList *l; + char *msg; + PurpleRequestFields *fields; + PurpleRequestField *field = purple_request_field_choice_new( + "resource", _("Resource"), 0); + PurpleRequestFieldGroup *group; + JabberMediaRequest *request; + + for(l = jb->resources; l; l = l->next) + { + JabberBuddyResource *ljbr = l->data; + PurpleMediaCaps caps; + gchar *name; + name = g_strdup_printf("%s/%s", who, ljbr->name); + caps = jabber_get_media_caps(gc, name); + g_free(name); + + if ((type & PURPLE_MEDIA_AUDIO) && + (type & PURPLE_MEDIA_VIDEO)) { + if (caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO) { + jbr = ljbr; + purple_request_field_choice_add( + field, jbr->name); + } + } else if (type & (PURPLE_MEDIA_AUDIO) && + (caps & PURPLE_MEDIA_CAPS_AUDIO)) { + jbr = ljbr; + purple_request_field_choice_add( + field, jbr->name); + }else if (type & (PURPLE_MEDIA_VIDEO) && + (caps & PURPLE_MEDIA_CAPS_VIDEO)) { + jbr = ljbr; + purple_request_field_choice_add( + field, jbr->name); + } + } + + if (jbr == NULL) { + purple_debug_error("jabber", + "No resources available\n"); + return FALSE; + } + + if (g_list_length(purple_request_field_choice_get_labels( + field)) <= 1) { + gchar *name; + gboolean result; + purple_request_field_destroy(field); + name = g_strdup_printf("%s/%s", who, jbr->name); + result = jabber_initiate_media(gc, name, type); + g_free(name); + return result; + } + + msg = g_strdup_printf(_("Please select the resource of %s to which you would like to start a media session with."), who); + fields = purple_request_fields_new(); + group = purple_request_field_group_new(NULL); + request = g_new0(JabberMediaRequest, 1); + request->pc = gc; + request->who = g_strdup(who); + request->type = type; + + purple_request_field_group_add_field(group, field); + purple_request_fields_add_group(fields, group); + purple_request_fields(gc, _("Select a Resource"), msg, NULL, + fields, _("Initiate Media"), + G_CALLBACK(jabber_media_ok_cb), _("Cancel"), + G_CALLBACK(jabber_media_cancel_cb), + gc->account, who, NULL, request); + + g_free(msg); + return TRUE; + } +#endif return FALSE; -#endif } PurpleMediaCaps jabber_get_media_caps(PurpleConnection *gc, const char *who) @@ -2650,7 +2797,9 @@ #ifdef USE_VV JabberStream *js = (JabberStream *) gc->proto_data; JabberBuddy *jb; + JabberBuddyResource *jbr; PurpleMediaCaps caps = PURPLE_MEDIA_CAPS_NONE; + gchar *resource; if (!js) { purple_debug_info("jabber", @@ -2658,35 +2807,75 @@ return FALSE; } - jb = jabber_buddy_find(js, who, FALSE); - - if (!jb) { - purple_debug_error("jabber", "Could not find buddy\n"); - return FALSE; + if ((resource = jabber_get_resource(who)) != NULL) { + /* they've specified a resource, no need to ask or + * default or anything, just do it */ + + jb = jabber_buddy_find(js, who, FALSE); + jbr = jabber_buddy_find_resource(jb, resource); + g_free(resource); + + if (!jbr) { + purple_debug_error("jabber", "jabber_get_media_caps:" + " Can't find resource %s\n", who); + return caps; + } + + if (jabber_resource_has_capability(jbr, + JINGLE_APP_RTP_SUPPORT_AUDIO)) + caps |= PURPLE_MEDIA_CAPS_AUDIO_SINGLE_DIRECTION | + PURPLE_MEDIA_CAPS_AUDIO; + if (jabber_resource_has_capability(jbr, + JINGLE_APP_RTP_SUPPORT_VIDEO)) + caps |= PURPLE_MEDIA_CAPS_VIDEO_SINGLE_DIRECTION | + PURPLE_MEDIA_CAPS_VIDEO; + if (caps & PURPLE_MEDIA_CAPS_AUDIO && caps & + PURPLE_MEDIA_CAPS_VIDEO) + caps |= PURPLE_MEDIA_CAPS_AUDIO_VIDEO; + if (caps != PURPLE_MEDIA_CAPS_NONE) { + if (!jabber_resource_has_capability(jbr, + JINGLE_TRANSPORT_ICEUDP) && + !jabber_resource_has_capability(jbr, + JINGLE_TRANSPORT_RAWUDP)) { + purple_debug_info("jingle-rtp", "Buddy doesn't " + "support the same transport types\n"); + caps = PURPLE_MEDIA_CAPS_NONE; + } else + caps |= PURPLE_MEDIA_CAPS_MODIFY_SESSION | + PURPLE_MEDIA_CAPS_CHANGE_DIRECTION; + } + if (jabber_resource_has_capability(jbr, GOOGLE_VOICE_CAP)) + caps |= PURPLE_MEDIA_CAPS_AUDIO; + return caps; } - if (jabber_buddy_has_capability(jb, JINGLE_APP_RTP_SUPPORT_AUDIO)) - caps |= PURPLE_MEDIA_CAPS_AUDIO | - PURPLE_MEDIA_CAPS_AUDIO_SINGLE_DIRECTION; - if (jabber_buddy_has_capability(jb, JINGLE_APP_RTP_SUPPORT_VIDEO)) - caps |= PURPLE_MEDIA_CAPS_VIDEO | - PURPLE_MEDIA_CAPS_VIDEO_SINGLE_DIRECTION; - if (caps & PURPLE_MEDIA_CAPS_AUDIO && caps & PURPLE_MEDIA_CAPS_VIDEO) - caps |= PURPLE_MEDIA_CAPS_AUDIO_VIDEO; - if (caps != PURPLE_MEDIA_CAPS_NONE) { - if (!jabber_buddy_has_capability(jb, - JINGLE_TRANSPORT_ICEUDP) && - !jabber_buddy_has_capability(jb, - JINGLE_TRANSPORT_RAWUDP)) { - purple_debug_info("jingle-rtp", "Buddy doesn't " - "support the same transport types\n"); - caps = PURPLE_MEDIA_CAPS_NONE; - } else - caps |= PURPLE_MEDIA_CAPS_MODIFY_SESSION | - PURPLE_MEDIA_CAPS_CHANGE_DIRECTION; + jb = jabber_buddy_find(js, who, FALSE); + + if(!jb || !jb->resources) { + /* no resources online, we're trying to get caps for someone + * whose presence we're not subscribed to, or + * someone who is offline. */ + return caps; + } else if(!jb->resources->next) { + /* only 1 resource online (probably our most common case) */ + gchar *name; + jbr = jb->resources->data; + name = g_strdup_printf("%s/%s", who, jbr->name); + caps = jabber_get_media_caps(gc, name); + g_free(name); + } else { + /* we've got multiple resources, combine their caps */ + GList *l; + + for(l = jb->resources; l; l = l->next) + { + gchar *name; + jbr = l->data; + name = g_strdup_printf("%s/%s", who, jbr->name); + caps |= jabber_get_media_caps(gc, name); + g_free(name); + } } - if (jabber_buddy_has_capability(jb, GOOGLE_VOICE_CAP)) - caps |= PURPLE_MEDIA_CAPS_AUDIO; return caps; #else
--- a/libpurple/protocols/jabber/jingle/rtp.c Sat Apr 04 07:05:23 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/rtp.c Sat Apr 04 07:08:33 2009 +0000 @@ -835,7 +835,7 @@ JabberBuddyResource *jbr; const gchar *transport_type; - gchar *jid = NULL, *me = NULL, *sid = NULL; + gchar *resource = NULL, *me = NULL, *sid = NULL; /* construct JID to send to */ jb = jabber_buddy_find(js, who, FALSE); @@ -843,7 +843,11 @@ purple_debug_error("jingle-rtp", "Could not find Jabber buddy\n"); return FALSE; } - jbr = jabber_buddy_find_resource(jb, NULL); + + resource = jabber_get_resource(who); + jbr = jabber_buddy_find_resource(jb, resource); + g_free(resource); + if (!jbr) { purple_debug_error("jingle-rtp", "Could not find buddy's resource\n"); } @@ -858,17 +862,11 @@ return FALSE; } - if ((strchr(who, '/') == NULL) && jbr && (jbr->name != NULL)) { - jid = g_strdup_printf("%s/%s", who, jbr->name); - } else { - jid = g_strdup(who); - } - /* set ourselves as initiator */ me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, js->user->resource); sid = jabber_get_next_id(js); - session = jingle_session_create(js, sid, me, jid, TRUE); + session = jingle_session_create(js, sid, me, who, TRUE); g_free(sid); @@ -889,7 +887,6 @@ jingle_rtp_init_media(content); } - g_free(jid); g_free(me); if (jingle_rtp_get_media(session) == NULL) {