pidgin: c7f905eb: Add jabber signals for IQ, Message, and ...

darkrain42 at pidgin.im darkrain42 at pidgin.im
Tue May 12 01:55:28 EDT 2009


-----------------------------------------------------------------
Revision: c7f905eba9a02b5b1d29807b92097e77e3187ede
Ancestor: abd58e080488d437ecaee1209172d094986d2ad5
Author: darkrain42 at pidgin.im
Date: 2009-05-12T05:49:34
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/c7f905eba9a02b5b1d29807b92097e77e3187ede

Modified files:
        ChangeLog.API libpurple/protocols/jabber/iq.c
        libpurple/protocols/jabber/iq.h
        libpurple/protocols/jabber/jabber.c
        libpurple/protocols/jabber/jabber.h
        libpurple/protocols/jabber/libxmpp.c
        libpurple/protocols/jabber/message.c
        libpurple/protocols/jabber/presence.c

ChangeLog: 

Add jabber signals for IQ, Message, and Presence stanzas. Lightly tested (it doesn't crash [Prove me wrong!]) and as you'll note, I refer to documentation that doesn't yet exist.

-------------- next part --------------
============================================================
--- ChangeLog.API	11bd5f30ff69471469a78c0b839b6e6c19e5186a
+++ ChangeLog.API	ca7d983fe02f8e38b5ce40742bd4ac549af4228f
@@ -15,6 +15,7 @@ version 2.6.0 (??/??/2009):
 			* account-destroying
 		* blist-node-added and blist-node-removed signals (see
 		  blist-signals.dox)
+		* Jabber plugin signals (see jabber-signals.dox)
 		* purple_buddy_destroy
 		* purple_buddy_get_protocol_data
 		* purple_buddy_set_protocol_data
============================================================
--- libpurple/protocols/jabber/iq.c	188f86d9ec085cba428cfbdc1c99964ac45656b1
+++ libpurple/protocols/jabber/iq.c	7fcf359237e0f43a8c783ebe2811e8961c942320
@@ -42,8 +42,8 @@ GHashTable *iq_handlers = NULL;
 #endif
 
 GHashTable *iq_handlers = NULL;
+GHashTable *signal_iq_handlers = NULL;
 
-
 JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type)
 {
 	JabberIq *iq;
@@ -289,7 +289,17 @@ void jabber_iq_parse(JabberStream *js, x
 	const char *xmlns;
 	const char *iq_type, *id, *from;
 	JabberIqType type = JABBER_IQ_NONE;
+	gboolean signal_return;
 
+	from = xmlnode_get_attrib(packet, "from");
+	id = xmlnode_get_attrib(packet, "id");
+	iq_type = xmlnode_get_attrib(packet, "type");
+
+	signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(jabber_plugin,
+			"jabber-receiving-iq", js->gc, iq_type, id, from, packet));
+	if (signal_return)
+		return;
+
 	/*
 	 * child will be either the first tag child or NULL if there is no child.
 	 * Historically, we used just the 'query' subchild, but newer XEPs use
@@ -301,10 +311,6 @@ void jabber_iq_parse(JabberStream *js, x
 			break;
 	}
 
-	iq_type = xmlnode_get_attrib(packet, "type");
-	from = xmlnode_get_attrib(packet, "from");
-	id = xmlnode_get_attrib(packet, "id");
-
 	if (iq_type) {
 		if (!strcmp(iq_type, "get"))
 			type = JABBER_IQ_GET;
@@ -361,12 +367,23 @@ void jabber_iq_parse(JabberStream *js, x
 		}
 	}
 
-	/* Apparently not, so lets see if we have a pre-defined handler */
+	/*
+	 * Apparently not, so let's see if we have a pre-defined handler
+	 * or if an outside plugin is interested.
+	 */
 	if(child && (xmlns = xmlnode_get_namespace(child))) {
 		char *key = g_strdup_printf("%s %s", child->name, xmlns);
 		JabberIqHandler *jih = g_hash_table_lookup(iq_handlers, key);
+		int signal_ref = GPOINTER_TO_INT(g_hash_table_lookup(signal_iq_handlers, key));
 		g_free(key);
 
+		if (signal_ref > 0) {
+			signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(jabber_plugin, "jabber-watched-iq",
+					js->gc, iq_type, id, from, child));
+			if (signal_return)
+				return;
+		}
+
 		if(jih) {
 			jih(js, from, type, id, child);
 			return;
@@ -408,9 +425,48 @@ void jabber_iq_register_handler(const ch
 	g_hash_table_replace(iq_handlers, key, handlerfunc);
 }
 
+void jabber_iq_signal_register(const gchar *node, const gchar *xmlns)
+{
+	gchar *key;
+	int ref;
+
+	g_return_if_fail(node != NULL && *node != '\0');
+	g_return_if_fail(xmlns != NULL && *xmlns != '\0');
+
+	key = g_strdup_printf("%s %s", node, xmlns);
+	ref = GPOINTER_TO_INT(g_hash_table_lookup(signal_iq_handlers, key));
+	if (ref == 0) {
+		g_hash_table_insert(signal_iq_handlers, key, GINT_TO_POINTER(1));
+	} else {
+		g_hash_table_insert(signal_iq_handlers, key, GINT_TO_POINTER(ref + 1));
+		g_free(key);
+	}
+}
+
+void jabber_iq_signal_unregister(const gchar *node, const gchar *xmlns)
+{
+	gchar *key;
+	int ref;
+
+	g_return_if_fail(node != NULL && *node != '\0');
+	g_return_if_fail(xmlns != NULL && *xmlns != '\0');
+
+	key = g_strdup_printf("%s %s", node, xmlns);
+	ref = GPOINTER_TO_INT(g_hash_table_lookup(signal_iq_handlers, key));
+
+	if (ref == 1) {
+		g_hash_table_remove(signal_iq_handlers, key);
+	} else if (ref > 1) {
+		g_hash_table_insert(signal_iq_handlers, key, GINT_TO_POINTER(ref - 1));
+	}
+
+	g_free(key);
+}
+
 void jabber_iq_init(void)
 {
 	iq_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+	signal_iq_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
 
 	jabber_iq_register_handler("jingle", JINGLE, jingle_parse);
 	jabber_iq_register_handler("mailbox", "google:mail:notify",
@@ -446,5 +502,6 @@ void jabber_iq_uninit(void)
 void jabber_iq_uninit(void)
 {
 	g_hash_table_destroy(iq_handlers);
-	iq_handlers = NULL;
+	g_hash_table_destroy(signal_iq_handlers);
+	iq_handlers = signal_iq_handlers = NULL;
 }
============================================================
--- libpurple/protocols/jabber/iq.h	4d71fd72742c2e96c449562d21daec4dbecdffe5
+++ libpurple/protocols/jabber/iq.h	5c7bbc10758bd17a93cc5f80e58deabafd9e292a
@@ -31,6 +31,7 @@ typedef enum {
 } JabberIqType;
 
 #include "jabber.h"
+#include "connection.h"
 
 typedef struct _JabberIq JabberIq;
 
@@ -106,4 +107,8 @@ void jabber_iq_register_handler(const ch
 void jabber_iq_register_handler(const char *node, const char *xmlns,
                                 JabberIqHandler *func);
 
+/* Connected to namespace-handler registration signals */
+void jabber_iq_signal_register(const gchar *node, const gchar *xmlns);
+void jabber_iq_signal_unregister(const gchar *node, const gchar *xmlns);
+
 #endif /* PURPLE_JABBER_IQ_H_ */
============================================================
--- libpurple/protocols/jabber/jabber.c	86ab306b3c9de6a66f39d2d6cf5f811fc297fc12
+++ libpurple/protocols/jabber/jabber.c	4309ede5f6dfeb83d4a2169c5495a60b50cb244f
@@ -3380,6 +3380,7 @@ jabber_init_plugin(PurplePlugin *plugin)
 							 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),
 							 purple_marshal_VOID__POINTER,
 							 NULL, 1,
@@ -3389,6 +3390,8 @@ jabber_uninit_plugin(void)
 void
 jabber_uninit_plugin(void)
 {
+	purple_plugin_ipc_unregister_all(jabber_plugin);
+
 	jabber_features_destroy();
 	jabber_identities_destroy();
 }
============================================================
--- libpurple/protocols/jabber/jabber.h	3aa5419d7cee083fb06962c961551cb75bc73301
+++ libpurple/protocols/jabber/jabber.h	36f320bd84b570deb1379f758c72a78019ca67f1
@@ -75,6 +75,8 @@ typedef struct _JabberStream JabberStrea
 /* Index into attention_types list */
 #define JABBER_BUZZ 0
 
+PurplePlugin *jabber_plugin;
+
 typedef enum {
 	JABBER_STREAM_OFFLINE,
 	JABBER_STREAM_CONNECTING,
============================================================
--- libpurple/protocols/jabber/libxmpp.c	12464d3b3137bab786be931cb77ebb4cbb129275
+++ libpurple/protocols/jabber/libxmpp.c	385d900e24573bbdd6ee0b02ec605cf013538720
@@ -46,6 +46,8 @@
 #include "data.h"
 #include "ibb.h"
 
+PurplePlugin *jabber_plugin = NULL;
+
 static PurplePluginProtocolInfo prpl_info =
 {
 	OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_MAIL_CHECK |
@@ -125,6 +127,8 @@ static gboolean load_plugin(PurplePlugin
 
 static gboolean load_plugin(PurplePlugin *plugin)
 {
+	jabber_plugin = plugin;
+
 	purple_signal_register(plugin, "jabber-receiving-xmlnode",
 			purple_marshal_VOID__POINTER_POINTER, NULL, 2,
 			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
@@ -140,17 +144,66 @@ static gboolean load_plugin(PurplePlugin
 			     purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
 			     purple_value_new_outgoing(PURPLE_TYPE_STRING));
 
+	purple_signal_register(plugin, "jabber-receiving-message",
+			purple_marshal_BOOLEAN__POINTER_POINTER_POINTER,
+			purple_value_new(PURPLE_TYPE_BOOLEAN), 6,
+			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
+			purple_value_new(PURPLE_TYPE_STRING), /* type */
+			purple_value_new(PURPLE_TYPE_STRING), /* id */
+			purple_value_new(PURPLE_TYPE_STRING), /* from */
+			purple_value_new(PURPLE_TYPE_STRING), /* to */
+			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE));
+
+	purple_signal_register(plugin, "jabber-receiving-iq",
+			purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
+			purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
+			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
+			purple_value_new(PURPLE_TYPE_STRING), /* type */
+			purple_value_new(PURPLE_TYPE_STRING), /* id */
+			purple_value_new(PURPLE_TYPE_STRING), /* from */
+			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE));
+
+	purple_signal_register(plugin, "jabber-watched-iq",
+			purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER,
+			purple_value_new(PURPLE_TYPE_BOOLEAN), 5,
+			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
+			purple_value_new(PURPLE_TYPE_STRING), /* type */
+			purple_value_new(PURPLE_TYPE_STRING), /* id */
+			purple_value_new(PURPLE_TYPE_STRING), /* from */
+			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE)); /* child */
+
+	purple_signal_register(plugin, "jabber-register-namespace-watcher",
+			purple_marshal_VOID__POINTER_POINTER_POINTER,
+			NULL, 2,
+			purple_value_new(PURPLE_TYPE_STRING),  /* node */
+			purple_value_new(PURPLE_TYPE_STRING)); /* namespace */
+
+	purple_signal_register(plugin, "jabber-unregister-namespace-watcher",
+			purple_marshal_VOID__POINTER_POINTER_POINTER,
+			NULL, 2,
+			purple_value_new(PURPLE_TYPE_STRING),  /* node */
+			purple_value_new(PURPLE_TYPE_STRING)); /* namespace */
+
+	purple_signal_connect(plugin, "jabber-register-namespace-watcher",
+			plugin, PURPLE_CALLBACK(jabber_iq_signal_register), NULL);
+	purple_signal_connect(plugin, "jabber-unregister-namespace-watcher",
+			plugin, PURPLE_CALLBACK(jabber_iq_signal_unregister), NULL);
+
+	purple_signal_register(plugin, "jabber-receiving-presence",
+			purple_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER,
+			purple_value_new(PURPLE_TYPE_BOOLEAN), 4,
+			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
+			purple_value_new(PURPLE_TYPE_STRING), /* type */
+			purple_value_new(PURPLE_TYPE_STRING), /* from */
+			purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_XMLNODE));
+
 	return TRUE;
 }
 
 static gboolean unload_plugin(PurplePlugin *plugin)
 {
-	purple_signal_unregister(plugin, "jabber-receiving-xmlnode");
+	purple_signals_unregister_by_instance(plugin);
 
-	purple_signal_unregister(plugin, "jabber-sending-xmlnode");
-
-	purple_signal_unregister(plugin, "jabber-sending-text");
-
 	/* reverse order of init_plugin */
 	jabber_bosh_uninit();
 	jabber_data_uninit();
@@ -166,6 +219,8 @@ static gboolean unload_plugin(PurplePlug
 	/* Stay on target...stay on target... Almost there... */
 	jabber_uninit_plugin();
 
+	jabber_plugin = NULL;
+
 	return TRUE;
 }
 
============================================================
--- libpurple/protocols/jabber/message.c	e854c47f850b8d4220b791dc5da2f826441201c1
+++ libpurple/protocols/jabber/message.c	ddcc5b005fa515cfef4849208c2bf972bd171e13
@@ -532,16 +532,25 @@ void jabber_message_parse(JabberStream *
 void jabber_message_parse(JabberStream *js, xmlnode *packet)
 {
 	JabberMessage *jm;
-	const char *type;
+	const char *id, *from, *to, *type;
 	xmlnode *child;
+	gboolean signal_return;
 
+	from = xmlnode_get_attrib(packet, "from");
+	id   = xmlnode_get_attrib(packet, "id");
+	to   = xmlnode_get_attrib(packet, "to");
+	type = xmlnode_get_attrib(packet, "type");
+
+	signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(jabber_plugin,
+			"jabber-receiving-message", js->gc, type, id, from, to, packet));
+	if (signal_return)
+		return;
+
 	jm = g_new0(JabberMessage, 1);
 	jm->js = js;
 	jm->sent = time(NULL);
 	jm->delayed = FALSE;
 
-	type = xmlnode_get_attrib(packet, "type");
-
 	if(type) {
 		if(!strcmp(type, "normal"))
 			jm->type = JABBER_MESSAGE_NORMAL;
@@ -559,9 +568,9 @@ void jabber_message_parse(JabberStream *
 		jm->type = JABBER_MESSAGE_NORMAL;
 	}
 
-	jm->from = g_strdup(xmlnode_get_attrib(packet, "from"));
-	jm->to = g_strdup(xmlnode_get_attrib(packet, "to"));
-	jm->id = g_strdup(xmlnode_get_attrib(packet, "id"));
+	jm->from = g_strdup(from);
+	jm->to   = g_strdup(to);
+	jm->id   = g_strdup(id);
 
 	for(child = packet->child; child; child = child->next) {
 		const char *xmlns = xmlnode_get_namespace(child);
============================================================
--- libpurple/protocols/jabber/presence.c	1ef4842a4a58e332423a1a871cb95772d5d53174
+++ libpurple/protocols/jabber/presence.c	01b74c2bdc3e885a6fede21fff8cb212afb4f1e4
@@ -446,8 +446,8 @@ void jabber_presence_parse(JabberStream 
 
 void jabber_presence_parse(JabberStream *js, xmlnode *packet)
 {
-	const char *from = xmlnode_get_attrib(packet, "from");
-	const char *type = xmlnode_get_attrib(packet, "type");
+	const char *from;
+	const char *type;
 	const char *real_jid = NULL;
 	const char *affiliation = NULL;
 	const char *role = NULL;
@@ -469,10 +469,19 @@ void jabber_presence_parse(JabberStream 
 	xmlnode *caps = NULL;
 	int idle = 0;
 	gchar *nickname = NULL;
+	gboolean signal_return;
 
+	from = xmlnode_get_attrib(packet, "from");
+	type = xmlnode_get_attrib(packet, "type");
+
 	if(!(jb = jabber_buddy_find(js, from, TRUE)))
 		return;
 
+	signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(jabber_plugin,
+			"jabber-receiving-presence", js->gc, type, from, packet));
+	if (signal_return)
+		return;
+
 	if(!(jid = jabber_id_new(from)))
 		return;
 


More information about the Commits mailing list