summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Lundblad <malu@pidgin.im>2010-03-15 21:49:02 +0000
committerMarcus Lundblad <malu@pidgin.im>2010-03-15 21:49:02 +0000
commitb1b0e31e78eb5c85628a27b3519e9d8d218a805f (patch)
treef812d7d3dabd0bffe334df0a171eb0376b580a31
parent3c621ea80131fee9e3f01f623dd9d05dca77b1d7 (diff)
downloadpidgin-b1b0e31e78eb5c85628a27b3519e9d8d218a805f.tar.gz
Allow PRPLs to specify the image formats acceptable for thumbnails (in
preferred order).
-rw-r--r--libpurple/ft.c10
-rw-r--r--libpurple/ft.h14
-rw-r--r--libpurple/protocols/jabber/libxmpp.c3
-rw-r--r--libpurple/protocols/jabber/si.c9
-rw-r--r--libpurple/protocols/msn/msn.c3
-rw-r--r--libpurple/protocols/msn/slp.c3
-rw-r--r--libpurple/prpl.h20
-rw-r--r--pidgin/gtkft.c56
8 files changed, 103 insertions, 15 deletions
diff --git a/libpurple/ft.c b/libpurple/ft.c
index ee461024b3..4c4e246ad2 100644
--- a/libpurple/ft.c
+++ b/libpurple/ft.c
@@ -179,6 +179,7 @@ purple_xfer_destroy(PurpleXfer *xfer)
g_hash_table_remove(xfers_data, xfer);
g_free(xfer->thumbnail_data);
+ g_free(xfer->thumbnail_mimetype);
PURPLE_DBUS_UNREGISTER_POINTER(xfer);
xfers = g_list_remove(xfers, xfer);
@@ -1630,13 +1631,20 @@ purple_xfer_get_thumbnail_size(const PurpleXfer *xfer)
return xfer->thumbnail_size;
}
+const gchar *
+purple_xfer_get_thumbnail_mimetype(const PurpleXfer *xfer)
+{
+ return xfer->thumbnail_mimetype;
+}
+
void
purple_xfer_set_thumbnail(PurpleXfer *xfer, gconstpointer thumbnail,
- gsize size)
+ gsize size, const gchar *mimetype)
{
if (thumbnail && size > 0) {
xfer->thumbnail_data = g_memdup(thumbnail, size);
xfer->thumbnail_size = size;
+ xfer->thumbnail_mimetype = g_strdup(mimetype);
}
}
diff --git a/libpurple/ft.h b/libpurple/ft.h
index a2261e7160..7fcc747210 100644
--- a/libpurple/ft.h
+++ b/libpurple/ft.h
@@ -189,6 +189,7 @@ struct _PurpleXfer
gpointer thumbnail_data; /**< thumbnail image */
gsize thumbnail_size;
+ gchar *thumbnail_mimetype;
};
#ifdef __cplusplus
@@ -711,16 +712,25 @@ const void *purple_xfer_get_thumbnail_data(const PurpleXfer *xfer);
*/
gsize purple_xfer_get_thumbnail_size(const PurpleXfer *xfer);
-
+/**
+ * Gets the mimetype of the thumbnail preview for a transfer
+ *
+ * @param xfer The file transfer to get the mimetype for
+ * @return The mimetype of the thumbnail, or @c NULL if not thumbnail is set
+ */
+const gchar *purple_xfer_get_thumbnail_mimetype(const PurpleXfer *xfer);
+
+
/**
* Sets the thumbnail data for a transfer
*
* @param xfer The file transfer to set the data for
* @param thumbnail A pointer to the thumbnail data, this will be copied
* @param size The size in bytes of the passed in thumbnail data
+ * @param mimetype The mimetype of the generated thumbnail
*/
void purple_xfer_set_thumbnail(PurpleXfer *xfer, gconstpointer thumbnail,
- gsize size);
+ gsize size, const gchar *mimetype);
/**
* Prepare a thumbnail for a transfer (if the UI supports it)
diff --git a/libpurple/protocols/jabber/libxmpp.c b/libpurple/protocols/jabber/libxmpp.c
index d41160b29d..db70ddbd87 100644
--- a/libpurple/protocols/jabber/libxmpp.c
+++ b/libpurple/protocols/jabber/libxmpp.c
@@ -127,7 +127,8 @@ static PurplePluginProtocolInfo prpl_info =
NULL, /* get_account_text_table */
jabber_initiate_media, /* initiate_media */
jabber_get_media_caps, /* get_media_caps */
- jabber_get_moods /* get_moods */
+ jabber_get_moods, /* get_moods */
+ {"jpeg,png"} /* file transfer thumbnail spec */
};
static gboolean load_plugin(PurplePlugin *plugin)
diff --git a/libpurple/protocols/jabber/si.c b/libpurple/protocols/jabber/si.c
index 99e1132532..4953e7dd16 100644
--- a/libpurple/protocols/jabber/si.c
+++ b/libpurple/protocols/jabber/si.c
@@ -1267,15 +1267,16 @@ static void jabber_si_xfer_send_request(PurpleXfer *xfer)
/* add thumbnail, if appropriate */
if (purple_xfer_get_thumbnail_data(xfer)) {
- JabberData *thumbnail_data =
+ const gchar *mimetype = purple_xfer_get_thumbnail_mimetype(xfer);
+ JabberData *thumbnail_data =
jabber_data_create_from_data(purple_xfer_get_thumbnail_data(xfer),
- purple_xfer_get_thumbnail_size(xfer), "image/png", TRUE,
+ purple_xfer_get_thumbnail_size(xfer), mimetype, TRUE,
jsx->js);
xmlnode *thumbnail = xmlnode_new_child(file, "thumbnail");
xmlnode_set_namespace(thumbnail, NS_THUMBS);
xmlnode_set_attrib(thumbnail, "cid",
jabber_data_get_cid(thumbnail_data));
- xmlnode_set_attrib(thumbnail, "mime-type", "image/png");
+ xmlnode_set_attrib(thumbnail, "mime-type", mimetype);
/* cache data */
jabber_data_associate_local(thumbnail_data, NULL);
}
@@ -1671,7 +1672,7 @@ jabber_si_thumbnail_cb(JabberStream *js, const char *from, JabberIqType type,
if (data) {
purple_xfer_set_thumbnail(xfer, jabber_data_get_data(data),
- jabber_data_get_size(data));
+ jabber_data_get_size(data), jabber_data_get_type(data));
jabber_data_destroy(data);
}
} else if (item_not_found) {
diff --git a/libpurple/protocols/msn/msn.c b/libpurple/protocols/msn/msn.c
index 0d34e0c298..67e303b910 100644
--- a/libpurple/protocols/msn/msn.c
+++ b/libpurple/protocols/msn/msn.c
@@ -2733,7 +2733,8 @@ static PurplePluginProtocolInfo prpl_info =
msn_get_account_text_table, /* get_account_text_table */
NULL, /* initiate_media */
NULL, /* get_media_caps */
- NULL /* get_moods */
+ NULL, /* get_moods */
+ {"png"} /* file transfer thumbnail spec */
};
static PurplePluginInfo info =
diff --git a/libpurple/protocols/msn/slp.c b/libpurple/protocols/msn/slp.c
index 74e27e02ef..b7b4fcfa15 100644
--- a/libpurple/protocols/msn/slp.c
+++ b/libpurple/protocols/msn/slp.c
@@ -424,7 +424,8 @@ got_sessionreq(MsnSlpCall *slpcall, const char *branch,
if (header->type == 0 && bin_len >= sizeof(MsnFileContext)) {
purple_xfer_set_thumbnail(xfer, &header->preview,
- bin_len - sizeof(MsnFileContext));
+ bin_len - sizeof(MsnFileContext),
+ "image/png");
}
purple_xfer_request(xfer);
diff --git a/libpurple/prpl.h b/libpurple/prpl.h
index 4ed0def2fc..0d4e6b8e65 100644
--- a/libpurple/prpl.h
+++ b/libpurple/prpl.h
@@ -52,6 +52,13 @@ typedef enum {
typedef struct _PurpleBuddyIconSpec PurpleBuddyIconSpec;
/**
+ * A description of a file transfer thumbnail specification.
+ * This tells the UI if and what image formats the prpl support for file
+ * transfer thumbnails.
+ */
+typedef struct _PurpleThumbnailSpec PurpleThumbnailSpec;
+
+/**
* This \#define exists just to make it easier to fill out the buddy icon
* field in the prpl info struct for protocols that couldn't care less.
*/
@@ -91,6 +98,14 @@ struct _PurpleBuddyIconSpec {
PurpleIconScaleRules scale_rules; /**< How to stretch this icon */
};
+/** @copydoc PurpleThumbnailSpec */
+struct _PurpleThumbnailSpec {
+ /** This is a comma-delimited list of image formats or @c NULL if the
+ * prpl does not support file transfer thumbnails
+ */
+ char *format;
+};
+
/** Represents an entry containing information that must be supplied by the
* user when joining a chat.
*/
@@ -575,6 +590,11 @@ struct _PurplePluginProtocolInfo
* "mood" set to @c NULL.
*/
PurpleMood *(*get_moods)(PurpleAccount *account);
+
+ /**
+ * File transfer thumbnail spec
+ */
+ PurpleThumbnailSpec thumbnail_spec;
};
#define PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, member) \
diff --git a/pidgin/gtkft.c b/pidgin/gtkft.c
index a83930f918..e9c384fbc3 100644
--- a/pidgin/gtkft.c
+++ b/pidgin/gtkft.c
@@ -1163,29 +1163,75 @@ pidgin_xfer_cancel_remote(PurpleXfer *xfer)
static void
pidgin_xfer_add_thumbnail(PurpleXfer *xfer)
{
+ PurpleAccount *account = purple_xfer_get_account(xfer);
+ PurpleConnection *gc = purple_account_get_connection(account);
+ PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
+ const char *thumbnail_format = prpl_info->thumbnail_spec.format;
+
purple_debug_info("pidgin", "creating thumbnail for transfer\n");
- if (purple_xfer_get_size(xfer) <= PIDGIN_XFER_MAX_SIZE_IMAGE_THUMBNAIL) {
+ if (thumbnail_format != NULL &&
+ purple_xfer_get_size(xfer) <= PIDGIN_XFER_MAX_SIZE_IMAGE_THUMBNAIL) {
GdkPixbuf *thumbnail =
gdk_pixbuf_new_from_file_at_size(
purple_xfer_get_local_filename(xfer), 128, 128, NULL);
if (thumbnail) {
+ gchar **formats = g_strsplit(thumbnail_format, ",", 0);
gchar *buffer = NULL;
gsize size;
- char *option_keys[2] = {"compression", NULL};
- char *option_values[2] = {"9", NULL};
- gdk_pixbuf_save_to_bufferv(thumbnail, &buffer, &size, "png",
+ char *option_keys[2] = {NULL, NULL};
+ char *option_values[2] = {NULL, NULL};
+ gboolean supports_jpeg = FALSE;
+ gboolean supports_png = FALSE;
+ int i;
+ gchar *format = NULL;
+
+ for (i = 0 ; formats[i] ; i++) {
+ if (purple_strequal(formats[i], "jpeg")) {
+ supports_jpeg = TRUE;
+ } else if (purple_strequal(formats[i], "png")) {
+ supports_png = TRUE;
+ }
+ }
+
+ /* prefer JPEG, then PNG, otherwise try the first format given
+ by the PRPL without options */
+ if (supports_jpeg) {
+ purple_debug_info("pidgin", "creating JPEG thumbnail\n");
+ option_keys[0] = "quality";
+ option_keys[1] = NULL;
+ option_values[0] = "90";
+ option_values[1] = NULL;
+ format = "jpeg";
+ } else if (supports_png) {
+ purple_debug_info("pidgin", "creating PNG thumbnail\n");
+ option_keys[0] = "compression";
+ option_keys[1] = NULL;
+ option_values[0] = "9";
+ option_values[1] = NULL;
+ format = "png";
+ } else {
+ purple_debug_info("pidgin",
+ "creating thumbnail of format %s as demanded by PRPL\n",
+ formats[0]);
+ format = formats[0];
+ }
+
+ gdk_pixbuf_save_to_bufferv(thumbnail, &buffer, &size, format,
option_keys, option_values, NULL);
if (buffer) {
+ const gchar *mimetype = g_strdup_printf("image/%s", format);
purple_debug_info("pidgin",
"created thumbnail of %" G_GSIZE_FORMAT " bytes\n",
size);
- purple_xfer_set_thumbnail(xfer, buffer, size);
+ purple_xfer_set_thumbnail(xfer, buffer, size, mimetype);
g_free(buffer);
+ g_free(mimetype);
}
g_object_unref(thumbnail);
+ g_strfreev(formats);
}
}
}