changeset 25760:f462fa160f06

Sprinkle around more support for xml:lang on JabberIdentities Change the IPC has_feature function to take a PurpleAccount and look up the caps via the jbr
author Paul Aurich <paul@darkrain42.org>
date Sat, 22 Nov 2008 18:26:45 +0000
parents 0e8b5b5c497a
children 1b64942c5fb2
files libpurple/protocols/jabber/caps.c libpurple/protocols/jabber/disco.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/jabber.h
diffstat 4 files changed, 70 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/caps.c	Sat Nov 22 04:32:11 2008 +0000
+++ b/libpurple/protocols/jabber/caps.c	Sat Nov 22 18:26:45 2008 +0000
@@ -821,31 +821,34 @@
 }
 
 void jabber_caps_calculate_own_hash(JabberStream *js) {
-	JabberCapsClientInfo *info;
+	JabberCapsClientInfo info;
 	GList *iter = 0;
 	GList *features = 0;
 
-	if (jabber_identities == 0 && jabber_features == 0) return;
+	if (!jabber_identities && !jabber_features) {
+		/* This really shouldn't ever happen */
+		purple_debug_warning("jabber", "No features or identities, cannot calculate own caps hash.\n");
+		g_free(js->caps_hash);
+		js->caps_hash = NULL;
+		return;
+	}
 
-	/* sort features */
+	/* build the currently-supported list of features */
 	if (jabber_features) {
 		for (iter = jabber_features; iter; iter = iter->next) {
 			JabberFeature *feat = iter->data;
-			if(feat->is_enabled == NULL || feat->is_enabled(js, feat->namespace) == TRUE) {
+			if(!feat->is_enabled || feat->is_enabled(js, feat->namespace)) {
 				features = g_list_append(features, feat->namespace);
 			}
 		}
 	}
 
-	info = g_new0(JabberCapsClientInfo, 1);
-	info->features = features;
-	info->identities = jabber_identities;
-	info->forms = 0;
-	
-	if (js->caps_hash)
-		g_free(js->caps_hash);
-	js->caps_hash = jabber_caps_calculate_hash(info, "sha1");
-	g_free(info);
+	info.features = features;
+	info.identities = jabber_identities;
+	info.forms = NULL;
+
+	g_free(js->caps_hash);
+	js->caps_hash = jabber_caps_calculate_hash(&info, "sha1");
 	g_list_free(features);
 }
 
--- a/libpurple/protocols/jabber/disco.c	Sat Nov 22 04:32:11 2008 +0000
+++ b/libpurple/protocols/jabber/disco.c	Sat Nov 22 18:26:45 2008 +0000
@@ -99,7 +99,7 @@
 		const char *node = NULL;
 		char *node_uri = NULL;
 		
-		// create custom caps node URI
+		/* create custom caps node URI */
 		node_uri = g_strconcat(CAPS0115_NODE, "#", jabber_caps_get_own_hash(js), NULL);
 
 		if((in_query = xmlnode_get_child(packet, "query"))) {
@@ -126,11 +126,14 @@
 				identity = xmlnode_new_child(query, "identity");
 				xmlnode_set_attrib(identity, "category", ident->category);
 				xmlnode_set_attrib(identity, "type", ident->type);
-				if (ident->name != 0) xmlnode_set_attrib(identity, "name", ident->name);
+				if (ident->lang)
+					xmlnode_set_attrib(identity, "xml:lang", ident->lang);
+				if (ident->name)
+					xmlnode_set_attrib(identity, "name", ident->name);
 			}
 			for(features = jabber_features; features; features = features->next) {
 				JabberFeature *feat = (JabberFeature*)features->data;
-				if(feat->is_enabled == NULL || feat->is_enabled(js, feat->namespace) == TRUE) {
+				if (!feat->is_enabled || feat->is_enabled(js, feat->namespace)) {
 					feature = xmlnode_new_child(query, "feature");
 					xmlnode_set_attrib(feature, "var", feat->namespace);
 				}	
--- a/libpurple/protocols/jabber/jabber.c	Sat Nov 22 04:32:11 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Sat Nov 22 18:26:45 2008 +0000
@@ -1520,7 +1520,7 @@
 	}
 }
 
-void jabber_add_identity(const gchar *category, const gchar *type, const gchar *name) {
+void jabber_add_identity(const gchar *category, const gchar *type, const gchar *lang, const gchar *name) {
 	GList *identity;
 	JabberIdentity *ident;
 	/* both required according to XEP-0030 */
@@ -1529,14 +1529,17 @@
 	
 	for(identity = jabber_identities; identity; identity = identity->next) {
 		JabberIdentity *ident = (JabberIdentity*)identity->data;
-		if(!strcmp(ident->category, category)) {
-			if (!strcmp(ident->type, type)) return;
+		if (!strcmp(ident->category, category) &&
+		    !strcmp(ident->type, type) &&
+		    ((!ident->lang && !lang) || (ident->lang && lang && !strcmp(ident->lang, lang)))) {
+			return;
 		}	
 	}
-	
+
 	ident = g_new0(JabberIdentity, 1);
 	ident->category = g_strdup(category);
 	ident->type = g_strdup(type);
+	ident->lang = g_strdup(lang);
 	ident->name = g_strdup(name);
 	jabber_identities = g_list_append(jabber_identities, ident);
 }
@@ -2541,27 +2544,47 @@
 					  _("buzz: Buzz a user to get their attention"), NULL);
 }
 
-/* IPC functions*/
+/* IPC functions */
 
-/*
- * IPC function for checking wheather a client at a full JID supports a certain feature.
- * 
- * @param fulljid 	The full JID of the client.
- * @param featrure 	The feature's namespace.
- * 
+/**
+ * IPC function for determining if a contact supports a certain feature.
+ *
+ * @param account   The PurpleAccount
+ * @param jid       The full JID of the contact.
+ * @param feature   The feature's namespace.
+ *
  * @return TRUE if supports feature; else FALSE.
  */
 static gboolean
-jabber_ipc_contact_has_feature(const gchar *fulljid, const gchar *feature)
+jabber_ipc_contact_has_feature(PurpleAccount *account, const gchar *jid,
+                               const gchar *feature)
 {
-	gpointer caps_hash = g_hash_table_lookup(jabber_contact_info, fulljid);
-	JabberCapsClientInfo *capabilities;
+	PurpleConnection *gc = purple_account_get_connection(account);
+	JabberStream *js;
+	JabberBuddy *jb;
+	JabberBuddyResource *jbr;
+	gchar *resource;
+
+	if (!purple_account_is_connected(account))
+		return FALSE;
+	js = gc->proto_data;
 
-	if (!caps_hash)
+	resource = jabber_get_resource(jid);
+	if (!(resource = jabber_get_resource(jid)) || 
+	    !(jb = jabber_buddy_find(js, jid, FALSE)) ||
+	    !(jbr = jabber_buddy_find_resource(jb, resource))) {
+		g_free(resource);
 		return FALSE;
+	}
 
-	capabilities = g_hash_table_lookup(capstable, caps_hash);
-	return g_list_find_custom(capabilities->features, feature, (GCompareFunc)strcmp) != NULL;
+	g_free(resource);
+
+	if (!jbr->caps) {
+		/* TODO: fetch them? */
+		return FALSE;
+	}
+
+	return NULL != g_list_find_custom(jbr->caps->features, feature, (GCompareFunc)strcmp);
 }
 
 static void
@@ -2580,7 +2603,7 @@
 {
 	my_protocol = plugin;
 
-	jabber_add_identity("client", "pc", PACKAGE);
+	jabber_add_identity("client", "pc", NULL, PACKAGE);
 
 	/* initialize jabber_features list */
 	jabber_add_feature("jabber:iq:last", 0);
@@ -2606,8 +2629,9 @@
 	
 	/* IPC functions */
 	purple_plugin_ipc_register(plugin, "contact_has_feature", PURPLE_CALLBACK(jabber_ipc_contact_has_feature),
-							 purple_marshal_BOOLEAN__POINTER_POINTER,
-							 purple_value_new(PURPLE_TYPE_BOOLEAN), 2,
+							 purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
+							 purple_value_new(PURPLE_TYPE_BOOLEAN), 3,
+							 purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_ACCOUNT),
 							 purple_value_new(PURPLE_TYPE_STRING),
 							 purple_value_new(PURPLE_TYPE_STRING));
 	purple_plugin_ipc_register(plugin, "add_feature", PURPLE_CALLBACK(jabber_ipc_add_feature),
--- a/libpurple/protocols/jabber/jabber.h	Sat Nov 22 04:32:11 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.h	Sat Nov 22 18:26:45 2008 +0000
@@ -308,10 +308,11 @@
 /** Adds an identitiy to this jabber library instance. For list of valid values vistit the 
  *	webiste of the XMPP Registrar ( http://www.xmpp.org/registrar/disco-categories.html#client ).
  *  @param category the category of the identity.
- *	@param type the type of the identity.
- *	@param name the name of the identity.
+ *  @param type the type of the identity.
+ *  @param language the language localization of the name. Can be NULL.
+ *  @param name the name of the identity.
  */
-void jabber_add_identity(const gchar *category, const gchar *type, const gchar *name); 
+void jabber_add_identity(const gchar *category, const gchar *type, const gchar *lang, const gchar *name); 
 
 /** PRPL functions */
 const char *jabber_list_icon(PurpleAccount *a, PurpleBuddy *b);