pidgin.custom_smiley: f78bb7f5: Introduce API for GtkIMHtmlSmiley. Use t...
sadrul at pidgin.im
sadrul at pidgin.im
Mon Mar 17 20:46:07 EDT 2008
-----------------------------------------------------------------
Revision: f78bb7f531a4f3868b35c70ede0cd791f4a23dac
Ancestor: ed4d097cef855179282cf0b8a45f6e670d407c15
Author: sadrul at pidgin.im
Date: 2008-03-18T00:47:52
Branch: im.pidgin.pidgin.custom_smiley
URL: http://d.pidgin.im/viewmtn/revision/info/f78bb7f531a4f3868b35c70ede0cd791f4a23dac
Modified files:
ChangeLog.API pidgin/gtkconv.c pidgin/gtkimhtml.c
pidgin/gtkimhtml.h pidgin/gtksmiley.c pidgin/gtkthemes.c
ChangeLog:
Introduce API for GtkIMHtmlSmiley. Use this to prevent leaking remote custom emoticons.
-------------- next part --------------
============================================================
--- ChangeLog.API 543e3539ffc2e562e2adfbc13e49f66fbc428bea
+++ ChangeLog.API e4f0882c1ee23208e43454e0f67103154e30442d
@@ -1,5 +1,11 @@ Pidgin and Finch: The Pimpin' Penguin IM
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
+version 2.5.0 (??/??/2008):
+ pidgin:
+ Added:
+ * gtk_imhtml_smiley_create, gtk_imhtml_smiley_reload and
+ gtk_imhtml_smiley_destroy to deal with GtkIMHtmlSmiley's.
+
version 2.4.0 (02/29/2008):
libpurple:
Added:
============================================================
--- pidgin/gtkconv.c cced448e12bb995b4cfcb1552a1716b0d9f457b7
+++ pidgin/gtkconv.c efeceb214ebbbc7e809a0a5444867ac5a95c1498
@@ -157,8 +157,6 @@ gboolean pidgin_conv_has_focus(PurpleCon
static void update_typing_message(PidginConversation *gtkconv, const char *message);
static const char *item_factory_translate_func (const char *path, gpointer func_data);
gboolean pidgin_conv_has_focus(PurpleConversation *conv);
-static void pidgin_conv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data);
-static void pidgin_conv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data);
static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
@@ -5985,119 +5983,24 @@ pidgin_conv_has_focus(PurpleConversation
return FALSE;
}
-static void pidgin_conv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data)
-{
- GtkIMHtmlSmiley *smiley;
-
- smiley = (GtkIMHtmlSmiley *)user_data;
- smiley->icon = gdk_pixbuf_loader_get_animation(loader);
-
- if (smiley->icon)
- g_object_ref(G_OBJECT(smiley->icon));
-#ifdef DEBUG_CUSTOM_SMILEY
- purple_debug_info("custom-smiley", "pidgin_conv_custom_smiley_allocated(): got GdkPixbufAnimation %p for smiley '%s'\n", smiley->icon, smiley->smile);
-#endif
-}
-
-static void pidgin_conv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data)
-{
- GtkIMHtmlSmiley *smiley;
- GtkWidget *icon = NULL;
- GtkTextChildAnchor *anchor = NULL;
- GSList *current = NULL;
-
- smiley = (GtkIMHtmlSmiley *)user_data;
- if (!smiley->imhtml) {
-#ifdef DEBUG_CUSTOM_SMILEY
- purple_debug_error("custom-smiley", "pidgin_conv_custom_smiley_closed(): orphan smiley found: %p\n", smiley);
-#endif
- g_object_unref(G_OBJECT(loader));
- smiley->loader = NULL;
- return;
- }
-
- for (current = smiley->anchors; current; current = g_slist_next(current)) {
-
- icon = gtk_image_new_from_animation(smiley->icon);
-
-#ifdef DEBUG_CUSTOM_SMILEY
- purple_debug_info("custom-smiley", "pidgin_conv_custom_smiley_closed(): got GtkImage %p from GtkPixbufAnimation %p for smiley '%s'\n",
- icon, smiley->icon, smiley->smile);
-#endif
- if (icon) {
- GList *wids;
- gtk_widget_show(icon);
-
- anchor = GTK_TEXT_CHILD_ANCHOR(current->data);
- wids = gtk_text_child_anchor_get_widgets(anchor);
-
- g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", purple_unescape_html(smiley->smile), g_free);
- g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley->smile), g_free);
-
- if (smiley->imhtml) {
- if (wids) {
- GList *children = gtk_container_get_children(GTK_CONTAINER(wids->data));
- g_list_foreach(children, (GFunc)gtk_widget_destroy, NULL);
- g_list_free(children);
- gtk_container_add(GTK_CONTAINER(wids->data), icon);
- } else
- gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(smiley->imhtml), icon, anchor);
- }
- g_list_free(wids);
- }
-
- }
-
- g_slist_free(smiley->anchors);
- smiley->anchors = NULL;
-
- g_object_unref(G_OBJECT(loader));
- smiley->loader = NULL;
-}
-
static gboolean
add_custom_smiley_for_imhtml(GtkIMHtml *imhtml, const char *sml, const char *smile)
{
GtkIMHtmlSmiley *smiley;
- GdkPixbufLoader *loader;
smiley = gtk_imhtml_smiley_get(imhtml, sml, smile);
if (smiley) {
-
if (!(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) {
return FALSE;
}
-
- /* Close the old GdkPixbufAnimation, then create a new one for
- * the smiley we are about to receive */
- g_object_unref(G_OBJECT(smiley->icon));
-
- /* XXX: Is it necessary to _unref the loader first? */
- smiley->loader = gdk_pixbuf_loader_new();
- smiley->icon = NULL;
-
- g_signal_connect(smiley->loader, "area_prepared", G_CALLBACK(pidgin_conv_custom_smiley_allocated), smiley);
- g_signal_connect(smiley->loader, "closed", G_CALLBACK(pidgin_conv_custom_smiley_closed), smiley);
-
+ gtk_imhtml_smiley_reload(smiley);
return TRUE;
}
- loader = gdk_pixbuf_loader_new();
-
- /* this is wrong, this file ought not call g_new on GtkIMHtmlSmiley */
- /* Let gtk_imhtml have a gtk_imhtml_smiley_new function, and let
- GtkIMHtmlSmiley by opaque */
- smiley = g_new0(GtkIMHtmlSmiley, 1);
- smiley->file = NULL;
- smiley->smile = g_strdup(smile);
- smiley->loader = loader;
- smiley->flags = smiley->flags | GTK_IMHTML_SMILEY_CUSTOM;
-
- g_signal_connect(smiley->loader, "area_prepared", G_CALLBACK(pidgin_conv_custom_smiley_allocated), smiley);
- g_signal_connect(smiley->loader, "closed", G_CALLBACK(pidgin_conv_custom_smiley_closed), smiley);
-
+ smiley = gtk_imhtml_smiley_create(NULL, smile, FALSE, GTK_IMHTML_SMILEY_CUSTOM);
gtk_imhtml_associate_smiley(imhtml, sml, smiley);
+ g_signal_connect_swapped(imhtml, "destroy", G_CALLBACK(gtk_imhtml_smiley_destroy), smiley);
return TRUE;
}
============================================================
--- pidgin/gtkimhtml.c 6ddec5d16cea88e2bbb7d511384fd9e616da527b
+++ pidgin/gtkimhtml.c 992dbcbc4f735572bde6bff768c24c2f4715e7c8
@@ -5200,4 +5200,123 @@ void gtk_imhtml_setup_entry(GtkIMHtml *i
gtk_imhtml_set_format_functions(imhtml, buttons);
}
+/*******
+ * GtkIMHtmlSmiley functions
+ *******/
+static void gtk_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data)
+{
+ GtkIMHtmlSmiley *smiley;
+ smiley = (GtkIMHtmlSmiley *)user_data;
+ smiley->icon = gdk_pixbuf_loader_get_animation(loader);
+
+ if (smiley->icon)
+ g_object_ref(G_OBJECT(smiley->icon));
+#ifdef DEBUG_CUSTOM_SMILEY
+ purple_debug_info("custom-smiley", "gtk_custom_smiley_allocated(): got GdkPixbufAnimation %p for smiley '%s'\n", smiley->icon, smiley->smile);
+#endif
+}
+
+static void gtk_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data)
+{
+ GtkIMHtmlSmiley *smiley;
+ GtkWidget *icon = NULL;
+ GtkTextChildAnchor *anchor = NULL;
+ GSList *current = NULL;
+
+ smiley = (GtkIMHtmlSmiley *)user_data;
+ if (!smiley->imhtml) {
+#ifdef DEBUG_CUSTOM_SMILEY
+ purple_debug_error("custom-smiley", "gtk_custom_smiley_closed(): orphan smiley found: %p\n", smiley);
+#endif
+ g_object_unref(G_OBJECT(loader));
+ smiley->loader = NULL;
+ return;
+ }
+
+ for (current = smiley->anchors; current; current = g_slist_next(current)) {
+
+ icon = gtk_image_new_from_animation(smiley->icon);
+
+#ifdef DEBUG_CUSTOM_SMILEY
+ purple_debug_info("custom-smiley", "gtk_custom_smiley_closed(): got GtkImage %p from GtkPixbufAnimation %p for smiley '%s'\n",
+ icon, smiley->icon, smiley->smile);
+#endif
+ if (icon) {
+ GList *wids;
+ gtk_widget_show(icon);
+
+ anchor = GTK_TEXT_CHILD_ANCHOR(current->data);
+ wids = gtk_text_child_anchor_get_widgets(anchor);
+
+ g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", purple_unescape_html(smiley->smile), g_free);
+ g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley->smile), g_free);
+
+ if (smiley->imhtml) {
+ if (wids) {
+ GList *children = gtk_container_get_children(GTK_CONTAINER(wids->data));
+ g_list_foreach(children, (GFunc)gtk_widget_destroy, NULL);
+ g_list_free(children);
+ gtk_container_add(GTK_CONTAINER(wids->data), icon);
+ } else
+ gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(smiley->imhtml), icon, anchor);
+ }
+ g_list_free(wids);
+ }
+
+ }
+
+ g_slist_free(smiley->anchors);
+ smiley->anchors = NULL;
+
+ g_object_unref(G_OBJECT(loader));
+ smiley->loader = NULL;
+}
+
+void
+gtk_imhtml_smiley_reload(GtkIMHtmlSmiley *smiley)
+{
+ if (smiley->icon)
+ g_object_unref(smiley->icon);
+ if (smiley->loader)
+ g_object_unref(smiley->loader); /* XXX: does this crash? */
+
+ smiley->icon = NULL;
+ smiley->loader = NULL;
+
+ if (smiley->file) {
+ /* We do not use the pixbuf loader for a smiley that can be loaded
+ * from a file. (e.g., local custom smileys)
+ */
+ return;
+ }
+
+ smiley->loader = gdk_pixbuf_loader_new();
+
+ g_signal_connect(smiley->loader, "area_prepared", G_CALLBACK(gtk_custom_smiley_allocated), smiley);
+ g_signal_connect(smiley->loader, "closed", G_CALLBACK(gtk_custom_smiley_closed), smiley);
+}
+
+GtkIMHtmlSmiley *gtk_imhtml_smiley_create(const char *file, const char *shortcut, gboolean hide,
+ GtkIMHtmlSmileyFlags flags)
+{
+ GtkIMHtmlSmiley *smiley = g_new0(GtkIMHtmlSmiley, 1);
+ smiley->file = g_strdup(file);
+ smiley->smile = g_strdup(shortcut);
+ smiley->hidden = hide;
+ smiley->flags = flags;
+ gtk_imhtml_smiley_reload(smiley);
+ return smiley;
+}
+
+void gtk_imhtml_smiley_destroy(GtkIMHtmlSmiley *smiley)
+{
+ g_free(smiley->smile);
+ g_free(smiley->file);
+ if (smiley->icon)
+ g_object_unref(smiley->icon);
+ if (smiley->loader)
+ g_object_unref(smiley->loader);
+ g_free(smiley);
+}
+
============================================================
--- pidgin/gtkimhtml.h 92ad0cd035ed124fdc45d3d9b6a6043048c3dd25
+++ pidgin/gtkimhtml.h 8f16694183c22862395dd5a58e27980c503dd024
@@ -852,6 +852,12 @@ void gtk_imhtml_setup_entry(GtkIMHtml *i
*/
void gtk_imhtml_setup_entry(GtkIMHtml *imhtml, PurpleConnectionFlags flags);
+GtkIMHtmlSmiley *gtk_imhtml_smiley_create(const char *file, const char *shortcut, gboolean hide,
+ GtkIMHtmlSmileyFlags flags);
+
+void gtk_imhtml_smiley_reload(GtkIMHtmlSmiley *smiley);
+
+void gtk_imhtml_smiley_destroy(GtkIMHtmlSmiley *smiley);
/*@}*/
#ifdef __cplusplus
============================================================
--- pidgin/gtksmiley.c f975d108cb4acab5fa5f1ad140743fbae8aa994a
+++ pidgin/gtksmiley.c d743480f99889780c59da3fe8f3c68baac3e9c2d
@@ -91,11 +91,9 @@ static GtkIMHtmlSmiley *smiley_purple_to
filename = g_build_filename(purple_smileys_get_storing_dir(),file, NULL);
- gtksmiley = g_new0(GtkIMHtmlSmiley,1);
- gtksmiley->smile = g_strdup(purple_smiley_get_shortcut(smiley));
- gtksmiley->hidden = FALSE;
- gtksmiley->file = filename;
- gtksmiley->flags = GTK_IMHTML_SMILEY_CUSTOM;
+ gtksmiley = gtk_imhtml_smiley_create(filename, purple_smiley_get_shortcut(smiley),
+ FALSE, GTK_IMHTML_SMILEY_CUSTOM);
+ g_free(filename);
return gtksmiley;
}
@@ -108,14 +106,6 @@ void pidgin_smiley_add_to_list(PurpleSmi
add_gtkimhtml_to_list(gtksmiley);
}
-static void destroy_gtksmiley(GtkIMHtmlSmiley *gtksmiley)
-{
- purple_debug_info("gtksmiley", "destroying %s\n", gtksmiley->smile);
- g_free(gtksmiley->smile);
- g_free(gtksmiley->file);
- g_free(gtksmiley);
-}
-
void pidgin_smiley_del_from_list(PurpleSmiley *smiley)
{
GSList *list = NULL;
@@ -132,7 +122,7 @@ void pidgin_smiley_del_from_list(PurpleS
if (strcmp(gtksmiley->smile, purple_smiley_get_shortcut(smiley)))
continue;
- destroy_gtksmiley(gtksmiley);
+ gtk_imhtml_smiley_destroy(gtksmiley);
break;
}
@@ -169,7 +159,7 @@ void pidgin_smileys_uninit(void)
for (; list; list = g_slist_delete_link(list, list)) {
gtksmiley = (GtkIMHtmlSmiley*)list->data;
- destroy_gtksmiley(gtksmiley);
+ gtk_imhtml_smiley_destroy(gtksmiley);
}
gtk_smileys = NULL;
============================================================
--- pidgin/gtkthemes.c 7a2ed108d00a89a1b809cee04e60d53338ccea93
+++ pidgin/gtkthemes.c e916342140982886e50abb172e5139f184256be9
@@ -135,7 +135,7 @@ static void _pidgin_themes_smiley_themei
gtk_imhtml_associate_smiley(GTK_IMHTML(imhtml), sml, icons->data);
icons = icons->next;
}
-
+
if (custom == TRUE) {
icons = pidgin_smileys_get_all();
@@ -295,7 +295,6 @@ void pidgin_themes_load_smiley_theme(con
} else if (load && list) {
gboolean hidden = FALSE;
char *sfile = NULL;
- gboolean have_used_sfile = FALSE;
if (*i == '!' && *(i + 1) == ' ') {
hidden = TRUE;
@@ -309,17 +308,12 @@ void pidgin_themes_load_smiley_theme(con
i++;
l[li++] = *(i++);
}
+ l[li] = 0;
if (!sfile) {
- l[li] = 0;
sfile = g_build_filename(dirname, l, NULL);
} else {
- GtkIMHtmlSmiley *smiley = g_new0(GtkIMHtmlSmiley, 1);
- l[li] = 0;
- smiley->file = sfile;
- smiley->smile = g_strdup(l);
- smiley->hidden = hidden;
+ GtkIMHtmlSmiley *smiley = gtk_imhtml_smiley_create(sfile, l, hidden, 0);
list->smileys = g_slist_prepend(list->smileys, smiley);
- have_used_sfile = TRUE;
}
while (isspace(*i))
i++;
@@ -327,8 +321,7 @@ void pidgin_themes_load_smiley_theme(con
}
- if (!have_used_sfile)
- g_free(sfile);
+ g_free(sfile);
}
}
More information about the Commits
mailing list