diff -r f4740b6e7525 -r 832cd077145e pidgin/gtkconv.c
--- a/pidgin/gtkconv.c Thu Apr 03 09:37:53 2014 +0530
+++ b/pidgin/gtkconv.c Mon Apr 07 20:02:22 2014 +0530
@@ -42,6 +42,7 @@
#include "plugins.h"
#include "protocol.h"
#include "request.h"
+#include "smiley-parser.h"
#include "theme-loader.h"
#include "theme-manager.h"
#include "util.h"
@@ -60,12 +61,10 @@
#include "gtkpounce.h"
#include "gtkprefs.h"
#include "gtkprivacy.h"
-#include "gtkthemes.h"
#include "gtkutils.h"
#include "gtkwebview.h"
#include "pidginstock.h"
#include "pidgintooltip.h"
-#include "smileyparser.h"
#include "gtknickcolors.h"
@@ -139,9 +138,6 @@
#define BUDDYICON_SIZE_MIN 32
#define BUDDYICON_SIZE_MAX 96
-/* Undef this to turn off "custom-smiley" debug messages */
-#define DEBUG_CUSTOM_SMILEY
-
#define LUMINANCE(c) (float)((0.3*(c.red))+(0.59*(c.green))+(0.11*(c.blue)))
/* From http://www.w3.org/TR/AERT#color-contrast */
@@ -2355,7 +2351,6 @@
PidginConversation *gtkconv;
PurpleConversation *old_conv;
PidginWebView *entry;
- const char *protocol_name;
PurpleConnectionFlags features;
g_return_if_fail(conv != NULL);
@@ -2372,13 +2367,14 @@
purple_conversation_close_logs(old_conv);
gtkconv->active_conv = conv;
+ pidgin_webview_switch_active_conversation(
+ PIDGIN_WEBVIEW(gtkconv->entry), conv);
+ pidgin_webview_switch_active_conversation(
+ PIDGIN_WEBVIEW(gtkconv->webview), conv);
purple_conversation_set_logging(conv,
gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu->logging)));
entry = PIDGIN_WEBVIEW(gtkconv->entry);
- protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv));
- pidgin_webview_set_protocol_name(entry, protocol_name);
- pidgin_webview_set_protocol_name(PIDGIN_WEBVIEW(gtkconv->webview), protocol_name);
features = purple_conversation_get_features(conv);
if (!(features & PURPLE_CONNECTION_FLAG_HTML))
@@ -5713,8 +5709,6 @@
_pidgin_widget_set_accessible_name(frame, "Message Input");
gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry");
- pidgin_webview_set_protocol_name(PIDGIN_WEBVIEW(gtkconv->entry),
- purple_account_get_protocol_name(purple_conversation_get_account(conv)));
g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup",
G_CALLBACK(entry_popup_menu_cb), gtkconv);
@@ -5767,8 +5761,9 @@
PidginConversation *gtkconv = NULL;
PurpleAccount *buddyaccount;
const char *buddyname;
-
- n = *(PurpleBlistNode **) data;
+ PurpleBlistNode **data_val = (gpointer)data;
+
+ n = *data_val;
if (PURPLE_IS_CONTACT(n))
b = purple_contact_get_priority_buddy((PurpleContact*)n);
@@ -6087,6 +6082,10 @@
pidgin_webview_show_toolbar(PIDGIN_WEBVIEW(gtkconv->entry));
else
pidgin_webview_hide_toolbar(PIDGIN_WEBVIEW(gtkconv->entry));
+ pidgin_webview_switch_active_conversation(
+ PIDGIN_WEBVIEW(gtkconv->entry), conv);
+ pidgin_webview_switch_active_conversation(
+ PIDGIN_WEBVIEW(gtkconv->webview), conv);
if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons"))
gtk_widget_show(gtkconv->infopane_hbox);
@@ -6111,9 +6110,6 @@
{
gtkconv->nick_colors = g_array_ref(generated_nick_colors);
}
-
- if (purple_conversation_get_features(conv) & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY)
- pidgin_themes_smiley_themeize_custom(gtkconv->entry);
}
static void
@@ -6584,6 +6580,94 @@
return g_string_free(str, FALSE);
}
+static gulong
+pidgin_smiley_get_unique_id(PurpleSmiley *smiley)
+{
+ static gulong max_id = 0;
+ gulong id;
+ g_return_val_if_fail(smiley != NULL, 0);
+
+ id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(smiley),
+ "pidgin-conv-smiley-unique-id"));
+ if (id != 0)
+ return id;
+
+ id = ++max_id;
+
+ g_object_set_data(G_OBJECT(smiley), "pidgin-conv-smiley-unique-id",
+ GINT_TO_POINTER(id));
+
+ return id;
+}
+
+static void
+pidgin_conv_remote_smiley_got(PurpleSmiley *smiley, gpointer _conv)
+{
+ PurpleConversation *conv = _conv;
+ PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
+ PurpleStoredImage *img;
+ gulong smiley_id;
+ int image_id;
+ gchar *js;
+
+ if (!gtkconv)
+ return;
+
+ img = purple_smiley_get_image(smiley);
+ smiley_id = pidgin_smiley_get_unique_id(smiley);
+ image_id = purple_imgstore_add_with_id(img);
+
+ purple_debug_info("gtkconv", "Smiley '%s' (%ld) is ready for display",
+ purple_smiley_get_shortcut(smiley), smiley_id);
+
+ js = g_strdup_printf("emoticonIsReady(%ld, '"
+ PURPLE_STORED_IMAGE_PROTOCOL "%d')", smiley_id, image_id);
+ pidgin_webview_safe_execute_script(
+ PIDGIN_WEBVIEW(gtkconv->webview), js);
+ g_free(js);
+}
+
+static gboolean
+pidgin_conv_write_smiley(GString *out, PurpleSmiley *smiley,
+ PurpleConversation *conv, gpointer _proto_name)
+{
+ gchar *escaped_shortcut;
+ const gchar *path = purple_smiley_get_path(smiley);
+ const gchar *path_prefix = "";
+
+#ifdef _WIN32
+ path_prefix = "file:///";
+#endif
+
+ escaped_shortcut = g_markup_escape_text(
+ purple_smiley_get_shortcut(smiley), -1);
+
+ if (purple_smiley_is_ready(smiley) && path) {
+ g_string_append_printf(out,
+ "
", escaped_shortcut,
+ escaped_shortcut, path_prefix, path);
+ } else if (purple_smiley_is_ready(smiley) && !path) {
+ PurpleStoredImage *img = purple_smiley_get_image(smiley);
+ int imgid = purple_imgstore_add_with_id(img);
+
+ g_string_append_printf(out, "
",
+ escaped_shortcut, escaped_shortcut, imgid);
+ } else {
+ g_string_append_printf(out, "%s",
+ pidgin_smiley_get_unique_id(smiley), escaped_shortcut);
+ g_signal_connect_object(smiley, "ready",
+ G_CALLBACK(pidgin_conv_remote_smiley_got), conv, 0);
+ }
+
+ g_free(escaped_shortcut);
+
+ return TRUE;
+}
+
static void
pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias,
const char *message, PurpleMessageFlags flags,
@@ -6710,7 +6794,9 @@
gtkconv->last_flags = flags;
gtkconv->last_conversed = conv;
- smileyed = pidgin_smiley_parse_markup(displaying, purple_account_get_protocol_id(account));
+ smileyed = purple_smiley_parse(conv, displaying, (flags & PURPLE_MESSAGE_RECV),
+ pidgin_conv_write_smiley,
+ (gpointer)purple_account_get_protocol_name(account));
msg = replace_message_tokens(message_html, conv, name, alias, smileyed, flags, mtime);
escape = pidgin_webview_quote_js_string(msg ? msg : "");
script = g_strdup_printf("%s(%s)", func, escape);
@@ -6774,12 +6860,6 @@
gtk_font_options |= GTK_IMHTML_USE_POINTSIZE;
}
- if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY))
- {
- /* We want to see our own smileys. Need to revert it after send*/
- pidgin_themes_smiley_themeize_custom(gtkconv->webview);
- }
-
/* TODO: These colors should not be hardcoded so log.c can use them */
if (flags & PURPLE_MESSAGE_RAW) {
pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), message);
@@ -6935,15 +7015,6 @@
gtkconv_set_unseen(gtkconv, unseen);
}
-#if 0
- if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_FLAG_ALLOW_CUSTOM_SMILEY))
- {
- /* Restore the smiley-data */
- pidgin_themes_smiley_themeize(gtkconv->webview);
- }
-#endif
-
-
/* on rejoin only request message history from after this message */
if (flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV) &&
PURPLE_IS_CHAT_CONVERSATION(conv)) {
@@ -7202,154 +7273,6 @@
return FALSE;
}
-static gboolean
-add_custom_smiley_for_webview(PidginWebView *webview, const char *sml, const char *smile)
-{
- PidginWebViewSmiley *smiley;
-
- smiley = pidgin_webview_smiley_find(webview, sml, smile);
-
- if (smiley) {
- if (!(pidgin_webview_smiley_get_flags(smiley) & PIDGIN_WEBVIEW_SMILEY_CUSTOM))
- return FALSE;
-
- pidgin_webview_smiley_reload(smiley);
- return TRUE;
- }
-
- smiley = pidgin_webview_smiley_create(NULL, smile, FALSE,
- PIDGIN_WEBVIEW_SMILEY_CUSTOM);
- pidgin_webview_associate_smiley(webview, sml, smiley);
- g_signal_connect_swapped(webview, "destroy",
- G_CALLBACK(pidgin_webview_smiley_destroy), smiley);
-
- return TRUE;
-}
-
-static gboolean
-pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gboolean remote)
-{
- PidginConversation *gtkconv;
- struct PidginSmileyList *list;
- const char *sml = NULL, *conv_sml;
-
- if (!conv || !smile || !*smile) {
- return FALSE;
- }
-
- /* If smileys are off, return false */
- if (pidgin_themes_smileys_disabled())
- return FALSE;
-
- /* If possible add this smiley to the current theme.
- * The addition is only temporary: custom smilies aren't saved to disk. */
- conv_sml = purple_account_get_protocol_name(purple_conversation_get_account(conv));
- gtkconv = PIDGIN_CONVERSATION(conv);
-
- for (list = (struct PidginSmileyList *)current_smiley_theme->list; list; list = list->next) {
- if (!strcmp(list->sml, conv_sml)) {
- sml = list->sml;
- break;
- }
- }
-
- if (!add_custom_smiley_for_webview(PIDGIN_WEBVIEW(gtkconv->webview), sml, smile))
- return FALSE;
-
- if (!remote) /* If it's a local custom smiley, then add it for the entry */
- if (!add_custom_smiley_for_webview(PIDGIN_WEBVIEW(gtkconv->entry), sml, smile))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile,
- const guchar *data, gsize size)
-{
-/* TODO WEBKIT */
-#if 0
- PidginConversation *gtkconv;
- GtkIMHtmlSmiley *smiley;
- const char *sml;
- GError *error = NULL;
-
- sml = purple_account_get_protocol_name(purple_conversation_get_account(conv));
- gtkconv = PIDGIN_CONVERSATION(conv);
- smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile);
-
- if (!smiley)
- return;
-
- smiley->data = g_realloc(smiley->data, smiley->datasize + size);
- g_memmove((guchar *)smiley->data + smiley->datasize, data, size);
- smiley->datasize += size;
-
- if (!smiley->loader)
- return;
-
- if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) {
- purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() "
- "failed with size=%" G_GSIZE_FORMAT ": %s\n", size,
- error ? error->message : "(no error message)");
- if (error)
- g_error_free(error);
- /* We must stop using the GdkPixbufLoader because trying to load
- certain invalid GIFs with at least gdk-pixbuf 2.23.3 can return
- a GdkPixbuf that will cause some operations (like
- gdk_pixbuf_scale_simple()) to consume memory in an infinite loop.
- But we also don't want to set smiley->loader to NULL because our
- code might expect it to be set. So create a new loader. */
- g_object_unref(G_OBJECT(smiley->loader));
- smiley->loader = gdk_pixbuf_loader_new();
- }
-#endif /* if 0 */
-}
-
-static void
-pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile)
-{
-/* TODO WEBKIT */
-#if 0
- PidginConversation *gtkconv;
- GtkIMHtmlSmiley *smiley;
- const char *sml;
- GError *error = NULL;
-
- g_return_if_fail(conv != NULL);
- g_return_if_fail(smile != NULL);
-
- sml = purple_account_get_protocol_name(purple_conversation_get_account(conv));
- gtkconv = PIDGIN_CONVERSATION(conv);
- smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile);
-
- if (!smiley)
- return;
-
- if (!smiley->loader)
- return;
-
- purple_debug_info("gtkconv", "About to close the smiley pixbuf\n");
-
- if (!gdk_pixbuf_loader_close(smiley->loader, &error) || error) {
- purple_debug_warning("gtkconv", "gdk_pixbuf_loader_close() "
- "failed: %s\n",
- error ? error->message : "(no error message)");
- if (error)
- g_error_free(error);
- /* We must stop using the GdkPixbufLoader because if we tried to
- load certain invalid GIFs with all current versions of GDK (as
- of 2011-06-15) then it's possible the loader will contain data
- that could cause some operations (like gdk_pixbuf_scale_simple())
- to consume memory in an infinite loop. But we also don't want
- to set smiley->loader to NULL because our code might expect it
- to be set. So create a new loader. */
- g_object_unref(G_OBJECT(smiley->loader));
- smiley->loader = gdk_pixbuf_loader_new();
- }
-#endif /* if 0 */
-}
-
static void
pidgin_conv_send_confirm(PurpleConversation *conv, const char *message)
{
@@ -7491,8 +7414,6 @@
buttons &= ~PIDGIN_WEBVIEW_CUSTOM_SMILEY;
pidgin_webview_set_format_functions(PIDGIN_WEBVIEW(gtkconv->entry), buttons);
- if (account != NULL)
- pidgin_webview_set_protocol_name(PIDGIN_WEBVIEW(gtkconv->entry), purple_account_get_protocol_id(account));
/* Deal with menu items */
gtk_action_set_sensitive(win->menu->view_log, TRUE);
@@ -7627,11 +7548,6 @@
}
}
-#if 0
- if (fields & PIDGIN_CONV_SMILEY_THEME)
- pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview);
-#endif
-
if ((fields & PIDGIN_CONV_COLORIZE_TITLE) ||
(fields & PIDGIN_CONV_SET_TITLE) ||
(fields & PIDGIN_CONV_TOPIC))
@@ -7749,7 +7665,7 @@
gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title);
if (pidgin_conv_window_is_active_conversation(conv)) {
const char* current_title = gtk_window_get_title(GTK_WINDOW(win->window));
- if (current_title == NULL || strcmp(current_title, title) != 0)
+ if (current_title == NULL || g_strcmp0(current_title, title) != 0)
gtk_window_set_title(GTK_WINDOW(win->window), title);
}
@@ -7846,9 +7762,6 @@
pidgin_conv_chat_update_user, /* chat_update_user */
pidgin_conv_present_conversation, /* present */
pidgin_conv_has_focus, /* has_focus */
- pidgin_conv_custom_smiley_add, /* custom_smiley_add */
- pidgin_conv_custom_smiley_write, /* custom_smiley_write */
- pidgin_conv_custom_smiley_close, /* custom_smiley_close */
pidgin_conv_send_confirm, /* send_confirm */
NULL,
NULL,
@@ -8784,6 +8697,7 @@
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_strike", FALSE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/spellcheck", TRUE);
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting", TRUE);
+ /* TODO: it's about *remote* smileys, not local ones */
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/resize_custom_smileys", TRUE);
purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/custom_smileys_size", 96);
purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines", 2);