Sun, 28 May 2017 13:26:27 +0300
Merged pidgin/main into default
| libpurple/buddyicon.c | file | annotate | diff | comparison | revisions | |
| libpurple/log.c | file | annotate | diff | comparison | revisions |
--- a/libpurple/buddyicon.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/buddyicon.c Sun May 28 13:26:27 2017 +0300 @@ -510,7 +510,7 @@ if (icon->img) { if (len != NULL) - *len = purple_image_get_size(icon->img); + *len = purple_image_get_data_size(icon->img); return purple_image_get_data(icon->img); }
--- a/libpurple/conversation.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/conversation.c Sun May 28 13:26:27 2017 +0300 @@ -837,16 +837,14 @@ return purple_protocol_client_iface_get_max_message_size(protocol, conv); } -PurpleSmiley * -purple_conversation_add_remote_smiley(PurpleConversation *conv, - const gchar *shortcut) -{ - PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv); - PurpleSmiley *smiley; +void +purple_conversation_add_smiley(PurpleConversation *conv, PurpleSmiley *smiley) { + PurpleConversationPrivate *priv = NULL; - g_return_val_if_fail(priv != NULL, NULL); - g_return_val_if_fail(shortcut != NULL, NULL); - g_return_val_if_fail(shortcut[0] != '\0', NULL); + g_return_if_fail(PURPLE_IS_CONVERSATION(conv)); + g_return_if_fail(smiley); + + priv = PURPLE_CONVERSATION_GET_PRIVATE(conv); if (priv->remote_smileys == NULL) { priv->remote_smileys = purple_smiley_list_new(); @@ -854,42 +852,33 @@ "drop-failed-remotes", TRUE, NULL); } - smiley = purple_smiley_list_get_by_shortcut( - priv->remote_smileys, shortcut); - - /* smiley was already added */ - if (smiley) - return NULL; - - smiley = purple_smiley_new_remote(shortcut); + if(purple_smiley_list_get_by_shortcut( + priv->remote_smileys, + purple_smiley_get_shortcut(smiley))) + { + /* smiley was already added */ + return; + } if (!purple_smiley_list_add(priv->remote_smileys, smiley)) { purple_debug_error("conversation", "failed adding remote " "smiley to the list"); - g_object_unref(smiley); - return NULL; } - - /* priv->remote_smileys holds the only one ref */ - g_object_unref(smiley); - return smiley; } PurpleSmiley * -purple_conversation_get_remote_smiley(PurpleConversation *conv, - const gchar *shortcut) -{ - PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv); +purple_conversation_get_smiley(PurpleConversation *conv, const gchar *shortcut) { + PurpleConversationPrivate *priv = NULL; - g_return_val_if_fail(priv != NULL, NULL); - g_return_val_if_fail(shortcut != NULL, NULL); - g_return_val_if_fail(shortcut[0] != '\0', NULL); + g_return_val_if_fail(PURPLE_IS_CONVERSATION(conv), NULL); + g_return_val_if_fail(shortcut, NULL); + + priv = PURPLE_CONVERSATION_GET_PRIVATE(conv); if (priv->remote_smileys == NULL) return NULL; - return purple_smiley_list_get_by_shortcut( - priv->remote_smileys, shortcut); + return purple_smiley_list_get_by_shortcut(priv->remote_smileys, shortcut); } PurpleSmileyList *
--- a/libpurple/conversation.h Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/conversation.h Sun May 28 13:26:27 2017 +0300 @@ -652,40 +652,24 @@ purple_conversation_get_max_message_size(PurpleConversation *conv); /** - * purple_conversation_add_remote_smiley: + * purple_conversation_add_smiley: * @conv: The conversation that receives new smiley. - * @shortcut: The shortcut for the new smiley. - * - * Adds new smiley to the list of remote smileys for this conversation. - * The smiley image have to be written and closed, when data is ready. + * @smiley: The smiley. * - * You can retrieve smiley's #PurpleImage object using #purple_smiley_get_image - * and set its data with #purple_image_transfer_write - * and #purple_image_transfer_close. - * - * Returns: (transfer none): New smiley, or %NULL if it's already being - * retrieved (or possibly, in case of error). + * Adds a smiley to the list of smileys that belong to this conversation. */ -PurpleSmiley * -purple_conversation_add_remote_smiley(PurpleConversation *conv, - const gchar *shortcut); +void purple_conversation_add_smiley(PurpleConversation *conv, PurpleSmiley *smiley); /** - * purple_conversation_get_remote_smiley: + * purple_conversation_get_smiley: * @conv: The conversation. * @shortcut: The shortcut. * - * Lookups for the remote smiley previously added to this conversation. - * - * You may use this function when you receive the smiley data, but it's - * better just to store and use the reference returned by - * #purple_conversation_add_remote_smiley. + * Lookups for the smiley previously added to this conversation. * * Returns: (transfer none): The smiley, or %NULL if it doesn't exists. */ -PurpleSmiley * -purple_conversation_get_remote_smiley(PurpleConversation *conv, - const gchar *shortcut); +PurpleSmiley *purple_conversation_get_smiley(PurpleConversation *conv, const gchar *shortcut); /** * purple_conversation_get_remote_smileys:
--- a/libpurple/image-store.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/image-store.c Sun May 28 13:26:27 2017 +0300 @@ -194,16 +194,14 @@ gchar * purple_image_store_get_uri(PurpleImage *image) { - gboolean is_ready; const gchar *path; guint img_id; g_return_val_if_fail(PURPLE_IS_IMAGE(image), NULL); - is_ready = purple_image_is_ready(image); path = purple_image_get_path(image); - if (is_ready && path) + if (path) return g_filename_to_uri(path, NULL, NULL); img_id = purple_image_store_add_weak(image);
--- a/libpurple/image.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/image.c Sun May 28 13:26:27 2017 +0300 @@ -30,176 +30,186 @@ typedef struct { gchar *path; - GString *contents; + + GBytes *contents; const gchar *extension; const gchar *mime; gchar *gen_filename; gchar *friendly_filename; - - gboolean is_ready; - gboolean has_failed; } PurpleImagePrivate; -enum -{ +enum { PROP_0, - PROP_IS_READY, - PROP_HAS_FAILED, + PROP_CONTENTS, + PROP_SIZE, PROP_LAST }; -enum -{ - SIG_READY, - SIG_FAILED, - SIG_LAST -}; - -static GObjectClass *parent_class; -static guint signals[SIG_LAST]; static GParamSpec *properties[PROP_LAST]; /****************************************************************************** - * Internal logic + * Helpers ******************************************************************************/ +static void +_purple_image_set_contents(PurpleImage *image, GBytes *bytes) { + PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); + + if(priv->contents) + g_bytes_unref(priv->contents); + + priv->contents = (bytes) ? g_bytes_ref(bytes) : NULL; +} + +/****************************************************************************** + * Object stuff + ******************************************************************************/ +G_DEFINE_TYPE_WITH_PRIVATE(PurpleImage, purple_image, G_TYPE_OBJECT); static void -has_failed(PurpleImage *image) -{ - gboolean ready_changed; - PurpleImagePrivate *priv; - priv = PURPLE_IMAGE_GET_PRIVATE(image); - - g_return_if_fail(!priv->has_failed); - - priv->has_failed = TRUE; - ready_changed = (priv->is_ready != FALSE); - priv->is_ready = FALSE; - - if (priv->contents) { - g_string_free(priv->contents, TRUE); - priv->contents = NULL; - } - - if (ready_changed) { - g_object_notify_by_pspec(G_OBJECT(image), - properties[PROP_IS_READY]); - } - g_object_notify_by_pspec(G_OBJECT(image), properties[PROP_HAS_FAILED]); - g_signal_emit(image, signals[SIG_FAILED], 0); +purple_image_init(PurpleImage *image) { } static void -became_ready(PurpleImage *image) +purple_image_finalize(GObject *obj) { + PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(obj); + + if(priv->contents) + g_bytes_unref(priv->contents); + + g_free(priv->path); + g_free(priv->gen_filename); + g_free(priv->friendly_filename); + + G_OBJECT_CLASS(purple_image_parent_class)->finalize(obj); +} + +static void +purple_image_set_property(GObject *obj, guint param_id, + const GValue *value, GParamSpec *pspec) { - PurpleImagePrivate *priv; - priv = PURPLE_IMAGE_GET_PRIVATE(image); + PurpleImage *image = PURPLE_IMAGE(obj); - g_return_if_fail(!priv->has_failed); - g_return_if_fail(!priv->is_ready); + switch (param_id) { + case PROP_CONTENTS: + _purple_image_set_contents(image, g_value_get_boxed(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} - priv->is_ready = TRUE; +static void +purple_image_get_property(GObject *obj, guint param_id, GValue *value, + GParamSpec *pspec) +{ + PurpleImage *image = PURPLE_IMAGE(obj); - g_object_notify_by_pspec(G_OBJECT(image), properties[PROP_IS_READY]); - g_signal_emit(image, signals[SIG_READY], 0); + switch (param_id) { + case PROP_CONTENTS: + g_value_set_boxed(value, purple_image_get_contents(image)); + break; + case PROP_SIZE: + g_value_set_uint64(value, purple_image_get_data_size(image)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } } static void -steal_contents(PurpleImagePrivate *priv, gpointer data, gsize length) -{ - g_return_if_fail(priv != NULL); - g_return_if_fail(priv->contents == NULL); - g_return_if_fail(data != NULL); - g_return_if_fail(length > 0); +purple_image_class_init(PurpleImageClass *klass) { + GObjectClass *gobj_class = G_OBJECT_CLASS(klass); + + gobj_class->finalize = purple_image_finalize; + gobj_class->get_property = purple_image_get_property; + gobj_class->set_property = purple_image_set_property; - priv->contents = g_string_new(NULL); - g_free(priv->contents->str); - priv->contents->str = data; - priv->contents->len = priv->contents->allocated_len = length; + properties[PROP_CONTENTS] = g_param_spec_boxed( + "contents", + "contents", + "The contents of the image stored in a GBytes", + G_TYPE_BYTES, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS + ); + + properties[PROP_SIZE] = g_param_spec_uint64( + "size", + "size", + "The size of the image in bytes", + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS + ); + + g_object_class_install_properties(gobj_class, PROP_LAST, properties); } -static void -fill_data(PurpleImage *image) -{ - PurpleImagePrivate *priv; - GError *error = NULL; - gchar *contents; - gsize length; - - priv = PURPLE_IMAGE_GET_PRIVATE(image); - if (priv->contents) - return; - - if (!priv->is_ready) - return; - - g_return_if_fail(priv->path); - (void)g_file_get_contents(priv->path, &contents, &length, &error); - if (error) { - purple_debug_error("image", "failed to read '%s' image: %s", - priv->path, error->message); - g_error_free(error); - - has_failed(image); - return; - } - - steal_contents(priv, contents, length); -} - - /****************************************************************************** - * API implementation + * API ******************************************************************************/ - PurpleImage * -purple_image_new_from_file(const gchar *path, gboolean be_eager) -{ - PurpleImagePrivate *priv; - PurpleImage *img; - - g_return_val_if_fail(path != NULL, NULL); - g_return_val_if_fail(g_file_test(path, G_FILE_TEST_EXISTS), NULL); - - img = g_object_new(PURPLE_TYPE_IMAGE, NULL); - purple_image_set_friendly_filename(img, path); - priv = PURPLE_IMAGE_GET_PRIVATE(img); - priv->path = g_strdup(path); - - if (be_eager) { - fill_data(img); - if (!priv->contents) { - g_object_unref(img); - return NULL; - } - - g_assert(priv->is_ready && !priv->has_failed); - } - - return img; +purple_image_new_from_bytes(GBytes *bytes) { + return g_object_new( + PURPLE_TYPE_IMAGE, + "contents", bytes, + NULL + ); } PurpleImage * -purple_image_new_from_data(gpointer data, gsize length) -{ - PurpleImage *img; - PurpleImagePrivate *priv; +purple_image_new_from_file(const gchar *path, GError **error) { + PurpleImage *image = NULL; + GBytes *bytes = NULL; + gchar *contents = NULL; + gsize length = 0; + + if(!g_file_get_contents(path, &contents, &length, error)) { + return NULL; + } + + bytes = g_bytes_new_take(contents, length); + + image = purple_image_new_from_bytes(bytes); + + g_bytes_unref(bytes); + + return image; +} - g_return_val_if_fail(data != NULL, NULL); - g_return_val_if_fail(length > 0, NULL); +PurpleImage * +purple_image_new_from_data(const guint8 *data, gsize length) { + PurpleImage *image; + GBytes *bytes = NULL; + + bytes = g_bytes_new(data, length); + + image = purple_image_new_from_bytes(bytes); + + g_bytes_unref(bytes); - img = g_object_new(PURPLE_TYPE_IMAGE, NULL); - priv = PURPLE_IMAGE_GET_PRIVATE(img); + return image; +} + +PurpleImage * +purple_image_new_take_data(guint8 *data, gsize length) { + PurpleImage *image; + GBytes *bytes = NULL; - steal_contents(priv, data, length); + bytes = g_bytes_new_take(data, length); + + image = purple_image_new_from_bytes(bytes); - return img; + g_bytes_unref(bytes); + + return image; } gboolean -purple_image_save(PurpleImage *image, const gchar *path) -{ +purple_image_save(PurpleImage *image, const gchar *path) { PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); gconstpointer data; gsize len; @@ -210,7 +220,7 @@ g_return_val_if_fail(path[0] != '\0', FALSE); data = purple_image_get_data(image); - len = purple_image_get_size(image); + len = purple_image_get_data_size(image); g_return_val_if_fail(data != NULL, FALSE); g_return_val_if_fail(len > 0, FALSE); @@ -222,9 +232,22 @@ return succ; } +GBytes * +purple_image_get_contents(const PurpleImage *image) { + PurpleImagePrivate *priv = NULL; + + g_return_val_if_fail(PURPLE_IS_IMAGE(image), NULL); + + priv = PURPLE_IMAGE_GET_PRIVATE(image); + + if(priv->contents) + return g_bytes_ref(priv->contents); + + return NULL; +} + const gchar * -purple_image_get_path(PurpleImage *image) -{ +purple_image_get_path(PurpleImage *image) { PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); g_return_val_if_fail(priv != NULL, NULL); @@ -232,58 +255,36 @@ return priv->path; } -gboolean -purple_image_is_ready(PurpleImage *image) -{ - PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); - - g_return_val_if_fail(priv != NULL, FALSE); - - return priv->is_ready; -} +gsize +purple_image_get_data_size(PurpleImage *image) { + PurpleImagePrivate *priv; -gboolean -purple_image_has_failed(PurpleImage *image) -{ - PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); - - g_return_val_if_fail(priv != NULL, TRUE); + g_return_val_if_fail(PURPLE_IS_IMAGE(image), 0); - return priv->has_failed; -} - -gsize -purple_image_get_size(PurpleImage *image) -{ - PurpleImagePrivate *priv; priv = PURPLE_IMAGE_GET_PRIVATE(image); - g_return_val_if_fail(priv != NULL, 0); - g_return_val_if_fail(priv->is_ready, 0); + if(priv->contents) + return g_bytes_get_size(priv->contents); - fill_data(image); - g_return_val_if_fail(priv->contents, 0); - - return priv->contents->len; + return 0; } gconstpointer -purple_image_get_data(PurpleImage *image) -{ - PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); +purple_image_get_data(PurpleImage *image) { + PurpleImagePrivate *priv = NULL; + + g_return_val_if_fail(PURPLE_IS_IMAGE(image), NULL); - g_return_val_if_fail(priv != NULL, NULL); - g_return_val_if_fail(priv->is_ready, NULL); + priv = PURPLE_IMAGE_GET_PRIVATE(image); - fill_data(image); - g_return_val_if_fail(priv->contents, NULL); + if(priv->contents) + return g_bytes_get_data(priv->contents, NULL); - return priv->contents->str; + return NULL; } const gchar * -purple_image_get_extension(PurpleImage *image) -{ +purple_image_get_extension(PurpleImage *image) { PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); gconstpointer data; @@ -292,7 +293,7 @@ if (priv->extension) return priv->extension; - if (purple_image_get_size(image) < 4) + if (purple_image_get_data_size(image) < 4) return NULL; data = purple_image_get_data(image); @@ -317,8 +318,7 @@ } const gchar * -purple_image_get_mimetype(PurpleImage *image) -{ +purple_image_get_mimetype(PurpleImage *image) { PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); const gchar *ext = purple_image_get_extension(image); @@ -346,8 +346,7 @@ } const gchar * -purple_image_generate_filename(PurpleImage *image) -{ +purple_image_generate_filename(PurpleImage *image) { PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); gconstpointer data; gsize len; @@ -361,7 +360,7 @@ ext = purple_image_get_extension(image); data = purple_image_get_data(image); - len = purple_image_get_size(image); + len = purple_image_get_data_size(image); g_return_val_if_fail(ext != NULL, NULL); g_return_val_if_fail(data != NULL, NULL); @@ -375,8 +374,7 @@ } void -purple_image_set_friendly_filename(PurpleImage *image, const gchar *filename) -{ +purple_image_set_friendly_filename(PurpleImage *image, const gchar *filename) { PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); gchar *newname; const gchar *escaped; @@ -400,223 +398,17 @@ } const gchar * -purple_image_get_friendly_filename(PurpleImage *image) -{ - PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); - - g_return_val_if_fail(priv != NULL, NULL); - - if (G_UNLIKELY(!priv->friendly_filename)) { - const gchar *newname = purple_image_generate_filename(image); - gsize newname_len = strlen(newname); - - if (newname_len < 10) - return NULL; - - /* let's use last 6 characters from checksum + 4 characters - * from file ext */ - newname += newname_len - 10; - priv->friendly_filename = g_strdup(newname); - } +purple_image_get_friendly_filename(PurpleImage *image) { + PurpleImagePrivate *priv = NULL; - if (G_UNLIKELY(priv->is_ready && - strchr(priv->friendly_filename, '.') == NULL)) - { - const gchar *ext = purple_image_get_extension(image); - gchar *tmp; - if (!ext) - return priv->friendly_filename; - - tmp = g_strdup_printf("%s.%s", priv->friendly_filename, ext); - g_free(priv->friendly_filename); - priv->friendly_filename = tmp; - } - - return priv->friendly_filename; -} - -PurpleImage * -purple_image_transfer_new(void) -{ - PurpleImage *img; - PurpleImagePrivate *priv; + g_return_val_if_fail(PURPLE_IS_IMAGE(image), NULL); - img = g_object_new(PURPLE_TYPE_IMAGE, NULL); - priv = PURPLE_IMAGE_GET_PRIVATE(img); - - priv->is_ready = FALSE; - priv->contents = g_string_new(NULL); - - return img; -} - -void -purple_image_transfer_write(PurpleImage *image, gconstpointer data, - gsize length) -{ - PurpleImagePrivate *priv = - PURPLE_IMAGE_GET_PRIVATE(image); - - g_return_if_fail(priv != NULL); - g_return_if_fail(!priv->has_failed); - g_return_if_fail(!priv->is_ready); - g_return_if_fail(priv->contents != NULL); - g_return_if_fail(data != NULL || length == 0); + priv = PURPLE_IMAGE_GET_PRIVATE(image); - if (length == 0) - return; - - g_string_append_len(priv->contents, (const gchar*)data, length); -} - -void -purple_image_transfer_close(PurpleImage *image) -{ - PurpleImagePrivate *priv = - PURPLE_IMAGE_GET_PRIVATE(image); - - g_return_if_fail(priv != NULL); - g_return_if_fail(!priv->has_failed); - g_return_if_fail(!priv->is_ready); - g_return_if_fail(priv->contents != NULL); - - if (priv->contents->len == 0) { - purple_debug_error("image", "image is empty"); - has_failed(image); - return; + if(priv->friendly_filename) { + return priv->friendly_filename; } - became_ready(image); -} - -void -purple_image_transfer_failed(PurpleImage *image) -{ - PurpleImagePrivate *priv = - PURPLE_IMAGE_GET_PRIVATE(image); - - g_return_if_fail(priv != NULL); - g_return_if_fail(!priv->has_failed); - g_return_if_fail(!priv->is_ready); - - has_failed(image); -} - -/****************************************************************************** - * Object stuff - ******************************************************************************/ - -static void -purple_image_init(GTypeInstance *instance, gpointer klass) -{ - PurpleImage *image = PURPLE_IMAGE(instance); - PurpleImagePrivate *priv = - PURPLE_IMAGE_GET_PRIVATE(image); - - priv->contents = NULL; - priv->is_ready = TRUE; - priv->has_failed = FALSE; -} - -static void -purple_image_finalize(GObject *obj) -{ - PurpleImage *image = PURPLE_IMAGE(obj); - PurpleImagePrivate *priv = - PURPLE_IMAGE_GET_PRIVATE(image); - - if (priv->contents) - g_string_free(priv->contents, TRUE); - g_free(priv->path); - g_free(priv->gen_filename); - g_free(priv->friendly_filename); - - G_OBJECT_CLASS(parent_class)->finalize(obj); -} - -static void -purple_image_get_property(GObject *object, guint par_id, GValue *value, - GParamSpec *pspec) -{ - PurpleImage *image = PURPLE_IMAGE(object); - PurpleImagePrivate *priv = PURPLE_IMAGE_GET_PRIVATE(image); - - switch (par_id) { - case PROP_IS_READY: - g_value_set_boolean(value, priv->is_ready); - break; - case PROP_HAS_FAILED: - g_value_set_boolean(value, priv->has_failed); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec); - break; - } + return purple_image_generate_filename(image); } - -static void -purple_image_class_init(PurpleImageClass *klass) -{ - GObjectClass *gobj_class = G_OBJECT_CLASS(klass); - - parent_class = g_type_class_peek_parent(klass); - - g_type_class_add_private(klass, sizeof(PurpleImagePrivate)); - - gobj_class->finalize = purple_image_finalize; - gobj_class->get_property = purple_image_get_property; - - properties[PROP_IS_READY] = g_param_spec_boolean("is-ready", - "Is ready", "The image is ready to be displayed. Image may " - "change the state to failed in a single case: if it's backed " - "by a file and that file fails to load", - TRUE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - properties[PROP_HAS_FAILED] = g_param_spec_boolean("has-failed", - "Has hailed", "The remote host has failed to send the image", - FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobj_class, PROP_LAST, properties); - - /** - * PurpleImage::failed: - * @image: a image that failed to transfer. - * - * Called when a @image fails to be transferred. It's guaranteed to be - * fired at most once for a particular @image. - */ - signals[SIG_FAILED] = g_signal_new("failed", G_OBJECT_CLASS_TYPE(klass), - 0, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - /** - * PurpleImage::ready: - * @image: a image that became ready. - * - * Called when a @image becames ready to be displayed. It's guaranteed to be - * fired at most once for a particular @image. - */ - signals[SIG_READY] = g_signal_new("ready", G_OBJECT_CLASS_TYPE(klass), - 0, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -} - -GType -purple_image_get_type(void) -{ - static GType type = 0; - - if (G_UNLIKELY(type == 0)) { - static const GTypeInfo info = { - .class_size = sizeof(PurpleImageClass), - .class_init = (GClassInitFunc)purple_image_class_init, - .instance_size = sizeof(PurpleImage), - .instance_init = purple_image_init, - }; - - type = g_type_register_static(G_TYPE_OBJECT, - "PurpleImage", &info, 0); - } - - return type; -} +
--- a/libpurple/image.h Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/image.h Sun May 28 13:26:27 2017 +0300 @@ -19,8 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#ifndef _PURPLE_IMAGE_H_ -#define _PURPLE_IMAGE_H_ +#ifndef PURPLE_IMAGE_H +#define PURPLE_IMAGE_H + /** * SECTION:image * @include:image.h @@ -39,13 +40,13 @@ #include <glib-object.h> -typedef struct _PurpleImage PurpleImage; +typedef struct _PurpleImage PurpleImage; typedef struct _PurpleImageClass PurpleImageClass; #define PURPLE_TYPE_IMAGE (purple_image_get_type()) -#define PURPLE_IMAGE(smiley) (G_TYPE_CHECK_INSTANCE_CAST((smiley), PURPLE_TYPE_IMAGE, PurpleImage)) +#define PURPLE_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_IMAGE, PurpleImage)) #define PURPLE_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_IMAGE, PurpleImageClass)) -#define PURPLE_IS_IMAGE(smiley) (G_TYPE_CHECK_INSTANCE_TYPE((smiley), PURPLE_TYPE_IMAGE)) +#define PURPLE_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_IMAGE)) #define PURPLE_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_IMAGE)) #define PURPLE_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_IMAGE, PurpleImageClass)) @@ -54,20 +55,12 @@ * * An image data container. */ -struct _PurpleImage -{ +struct _PurpleImage { /*< private >*/ GObject parent; }; -/** - * PurpleImageClass: - * - * Base class for #PurpleImage objects. - */ -struct _PurpleImageClass -{ - /*< private >*/ +struct _PurpleImageClass { GObjectClass parent_class; void (*purple_reserved1)(void); @@ -83,13 +76,22 @@ * * Returns: the #GType for an image. */ -GType -purple_image_get_type(void); +GType purple_image_get_type(void); + +/** + * purple_image_new_from_bytes: + * @bytes: (transfer none) A #GBytes containing the raw image data. + * + * Loads a raw image data as a new #PurpleImage object. + * + * Returns: the new #PurpleImage. + */ +PurpleImage *purple_image_new_from_bytes(GBytes *bytes); /** * purple_image_new_from_file: * @path: the path to the image file. - * @be_eager: %TRUE, if file should be loaded now, %FALSE when needed. + * @error: (optional) An optional return address for a #GError * * Loads an image file as a new #PurpleImage object. The @path must exists, be * readable and should point to a valid image file. If you don't set @be_eager @@ -98,8 +100,7 @@ * * Returns: the new #PurpleImage. */ -PurpleImage * -purple_image_new_from_file(const gchar *path, gboolean be_eager); +PurpleImage *purple_image_new_from_file(const gchar *path, GError **error); /** * purple_image_new_from_data: @@ -113,8 +114,21 @@ * * Returns: the new #PurpleImage. */ -PurpleImage * -purple_image_new_from_data(gpointer data, gsize length); +PurpleImage *purple_image_new_from_data(const guint8 *data, gsize length); + +/** + * purple_image_new_take_data: + * @data: (transfer full) the pointer to the image data buffer. + * @length: the length of @data. + * + * Creates a new #PurpleImage object with contents of @data buffer. + * + * The @data buffer is owned by #PurpleImage object, so you might want + * to #g_memdup it first. + * + * Returns: the new #PurpleImage. + */ +PurpleImage *purple_image_new_take_data(guint8 *data, gsize length); /** * purple_image_save: @@ -125,8 +139,18 @@ * * Returns: %TRUE if succeeded, %FALSE otherwise. */ -gboolean -purple_image_save(PurpleImage *image, const gchar *path); +gboolean purple_image_save(PurpleImage *image, const gchar *path); + +/** + * purple_image_get_contents: + * @image: The #PurpleImage. + * + * Returns a new reference to the #GBytes that contains the image data. + * + * Returns: (transfer full): A #GBytes containing the image data. + */ +GBytes *purple_image_get_contents(const PurpleImage *image); + /** * purple_image_get_path: @@ -137,46 +161,17 @@ * * Returns: the physical path of the @image, or %NULL. */ -const gchar * -purple_image_get_path(PurpleImage *image); +const gchar *purple_image_get_path(PurpleImage *image); /** - * purple_image_is_ready: - * @image: the image. - * - * Checks, if the @image data is ready to be displayed. Remote image data may - * not be accessible at the moment, so you should check it before using - * #purple_image_get_data. If the image is not ready yet, you may wait for - * #PurpleImage::ready signal. - * - * Returns: %TRUE, if the @image is ready. - */ -gboolean -purple_image_is_ready(PurpleImage *image); - -/** - * purple_image_has_failed: - * @image: the image. - * - * Checks, if the @image has failed to load its data. It can be caused either by - * a remote failure (and #purple_image_transfer_failed call) or local file being - * removed (see #purple_image_new_from_file). - * - * Returns: %TRUE, if the @image has failed to load. - */ -gboolean -purple_image_has_failed(PurpleImage *image); - -/** - * purple_image_get_size: + * purple_image_get_data_size: * @image: the image. * * Returns the size of @image's data. * * Returns: the size of data, or 0 in case of failure. */ -gsize -purple_image_get_size(PurpleImage *image); +gsize purple_image_get_data_size(PurpleImage *image); /** * purple_image_get_data: @@ -186,8 +181,7 @@ * * Returns: (transfer none): the @image data. */ -gconstpointer -purple_image_get_data(PurpleImage *image); +gconstpointer purple_image_get_data(PurpleImage *image); /** * purple_image_get_extension: @@ -197,8 +191,7 @@ * * Returns: (transfer none): the file extension suitable for @image format. */ -const gchar * -purple_image_get_extension(PurpleImage *image); +const gchar *purple_image_get_extension(PurpleImage *image); /** * purple_image_get_mimetype: @@ -208,8 +201,7 @@ * * Returns: (transfer none): the mime-type suitable for @image format. */ -const gchar * -purple_image_get_mimetype(PurpleImage *image); +const gchar *purple_image_get_mimetype(PurpleImage *image); /** * purple_image_generate_filename: @@ -221,8 +213,7 @@ * * Returns: (transfer none): the generated file name. */ -const gchar * -purple_image_generate_filename(PurpleImage *image); +const gchar *purple_image_generate_filename(PurpleImage *image); /** * purple_image_set_friendly_filename: @@ -236,8 +227,7 @@ * The provided @filename may either be a full path, or contain * filesystem-unfriendly characters, because it will be reformatted. */ -void -purple_image_set_friendly_filename(PurpleImage *image, const gchar *filename); +void purple_image_set_friendly_filename(PurpleImage *image, const gchar *filename); /** * purple_image_get_friendly_filename: @@ -252,54 +242,8 @@ * * Returns: (transfer none): the friendly filename. */ -const gchar * -purple_image_get_friendly_filename(PurpleImage *image); - -/** - * purple_image_transfer_new: - * - * Creates a new remote image, with a possibility to load data with - * #purple_image_transfer_write and #purple_image_transfer_close. In case of - * failure, you should call #urple_image_transfer_failed. - * - * Returns: the new image object. - */ -PurpleImage * -purple_image_transfer_new(void); - -/** - * purple_image_transfer_write: - * @image: the image. - * @data: the incoming data buffer. - * @length: the length of @data. - * - * Adds a chunk of data to the internal receive buffer. Called when receiving - * a remote file. - */ -void -purple_image_transfer_write(PurpleImage *image, gconstpointer data, - gsize length); - -/** - * purple_image_transfer_close: - * @image: the image. - * - * Marks a remote @image as ready to be displayed. Called when finishing - * transfer of remote file. You may call this only once for a certain @image. - */ -void -purple_image_transfer_close(PurpleImage *image); - -/** - * purple_image_transfer_failed: - * @image: the image. - * - * Marks a remote @image as failed to transfer. Called on error in remote file - * transfer. You may call this only once for a certain @image. - */ -void -purple_image_transfer_failed(PurpleImage *image); +const gchar *purple_image_get_friendly_filename(PurpleImage *image); G_END_DECLS -#endif /* _PURPLE_IMAGE_H_ */ +#endif /* PURPLE_IMAGE_H */
--- a/libpurple/log.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/log.c Sun May 28 13:26:27 2017 +0300 @@ -845,7 +845,7 @@ } image_data = purple_image_get_data(image); - image_byte_count = purple_image_get_size(image); + image_byte_count = purple_image_get_data_size(image); dir = purple_log_get_log_dir(log->type, log->name, log->account); new_filename = purple_image_generate_filename(image);
--- a/libpurple/protocols/bonjour/mdns_common.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/bonjour/mdns_common.c Sun May 28 13:26:27 2017 +0300 @@ -186,7 +186,7 @@ gsize avatar_len; avatar_data = purple_image_get_data(img); - avatar_len = purple_image_get_size(img); + avatar_len = purple_image_get_data_size(img); if (_mdns_set_buddy_icon_data(data, avatar_data, avatar_len)) { g_free(data->phsh);
--- a/libpurple/protocols/gg/avatar.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/gg/avatar.c Sun May 28 13:26:27 2017 +0300 @@ -354,7 +354,7 @@ own_data->img = NULL; img_data = purple_base64_encode(purple_image_get_data(img), - purple_image_get_size(img)); + purple_image_get_data_size(img)); img_data_e = g_uri_escape_string(img_data, NULL, FALSE); g_free(img_data); request_data = g_strdup_printf("uin=%d&photo=%s", uin, img_data_e);
--- a/libpurple/protocols/gg/image-prpl.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/gg/image-prpl.c Sun May 28 13:26:27 2017 +0300 @@ -104,7 +104,7 @@ g_return_val_if_fail(image, GGP_IMAGE_PREPARE_FAILURE); - image_size = purple_image_get_size(image); + image_size = purple_image_get_data_size(image); if (image_size > GGP_IMAGE_SIZE_MAX) { purple_debug_warning("gg", "ggp_image_prepare: image " @@ -153,12 +153,13 @@ image_reply->crc32, image_reply->size, image_reply->filename, id); + img = purple_image_new_from_data( + (const guint8 *)image_reply->image, + image_reply->size + ); purple_image_set_friendly_filename(img, image_reply->filename); - purple_image_transfer_write(img, - g_memdup(image_reply->image, image_reply->size), - image_reply->size); - purple_image_transfer_close(img); + g_hash_table_insert(sdata->recv_images, &id, img); } void ggp_image_send(PurpleConnection *gc, @@ -205,7 +206,7 @@ gg_image_reply(accdata->session, image_request->sender, gg_filename, purple_image_get_data(sent_image->image), - purple_image_get_size(sent_image->image)); + purple_image_get_data_size(sent_image->image)); g_free(gg_filename); conv = purple_conversations_find_with_account( @@ -247,8 +248,7 @@ } - img = purple_image_transfer_new(); - g_hash_table_insert(sdata->recv_images, ggp_uint64dup(id), img); + g_hash_table_insert(sdata->recv_images, ggp_uint64dup(id), NULL); purple_debug_info("gg", "ggp_image_request: requesting image " GGP_IMAGE_ID_FORMAT, id);
--- a/libpurple/protocols/jabber/buddy.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/jabber/buddy.c Sun May 28 13:26:27 2017 +0300 @@ -474,7 +474,9 @@ if (image != NULL) { js->initial_avatar_hash = jabber_calculate_data_hash( purple_image_get_data(image), - purple_image_get_size(image), "sha1"); + purple_image_get_data_size(image), + "sha1" + ); g_object_unref(image); } else { js->initial_avatar_hash = NULL; @@ -514,7 +516,7 @@ } avatar_data = purple_image_get_data(img); - avatar_len = purple_image_get_size(img); + avatar_len = purple_image_get_data_size(img); /* Get rid of an old PHOTO if one exists. * TODO: This may want to be modified to remove all old PHOTO * children, at the moment some people have managed to get
--- a/libpurple/protocols/jabber/jabber.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/jabber/jabber.c Sun May 28 13:26:27 2017 +0300 @@ -1137,7 +1137,9 @@ if (image != NULL) { js->initial_avatar_hash = jabber_calculate_data_hash( purple_image_get_data(image), - purple_image_get_size(image), "sha1"); + purple_image_get_data_size(image), + "sha1" + ); g_object_unref(image); }
--- a/libpurple/protocols/jabber/message.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/jabber/message.c Sun May 28 13:26:27 2017 +0300 @@ -41,6 +41,11 @@ #include <string.h> +typedef struct { + PurpleConversation *conv; + gchar *shortcut; +} JabberMessageRemoteSmileyAddData; + void jabber_message_free(JabberMessage *jm) { g_free(jm->from); @@ -487,63 +492,75 @@ } static void -jabber_message_remote_smiley_got(JabberData *data, gchar *alt, gpointer _smiley) -{ - PurpleSmiley *smiley = _smiley; - PurpleImage *image = purple_smiley_get_image(smiley); +jabber_message_remote_smiley_got(JabberData *jdata, gchar *alt, gpointer d) { + JabberMessageRemoteSmileyAddData *data = (JabberMessageRemoteSmileyAddData *)d; - g_free(alt); /* we really don't need it */ + if (jdata) { + PurpleSmiley *smiley = NULL; - if (data) { purple_debug_info("jabber", "smiley data retrieved successfully"); - purple_image_transfer_write(image, jabber_data_get_data(data), - jabber_data_get_size(data)); - purple_image_transfer_close(image); + + smiley = purple_smiley_new_from_data( + data->shortcut, + jabber_data_get_data(jdata), + jabber_data_get_size(jdata) + ); + + purple_conversation_add_smiley(data->conv, smiley); + + g_object_unref(G_OBJECT(smiley)); } else { purple_debug_error("jabber", "failed retrieving smiley data"); - purple_image_transfer_failed(image); } - g_object_unref(smiley); + g_object_unref(G_OBJECT(data->conv)); + g_free(data->shortcut); + g_slice_free(JabberMessageRemoteSmileyAddData, data); } static void jabber_message_remote_smiley_add(JabberStream *js, PurpleConversation *conv, const gchar *from, const gchar *shortcut, const gchar *cid) { - PurpleSmiley *smiley; - const JabberData *jdata; + PurpleSmiley *smiley = NULL; + const JabberData *jdata = NULL; purple_debug_misc("jabber", "about to add remote smiley %s to the conv", shortcut); - smiley = purple_conversation_add_remote_smiley(conv, shortcut); - if (!smiley) { + smiley = purple_conversation_get_smiley(conv, shortcut); + if(PURPLE_IS_SMILEY(smiley)) { purple_debug_misc("jabber", "smiley was already present"); return; } /* TODO: cache lookup by "cid" */ - jdata = jabber_data_find_remote_by_cid(js, from, cid); if (jdata) { - PurpleImage *image = purple_smiley_get_image(smiley); - purple_debug_info("jabber", "smiley data is already known"); - purple_image_transfer_write(image, jabber_data_get_data(jdata), - jabber_data_get_size(jdata)); - purple_image_transfer_close(image); + smiley = purple_smiley_new_from_data( + shortcut, + jabber_data_get_data(jdata), + jabber_data_get_size(jdata) + ); + + purple_conversation_add_smiley(conv, smiley); + + g_object_unref(G_OBJECT(smiley)); } else { - gchar *alt = g_strdup(shortcut); /* it it really necessary? */ + JabberMessageRemoteSmileyAddData *data = NULL; + + data = g_slice_new(JabberMessageRemoteSmileyAddData); + data->conv = g_object_ref(G_OBJECT(conv)); + data->shortcut = g_strdup(shortcut); purple_debug_info("jabber", "smiley data is unknown, " "need to request it"); - g_object_ref(smiley); - jabber_data_request(js, cid, from, alt, FALSE, - jabber_message_remote_smiley_got, smiley); + jabber_data_request(js, cid, from, NULL, FALSE, + jabber_message_remote_smiley_got, data); } } @@ -914,19 +931,11 @@ for (it = found_smileys; it; it = it_next) { PurpleSmiley *smiley = it->data; - PurpleImage *smiley_image; gboolean valid = TRUE; it_next = g_list_next(it); - smiley_image = purple_smiley_get_image(smiley); - if (!smiley_image) { - valid = FALSE; - purple_debug_warning("jabber", "broken smiley %s", - purple_smiley_get_shortcut(smiley)); - } else if (purple_image_get_size(smiley_image) > - JABBER_DATA_MAX_SIZE) - { + if (purple_image_get_data_size(PURPLE_IMAGE(smiley)) > JABBER_DATA_MAX_SIZE) { has_too_large_smiley = TRUE; valid = FALSE; purple_debug_warning("jabber", "Refusing to send " @@ -950,7 +959,6 @@ for (it = found_smileys; it; it = g_list_next(it)) { PurpleSmiley *smiley = it->data; - PurpleImage *smiley_image; const gchar *shortcut = purple_smiley_get_shortcut(smiley); const gchar *mimetype; JabberData *jdata; @@ -959,10 +967,7 @@ if (jabber_data_find_local_by_alt(shortcut)) continue; - smiley_image = purple_smiley_get_image(smiley); - g_assert(smiley_image != NULL); - - mimetype = purple_image_get_mimetype(smiley_image); + mimetype = purple_image_get_mimetype(PURPLE_IMAGE(smiley)); if (!mimetype) { purple_debug_error("jabber", "unknown mime type for image"); @@ -970,8 +975,8 @@ } jdata = jabber_data_create_from_data( - purple_image_get_data(smiley_image), - purple_image_get_size(smiley_image), + purple_image_get_data(PURPLE_IMAGE(smiley)), + purple_image_get_data_size(PURPLE_IMAGE(smiley)), mimetype, FALSE, jm->js); purple_debug_info("jabber", "cache local smiley alt=%s, cid=%s",
--- a/libpurple/protocols/jabber/useravatar.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/jabber/useravatar.c Sun May 28 13:26:27 2017 +0300 @@ -130,7 +130,7 @@ } ihdr; } *png = NULL; - if (purple_image_get_size(img) > sizeof(*png)) + if (purple_image_get_data_size(img) > sizeof(*png)) png = purple_image_get_data(img); /* check if the data is a valid png file (well, at least to some extent) */ @@ -156,10 +156,10 @@ /* compute the sha1 hash */ char *hash = jabber_calculate_data_hash( purple_image_get_data(img), - purple_image_get_size(img), "sha1"); + purple_image_get_data_size(img), "sha1"); char *base64avatar = purple_base64_encode( purple_image_get_data(img), - purple_image_get_size(img)); + purple_image_get_data_size(img)); publish = purple_xmlnode_new("publish"); purple_xmlnode_set_attrib(publish, "node", NS_AVATAR_1_1_DATA); @@ -177,7 +177,7 @@ g_free(base64avatar); lengthstring = g_strdup_printf("%" G_GSIZE_FORMAT, - purple_image_get_size(img)); + purple_image_get_data_size(img)); widthstring = g_strdup_printf("%u", width); heightstring = g_strdup_printf("%u", height);
--- a/libpurple/protocols/oscar/family_oservice.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/oscar/family_oservice.c Sun May 28 13:26:27 2017 +0300 @@ -928,7 +928,7 @@ "Uploading icon to icon server\n"); aim_bart_upload(od, purple_image_get_data(img), - purple_image_get_size(img)); + purple_image_get_data_size(img)); g_object_unref(img); } }
--- a/libpurple/protocols/oscar/oscar.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/oscar/oscar.c Sun May 28 13:26:27 2017 +0300 @@ -1422,7 +1422,7 @@ if ((img != NULL) && (args->icbmflags & AIM_IMFLAGS_BUDDYREQ) && !bi->ico_sent && bi->ico_informed) { gconstpointer data = purple_image_get_data(img); - size_t len = purple_image_get_size(img); + size_t len = purple_image_get_data_size(img); purple_debug_info("oscar", "Sending buddy icon to %s (%" G_GSIZE_FORMAT " bytes)\n", userinfo->bn, len); @@ -2546,7 +2546,7 @@ purple_debug_info("oscar", "Uploading icon to icon server"); aim_bart_upload(od, purple_image_get_data(img), - purple_image_get_size(img)); + purple_image_get_data_size(img)); g_object_unref(img); } od->set_icon = FALSE; @@ -3057,7 +3057,7 @@ /* ... if it refers to a valid purple image ... */ if (image) { /* ... append the message from start to the tag ... */ - unsigned long size = purple_image_get_size(image); + unsigned long size = purple_image_get_data_size(image); const gchar *filename = purple_image_get_friendly_filename(image); gconstpointer imgdata = purple_image_get_data(image); @@ -3205,7 +3205,7 @@ img = purple_buddy_icons_find_account_icon(account); if (img) { gconstpointer data = purple_image_get_data(img); - args.iconlen = purple_image_get_size(img); + args.iconlen = purple_image_get_data_size(img); args.iconsum = aimutil_iconsum(data, args.iconlen); args.iconstamp = purple_buddy_icons_get_account_icon_timestamp(account); @@ -5241,7 +5241,7 @@ PurpleHash *hash; guchar md5[16]; gconstpointer data = purple_image_get_data(img); - size_t len = purple_image_get_size(img); + size_t len = purple_image_get_data_size(img); hash = purple_md5_hash_new(); purple_hash_append(hash, data, len);
--- a/libpurple/protocols/sametime/sametime.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/sametime/sametime.c Sun May 28 13:26:27 2017 +0300 @@ -3878,7 +3878,7 @@ /* obtain and base64 encode the image data, and put it in the mime part */ - size = purple_image_get_size(img); + size = purple_image_get_data_size(img); data = purple_base64_encode(purple_image_get_data(img), size); purple_mime_part_set_data(part, data); g_free(data);
--- a/libpurple/protocols/silc/buddy.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/silc/buddy.c Sun May 28 13:26:27 2017 +0300 @@ -1751,7 +1751,7 @@ silc_mime_add_field(mime, "Content-Type", type); silc_mime_add_data(mime, purple_image_get_data(img), - purple_image_get_size(img)); + purple_image_get_data_size(img)); silc_client_attribute_add(client, conn, SILC_ATTRIBUTE_USER_ICON, mime, sizeof(*mime));
--- a/libpurple/protocols/silc/util.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/protocols/silc/util.c Sun May 28 13:26:27 2017 +0300 @@ -623,7 +623,7 @@ if (uri) image = purple_image_store_get_from_uri(uri); if (uri) { - unsigned long imglen = purple_image_get_size(image); + unsigned long imglen = purple_image_get_data_size(image); gconstpointer img = purple_image_get_data(image); const gchar *type;
--- a/libpurple/smiley-custom.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/smiley-custom.c Sun May 28 13:26:27 2017 +0300 @@ -1,4 +1,4 @@ -/* purpleOB +/* purple * * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this @@ -133,7 +133,7 @@ purple_xmlnode_set_attrib(smiley_node, "shortcut", purple_smiley_get_shortcut(smiley)); basename = g_path_get_basename(purple_image_get_path( - purple_smiley_get_image(smiley))); + PURPLE_IMAGE(smiley))); purple_xmlnode_set_attrib(smiley_node, "filename", basename); g_free(basename); } @@ -175,7 +175,7 @@ return g_compute_checksum_for_data(G_CHECKSUM_SHA1, purple_image_get_data(img), - purple_image_get_size(img)); + purple_image_get_data_size(img)); } @@ -262,14 +262,13 @@ g_object_ref(smiley); purple_smiley_list_remove(smileys_list, smiley); - path = purple_image_get_path(purple_smiley_get_image(smiley)); + path = purple_image_get_path(PURPLE_IMAGE(smiley)); other_smileys = purple_smiley_list_get_unique(smileys_list); is_unique = TRUE; for (it = other_smileys; it; it = g_list_next(it)) { PurpleSmiley *other = it->data; - const gchar *other_path = purple_image_get_path( - purple_smiley_get_image(other)); + const gchar *other_path = purple_image_get_path(PURPLE_IMAGE(other)); if (g_strcmp0(other_path, path) == 0) { is_unique = FALSE; break;
--- a/libpurple/smiley-list.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/smiley-list.c Sun May 28 13:26:27 2017 +0300 @@ -47,9 +47,106 @@ PROP_LAST }; -static GObjectClass *parent_class; static GParamSpec *properties[PROP_LAST]; +/******************************************************************************* + * Object stuff + ******************************************************************************/ +G_DEFINE_TYPE_WITH_PRIVATE(PurpleSmileyList, purple_smiley_list, G_TYPE_OBJECT); + +static void +purple_smiley_list_init(PurpleSmileyList *list) { + PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); + + priv->trie = purple_trie_new(); + priv->path_map = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); + priv->shortcut_map = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); + + PURPLE_DBUS_REGISTER_POINTER(list, PurpleSmileyList); +} + +static void +purple_smiley_list_finalize(GObject *obj) { + PurpleSmileyList *sl = PURPLE_SMILEY_LIST(obj); + PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl); + GList *it; + + g_object_unref(priv->trie); + g_hash_table_destroy(priv->path_map); + g_hash_table_destroy(priv->shortcut_map); + + for (it = priv->smileys; it; it = g_list_next(it)) { + PurpleSmiley *smiley = it->data; + g_object_set_data(G_OBJECT(smiley), "purple-smiley-list", NULL); + g_object_set_data(G_OBJECT(smiley), "purple-smiley-list-elem", NULL); + g_object_unref(smiley); + } + g_list_free(priv->smileys); + + PURPLE_DBUS_UNREGISTER_POINTER(sl); + + G_OBJECT_CLASS(purple_smiley_list_parent_class)->finalize(obj); +} + +static void +purple_smiley_list_get_property(GObject *obj, guint param_id, GValue *value, + GParamSpec *pspec) +{ + PurpleSmileyList *sl = PURPLE_SMILEY_LIST(obj); + PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl); + + switch (param_id) { + case PROP_DROP_FAILED_REMOTES: + g_value_set_boolean(value, priv->drop_failed_remotes); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +purple_smiley_list_set_property(GObject *obj, guint param_id, + const GValue *value, GParamSpec *pspec) +{ + PurpleSmileyList *sl = PURPLE_SMILEY_LIST(obj); + PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl); + + switch (param_id) { + case PROP_DROP_FAILED_REMOTES: + priv->drop_failed_remotes = g_value_get_boolean(value); + /* XXX: we could scan for remote smiley's on our list + * and change the setting, but we don't care that much. + */ + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +purple_smiley_list_class_init(PurpleSmileyListClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + obj_class->get_property = purple_smiley_list_get_property; + obj_class->set_property = purple_smiley_list_set_property; + obj_class->finalize = purple_smiley_list_finalize; + + properties[PROP_DROP_FAILED_REMOTES] = g_param_spec_boolean( + "drop-failed-remotes", "Drop failed PurpleRemoteSmileys", + "Watch added remote smileys and remove them from the list, " + "if they change their state to failed", FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, PROP_LAST, properties); +} + +/****************************************************************************** + * Helpers + *****************************************************************************/ static void _list_append2(GList **head_p, GList **tail_p, gpointer data) { @@ -89,40 +186,20 @@ static const gchar * smiley_get_uniqid(PurpleSmiley *smiley) { - return purple_image_get_path(purple_smiley_get_image(smiley)); + return purple_image_get_path(PURPLE_IMAGE(smiley)); } /******************************************************************************* * API implementation ******************************************************************************/ - PurpleSmileyList * -purple_smiley_list_new(void) -{ +purple_smiley_list_new(void) { return g_object_new(PURPLE_TYPE_SMILEY_LIST, NULL); } -static void -remote_smiley_failed(PurpleImage *smiley_img, gpointer _list) -{ - PurpleSmileyList *list = _list; - PurpleSmiley *smiley; - - smiley = g_object_get_data(G_OBJECT(smiley_img), - "purple-smiley-list-smiley"); - - purple_debug_info("smiley-list", "remote smiley '%s' has failed, " - "removing it from the list...", - purple_smiley_get_shortcut(smiley)); - - purple_smiley_list_remove(list, smiley); -} - gboolean -purple_smiley_list_add(PurpleSmileyList *list, PurpleSmiley *smiley) -{ +purple_smiley_list_add(PurpleSmileyList *list, PurpleSmiley *smiley) { PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); - PurpleImage *smiley_img; const gchar *smiley_path; gboolean succ; gchar *shortcut_escaped; @@ -168,14 +245,6 @@ g_hash_table_insert(priv->shortcut_map, g_strdup(shortcut), smiley); - smiley_img = purple_smiley_get_image(smiley); - if (priv->drop_failed_remotes && !purple_image_is_ready(smiley_img)) { - g_object_set_data(G_OBJECT(smiley_img), - "purple-smiley-list-smiley", smiley); - g_signal_connect_object(smiley_img, "failed", - G_CALLBACK(remote_smiley_failed), list, 0); - } - smiley_path = smiley_get_uniqid(smiley); /* TODO: add to the table, when the smiley sets the path */ @@ -191,8 +260,7 @@ } void -purple_smiley_list_remove(PurpleSmileyList *list, PurpleSmiley *smiley) -{ +purple_smiley_list_remove(PurpleSmileyList *list, PurpleSmiley *smiley) { PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); GList *list_elem, *it; const gchar *shortcut, *path; @@ -239,8 +307,7 @@ } gboolean -purple_smiley_list_is_empty(PurpleSmileyList *list) -{ +purple_smiley_list_is_empty(const PurpleSmileyList *list) { PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); g_return_val_if_fail(priv != NULL, TRUE); @@ -250,7 +317,7 @@ PurpleSmiley * purple_smiley_list_get_by_shortcut(PurpleSmileyList *list, - const gchar *shortcut) + const gchar *shortcut) { PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); @@ -260,8 +327,7 @@ } PurpleTrie * -purple_smiley_list_get_trie(PurpleSmileyList *list) -{ +purple_smiley_list_get_trie(PurpleSmileyList *list) { PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); g_return_val_if_fail(priv != NULL, NULL); @@ -270,8 +336,7 @@ } GList * -purple_smiley_list_get_unique(PurpleSmileyList *list) -{ +purple_smiley_list_get_unique(PurpleSmileyList *list) { GList *unique = NULL, *it; GHashTable *unique_map; PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); @@ -300,134 +365,12 @@ } GList * -purple_smiley_list_get_all(PurpleSmileyList *list) -{ - PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); +purple_smiley_list_get_all(PurpleSmileyList *list) { + PurpleSmileyListPrivate *priv = NULL; - g_return_val_if_fail(priv != NULL, NULL); + g_return_val_if_fail(PURPLE_IS_SMILEY_LIST(list), NULL); + + priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); return g_hash_table_get_values(priv->shortcut_map); } - - -/******************************************************************************* - * Object stuff - ******************************************************************************/ - -static void -purple_smiley_list_init(GTypeInstance *instance, gpointer klass) -{ - PurpleSmileyList *sl = PURPLE_SMILEY_LIST(instance); - PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl); - - priv->trie = purple_trie_new(); - priv->path_map = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, NULL); - priv->shortcut_map = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, NULL); - - PURPLE_DBUS_REGISTER_POINTER(sl, PurpleSmileyList); -} - -static void -purple_smiley_list_finalize(GObject *obj) -{ - PurpleSmileyList *sl = PURPLE_SMILEY_LIST(obj); - PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl); - GList *it; - - g_object_unref(priv->trie); - g_hash_table_destroy(priv->path_map); - g_hash_table_destroy(priv->shortcut_map); - - for (it = priv->smileys; it; it = g_list_next(it)) { - PurpleSmiley *smiley = it->data; - g_object_set_data(G_OBJECT(smiley), "purple-smiley-list", NULL); - g_object_set_data(G_OBJECT(smiley), "purple-smiley-list-elem", NULL); - g_object_unref(smiley); - } - g_list_free(priv->smileys); - - PURPLE_DBUS_UNREGISTER_POINTER(sl); - - G_OBJECT_CLASS(parent_class)->finalize(obj); -} - -static void -purple_smiley_list_get_property(GObject *object, guint par_id, GValue *value, - GParamSpec *pspec) -{ - PurpleSmileyList *sl = PURPLE_SMILEY_LIST(object); - PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl); - - switch (par_id) { - case PROP_DROP_FAILED_REMOTES: - g_value_set_boolean(value, priv->drop_failed_remotes); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec); - break; - } -} - -static void -purple_smiley_list_set_property(GObject *object, guint par_id, const GValue *value, - GParamSpec *pspec) -{ - PurpleSmileyList *sl = PURPLE_SMILEY_LIST(object); - PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(sl); - - switch (par_id) { - case PROP_DROP_FAILED_REMOTES: - priv->drop_failed_remotes = g_value_get_boolean(value); - /* XXX: we could scan for remote smiley's on our list - * and change the setting, but we don't care that much. - */ - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec); - break; - } -} - -static void -purple_smiley_list_class_init(PurpleSmileyListClass *klass) -{ - GObjectClass *gobj_class = G_OBJECT_CLASS(klass); - - parent_class = g_type_class_peek_parent(klass); - - g_type_class_add_private(klass, sizeof(PurpleSmileyListPrivate)); - - gobj_class->get_property = purple_smiley_list_get_property; - gobj_class->set_property = purple_smiley_list_set_property; - gobj_class->finalize = purple_smiley_list_finalize; - - properties[PROP_DROP_FAILED_REMOTES] = g_param_spec_boolean( - "drop-failed-remotes", "Drop failed PurpleRemoteSmileys", - "Watch added remote smileys and remove them from the list, " - "if they change their state to failed", FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobj_class, PROP_LAST, properties); -} - -GType -purple_smiley_list_get_type(void) -{ - static GType type = 0; - - if (G_UNLIKELY(type == 0)) { - static const GTypeInfo info = { - .class_size = sizeof(PurpleSmileyListClass), - .class_init = (GClassInitFunc)purple_smiley_list_class_init, - .instance_size = sizeof(PurpleSmileyList), - .instance_init = purple_smiley_list_init, - }; - - type = g_type_register_static(G_TYPE_OBJECT, - "PurpleSmileyList", &info, 0); - } - - return type; -}
--- a/libpurple/smiley-list.h Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/smiley-list.h Sun May 28 13:26:27 2017 +0300 @@ -19,8 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#ifndef _PURPLE_SMILEY_LIST_H_ -#define _PURPLE_SMILEY_LIST_H_ +#ifndef PURPLE_SMILEY_LIST_H +#define PURPLE_SMILEY_LIST_H + /** * SECTION:smiley-list * @include:smiley-list.h @@ -42,9 +43,9 @@ typedef struct _PurpleSmileyListClass PurpleSmileyListClass; #define PURPLE_TYPE_SMILEY_LIST (purple_smiley_list_get_type()) -#define PURPLE_SMILEY_LIST(smiley) (G_TYPE_CHECK_INSTANCE_CAST((smiley), PURPLE_TYPE_SMILEY_LIST, PurpleSmileyList)) +#define PURPLE_SMILEY_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_SMILEY_LIST, PurpleSmileyList)) #define PURPLE_SMILEY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_SMILEY_LIST, PurpleSmileyListClass)) -#define PURPLE_IS_SMILEY_LIST(smiley) (G_TYPE_CHECK_INSTANCE_TYPE((smiley), PURPLE_TYPE_SMILEY_LIST)) +#define PURPLE_IS_SMILEY_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_SMILEY_LIST)) #define PURPLE_IS_SMILEY_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_SMILEY_LIST)) #define PURPLE_SMILEY_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_SMILEY_LIST, PurpleSmileyListClass)) @@ -53,19 +54,12 @@ * * A container for #PurpleSmiley's. */ -struct _PurpleSmileyList -{ +struct _PurpleSmileyList { /*< private >*/ GObject parent; }; -/** - * PurpleSmileyListClass: - * - * Base class for #PurpleSmileyList objects. - */ -struct _PurpleSmileyListClass -{ +struct _PurpleSmileyListClass { /*< private >*/ GObjectClass parent_class; @@ -82,8 +76,7 @@ * * Returns: the #GType for a smiley list. */ -GType -purple_smiley_list_get_type(void); +GType purple_smiley_list_get_type(void); /** * purple_smiley_list_new: @@ -96,8 +89,7 @@ * * Returns: newly created #PurpleSmileyList. */ -PurpleSmileyList * -purple_smiley_list_new(void); +PurpleSmileyList *purple_smiley_list_new(void); /** * purple_smiley_list_add: @@ -112,8 +104,7 @@ * * Returns: %TRUE if the @smiley was successfully added to the list. */ -gboolean -purple_smiley_list_add(PurpleSmileyList *list, PurpleSmiley *smiley); +gboolean purple_smiley_list_add(PurpleSmileyList *list, PurpleSmiley *smiley); /** * purple_smiley_list_remove: @@ -123,8 +114,7 @@ * Removes a @smiley from the @list. If @smiley's reference count drops to zero, * it's destroyed. */ -void -purple_smiley_list_remove(PurpleSmileyList *list, PurpleSmiley *smiley); +void purple_smiley_list_remove(PurpleSmileyList *list, PurpleSmiley *smiley); /** * purple_smiley_list_is_empty: @@ -134,8 +124,7 @@ * * Returns: %TRUE if the @list is empty, %FALSE otherwise. */ -gboolean -purple_smiley_list_is_empty(PurpleSmileyList *list); +gboolean purple_smiley_list_is_empty(const PurpleSmileyList *list); /** * purple_smiley_list_get_by_shortcut: @@ -146,9 +135,7 @@ * * Returns: a #PurpleSmiley if the smiley was found, %NULL otherwise. */ -PurpleSmiley * -purple_smiley_list_get_by_shortcut(PurpleSmileyList *list, - const gchar *shortcut); +PurpleSmiley *purple_smiley_list_get_by_shortcut(PurpleSmileyList *list, const gchar *shortcut); /** * purple_smiley_list_get_trie: @@ -161,8 +148,7 @@ * * Returns: (transfer none): a #PurpleTrie for contained smileys. */ -PurpleTrie * -purple_smiley_list_get_trie(PurpleSmileyList *list); +PurpleTrie *purple_smiley_list_get_trie(PurpleSmileyList *list); /** * purple_smiley_list_get_unique: @@ -173,8 +159,7 @@ * Returns: (transfer container): the #GList of unique smileys. Use #g_list_free * when done using it. */ -GList * -purple_smiley_list_get_unique(PurpleSmileyList *list_); +GList *purple_smiley_list_get_unique(PurpleSmileyList *list_); /** * purple_smiley_list_get_all: @@ -185,9 +170,8 @@ * Returns: (transfer container): the #GList of smileys. Use #g_list_free * when done using it. */ -GList * -purple_smiley_list_get_all(PurpleSmileyList *list_); +GList *purple_smiley_list_get_all(PurpleSmileyList *list_); G_END_DECLS -#endif /* _PURPLE_SMILEY_H_ */ +#endif /* PURPLE_SMILEY_LIST_H */
--- a/libpurple/smiley.c Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/smiley.c Sun May 28 13:26:27 2017 +0300 @@ -19,20 +19,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include "internal.h" -#include "glibcompat.h" +#include "smiley.h" #include "dbus-maybe.h" -#include "debug.h" -#include "smiley.h" -#include "util.h" -#include "xmlnode.h" #define PURPLE_SMILEY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_SMILEY, PurpleSmileyPrivate)) typedef struct { gchar *shortcut; - PurpleImage *image; } PurpleSmileyPrivate; enum @@ -42,175 +36,169 @@ PROP_LAST }; -static GObjectClass *parent_class; static GParamSpec *properties[PROP_LAST]; /******************************************************************************* - * API implementation + * Helpers + ******************************************************************************/ +static void +_purple_smiley_set_shortcut(PurpleSmiley *smiley, const gchar *shortcut) { + PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley); + + g_free(priv->shortcut); + + priv->shortcut = g_strdup(shortcut); + + g_object_notify(G_OBJECT(smiley), "shortcut"); +} + +/******************************************************************************* + * Object stuff ******************************************************************************/ +G_DEFINE_TYPE_WITH_PRIVATE(PurpleSmiley, purple_smiley, PURPLE_TYPE_IMAGE); +static void +purple_smiley_init(PurpleSmiley *smiley) { + PURPLE_DBUS_REGISTER_POINTER(smiley, PurpleSmiley); +} + +static void +purple_smiley_finalize(GObject *obj) { + PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(obj); + + g_free(priv->shortcut); + + PURPLE_DBUS_UNREGISTER_POINTER(smiley); + + G_OBJECT_CLASS(purple_smiley_parent_class)->finalize(obj); +} + +static void +purple_smiley_get_property(GObject *obj, guint param_id, GValue *value, + GParamSpec *pspec) +{ + PurpleSmiley *smiley = PURPLE_SMILEY(obj); + + switch (param_id) { + case PROP_SHORTCUT: + g_value_set_string(value, purple_smiley_get_shortcut(smiley)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +purple_smiley_set_property(GObject *obj, guint param_id, const GValue *value, + GParamSpec *pspec) +{ + PurpleSmiley *smiley = PURPLE_SMILEY(obj); + + switch (param_id) { + case PROP_SHORTCUT: + _purple_smiley_set_shortcut(smiley, g_value_get_string(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +purple_smiley_class_init(PurpleSmileyClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + obj_class->get_property = purple_smiley_get_property; + obj_class->set_property = purple_smiley_set_property; + obj_class->finalize = purple_smiley_finalize; + + properties[PROP_SHORTCUT] = g_param_spec_string( + "shortcut", + "Shortcut", + "A non-escaped textual representation of a smiley.", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS + ); + + g_object_class_install_properties(obj_class, PROP_LAST, properties); +} + +/******************************************************************************* + * API + ******************************************************************************/ PurpleSmiley * purple_smiley_new(const gchar *shortcut, const gchar *path) { - PurpleSmiley *smiley; - PurpleSmileyPrivate *priv; + PurpleSmiley *smiley = NULL; + GBytes *bytes = NULL; + gchar *contents = NULL; + gsize length = 0; g_return_val_if_fail(shortcut != NULL, NULL); g_return_val_if_fail(path != NULL, NULL); - smiley = g_object_new(PURPLE_TYPE_SMILEY, - "shortcut", shortcut, - NULL); - priv = PURPLE_SMILEY_GET_PRIVATE(smiley); - - priv->image = purple_image_new_from_file(path, FALSE); - if (!priv->image) { - purple_debug_error("smiley", "Couldn't load smiley data "); - g_object_unref(smiley); + if(!g_file_get_contents(path, &contents, &length, NULL)) { return NULL; } + bytes = g_bytes_new_take(contents, length); + + smiley = g_object_new( + PURPLE_TYPE_SMILEY, + "contents", bytes, + "shortcut", shortcut, + NULL + ); + + g_bytes_unref(bytes); + return smiley; } PurpleSmiley * -purple_smiley_new_remote(const gchar *shortcut) +purple_smiley_new_from_data(const gchar *shortcut, + const guint8 *data, + gsize length) { - PurpleSmiley *smiley; - PurpleSmileyPrivate *priv; + PurpleSmiley *smiley = NULL; + GBytes *bytes = NULL; g_return_val_if_fail(shortcut != NULL, NULL); - smiley = g_object_new(PURPLE_TYPE_SMILEY, + bytes = g_bytes_new(data, length); + + smiley = g_object_new( + PURPLE_TYPE_SMILEY, "shortcut", shortcut, - NULL); - priv = PURPLE_SMILEY_GET_PRIVATE(smiley); + "contents", bytes, + NULL + ); - priv->image = purple_image_transfer_new(); + g_bytes_unref(bytes); return smiley; + +} + +PurpleSmiley * +purple_smiley_new_remote(const gchar *shortcut) { + g_return_val_if_fail(shortcut != NULL, NULL); + + return g_object_new( + PURPLE_TYPE_SMILEY, + "shortcut", shortcut, + NULL + ); } const gchar * -purple_smiley_get_shortcut(const PurpleSmiley *smiley) -{ - PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley); +purple_smiley_get_shortcut(const PurpleSmiley *smiley) { + PurpleSmileyPrivate *priv = NULL; - g_return_val_if_fail(priv != NULL, NULL); + g_return_val_if_fail(PURPLE_IS_SMILEY(smiley), NULL); + + priv = PURPLE_SMILEY_GET_PRIVATE(smiley); return priv->shortcut; } - -PurpleImage * -purple_smiley_get_image(PurpleSmiley *smiley) -{ - PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley); - - g_return_val_if_fail(priv != NULL, NULL); - g_return_val_if_fail(priv->image != NULL, NULL); - - return priv->image; -} - - -/******************************************************************************* - * Object stuff - ******************************************************************************/ - -static void -purple_smiley_init(GTypeInstance *instance, gpointer klass) -{ - PurpleSmiley *smiley = PURPLE_SMILEY(instance); - PURPLE_DBUS_REGISTER_POINTER(smiley, PurpleSmiley); -} - -static void -purple_smiley_finalize(GObject *obj) -{ - PurpleSmiley *smiley = PURPLE_SMILEY(obj); - PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley); - - g_free(priv->shortcut); - - if (priv->image) - g_object_unref(priv->image); - - PURPLE_DBUS_UNREGISTER_POINTER(smiley); - - G_OBJECT_CLASS(parent_class)->finalize(obj); -} - -static void -purple_smiley_get_property(GObject *object, guint par_id, GValue *value, - GParamSpec *pspec) -{ - PurpleSmiley *smiley = PURPLE_SMILEY(object); - PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley); - - switch (par_id) { - case PROP_SHORTCUT: - g_value_set_string(value, priv->shortcut); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec); - break; - } -} - -static void -purple_smiley_set_property(GObject *object, guint par_id, const GValue *value, - GParamSpec *pspec) -{ - PurpleSmiley *smiley = PURPLE_SMILEY(object); - PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley); - - switch (par_id) { - case PROP_SHORTCUT: - g_free(priv->shortcut); - priv->shortcut = g_strdup(g_value_get_string(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec); - break; - } -} - -static void -purple_smiley_class_init(PurpleSmileyClass *klass) -{ - GObjectClass *gobj_class = G_OBJECT_CLASS(klass); - - parent_class = g_type_class_peek_parent(klass); - - g_type_class_add_private(klass, sizeof(PurpleSmileyPrivate)); - - gobj_class->get_property = purple_smiley_get_property; - gobj_class->set_property = purple_smiley_set_property; - gobj_class->finalize = purple_smiley_finalize; - - properties[PROP_SHORTCUT] = g_param_spec_string("shortcut", "Shortcut", - "A non-escaped textual representation of a smiley.", NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(gobj_class, PROP_LAST, properties); -} - -GType -purple_smiley_get_type(void) -{ - static GType type = 0; - - if (G_UNLIKELY(type == 0)) { - static const GTypeInfo info = { - .class_size = sizeof(PurpleSmileyClass), - .class_init = (GClassInitFunc)purple_smiley_class_init, - .instance_size = sizeof(PurpleSmiley), - .instance_init = purple_smiley_init, - }; - - type = g_type_register_static(G_TYPE_OBJECT, - "PurpleSmiley", &info, 0); - } - - return type; -}
--- a/libpurple/smiley.h Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/smiley.h Sun May 28 13:26:27 2017 +0300 @@ -19,8 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#ifndef _PURPLE_SMILEY_H_ -#define _PURPLE_SMILEY_H_ +#ifndef PURPLE_SMILEY_H +#define PURPLE_SMILEY_H + /** * SECTION:smiley * @include:smiley.h @@ -45,9 +46,9 @@ typedef struct _PurpleSmileyClass PurpleSmileyClass; #define PURPLE_TYPE_SMILEY (purple_smiley_get_type()) -#define PURPLE_SMILEY(smiley) (G_TYPE_CHECK_INSTANCE_CAST((smiley), PURPLE_TYPE_SMILEY, PurpleSmiley)) +#define PURPLE_SMILEY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_SMILEY, PurpleSmiley)) #define PURPLE_SMILEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_SMILEY, PurpleSmileyClass)) -#define PURPLE_IS_SMILEY(smiley) (G_TYPE_CHECK_INSTANCE_TYPE((smiley), PURPLE_TYPE_SMILEY)) +#define PURPLE_IS_SMILEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_SMILEY)) #define PURPLE_IS_SMILEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_SMILEY)) #define PURPLE_SMILEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_SMILEY, PurpleSmileyClass)) @@ -56,10 +57,9 @@ * * A generic smiley. It can either be a theme smiley, or a custom smiley. */ -struct _PurpleSmiley -{ +struct _PurpleSmiley { /*< private >*/ - GObject parent; + PurpleImage parent; }; /** @@ -67,10 +67,9 @@ * * Base class for #PurpleSmiley objects. */ -struct _PurpleSmileyClass -{ +struct _PurpleSmileyClass { /*< private >*/ - GObjectClass parent_class; + PurpleImageClass parent_class; /*< private >*/ void (*purple_reserved1)(void); @@ -86,8 +85,7 @@ * * Returns: the #GType for a smiley. */ -GType -purple_smiley_get_type(void); +GType purple_smiley_get_type(void); /** * purple_smiley_new: @@ -99,8 +97,19 @@ * * Returns: the new #PurpleSmiley. */ -PurpleSmiley * -purple_smiley_new(const gchar *shortcut, const gchar *path); +PurpleSmiley *purple_smiley_new(const gchar *shortcut, const gchar *path); + +/** + * purple_smiley_new_from_data: + * @shortcut: The smiley shortcut (unescaped). + * @data: The raw data of the image. + * @length: The length of @data in bytes. + * + * Creates new smiley from @data. + * + * Returns: A new #PurpleSmiley. + */ +PurpleSmiley *purple_smiley_new_from_data(const gchar *shortcut, const guint8 *data, gsize length); /** * purple_smiley_new_remote: @@ -112,8 +121,7 @@ * * Returns: the new remote #PurpleSmiley. */ -PurpleSmiley * -purple_smiley_new_remote(const gchar *shortcut); +PurpleSmiley *purple_smiley_new_remote(const gchar *shortcut); /** * purple_smiley_get_shortcut: @@ -124,23 +132,8 @@ * * Returns: the unescaped shortcut. */ -const gchar * -purple_smiley_get_shortcut(const PurpleSmiley *smiley); - -/** - * purple_smiley_get_image: - * @smiley: the smiley. - * - * Returns the image contents for a @smiley. It may not be ready for remote - * smileys, so check it with #purple_image_is_ready. - * - * If you want to save it, increase a ref count for the returned object. - * - * Returns: (transfer none): the image contents for a @smiley. - */ -PurpleImage * -purple_smiley_get_image(PurpleSmiley *smiley); +const gchar *purple_smiley_get_shortcut(const PurpleSmiley *smiley); G_END_DECLS -#endif /* _PURPLE_SMILEY_H_ */ +#endif /* PURPLE_SMILEY_H */
--- a/libpurple/tests/.hgignore Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/tests/.hgignore Sun May 28 13:26:27 2017 +0300 @@ -3,6 +3,8 @@ ^test_sha(1|256)$ ^test_des3?$ ^test_hmac$ +^test_image$ +^test_smiley$ ^test_trie$ ^test_util$ ^test_xmlnode$
--- a/libpurple/tests/Makefile.am Thu Mar 23 19:11:37 2017 +0300 +++ b/libpurple/tests/Makefile.am Sun May 28 13:26:27 2017 +0300 @@ -9,15 +9,16 @@ test_des \ test_des3 \ test_hmac \ + test_image \ test_md4 \ test_md5 \ test_sha1 \ test_sha256 \ + test_smiley \ test_trie \ test_util \ test_xmlnode - test_des_SOURCES=test_des.c test_des_LDADD=$(COMMON_LIBS) @@ -27,6 +28,9 @@ test_hmac_SOURCES=test_hmac.c test_hmac_LDADD=$(COMMON_LIBS) +test_image_SOURCES=test_image.c +test_image_LDADD=$(COMMON_LIBS) + test_md4_SOURCES=test_md4.c test_md4_LDADD=$(COMMON_LIBS) @@ -39,6 +43,9 @@ test_sha256_SOURCES=test_sha256.c test_sha256_LDADD=$(COMMON_LIBS) +test_smiley_SOURCES=test_smiley.c +test_smiley_LDADD=$(COMMON_LIBS) + test_trie_SOURCES=test_trie.c test_trie_LDADD=$(COMMON_LIBS) @@ -51,9 +58,13 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/libpurple \ -I$(top_builddir)/libpurple \ + -DTEST_DATA_DIR=\"$(srcdir)/data\" \ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(GPLUGIN_CFLAGS) \ $(PLUGIN_CFLAGS) \ $(DBUS_CFLAGS) \ $(NSS_CFLAGS) + +EXTRA_DIST = \ + data/test-image.png
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/tests/test_image.c Sun May 28 13:26:27 2017 +0300 @@ -0,0 +1,132 @@ +/* + * Purple + * + * Purple is the legal property of its developers, whose names are too + * numerous to list here. Please refer to the COPYRIGHT file distributed + * with this source distribution + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#include <glib.h> + +#include <purple.h> + +// generated via: +// $ cat test-image.png | hexdump -v -e '1 1 "0x%02x," " "' | xargs -n 8 echo +static const gsize test_image_data_len = 160; +static const guint8 test_image_data[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, + 0x08, 0x02, 0x00, 0x00, 0x00, 0xfd, 0xd4, 0x9a, + 0x73, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, + 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, + 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, + 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xe0, + 0x0a, 0x02, 0x16, 0x30, 0x22, 0x28, 0xa4, 0xc9, + 0xdd, 0x00, 0x00, 0x00, 0x1d, 0x69, 0x54, 0x58, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x64, 0x2e, + 0x65, 0x07, 0x00, 0x00, 0x00, 0x16, 0x49, 0x44, + 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff, 0xff, + 0x3f, 0x03, 0x03, 0x03, 0xe3, 0xb3, 0x4c, 0xb5, + 0x9b, 0x4e, 0x0b, 0x00, 0x2f, 0xa9, 0x06, 0x2f, + 0x8a, 0xd1, 0xc6, 0xb3, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +/****************************************************************************** + * Helpers + *****************************************************************************/ +static void +_test_image(PurpleImage *image, + const guint8 *edata, + gsize elen, + const gchar *ext, + const gchar *mimetype) +{ + GBytes *bytes = NULL; + const guint8 *adata = NULL; + gsize alen; + + g_assert(PURPLE_IS_IMAGE(image)); + + bytes = purple_image_get_contents(image); + adata = g_bytes_get_data(bytes, &alen); + g_assert_cmpmem(adata, alen, edata, elen); + g_bytes_unref(bytes); + + g_assert_cmpstr(purple_image_get_extension(image), ==, ext); + g_assert_cmpstr(purple_image_get_mimetype(image), ==, mimetype); + + g_object_unref(G_OBJECT(image)); +} + +static void +test_image_new_from_data(void) { + PurpleImage *image = purple_image_new_from_data( + test_image_data, + test_image_data_len + ); + + _test_image( + image, + test_image_data, + test_image_data_len, + "png", + "image/png" + ); +} + +static void +test_image_new_from_file(void) { + PurpleImage *image = NULL; + GError *error = NULL; + gchar *path = NULL; + gchar *edata = NULL; + gsize elen; + + path = g_build_filename(TEST_DATA_DIR, "test-image.png", NULL); + image = purple_image_new_from_file(path, &error); + g_assert_no_error(error); + + g_file_get_contents(path, &edata, &elen, &error); + g_free(path); + g_assert_no_error(error); + + _test_image( + image, + (guint8 *)edata, + elen, + "png", + "image/png" + ); +} + +/****************************************************************************** + * Main + *****************************************************************************/ +gint +main(gint argc, gchar **argv) { + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/image/new-from-data", test_image_new_from_data); + g_test_add_func("/image/new-from-file", test_image_new_from_file); + + return g_test_run(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/tests/test_smiley.c Sun May 28 13:26:27 2017 +0300 @@ -0,0 +1,145 @@ +/* + * Purple + * + * Purple is the legal property of its developers, whose names are too + * numerous to list here. Please refer to the COPYRIGHT file distributed + * with this source distribution + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#include <glib.h> + +#include <purple.h> + +// generated via: +// $ cat test-image.png | hexdump -v -e '1 1 "0x%02x," " "' | xargs -n 8 echo +static const gsize test_image_data_len = 160; +static const guint8 test_image_data[] = { + 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, + 0x08, 0x02, 0x00, 0x00, 0x00, 0xfd, 0xd4, 0x9a, + 0x73, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, + 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, + 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, + 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xe0, + 0x0a, 0x02, 0x16, 0x30, 0x22, 0x28, 0xa4, 0xc9, + 0xdd, 0x00, 0x00, 0x00, 0x1d, 0x69, 0x54, 0x58, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x64, 0x2e, + 0x65, 0x07, 0x00, 0x00, 0x00, 0x16, 0x49, 0x44, + 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff, 0xff, + 0x3f, 0x03, 0x03, 0x03, 0xe3, 0xb3, 0x4c, 0xb5, + 0x9b, 0x4e, 0x0b, 0x00, 0x2f, 0xa9, 0x06, 0x2f, + 0x8a, 0xd1, 0xc6, 0xb3, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +/****************************************************************************** + * Helpers + *****************************************************************************/ +static void +_test_smiley(PurpleSmiley *smiley, + const guint8 *edata, + gsize elen, + const gchar *ext, + const gchar *mimetype, + const gchar *shortcut) +{ + GBytes *bytes = NULL; + const guint8 *adata = NULL; + gsize alen; + + g_assert(PURPLE_IS_SMILEY(PURPLE_IMAGE(smiley))); + + bytes = purple_image_get_contents(PURPLE_IMAGE(smiley)); + adata = g_bytes_get_data(bytes, &alen); + g_assert_cmpmem(adata, alen, edata, elen); + g_bytes_unref(bytes); + + g_assert_cmpstr( + purple_image_get_extension(PURPLE_IMAGE(smiley)), + ==, + ext + ); + g_assert_cmpstr( + purple_image_get_mimetype(PURPLE_IMAGE(smiley)), + ==, + mimetype + ); + g_assert_cmpstr(purple_smiley_get_shortcut(smiley), ==, shortcut); + + g_object_unref(G_OBJECT(smiley)); +} + +static void +test_smiley_new_from_data(void) { + PurpleSmiley *smiley = purple_smiley_new_from_data( + ":-X", + test_image_data, + test_image_data_len + ); + + _test_smiley( + smiley, + test_image_data, + test_image_data_len, + "png", + "image/png", + ":-X" + ); +} + +static void +test_smiley_new_from_file(void) { + PurpleSmiley *smiley = NULL; + GError *error = NULL; + gchar *path = NULL; + gchar *edata = NULL; + gsize elen; + + path = g_build_filename(TEST_DATA_DIR, "test-image.png", NULL); + smiley = purple_smiley_new("^_^", path); + g_assert_no_error(error); + + g_file_get_contents(path, &edata, &elen, &error); + g_free(path); + g_assert_no_error(error); + + _test_smiley( + smiley, + (guint8 *)edata, + elen, + "png", + "image/png", + "^_^" + ); +} + +/****************************************************************************** + * Main + *****************************************************************************/ +gint +main(gint argc, gchar **argv) { + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/smiley/new-from-data", test_smiley_new_from_data); + g_test_add_func("/smiley/new-from-file", test_smiley_new_from_file); + + return g_test_run(); +}
--- a/pidgin/gtkaccount.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/gtkaccount.c Sun May 28 13:26:27 2017 +0300 @@ -183,7 +183,7 @@ } if (new_icon_path != NULL) { - dialog->icon_img = purple_image_new_from_file(new_icon_path, TRUE); + dialog->icon_img = purple_image_new_from_file(new_icon_path, NULL); purple_debug_warning("gtkaccount", "data was not necessary"); g_free(data); } else if (data != NULL) { @@ -735,7 +735,7 @@ img = purple_buddy_icons_find_account_icon(dialog->account); if (img) { - len = purple_image_get_size(img); + len = purple_image_get_data_size(img); data = g_memdup(purple_image_get_data(img), len); } set_dialog_icon(dialog, data, len, @@ -1374,7 +1374,7 @@ { if (dialog->icon_img) { - size_t len = purple_image_get_size(dialog->icon_img); + size_t len = purple_image_get_data_size(dialog->icon_img); purple_buddy_icons_set_account_icon(account, g_memdup(purple_image_get_data(dialog->icon_img), len), len); purple_account_set_buddy_icon_path(account, @@ -2133,7 +2133,7 @@ const char *path; path = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon"); if ((path != NULL) && (*path != '\0')) { - img = purple_image_new_from_file(path, TRUE); + img = purple_image_new_from_file(path, NULL); } } } else {
--- a/pidgin/gtkblist.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/gtkblist.c Sun May 28 13:26:27 2017 +0300 @@ -2692,7 +2692,7 @@ if (custom_img) { data = purple_image_get_data(custom_img); - len = purple_image_get_size(custom_img); + len = purple_image_get_data_size(custom_img); } if (data == NULL) { @@ -2715,7 +2715,7 @@ account ? purple_account_get_username(account) : "(no account)", account ? purple_account_get_protocol_id(account) : "(no account)", buddy ? purple_buddy_get_name(buddy) : "(no buddy)", - custom_img ? purple_image_get_size(custom_img) : 0); + custom_img ? purple_image_get_data_size(custom_img) : 0); if (custom_img) g_object_unref(custom_img); return NULL;
--- a/pidgin/gtkconv.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/gtkconv.c Sun May 28 13:26:27 2017 +0300 @@ -4181,7 +4181,7 @@ g_snprintf(filename, sizeof(filename), "%s.png", stock_name); path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", "e2ee", "16", filename, NULL); - image = purple_image_new_from_file(path, FALSE); + image = purple_image_new_from_file(path, NULL); g_free(path); g_hash_table_insert(e2ee_stock, g_strdup(stock_name), image); @@ -6536,14 +6536,12 @@ pidgin_conv_write_smiley(GString *out, PurpleSmiley *smiley, PurpleConversation *conv, gpointer _proto_name) { - PurpleImage *image; gchar *escaped_shortcut; gchar *uri; escaped_shortcut = g_markup_escape_text( purple_smiley_get_shortcut(smiley), -1); - image = purple_smiley_get_image(smiley); - uri = purple_image_store_get_uri(image); + uri = purple_image_store_get_uri(PURPLE_IMAGE(smiley)); g_string_append_printf(out, "<img class=\"emoticon\" alt=\"%s\" title=\"%s\" " @@ -6592,11 +6590,14 @@ full = g_match_info_fetch(info, 0); +#warning fix this +#if 0 if (purple_image_is_ready(image)) { g_string_append(result, full); g_free(full); return FALSE; } +#endif /* search for alt */ alt = strstr(full, "alt=\""); @@ -7859,7 +7860,7 @@ if (custom_img) { /* There is a custom icon for this user */ data = purple_image_get_data(custom_img); - len = purple_image_get_size(custom_img); + len = purple_image_get_data_size(custom_img); } } }
--- a/pidgin/gtksmiley-manager.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/gtksmiley-manager.c Sun May 28 13:26:27 2017 +0300 @@ -163,7 +163,7 @@ if (!filename) return; - image = purple_image_new_from_file(filename, TRUE); + image = purple_image_new_from_file(filename, NULL); if (!image) return; @@ -249,8 +249,7 @@ } if (edit_dialog->new_image == NULL) { - edit_dialog->new_image = - purple_smiley_get_image(edit_dialog->smiley); + edit_dialog->new_image = PURPLE_IMAGE(edit_dialog->smiley); g_return_if_fail(edit_dialog->new_image); } @@ -392,7 +391,7 @@ if (smiley) { edit_dialog->filename = g_strdup(purple_image_get_path( - purple_smiley_get_image(smiley))); + PURPLE_IMAGE(smiley))); gtk_entry_set_text(edit_dialog->shortcut, purple_smiley_get_shortcut(smiley)); } @@ -506,7 +505,7 @@ return; } - image = purple_image_new_from_file(filename, TRUE); + image = purple_image_new_from_file(filename, NULL); if (!image) { purple_debug_warning("gtksmiley-manager", "dropped file is not a valid image"); @@ -587,8 +586,7 @@ smiley_image = g_object_get_data(G_OBJECT(smiley), "pidgin-smiley-manager-list-thumb"); if (smiley_image == NULL) { - smiley_image = pidgin_pixbuf_from_image( - purple_smiley_get_image(smiley)); + smiley_image = pidgin_pixbuf_from_image(PURPLE_IMAGE(smiley)); smiley_image = pidgin_pixbuf_scale_down(smiley_image, 22, 22, GDK_INTERP_BILINEAR, TRUE); g_object_set_data_full(G_OBJECT(smiley),
--- a/pidgin/gtkstatusbox.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/gtkstatusbox.c Sun May 28 13:26:27 2017 +0300 @@ -412,7 +412,7 @@ PurpleImage *img = NULL; if (filename && *filename) - img = purple_image_new_from_file(filename, TRUE); + img = purple_image_new_from_file(filename, NULL); pidgin_status_box_set_buddy_icon(status_box, img); if (img) @@ -1450,7 +1450,7 @@ /* Even if no accounts were processed, load the icon that was set. */ if (filename != NULL) - img = purple_image_new_from_file(filename, TRUE); + img = purple_image_new_from_file(filename, NULL); } pidgin_status_box_set_buddy_icon(box, img); @@ -2191,12 +2191,12 @@ g_signal_connect(G_OBJECT(loader), "size-prepared", G_CALLBACK(pixbuf_size_prepared_cb), NULL); if (!gdk_pixbuf_loader_write(loader, purple_image_get_data(status_box->buddy_icon_img), - purple_image_get_size(status_box->buddy_icon_img), + purple_image_get_data_size(status_box->buddy_icon_img), &error) || error) { purple_debug_warning("gtkstatusbox", "gdk_pixbuf_loader_write() failed with size=%" - G_GSIZE_FORMAT ": %s", purple_image_get_size( + G_GSIZE_FORMAT ": %s", purple_image_get_data_size( status_box->buddy_icon_img), error ? error->message : "(no error message)"); if (error) @@ -2205,7 +2205,7 @@ purple_debug_warning("gtkstatusbox", "gdk_pixbuf_loader_close() failed for image of " "size %" G_GSIZE_FORMAT ": %s", - purple_image_get_size(status_box->buddy_icon_img), + purple_image_get_data_size(status_box->buddy_icon_img), error ? error->message : "(no error message)"); if (error) g_error_free(error);
--- a/pidgin/gtkutils.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/gtkutils.c Sun May 28 13:26:27 2017 +0300 @@ -3077,7 +3077,7 @@ pidgin_pixbuf_from_image(PurpleImage *image) { return pidgin_pixbuf_from_data(purple_image_get_data(image), - purple_image_get_size(image)); + purple_image_get_data_size(image)); } GdkPixbuf *pidgin_pixbuf_new_from_file(const gchar *filename)
--- a/pidgin/gtkwebview.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/gtkwebview.c Sun May 28 13:26:27 2017 +0300 @@ -206,7 +206,7 @@ b64 = purple_base64_encode( purple_image_get_data(img), - purple_image_get_size(img)); + purple_image_get_data_size(img)); type = purple_image_get_mimetype(img); src = g_strdup_printf("data:%s;base64,%s", type, b64); g_free(b64);
--- a/pidgin/gtkwebviewtoolbar.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/gtkwebviewtoolbar.c Sun May 28 13:26:27 2017 +0300 @@ -134,9 +134,14 @@ if (strcmp(str, "inherit") == 0) { return FALSE; - } else { - return gdk_rgba_parse(color, str); } + + if (!gdk_rgba_parse(color, str)) { + return FALSE; + } + + /* FALSE for fully transparent color (same behavior as with "inherit") */ + return color->alpha > 0; } static gchar* @@ -562,7 +567,7 @@ if (filename == NULL) return; - img = purple_image_new_from_file(filename, TRUE); + img = purple_image_new_from_file(filename, NULL); if (!img) { gchar *buf = g_strdup_printf(_("Failed to store image: %s"), @@ -633,15 +638,13 @@ insert_smiley_text(GtkWidget *widget, PidginWebViewToolbar *toolbar) { PurpleSmiley *smiley; - PurpleImage *image; guint image_id; gchar *escaped_smiley, *smiley_html; const gchar *smiley_class; smiley = g_object_get_data(G_OBJECT(widget), "smiley"); smiley_class = g_object_get_data(G_OBJECT(widget), "smiley-class"); - image = purple_smiley_get_image(smiley); - image_id = purple_image_store_add(image); + image_id = purple_image_store_add(PURPLE_IMAGE(smiley)); escaped_smiley = g_markup_escape_text( purple_smiley_get_shortcut(smiley), -1); @@ -694,8 +697,7 @@ continue; } - pixbuf = pidgin_pixbuf_from_image( - purple_smiley_get_image(smiley)); + pixbuf = pidgin_pixbuf_from_image(PURPLE_IMAGE(smiley)); pixbuf = pidgin_pixbuf_scale_down(pixbuf, 24, 24, GDK_INTERP_BILINEAR, TRUE);
--- a/pidgin/plugins/imgupload.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/plugins/imgupload.c Sun May 28 13:26:27 2017 +0300 @@ -122,7 +122,7 @@ /* TODO: make it a plain, multipart/form-data request */ img_data = purple_base64_encode(purple_image_get_data(image), - purple_image_get_size(image)); + purple_image_get_data_size(image)); img_data_e = g_uri_escape_string(img_data, NULL, FALSE); g_free(img_data); req_data = g_strdup_printf("type=base64&image=%s", img_data_e);
--- a/pidgin/plugins/screencap.c Thu Mar 23 19:11:37 2017 +0300 +++ b/pidgin/plugins/screencap.c Sun May 28 13:26:27 2017 +0300 @@ -119,11 +119,11 @@ static gboolean scrncap_pixbuf_to_image_cb(const gchar *buf, gsize count, GError **error, - gpointer _image) + gpointer data) { - PurpleImage *image = PURPLE_IMAGE(_image); + PurpleImage *image = *(PurpleImage **)data; - purple_image_transfer_write(image, buf, count); + image = purple_image_new_from_data(buf, count); return TRUE; } @@ -131,16 +131,12 @@ static PurpleImage * scrncap_pixbuf_to_image(GdkPixbuf *pixbuf) { - PurpleImage *image; + PurpleImage *image = NULL; GError *error = NULL; - image = purple_image_transfer_new(); - - gdk_pixbuf_save_to_callback(pixbuf, scrncap_pixbuf_to_image_cb, image, + gdk_pixbuf_save_to_callback(pixbuf, scrncap_pixbuf_to_image_cb, &image, "png", &error, NULL); - purple_image_transfer_close(image); - if (error != NULL) { purple_debug_error("screencap", "Failed saving an image: %s", error->message); @@ -149,14 +145,8 @@ return NULL; } - if (purple_image_is_ready(image)) { - if (purple_image_get_extension(image) == NULL) { - purple_debug_error("screencap", "Invalid image format"); - g_object_unref(image); - return NULL; - } - } else { - purple_debug_error("screencap", "Image is not ready"); + if (purple_image_get_extension(image) == NULL) { + purple_debug_error("screencap", "Invalid image format"); g_object_unref(image); return NULL; }