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