summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Aurich <darkrain42@pidgin.im>2009-05-12 05:49:34 +0000
committerPaul Aurich <darkrain42@pidgin.im>2009-05-12 05:49:34 +0000
commit46c7ef2d181dc663efae502fcf909b1e91c91c64 (patch)
treef724cab6f3301aa7765715adf80fbc329edb60df
parent5da30341d3f29bad9060f3995bc48685e1954882 (diff)
downloadpidgin-46c7ef2d181dc663efae502fcf909b1e91c91c64.tar.gz
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.
-rw-r--r--ChangeLog.API1
-rw-r--r--libpurple/protocols/jabber/iq.c71
-rw-r--r--libpurple/protocols/jabber/iq.h5
-rw-r--r--libpurple/protocols/jabber/jabber.c3
-rw-r--r--libpurple/protocols/jabber/jabber.h2
-rw-r--r--libpurple/protocols/jabber/libxmpp.c65
-rw-r--r--libpurple/protocols/jabber/message.c21
-rw-r--r--libpurple/protocols/jabber/presence.c13
8 files changed, 161 insertions, 20 deletions
diff --git a/ChangeLog.API b/ChangeLog.API
index af53365854..1bac4f477e 100644
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -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
diff --git a/libpurple/protocols/jabber/iq.c b/libpurple/protocols/jabber/iq.c
index 33d194b78b..d622d30ad7 100644
--- a/libpurple/protocols/jabber/iq.c
+++ b/libpurple/protocols/jabber/iq.c
@@ -42,7 +42,7 @@
#endif
GHashTable *iq_handlers = NULL;
-
+GHashTable *signal_iq_handlers = NULL;
JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type)
{
@@ -289,6 +289,16 @@ void jabber_iq_parse(JabberStream *js, xmlnode *packet)
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.
@@ -301,10 +311,6 @@ void jabber_iq_parse(JabberStream *js, xmlnode *packet)
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, xmlnode *packet)
}
}
- /* 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 char *node, const char *xmlns, JabberIqHan
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_init(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;
}
diff --git a/libpurple/protocols/jabber/iq.h b/libpurple/protocols/jabber/iq.h
index f225bba152..5d506841dc 100644
--- a/libpurple/protocols/jabber/iq.h
+++ b/libpurple/protocols/jabber/iq.h
@@ -31,6 +31,7 @@ typedef enum {
} JabberIqType;
#include "jabber.h"
+#include "connection.h"
typedef struct _JabberIq JabberIq;
@@ -106,4 +107,8 @@ void jabber_iq_uninit(void);
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_ */
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index a58b09f6ae..5ff7afef11 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -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_init_plugin(PurplePlugin *plugin)
void
jabber_uninit_plugin(void)
{
+ purple_plugin_ipc_unregister_all(jabber_plugin);
+
jabber_features_destroy();
jabber_identities_destroy();
}
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
index ddc6b997da..5dc7379dda 100644
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -75,6 +75,8 @@ typedef struct _JabberStream JabberStream;
/* Index into attention_types list */
#define JABBER_BUZZ 0
+PurplePlugin *jabber_plugin;
+
typedef enum {
JABBER_STREAM_OFFLINE,
JABBER_STREAM_CONNECTING,
diff --git a/libpurple/protocols/jabber/libxmpp.c b/libpurple/protocols/jabber/libxmpp.c
index 441b489eb3..6d2565dfc3 100644
--- a/libpurple/protocols/jabber/libxmpp.c
+++ b/libpurple/protocols/jabber/libxmpp.c
@@ -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 PurplePluginProtocolInfo prpl_info =
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,16 +144,65 @@ static gboolean load_plugin(PurplePlugin *plugin)
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_signal_unregister(plugin, "jabber-sending-xmlnode");
-
- purple_signal_unregister(plugin, "jabber-sending-text");
+ purple_signals_unregister_by_instance(plugin);
/* reverse order of init_plugin */
jabber_bosh_uninit();
@@ -166,6 +219,8 @@ static gboolean unload_plugin(PurplePlugin *plugin)
/* Stay on target...stay on target... Almost there... */
jabber_uninit_plugin();
+ jabber_plugin = NULL;
+
return TRUE;
}
diff --git a/libpurple/protocols/jabber/message.c b/libpurple/protocols/jabber/message.c
index 9f4cec8cf2..300fcd0666 100644
--- a/libpurple/protocols/jabber/message.c
+++ b/libpurple/protocols/jabber/message.c
@@ -532,16 +532,25 @@ jabber_message_send_data_request(JabberStream *js, PurpleConversation *conv,
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 *js, xmlnode *packet)
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);
diff --git a/libpurple/protocols/jabber/presence.c b/libpurple/protocols/jabber/presence.c
index d134bdbacd..ef74cb31ec 100644
--- a/libpurple/protocols/jabber/presence.c
+++ b/libpurple/protocols/jabber/presence.c
@@ -446,8 +446,8 @@ jabber_presence_set_capabilities(JabberCapsClientInfo *info, GList *exts,
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 *js, xmlnode *packet)
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;