# HG changeset patch # User Richard Laager # Date 1131841152 0 # Node ID 29dc8fc0dd6c06846ab8bf1234d281f43df2b9da # Parent f7d2f637ff03048ed7c2f2ec107c15c2d5d5aa00 [gaim-migrate @ 14356] SF Patch #1351190 from Michael Hearn "This allows Linux binaries of Gaim to operate even when GTKspell is not available at runtime. Useful for the autopackages." I made a number of changes to this, so blame me first if it's busted. committer: Tailor Script diff -r f7d2f637ff03 -r 29dc8fc0dd6c COPYRIGHT --- a/COPYRIGHT Sun Nov 13 00:05:44 2005 +0000 +++ b/COPYRIGHT Sun Nov 13 00:19:12 2005 +0000 @@ -103,6 +103,7 @@ Andrew Hart (arhart) G. Sumner Hayes Michael R. Head +Michael Hearn Mike Heffner Benjamin Herrenschmidt Fernando Herrera diff -r f7d2f637ff03 -r 29dc8fc0dd6c ChangeLog --- a/ChangeLog Sun Nov 13 00:05:44 2005 +0000 +++ b/ChangeLog Sun Nov 13 00:19:12 2005 +0000 @@ -110,6 +110,7 @@ * GNOME users can open received files by clicking on "Open" in the file transfer window * Mouse-over hyperlink coloring is now themeable + * GtkSpell is now loaded dynamically at runtime (Michael Hearn) Preference Changes: * Preferences have been substantially reorganized and cleaned up diff -r f7d2f637ff03 -r 29dc8fc0dd6c configure.ac --- a/configure.ac Sun Nov 13 00:05:44 2005 +0000 +++ b/configure.ac Sun Nov 13 00:19:12 2005 +0000 @@ -1280,7 +1280,6 @@ PKG_CHECK_MODULES(GTKSPELL, gtkspell-2.0 >= 2.0.2, , enable_gtkspell=no) if test "$enable_gtkspell" = "yes" ; then AC_SUBST(GTKSPELL_CFLAGS) - AC_SUBST(GTKSPELL_LIBS) AC_DEFINE(USE_GTKSPELL,,[do we have gtkspell?]) fi fi diff -r f7d2f637ff03 -r 29dc8fc0dd6c plugins/ChangeLog.API --- a/plugins/ChangeLog.API Sun Nov 13 00:05:44 2005 +0000 +++ b/plugins/ChangeLog.API Sun Nov 13 00:19:12 2005 +0000 @@ -143,6 +143,8 @@ a visibility manager - see the docs for more information * gaim_gtk_conversations_get_first_unseen() to find the first conv with an "unseen" state >= to the specified state + * gaim_gtk_gtkspell_is_available() + * gaim_gtk_gtkspell_unsetup() Signals - Changed: * "received-im-msg" and "received-chat-msg" to match, both now pass a diff -r f7d2f637ff03 -r 29dc8fc0dd6c src/Makefile.am --- a/src/Makefile.am Sun Nov 13 00:05:44 2005 +0000 +++ b/src/Makefile.am Sun Nov 13 00:19:12 2005 +0000 @@ -352,7 +352,6 @@ $(XSS_LIBS) \ $(SM_LIBS) \ $(INTLLIBS) \ - $(GTKSPELL_LIBS) \ $(STARTUP_NOTIFICATION_LIBS) \ $(VV_LIBS) \ $(MS_LIBS) diff -r f7d2f637ff03 -r 29dc8fc0dd6c src/gtkconv.c --- a/src/gtkconv.c Sun Nov 13 00:05:44 2005 +0000 +++ b/src/gtkconv.c Sun Nov 13 00:19:12 2005 +0000 @@ -5425,11 +5425,9 @@ gtkconv = GAIM_GTK_CONVERSATION(conv); if (value) - gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(gtkconv->entry)); - else { - spell = gtkspell_get_from_text_view(GTK_TEXT_VIEW(gtkconv->entry)); - gtkspell_detach(spell); - } + gaim_gtk_gtkspell_setup(GTK_TEXT_VIEW(gtkconv->entry)); + else + gaim_gtk_gtkspell_unsetup(GTK_TEXT_VIEW(gtkconv->entry)); } #endif } diff -r f7d2f637ff03 -r 29dc8fc0dd6c src/gtkdialogs.c --- a/src/gtkdialogs.c Sun Nov 13 00:05:44 2005 +0000 +++ b/src/gtkdialogs.c Sun Nov 13 00:19:12 2005 +0000 @@ -370,9 +370,12 @@ #endif #ifdef USE_GTKSPELL - g_string_append(str, " GtkSpell: Enabled
"); + if (gaim_gtk_gtkspell_is_available()) + g_string_append(str, " GtkSpell: Enabled
"); + else + g_string_append(str, " GtkSpell: Disabled (Library Not Found)
"); #else - g_string_append(str, " GtkSpell: Disabled
"); + g_string_append(str, " GtkSpell: Disabled (Not Compiled)
"); #endif #ifdef HAVE_GNUTLS diff -r f7d2f637ff03 -r 29dc8fc0dd6c src/gtkprefs.c --- a/src/gtkprefs.c Sun Nov 13 00:05:44 2005 +0000 +++ b/src/gtkprefs.c Sun Nov 13 00:19:12 2005 +0000 @@ -798,6 +798,7 @@ GtkWidget *vbox2; GtkWidget *iconpref1; GtkWidget *iconpref2; + GtkWidget *spellpref; ret = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); gtk_container_set_border_width(GTK_CONTAINER(ret), GAIM_HIG_BORDER); @@ -820,10 +821,21 @@ gaim_gtk_prefs_checkbox(_("_Notify buddies that you are typing to them"), "/core/conversations/im/send_typing", vbox); -#ifdef USE_GTKSPELL - gaim_gtk_prefs_checkbox(_("_Highlight misspelled words"), - "/gaim/gtk/conversations/spellcheck", vbox); -#endif + + spellpref = gaim_gtk_prefs_checkbox(_("_Highlight misspelled words"), + "/gaim/gtk/conversations/spellcheck", vbox); + + if (!gaim_gtk_gtkspell_is_available()) + { + gboolean gtkspell_enabled = gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck"); + + gtk_widget_set_sensitive(spellpref, FALSE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(spellpref), FALSE); + + /* Preserve the preference. If the user had it enabled, we want it to + * stay enabled if they install gtkspell again. */ + gaim_prefs_set_bool("/gaim/gtk/conversations/spellcheck", gtkspell_enabled); + } frame = gaim_gtk_create_imhtml(TRUE, &imhtml, &toolbar); gtk_widget_set_name(imhtml, "gaim_gtkprefs_font_imhtml"); diff -r f7d2f637ff03 -r 29dc8fc0dd6c src/gtkrequest.c --- a/src/gtkrequest.c Sun Nov 13 00:05:44 2005 +0000 +++ b/src/gtkrequest.c Sun Nov 13 00:19:12 2005 +0000 @@ -398,7 +398,7 @@ gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck")) - gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(entry)); + gaim_gtk_gtkspell_setup(GTK_TEXT_VIEW(entry)); gtk_container_add(GTK_CONTAINER(sw), entry); } @@ -1085,7 +1085,7 @@ GTK_WRAP_WORD_CHAR); if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck")) - gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(textview)); + gaim_gtk_gtkspell_setup(GTK_TEXT_VIEW(textview)); gtk_container_add(GTK_CONTAINER(widget), textview); gtk_widget_show(textview); diff -r f7d2f637ff03 -r 29dc8fc0dd6c src/gtkutils.c --- a/src/gtkutils.c Sun Nov 13 00:05:44 2005 +0000 +++ b/src/gtkutils.c Sun Nov 13 00:19:12 2005 +0000 @@ -147,7 +147,7 @@ gtk_imhtml_set_format_functions(GTK_IMHTML(imhtml), GTK_IMHTML_ALL ^ GTK_IMHTML_IMAGE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(imhtml), GTK_WRAP_WORD_CHAR); if (editable && gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck")) - gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(imhtml)); + gaim_gtk_gtkspell_setup(GTK_TEXT_VIEW(imhtml)); gtk_widget_show(imhtml); if (editable) { @@ -897,25 +897,102 @@ return buf; } +#ifdef USE_GTKSPELL +static GtkSpell* (*gtkspell_get_from_text_view_ptr)(GtkTextView *view); +static void (*gtkspell_detach_ptr)(GtkSpell *spell); +static GtkSpell* (*gtkspell_new_attach_ptr)(GtkTextView *view, const gchar *lang, GError **error); +static int gtkspell_available = -1; /* -1 unknown, 0 false, 1 true */ + +static void +setup_gtkspell() +{ +#if GLIB_CHECK_VERSION(2,3,3) + GModule *handle = g_module_open("libgtkspell", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); +#else + GModule *handle = g_module_open("libgtkspell", G_MODULE_BIND_LAZY); +#endif + if (handle != NULL) + { + gpointer ptr; /* squash GCC strict aliasing warnings */ + + g_module_symbol(handle, "gtkspell_new_attach", &ptr); + gtkspell_new_attach_ptr = ptr; + + g_module_symbol(handle, "gtkspell_detach", &ptr); + gtkspell_detach_ptr = ptr; + + g_module_symbol(handle, "gtkspell_get_from_text_view", &ptr); + gtkspell_get_from_text_view_ptr = ptr; + + gtkspell_available = TRUE; + } + else + { + gaim_debug_warning("gtkspell", "Failed to load libgtkspell.so.0: %s\n", dlerror()); + gtkspell_available = FALSE; + } +} + +gboolean +gaim_gtk_gtkspell_is_available() +{ + if (gtkspell_available == -1) + setup_gtkspell(); + + return gtkspell_available; +} + void -gaim_gtk_setup_gtkspell(GtkTextView *textview) +gaim_gtk_gtkspell_setup(GtkTextView *textview) { -#ifdef USE_GTKSPELL GError *error = NULL; char *locale = NULL; g_return_if_fail(textview != NULL); g_return_if_fail(GTK_IS_TEXT_VIEW(textview)); - if (gtkspell_new_attach(textview, locale, &error) == NULL && error) + if (!gaim_gtk_gtkspell_is_available()) + return; + + if (gtkspell_new_attach_ptr(textview, locale, &error) == NULL && error) { - gaim_debug_warning("gtkspell", "Failed to setup GtkSpell: %s\n", - error->message); + gaim_debug_warning("gtkspell", "Failed to setup GtkSpell: %s\n", error->message); g_error_free(error); } -#endif /* USE_GTKSPELL */ +} + +void +gaim_gtk_gtkspell_unsetup(GtkTextView *textview) +{ + GtkSpell *spell; + + if (!gtkspell_available) + return; + + spell = gtkspell_get_from_text_view_ptr(textview); + gtkspell_detach_ptr(spell); } +#else /* !USE_GTKSPELL */ + +gboolean +gaim_gtk_gtkspell_is_available() +{ + return FALSE; +} + +void +gaim_gtk_gtkspell_setup(GtkTextView *textview) +{ +} + +void +gaim_gtk_gtkspell_unsetup(GtkTextView *textview) +{ +} + +#endif /* !USE_GTKSPELL */ + void gaim_gtk_save_accels_cb(GtkAccelGroup *accel_group, guint arg1, GdkModifierType arg2, GClosure *arg3, diff -r f7d2f637ff03 -r 29dc8fc0dd6c src/gtkutils.h --- a/src/gtkutils.h Sun Nov 13 00:05:44 2005 +0000 +++ b/src/gtkutils.h Sun Nov 13 00:19:12 2005 +0000 @@ -259,14 +259,32 @@ gboolean gaim_gtk_check_if_dir(const char *path, GtkFileSelection *filesel); /** + * Returns @c TRUE if Gaim was compiled with GtkSpell support and the + * library is available at runtime. + */ +gboolean gaim_gtk_gtkspell_is_available(); + +/** * Sets up GtkSpell for the given GtkTextView, reporting errors * if encountered. * - * This does nothing if Gaim is not compiled with GtkSpell support. + * This does nothing if Gaim is not compiled with GtkSpell support, or + * the GtkSpell library cannot be located at runtime. * * @param textview The textview widget to setup spellchecking for. */ -void gaim_gtk_setup_gtkspell(GtkTextView *textview); +void gaim_gtk_gtkspell_setup(GtkTextView *textview); + +/** + * Does the inverse of gaim_gtk_setup_gtkspell, detaching the spelling + * checker from the text view widget. + * + * This does nothing if Gaim is not compiled with GtkSpell support, or + * the GtkSpell library cannot be located at runtime. + * + * @param textview The textview widget to unsetup spellchecking for. + */ +void gaim_gtk_gtkspell_unsetup(GtkTextView *textview); /** * Stylizes the specified text using HTML, according to the current