diff options
author | Marcus Lundblad <malu@pidgin.im> | 2010-03-15 21:49:02 +0000 |
---|---|---|
committer | Marcus Lundblad <malu@pidgin.im> | 2010-03-15 21:49:02 +0000 |
commit | b1b0e31e78eb5c85628a27b3519e9d8d218a805f (patch) | |
tree | f812d7d3dabd0bffe334df0a171eb0376b580a31 | |
parent | 3c621ea80131fee9e3f01f623dd9d05dca77b1d7 (diff) | |
download | pidgin-b1b0e31e78eb5c85628a27b3519e9d8d218a805f.tar.gz |
Allow PRPLs to specify the image formats acceptable for thumbnails (in
preferred order).
-rw-r--r-- | libpurple/ft.c | 10 | ||||
-rw-r--r-- | libpurple/ft.h | 14 | ||||
-rw-r--r-- | libpurple/protocols/jabber/libxmpp.c | 3 | ||||
-rw-r--r-- | libpurple/protocols/jabber/si.c | 9 | ||||
-rw-r--r-- | libpurple/protocols/msn/msn.c | 3 | ||||
-rw-r--r-- | libpurple/protocols/msn/slp.c | 3 | ||||
-rw-r--r-- | libpurple/prpl.h | 20 | ||||
-rw-r--r-- | pidgin/gtkft.c | 56 |
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); } } } |