xmpp.custom_smiley: 11d7e28e: Updated to use latest spec. in XEP-0231
malu at pidgin.im
malu at pidgin.im
Sat Sep 6 13:35:43 EDT 2008
-----------------------------------------------------------------
Revision: 11d7e28e459d02d4584e4d88d21aa4fcaea0c714
Ancestor: df0bccd98ce9a8798361892a7d443343e0842e15
Author: malu at pidgin.im
Date: 2008-09-05T21:55:09
Branch: im.pidgin.xmpp.custom_smiley
URL: http://d.pidgin.im/viewmtn/revision/info/11d7e28e459d02d4584e4d88d21aa4fcaea0c714
Modified files:
libpurple/protocols/jabber/chat.c
libpurple/protocols/jabber/data.c
libpurple/protocols/jabber/data.h
libpurple/protocols/jabber/iq.c
libpurple/protocols/jabber/jabber.c
libpurple/protocols/jabber/libxmpp.c
libpurple/protocols/jabber/message.c pidgin/gtksmiley.c
ChangeLog:
Updated to use latest spec. in XEP-0231
New namespace. Cache data globally in a running instance based on CID.
Set the PNG compression level param when saving a custom smiley from
GTKIMHTML.
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/chat.c 03d17931c489b8e59acfff1ebb8d5580b1461325
+++ libpurple/protocols/jabber/chat.c 45a5aa6aa6f6e9d92f5d03c9818b8e1af7da41e0
@@ -685,9 +685,7 @@ void jabber_chat_part(JabberChat *chat,
xmlnode_insert_data(status, msg, -1);
}
jabber_send(chat->js, presence);
-
- jabber_data_delete_associated_with_conv(chat->conv);
-
+
xmlnode_free(presence);
g_free(room_jid);
}
============================================================
--- libpurple/protocols/jabber/data.c 49260e93548a3c276fe802c1b38cea3e23474e86
+++ libpurple/protocols/jabber/data.c 720f00ec45545ac07132cd09aad4c334a9f26633
@@ -25,43 +25,23 @@
#include "conversation.h"
#include "iq.h"
-/* hash table to store locally supplied data objects, by conversation and
- alt text (smiley shortcut) */
-static GHashTable *local_datas_by_alt = NULL;
+static GHashTable *local_data_by_alt = NULL;
+static GHashTable *local_data_by_cid = NULL;
+static GHashTable *remote_data_by_cid = NULL;
-/* hash table to store locally supplied data objects, by content id */
-static GHashTable *local_datas_by_cid = NULL;
-
-/* remote supplied data objects by content id */
-static GHashTable *remote_datas_by_cid = NULL;
-
-
-void
-jabber_data_init(void)
-{
- /* setup hash tables for storing data instances here */
- purple_debug_info("jabber", "Setting up data handling\n");
-
- local_datas_by_alt = g_hash_table_new(NULL, NULL);
- local_datas_by_cid = g_hash_table_new(NULL, NULL);
- remote_datas_by_cid = g_hash_table_new(NULL, NULL);
-}
-
JabberData *
jabber_data_create_from_data(gconstpointer rawdata, gsize size, const char *type,
- const char *alt)
+ JabberStream *js)
{
JabberData *data = g_new0(JabberData, 1);
gchar *checksum = purple_util_get_image_checksum(rawdata, size);
gchar cid[256];
- /* is there some better way to generate a content ID? */
- g_snprintf(cid, sizeof(cid), "%s@%s", checksum, g_get_host_name());
+ g_snprintf(cid, sizeof(cid), "sha1+%s at bob.xmpp.org", checksum);
g_free(checksum);
data->cid = g_strdup(cid);
data->type = g_strdup(type);
- data->alt = g_strdup(alt);
data->size = size;
data->data = g_memdup(rawdata, size);
@@ -91,8 +71,7 @@ jabber_data_create_from_xml(xmlnode *tag
data->cid = g_strdup(xmlnode_get_attrib(tag, "cid"));
data->type = g_strdup(xmlnode_get_attrib(tag, "type"));
- data->alt = g_strdup(xmlnode_get_attrib(tag, "alt"));
-
+
raw_data = xmlnode_get_data(tag);
data->data = purple_base64_decode(raw_data, &size);
data->size = size;
@@ -107,7 +86,6 @@ jabber_data_delete(JabberData *data)
jabber_data_delete(JabberData *data)
{
g_free(data->cid);
- g_free(data->alt);
g_free(data->type);
g_free(data->data);
g_free(data);
@@ -119,11 +97,6 @@ jabber_data_get_cid(const JabberData *da
return data->cid;
}
-const char *
-jabber_data_get_alt(const JabberData *data)
-{
- return data->alt;
-}
const char *
jabber_data_get_type(const JabberData *data)
@@ -150,7 +123,6 @@ jabber_data_get_xml_definition(const Jab
char *base64data = purple_base64_encode(data->data, data->size);
xmlnode_set_namespace(tag, XEP_0231_NAMESPACE);
- xmlnode_set_attrib(tag, "alt", data->alt);
xmlnode_set_attrib(tag, "cid", data->cid);
xmlnode_set_attrib(tag, "type", data->type);
@@ -162,12 +134,12 @@ xmlnode *
}
xmlnode *
-jabber_data_get_xhtml_im(const JabberData *data)
+jabber_data_get_xhtml_im(const JabberData *data, const gchar *alt)
{
xmlnode *img = xmlnode_new("img");
char src[128];
- xmlnode_set_attrib(img, "alt", data->alt);
+ xmlnode_set_attrib(img, "alt", alt);
g_snprintf(src, sizeof(src), "cid:%s", data->cid);
xmlnode_set_attrib(img, "src", src);
@@ -186,123 +158,48 @@ const JabberData *
}
const JabberData *
-jabber_data_find_local_by_alt(const PurpleConversation *conv, const char *alt)
+jabber_data_find_local_by_alt(const gchar *alt)
{
- GHashTable *local_datas = g_hash_table_lookup(local_datas_by_alt, conv);
-
- if (local_datas) {
- return g_hash_table_lookup(local_datas, alt);
- } else {
- return NULL;
- }
+ return g_hash_table_lookup(local_data_by_alt, alt);
}
-
const JabberData *
-jabber_data_find_local_by_cid(const PurpleConversation *conv, const char *cid)
+jabber_data_find_local_by_cid(const gchar *cid)
{
- GHashTable *local_datas = g_hash_table_lookup(local_datas_by_cid, conv);
-
- if (local_datas) {
- return g_hash_table_lookup(local_datas, cid);
- } else {
- return NULL;
- }
+ return g_hash_table_lookup(local_data_by_cid, cid);
}
const JabberData *
-jabber_data_find_remote_by_cid(const PurpleConversation *conv, const char *cid)
+jabber_data_find_remote_by_cid(const gchar *cid)
{
- GHashTable *remote_datas = g_hash_table_lookup(remote_datas_by_cid, conv);
-
- if (remote_datas) {
- return g_hash_table_lookup(remote_datas, cid);
- } else {
- return NULL;
- }
+ return g_hash_table_lookup(remote_data_by_cid, cid);
}
void
-jabber_data_associate_local_with_conv(JabberData *data, PurpleConversation *conv)
+jabber_data_associate_local(JabberData *data, const gchar *alt)
{
- GHashTable *datas_by_alt = g_hash_table_lookup(local_datas_by_alt, conv);
- GHashTable *datas_by_cid = g_hash_table_lookup(local_datas_by_cid, conv);
-
- if (!datas_by_alt) {
- datas_by_alt = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(local_datas_by_alt, conv, datas_by_alt);
- }
-
- if (!datas_by_cid) {
- datas_by_cid = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(local_datas_by_cid, conv, datas_by_cid);
- }
-
- g_hash_table_insert(datas_by_alt, g_strdup(jabber_data_get_alt(data)), data);
- g_hash_table_insert(datas_by_cid, g_strdup(jabber_data_get_cid(data)), data);
+ g_hash_table_insert(local_data_by_alt, g_strdup(alt), data);
+ g_hash_table_insert(local_data_by_cid, g_strdup(jabber_data_get_cid(data)),
+ data);
}
void
-jabber_data_associate_remote_with_conv(JabberData *data, PurpleConversation *conv)
+jabber_data_associate_remote(JabberData *data)
{
- GHashTable *datas_by_cid = g_hash_table_lookup(remote_datas_by_cid, conv);
-
- if (!datas_by_cid) {
- datas_by_cid = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(remote_datas_by_cid, conv, datas_by_cid);
- }
-
- g_hash_table_insert(datas_by_cid, g_strdup(jabber_data_get_cid(data)), data);
+ g_hash_table_insert(remote_data_by_cid, g_strdup(jabber_data_get_cid(data)),
+ data);
}
-static void
-jabber_data_delete_from_hash_table(gpointer key, gpointer value,
- gpointer user_data)
-{
- JabberData *data = (JabberData *) value;
- jabber_data_delete(data);
- g_free(key);
-}
-
void
-jabber_data_delete_associated_with_conv(PurpleConversation *conv)
-{
- GHashTable *local_datas = g_hash_table_lookup(local_datas_by_cid, conv);
- GHashTable *remote_datas = g_hash_table_lookup(remote_datas_by_cid, conv);
- GHashTable *local_datas_alt = g_hash_table_lookup(local_datas_by_alt, conv);
-
- if (local_datas) {
- g_hash_table_foreach(local_datas, jabber_data_delete_from_hash_table,
- NULL);
- g_hash_table_destroy(local_datas);
- g_hash_table_remove(local_datas_by_cid, conv);
- }
- if (remote_datas) {
- g_hash_table_foreach(remote_datas, jabber_data_delete_from_hash_table,
- NULL);
- g_hash_table_destroy(remote_datas);
- g_hash_table_remove(remote_datas_by_cid, conv);
- }
- if (local_datas_alt) {
- g_hash_table_destroy(local_datas_alt);
- g_hash_table_remove(local_datas_by_alt, conv);
- }
-}
-
-void
jabber_data_parse(JabberStream *js, xmlnode *packet)
{
JabberIq *result = NULL;
const char *who = xmlnode_get_attrib(packet, "from");
- const PurpleConnection *gc = js->gc;
- const PurpleAccount *account = purple_connection_get_account(gc);
- const PurpleConversation *conv =
- purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, account);
xmlnode *data_node = xmlnode_get_child(packet, "data");
const JabberData *data =
- jabber_data_find_local_by_cid(conv, xmlnode_get_attrib(data_node, "cid"));
+ jabber_data_find_local_by_cid(xmlnode_get_attrib(data_node, "cid"));
- if (!conv || !data) {
+ if (!data) {
xmlnode *item_not_found = xmlnode_new("item-not-found");
result = jabber_iq_new(js, JABBER_IQ_ERROR);
@@ -318,3 +215,24 @@ jabber_data_parse(JabberStream *js, xmln
}
jabber_iq_send(result);
}
+
+void
+jabber_data_init(void)
+{
+ purple_debug_info("jabber", "creating hash tables for data objects\n");
+ local_data_by_alt = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+ local_data_by_cid = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, jabber_data_delete);
+ remote_data_by_cid = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, jabber_data_delete);
+}
+
+void
+jabber_data_uninit(void)
+{
+ purple_debug_info("jabber", "destroying hash tables for data objects\n");
+ g_hash_table_destroy(local_data_by_alt);
+ g_hash_table_destroy(local_data_by_cid);
+ g_hash_table_destroy(remote_data_by_cid);
+}
============================================================
--- libpurple/protocols/jabber/data.h 7b1d2be796e6180402ee9be0a0664f3fbd1b2e1a
+++ libpurple/protocols/jabber/data.h bcb82f4647411e03ba16b4cc1265d3835f7ded4b
@@ -21,24 +21,20 @@
#include "conversation.h"
#include "jabber.h"
-#define XEP_0231_NAMESPACE "urn:xmpp:tmp:data-element"
-#define XEP_0231_IB_IMAGE_NAMESPACE "urn:xmpp:tmp:data-element:inband-image"
+#define XEP_0231_NAMESPACE "urn:xmpp:bob"
#include <glib.h>
typedef struct {
char *cid;
- char *alt;
char *type;
gsize size;
gpointer data;
} JabberData;
-void jabber_data_init(void);
-
/* creates a JabberData instance from raw data */
JabberData *jabber_data_create_from_data(gconstpointer data, gsize size,
- const char *type, const char *alt);
+ const char *type, JabberStream *js);
/* create a JabberData instance from an XML "data" element (as defined by
XEP 0231 */
@@ -47,7 +43,6 @@ const char *jabber_data_get_cid(const Ja
void jabber_data_delete(JabberData *data);
const char *jabber_data_get_cid(const JabberData *data);
-const char *jabber_data_get_alt(const JabberData *data);
const char *jabber_data_get_type(const JabberData *data);
gsize jabber_data_get_size(const JabberData *data);
@@ -57,27 +52,39 @@ xmlnode *jabber_data_get_xml_definition(
xmlnode *jabber_data_get_xml_definition(const JabberData *data);
/* returns an XHTML-IM "img" tag given a data instance */
-xmlnode *jabber_data_get_xhtml_im(const JabberData *data);
+xmlnode *jabber_data_get_xhtml_im(const JabberData *data, const gchar *alt);
/* returns a data request element (to be included in an iq stanza) for requesting
data */
xmlnode *jabber_data_get_xml_request(const gchar *cid);
/* lookup functions */
-const JabberData *jabber_data_find_local_by_alt(const PurpleConversation *conv,
+const JabberData *jabber_data_find_local_by_alt(const gchar *alt);
+const JabberData *jabber_data_find_local_by_cid(const gchar *cid);
+const JabberData *jabber_data_find_remote_by_cid(const gchar *cid);
+/*
+const JabberData *jabber_data_find_local_by_alt(PurpleConversation *conv,
const char *alt);
-const JabberData *jabber_data_find_local_by_cid(const PurpleConversation *conv,
+const JabberData *jabber_data_find_local_by_cid(PurpleConversation *conv,
const char *cid);
-const JabberData *jabber_data_find_remote_by_cid(const PurpleConversation *conv,
+const JabberData *jabber_data_find_remote_by_cid(PurpleConversation *conv,
const char *cid);
-
-/* associate data objects with a conversation */
-void jabber_data_associate_local_with_conv(JabberData *data, PurpleConversation *conv);
+*/
+
+/* store data objects */
+void jabber_data_associate_local(JabberData *data, const gchar *alt);
+void jabber_data_associate_remote(JabberData *data);
+/*
+void jabber_data_associate_local_with_conv(JabberData *data, PurpleConversation *conv,
+ const gchar *alt);
void jabber_data_associate_remote_with_conv(JabberData *data, PurpleConversation *conv);
void jabber_data_delete_associated_with_conv(PurpleConversation *conv);
+*/
/* handles iq requests */
void jabber_data_parse(JabberStream *js, xmlnode *packet);
+void jabber_data_init(void);
+void jabber_data_uninit(void);
#endif /* JABBER_DATA_H */
============================================================
--- libpurple/protocols/jabber/iq.c d806fe4817c107edc9d45810b776e538b7a19f75
+++ libpurple/protocols/jabber/iq.c a479d82512a1984842fded29b85ace2d269c2978
@@ -356,8 +356,7 @@ void jabber_iq_parse(JabberStream *js, x
return;
}
- if (xmlnode_get_child_with_namespace(packet, "data",
- "urn:xmpp:tmp:data-element")) {
+ if (xmlnode_get_child_with_namespace(packet, "data", XEP_0231_NAMESPACE)) {
jabber_data_parse(js, packet);
return;
}
============================================================
--- libpurple/protocols/jabber/jabber.c c11891dacbdd3c5d8af6714bd0b3ae8cae5d3367
+++ libpurple/protocols/jabber/jabber.c 825251d252c4ea07a3cfb8778cedad0ccde46026
@@ -1902,11 +1902,7 @@ void jabber_convo_closed(PurpleConnectio
JabberID *jid;
JabberBuddy *jb;
JabberBuddyResource *jbr;
- PurpleAccount *account = purple_connection_get_account(gc);
- PurpleConversation *conv =
- purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY,
- who, account);
-
+
if(!(jid = jabber_id_new(who)))
return;
@@ -1920,8 +1916,6 @@ void jabber_convo_closed(PurpleConnectio
jabber_message_conv_closed(js, who);
}
- jabber_data_delete_associated_with_conv(conv);
-
jabber_id_free(jid);
}
============================================================
--- libpurple/protocols/jabber/libxmpp.c a681dc144e6a46f8e6f19cf2be03e4c10d68f8dd
+++ libpurple/protocols/jabber/libxmpp.c 9a06006ad08d53731970b6166ec19f07eb8d52dd
@@ -138,7 +138,8 @@ static gboolean load_plugin(PurplePlugin
purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION),
purple_value_new_outgoing(PURPLE_TYPE_STRING));
-
+ jabber_data_uninit();
+
return TRUE;
}
@@ -277,14 +278,14 @@ init_plugin(PurplePlugin *plugin)
jabber_tune_init();
jabber_caps_init();
+
jabber_data_init();
-
+
jabber_add_feature("avatarmeta", AVATARNAMESPACEMETA, jabber_pep_namespace_only_when_pep_enabled_cb);
jabber_add_feature("avatardata", AVATARNAMESPACEDATA, jabber_pep_namespace_only_when_pep_enabled_cb);
jabber_add_feature("buzz", "http://www.xmpp.org/extensions/xep-0224.html#ns",
jabber_buzz_isenabled);
- /* this string will need to be updated when XEP-0231 turns "draft" */
- jabber_add_feature("smileys", XEP_0231_IB_IMAGE_NAMESPACE,
+ jabber_add_feature("bob", XEP_0231_NAMESPACE,
jabber_custom_smileys_isenabled);
jabber_pep_register_handler("avatar", AVATARNAMESPACEMETA, jabber_buddy_avatar_update_metadata);
============================================================
--- libpurple/protocols/jabber/message.c c788446fde83459cab89731cf6c2e43c92ad752d
+++ libpurple/protocols/jabber/message.c 5adb5ae2631ff98a1c3a1f2bd90dfd1fbd89f5d9
@@ -24,7 +24,6 @@
#include "notify.h"
#include "server.h"
#include "util.h"
-
#include "buddy.h"
#include "chat.h"
#include "data.h"
@@ -323,66 +322,67 @@ typedef struct {
gchar *alt;
} JabberSmileyRef;
-static GList *
-_jabber_message_get_refs_from_xmlnode(const xmlnode *message)
+
+static void
+jabber_message_get_refs_from_xmlnode_internal(const xmlnode *message,
+ GHashTable *table)
{
xmlnode *child;
- GList *refs = NULL;
-
+
for (child = xmlnode_get_child(message, "img") ; child ;
child = xmlnode_get_next_twin(child)) {
const gchar *src = xmlnode_get_attrib(child, "src");
- const gssize len = strlen(src);
-
- if (len > 4 && g_str_has_prefix(src, "cid:")) {
- JabberSmileyRef *ref = g_new0(JabberSmileyRef, 1);
- ref->cid = g_strdup(&(src[4]));
- ref->alt = g_strdup(xmlnode_get_attrib(child, "alt"));
- refs = g_list_append(refs, ref);
+
+ if (g_str_has_prefix(src, "cid:")) {
+ const gchar *cid = src + 4;
+
+ /* if we haven't "fetched" this yet... */
+ if (!g_hash_table_lookup(table, cid)) {
+ /* take a copy of the cid and let the SmileyRef own it... */
+ gchar *temp_cid = g_strdup(cid);
+ JabberSmileyRef *ref = g_new0(JabberSmileyRef, 1);
+ const gchar *alt = xmlnode_get_attrib(child, "alt");
+ ref->cid = temp_cid;
+ /* if there is no "alt" string, use the cid... */
+ if (alt && alt[0] != '\0') {
+ ref->alt = g_strdup(xmlnode_get_attrib(child, "alt"));
+ } else {
+ ref->alt = g_strdup(cid);
+ }
+ g_hash_table_insert(table, temp_cid, ref);
+ }
}
}
-
+
for (child = message->child ; child ; child = child->next) {
- refs = g_list_concat(refs,
- _jabber_message_get_refs_from_xmlnode(child));
+ jabber_message_get_refs_from_xmlnode_internal(child, table);
}
+}
- return refs;
+static gboolean
+jabber_message_get_refs_steal(gpointer key, gpointer value, gpointer user_data)
+{
+ GList **refs = (GList **) user_data;
+ JabberSmileyRef *ref = (JabberSmileyRef *) value;
+
+ *refs = g_list_append(*refs, ref);
+
+ return TRUE;
}
static GList *
jabber_message_get_refs_from_xmlnode(const xmlnode *message)
{
- GList *refs = _jabber_message_get_refs_from_xmlnode(message);
+ GList *refs = NULL;
GHashTable *unique_refs = g_hash_table_new(g_str_hash, g_str_equal);
- GList *result = NULL;
- GList *iterator = NULL;
-
- for (iterator = refs ; iterator ; iterator = g_list_next(iterator)) {
- JabberSmileyRef *ref = (JabberSmileyRef *) iterator->data;
- if (!g_hash_table_lookup(unique_refs, ref->cid)) {
- JabberSmileyRef *new_ref = g_new0(JabberSmileyRef, 1);
- new_ref->cid = g_strdup(ref->cid);
- new_ref->alt = g_strdup(ref->alt);
- g_hash_table_insert(unique_refs, ref->cid, ref);
- result = g_list_append(result, new_ref);
- }
- }
-
- for (iterator = refs ; iterator ; iterator = g_list_next(iterator)) {
- JabberSmileyRef *ref = (JabberSmileyRef *) iterator->data;
- g_free(ref->cid);
- g_free(ref->alt);
- g_free(ref);
- }
-
+
+ jabber_message_get_refs_from_xmlnode_internal(message, unique_refs);
+ (void) g_hash_table_foreach_steal(unique_refs,
+ jabber_message_get_refs_steal, (gpointer) &refs);
g_hash_table_destroy(unique_refs);
-
- return result;
+ return refs;
}
-
-
static gchar *
jabber_message_xml_to_string_strip_img_smileys(xmlnode *xhtml)
{
@@ -404,6 +404,9 @@ jabber_message_xml_to_string_strip_img_s
if (g_str_has_prefix(&(markup[pos2]), "/>")) {
pos2 += 2;
break;
+ } else if (g_str_has_prefix(&(markup[pos2]), "</img>")) {
+ pos2 += 5;
+ break;
}
}
@@ -417,10 +420,16 @@ jabber_message_xml_to_string_strip_img_s
if (g_str_has_prefix(src, "cid:")) {
const gchar *alt = xmlnode_get_attrib(img, "alt");
- gchar *escaped = g_markup_escape_text(alt, -1);
- out = g_string_append(out, escaped);
+ gchar *escaped = NULL;
+ /* if the "alt" attribute is empty, put the cid as smiley string */
+ if (alt && alt[0] != '\0') {
+ escaped = g_markup_escape_text(alt, -1);
+ out = g_string_append(out, escaped);
+ g_free(escaped);
+ } else {
+ out = g_string_append(out, src + 4);
+ }
pos += pos2 - pos;
- g_free(escaped);
} else {
out = g_string_append_c(out, markup[pos]);
pos++;
@@ -438,27 +447,36 @@ static void
}
static void
-jabber_message_add_remote_smileys_to_conv(PurpleConversation *conv,
- const xmlnode *message)
+jabber_message_add_remote_smileys(const xmlnode *message)
{
xmlnode *data_tag;
- for (data_tag = xmlnode_get_child(message, "data") ; data_tag ;
+ for (data_tag = xmlnode_get_child_with_namespace(message, "data", XEP_0231_NAMESPACE) ;
+ data_tag ;
data_tag = xmlnode_get_next_twin(data_tag)) {
const gchar *cid = xmlnode_get_attrib(data_tag, "cid");
- const JabberData *data = jabber_data_find_remote_by_cid(conv, cid);
+ const JabberData *data = jabber_data_find_remote_by_cid(cid);
- if (!data) {
+ if (!data && cid != NULL) {
/* we haven't cached this already, let's add it */
JabberData *new_data = jabber_data_create_from_xml(data_tag);
- jabber_data_associate_remote_with_conv(new_data, conv);
+ jabber_data_associate_remote(new_data);
}
}
}
+/* used in the function below to supply a conversation and shortcut for a
+ smiley */
+typedef struct {
+ PurpleConversation *conv;
+ const gchar *alt;
+} JabberDataRef;
+
static void
jabber_message_get_data_cb(JabberStream *js, xmlnode *packet, gpointer data)
{
- PurpleConversation *conv = (PurpleConversation *) data;
+ JabberDataRef *ref = (JabberDataRef *) data;
+ PurpleConversation *conv = ref->conv;
+ const gchar *alt = ref->alt;
xmlnode *data_element = xmlnode_get_child(packet, "data");
xmlnode *item_not_found = xmlnode_get_child(packet, "item-not-found");
@@ -467,11 +485,11 @@ jabber_message_get_data_cb(JabberStream
JabberData *data = jabber_data_create_from_xml(data_element);
if (data) {
- jabber_data_associate_remote_with_conv(data, conv);
- purple_conv_custom_smiley_write(conv, jabber_data_get_alt(data),
+ jabber_data_associate_remote(data);
+ purple_conv_custom_smiley_write(conv, alt,
jabber_data_get_data(data),
jabber_data_get_size(data));
- purple_conv_custom_smiley_close(conv, jabber_data_get_alt(data));
+ purple_conv_custom_smiley_close(conv, alt);
}
} else if (item_not_found) {
@@ -480,17 +498,23 @@ jabber_message_get_data_cb(JabberStream
} else {
purple_debug_error("jabber", "Unknown response to data request\n");
}
+
+ g_free(ref);
}
static void
jabber_message_send_data_request(JabberStream *js, PurpleConversation *conv,
- const gchar *cid, const gchar *who)
+ const gchar *cid, const gchar *who,
+ const gchar *alt)
{
JabberIq *request = jabber_iq_new(js, JABBER_IQ_GET);
+ JabberDataRef *ref = g_new0(JabberDataRef, 1);
xmlnode *data_request = jabber_data_get_xml_request(cid);
xmlnode_set_attrib(request->node, "to", who);
- jabber_iq_set_callback(request, jabber_message_get_data_cb, conv);
+ ref->conv = conv;
+ ref->alt = alt;
+ jabber_iq_set_callback(request, jabber_message_get_data_cb, ref);
xmlnode_insert_child(request->node, data_request);
jabber_iq_send(request);
@@ -565,7 +589,9 @@ void jabber_message_parse(JabberStream *
/* find a list of smileys ("cid" and "alt" text pairs)
occuring in the message */
smiley_refs = jabber_message_get_refs_from_xmlnode(child);
-
+ purple_debug_info("jabber", "found %d smileys\n",
+ g_list_length(smiley_refs));
+
if (jm->type == JABBER_MESSAGE_GROUPCHAT) {
JabberID *jid = jabber_id_new(jm->from);
JabberChat *chat = NULL;
@@ -582,17 +608,8 @@ void jabber_message_parse(JabberStream *
who, account);
}
- /* if the conversation doesn't exist yet we need to create it
- now */
- if (!conv) {
- /* if a message of this type is initiating a conversation,
- that must be an IM */
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM,
- account, who);
- }
-
/* process any newly provided smileys */
- jabber_message_add_remote_smileys_to_conv(conv, packet);
+ jabber_message_add_remote_smileys(packet);
}
/* reformat xhtml so that img tags with a "cid:" src gets
@@ -617,7 +634,7 @@ void jabber_message_parse(JabberStream *
if (purple_conv_custom_smiley_add(conv, alt, "cid", cid,
TRUE)) {
const JabberData *data =
- jabber_data_find_remote_by_cid(conv, cid);
+ jabber_data_find_remote_by_cid(cid);
/* if data is already known, we add write it immediatly */
if (data) {
purple_conv_custom_smiley_write(conv, alt,
@@ -626,7 +643,8 @@ void jabber_message_parse(JabberStream *
purple_conv_custom_smiley_close(conv, alt);
} else {
/* we need to request the smiley (data) */
- jabber_message_send_data_request(js, conv, cid, who);
+ jabber_message_send_data_request(js, conv, cid, who,
+ alt);
}
}
}
@@ -814,8 +832,7 @@ static gchar *
}
static gchar *
-jabber_message_get_smileyfied_xhtml(const PurpleConversation *conv,
- const gchar *xhtml, const GList *smileys)
+jabber_message_get_smileyfied_xhtml(const gchar *xhtml, const GList *smileys)
{
/* create XML element for all smileys (img tags) */
GString *result = g_string_new(NULL);
@@ -836,8 +853,8 @@ jabber_message_get_smileyfied_xhtml(cons
if (g_str_has_prefix(&(xhtml[pos]), escaped)) {
/* we found the current smiley at this position */
const JabberData *data =
- jabber_data_find_local_by_alt(conv, shortcut);
- xmlnode *img = jabber_data_get_xhtml_im(data);
+ jabber_data_find_local_by_alt(shortcut);
+ xmlnode *img = jabber_data_get_xhtml_im(data, shortcut);
int len;
gchar *img_text = xmlnode_to_str(img, &len);
@@ -868,18 +885,27 @@ jabber_conv_support_custom_smileys(const
const gchar *who)
{
JabberStream *js = (JabberStream *) gc->proto_data;
- JabberBuddy *jb = jabber_buddy_find(js, who, FALSE);
+ JabberBuddy *jb;
+
+ if (!js) {
+ purple_debug_error("jabber",
+ "jabber_conv_support_custom_smileys: could not find stream\n");
+ return FALSE;
+ }
+ jb = jabber_buddy_find(js, who, FALSE);
if (!jb) {
purple_debug_error("jabber",
"jabber_conv_support_custom smileys: could not find buddy\n");
return FALSE;
}
+
+
switch (purple_conversation_get_type(conv)) {
/* for the time being, we will not support custom smileys in MUCs */
case PURPLE_CONV_TYPE_IM:
- return jabber_buddy_has_capability(jb, XEP_0231_IB_IMAGE_NAMESPACE);
+ return jabber_buddy_has_capability(jb, XEP_0231_NAMESPACE);
break;
default:
return FALSE;
@@ -976,7 +1002,7 @@ void jabber_message_send(JabberMessage *
PurpleConversation *conv =
purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, jm->to,
account);
-
+
if (jabber_conv_support_custom_smileys(jm->js->gc, conv, jm->to)) {
GList *found_smileys = jabber_message_xhtml_find_smileys(jm->xhtml);
@@ -990,28 +1016,33 @@ void jabber_message_send(JabberMessage *
(PurpleSmiley *) iterator->data;
const gchar *shortcut = purple_smiley_get_shortcut(smiley);
const JabberData *data =
- jabber_data_find_local_by_alt(conv, shortcut);
-
- /* if data has not been sent before, include data */
+ jabber_data_find_local_by_alt(shortcut);
+
+ /* the object has not been sent before */
if (!data) {
PurpleStoredImage *image =
purple_smiley_get_stored_image(smiley);
const gchar *ext = purple_imgstore_get_extension(image);
-
+ JabberStream *js = jm->js;
+
JabberData *new_data =
jabber_data_create_from_data(purple_imgstore_get_data(image),
- purple_imgstore_get_size(image),
- jabber_message_get_mimetype_from_ext(ext),
- shortcut);
- jabber_data_associate_local_with_conv(new_data, conv);
- xmlnode_insert_child(message,
- jabber_data_get_xml_definition(new_data));
+ purple_imgstore_get_size(image),
+ jabber_message_get_mimetype_from_ext(ext), js);
+ purple_debug_info("jabber",
+ "cache local smiley alt = %s, cid = %s\n",
+ shortcut, jabber_data_get_cid(new_data));
+ jabber_data_associate_local(new_data, shortcut);
+ /* if the size of the data is small enough, include it */
+ if (jabber_data_get_size(new_data) <= 1024) {
+ xmlnode_insert_child(message,
+ jabber_data_get_xml_definition(new_data));
+ }
}
}
smileyfied_xhtml =
- jabber_message_get_smileyfied_xhtml(conv, jm->xhtml,
- found_smileys);
+ jabber_message_get_smileyfied_xhtml(jm->xhtml, found_smileys);
child = xmlnode_from_str(smileyfied_xhtml, -1);
g_free(smileyfied_xhtml);
g_list_free(found_smileys);
============================================================
--- pidgin/gtksmiley.c 23e08e5665b4f78928d54d8ee8f57f74dd2b2b6c
+++ pidgin/gtksmiley.c 09bdcafc0ddd630ebe5f87329a204a474cd438a4
@@ -273,8 +273,8 @@ static void do_add(GtkWidget *widget, Pi
gsize size = 0;
gchar *filename;
- gdk_pixbuf_save_to_bufferv(s->custom_pixbuf, &buffer, &size,
- "png", NULL, NULL, NULL);
+ gdk_pixbuf_save_to_buffer(s->custom_pixbuf, &buffer, &size,
+ "png", NULL, "compression", "9", NULL, NULL);
filename = purple_util_get_image_filename(buffer, size);
s->filename = g_build_filename(purple_smileys_get_storing_dir(), filename, NULL);
purple_util_write_data_to_file_absolute(s->filename, buffer, size);
More information about the Commits
mailing list