# HG changeset patch # User Andreas Monitzer # Date 1181095673 0 # Node ID 0370da969e8adc9b7253d3aadc5a20db4c6621ec # Parent 2f67cb504a51d7f9e03f4be5bf4415d578a78ddf Implemented adding callbacks for PEP events. Moved the feature list to be application-global instead of per-connection (makes more sense). diff -r 2f67cb504a51 -r 0370da969e8a libpurple/protocols/jabber/disco.c --- a/libpurple/protocols/jabber/disco.c Wed Jun 06 01:37:28 2007 +0000 +++ b/libpurple/protocols/jabber/disco.c Wed Jun 06 02:07:53 2007 +0000 @@ -100,7 +100,7 @@ if(!node) { /* non-caps disco#info, add all extensions */ GList *features; - for(features = js->features; features; features = features->next) { + for(features = jabber_features; features; features = features->next) { JabberFeature *feat = (JabberFeature*)features->data; SUPPORT_FEATURE(feat->namespace); } @@ -126,7 +126,7 @@ if(ext != NULL) { /* look for that ext */ GList *features; - for(features = js->features; features; features = features->next) { + for(features = jabber_features; features; features = features->next) { JabberFeature *feat = (JabberFeature*)features->data; if(!strcmp(feat->shortname, ext)) { SUPPORT_FEATURE(feat->namespace); @@ -307,10 +307,8 @@ const char *category, *type, *name; category = xmlnode_get_attrib(child, "category"); type = xmlnode_get_attrib(child, "type"); - if(category && type && !strcmp(category, "pubsub") && !strcmp(type,"pep")) { - /* server supports pep, initialize it */ - jabber_pep_init(js); - } + if(category && type && !strcmp(category, "pubsub") && !strcmp(type,"pep")) + js->pep = TRUE; if (!category || strcmp(category, "server")) continue; if (!type || strcmp(type, "im")) diff -r 2f67cb504a51 -r 0370da969e8a libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Wed Jun 06 01:37:28 2007 +0000 +++ b/libpurple/protocols/jabber/jabber.c Wed Jun 06 02:07:53 2007 +0000 @@ -59,6 +59,7 @@ #define JABBER_CONNECT_STEPS (js->gsc ? 8 : 5) static PurplePlugin *my_protocol = NULL; +GList *jabber_features; static void jabber_stream_init(JabberStream *js) { @@ -1024,12 +1025,6 @@ #endif if(js->serverFQDN) g_free(js->serverFQDN); - while(js->features) { - g_free(((JabberFeature*)js->features->data)->shortname); - g_free(((JabberFeature*)js->features->data)->namespace); - g_free(js->features->data); - js->features = g_list_delete_link(js->features, js->features); - } g_free(js->server_name); g_free(js->gmail_last_time); g_free(js->gmail_last_tid); @@ -1099,20 +1094,20 @@ js->idle = idle ? time(NULL) - idle : idle; } -void jabber_add_feature(JabberStream *js, const char *shortname, const char *namespace) { +void jabber_add_feature(const char *shortname, const char *namespace) { JabberFeature *feat = g_new0(JabberFeature,1); feat->shortname = g_strdup(shortname); feat->namespace = g_strdup(namespace); /* try to remove just in case it already exists in the list */ - jabber_remove_feature(js, shortname); + jabber_remove_feature(shortname); - js->features = g_list_append(js->features, feat); + jabber_features = g_list_append(jabber_features, feat); } -void jabber_remove_feature(JabberStream *js, const char *shortname) { +void jabber_remove_feature(const char *shortname) { GList *feature; - for(feature = js->features; feature; feature = feature->next) { + for(feature = jabber_features; feature; feature = feature->next) { JabberFeature *feat = (JabberFeature*)feature->data; if(!strcmp(feat->shortname, shortname)) { g_free(feat->shortname); diff -r 2f67cb504a51 -r 0370da969e8a libpurple/protocols/jabber/jabber.h --- a/libpurple/protocols/jabber/jabber.h Wed Jun 06 01:37:28 2007 +0000 +++ b/libpurple/protocols/jabber/jabber.h Wed Jun 06 02:07:53 2007 +0000 @@ -71,12 +71,6 @@ JABBER_STREAM_CONNECTED } JabberStreamState; -typedef struct _JabberFeature -{ - gchar *shortname; - gchar *namespace; -} JabberFeature; - typedef struct _JabberStream { int fd; @@ -156,8 +150,8 @@ #endif char *serverFQDN; - /* what kind of additional features as returned from disco#info are supported? */ - GList *features; + /* does the local server support PEP? */ + gboolean pep; } JabberStream; void jabber_process_packet(JabberStream *js, xmlnode *packet); @@ -173,8 +167,8 @@ char *jabber_parse_error(JabberStream *js, xmlnode *packet); -void jabber_add_feature(JabberStream *js, const gchar *shortname, const gchar *namespace); -void jabber_remove_feature(JabberStream *js, const gchar *shortname); +void jabber_add_feature(const gchar *shortname, const gchar *namespace); +void jabber_remove_feature(const gchar *shortname); /** PRPL functions */ const char *jabber_list_icon(PurpleAccount *a, PurpleBuddy *b); @@ -195,4 +189,13 @@ void jabber_register_commands(void); void jabber_init_plugin(PurplePlugin *plugin); +typedef struct _JabberFeature +{ + gchar *shortname; + gchar *namespace; +} JabberFeature; + +/* what kind of additional features as returned from disco#info are supported? */ +extern GList *jabber_features; + #endif /* _PURPLE_JABBER_H_ */ diff -r 2f67cb504a51 -r 0370da969e8a libpurple/protocols/jabber/libxmpp.c --- a/libpurple/protocols/jabber/libxmpp.c Wed Jun 06 01:37:28 2007 +0000 +++ b/libpurple/protocols/jabber/libxmpp.c Wed Jun 06 02:07:53 2007 +0000 @@ -38,6 +38,7 @@ #include "message.h" #include "presence.h" #include "google.h" +#include "pep.h" static PurplePluginProtocolInfo prpl_info = { @@ -229,6 +230,7 @@ jabber_register_commands(); jabber_iq_init(); + jabber_pep_init(); } diff -r 2f67cb504a51 -r 0370da969e8a libpurple/protocols/jabber/pep.c --- a/libpurple/protocols/jabber/pep.c Wed Jun 06 01:37:28 2007 +0000 +++ b/libpurple/protocols/jabber/pep.c Wed Jun 06 02:07:53 2007 +0000 @@ -21,18 +21,48 @@ #include "pep.h" #include "iq.h" +#include -void jabber_pep_init(JabberStream *js) { - +static GHashTable *pep_handlers = NULL; + +void jabber_pep_init(void) { + if(!pep_handlers) { + pep_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + + /* register PEP handlers here */ + } +} + +void jabber_pep_register_handler(const char *shortname, const char *xmlns, JabberPEPHandler handlerfunc) { + char *notifyns = malloc(strlen(xmlns) + 8); + sprintf(notifyns,"%s+notify", xmlns); + jabber_add_feature(shortname, notifyns); + free(notifyns); + g_hash_table_replace(pep_handlers, g_strdup(xmlns), handlerfunc); } void jabber_handle_event(JabberMessage *jm) { /* this may be called even when the own server doesn't support pep! */ + JabberPEPHandler *jph; + GList *itemslist; + for(itemslist = jm->eventitems; itemslist; itemslist = itemslist->next) { + xmlnode *items = (xmlnode*)itemslist->data; + const char *xmlns = xmlnode_get_namespace(items); + + if((jph = g_hash_table_lookup(pep_handlers, xmlns))) + jph(jm->js, items); + } + /* discard items we don't have a handler for */ } void jabber_pep_publish(JabberStream *js, xmlnode *publish) { - JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET); + JabberIq *iq; + + if(js->pep != TRUE) /* ignore when there's no PEP support on the server */ + return; + + iq = jabber_iq_new(js, JABBER_IQ_SET); xmlnode *pubsub = xmlnode_new("pubsub"); xmlnode_set_namespace(pubsub, "http://jabber.org/protocol/pubsub"); diff -r 2f67cb504a51 -r 0370da969e8a libpurple/protocols/jabber/pep.h --- a/libpurple/protocols/jabber/pep.h Wed Jun 06 01:37:28 2007 +0000 +++ b/libpurple/protocols/jabber/pep.h Wed Jun 06 02:07:53 2007 +0000 @@ -25,8 +25,25 @@ #include "jabber.h" #include "message.h" -/* called when the own server supports pep */ -void jabber_pep_init(JabberStream *js); +void jabber_pep_init(void); + +/* + * Callback for receiving PEP events. + * + * @parameter js The JabberStream this item was received on + * @parameter items The <items/>-tag with the <item/>-children + */ +typedef void (JabberPEPHandler)(JabberStream *js, xmlnode *items); + +/* + * Registers a callback for PEP events. Also automatically announces this receiving capability via disco#info. + * Don't forget to use jabber_add_feature when supporting the sending of PEP events of this type. + * + * @parameter shortname A short name for this feature for XEP-0115. It has no semantic meaning, it just has to be unique. + * @parameter xmlns The namespace for this event + * @parameter handlerfunc The callback to be used when receiving an event with this namespace + */ +void jabber_pep_register_handler(const char *shortname, const char *xmlns, JabberPEPHandler handlerfunc); void jabber_handle_event(JabberMessage *jm); diff -r 2f67cb504a51 -r 0370da969e8a libpurple/protocols/jabber/presence.c --- a/libpurple/protocols/jabber/presence.c Wed Jun 06 01:37:28 2007 +0000 +++ b/libpurple/protocols/jabber/presence.c Wed Jun 06 02:07:53 2007 +0000 @@ -185,7 +185,7 @@ GList *feature; extlist[0] = '\0'; - for(feature = js->features; feature && remaining > 0; feature = feature->next) { + for(feature = jabber_features; feature && remaining > 0; feature = feature->next) { JabberFeature *feat = (JabberFeature*)feature->data; unsigned featlen = strlen(feat->shortname);