changeset 17839:0370da969e8a

Implemented adding callbacks for PEP events. Moved the feature list to be application-global instead of per-connection (makes more sense).
author Andreas Monitzer <pidgin@monitzer.com>
date Wed, 06 Jun 2007 02:07:53 +0000
parents 2f67cb504a51
children cac26c30047a
files libpurple/protocols/jabber/disco.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/jabber.h libpurple/protocols/jabber/libxmpp.c libpurple/protocols/jabber/pep.c libpurple/protocols/jabber/pep.h libpurple/protocols/jabber/presence.c
diffstat 7 files changed, 78 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- 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"))
--- 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);
--- 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_ */
--- 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();
 }
 
 
--- 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 <string.h>
 
-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");
--- 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 &lt;items/>-tag with the &lt;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);
 
--- 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);