X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkmodules.c;h=5a15925993be61c7849cf524090b0515b43c4174;hb=HEAD;hp=ff4ff921eb5b81f04a95603952908b93b81bdec0;hpb=f4bbe8f0deb8d1c36829acfc791d632d27805f30;p=~andy%2Fgtk diff --git a/gtk/gtkmodules.c b/gtk/gtkmodules.c index ff4ff921e..5a1592599 100644 --- a/gtk/gtkmodules.c +++ b/gtk/gtkmodules.c @@ -13,22 +13,21 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ -#include +#include "config.h" #include #include "gtkmodules.h" #include "gtksettings.h" #include "gtkdebug.h" -#include "gtkprivate.h" /* GTK_LIBDIR */ +#include "gtkprivate.h" +#include "gtkmodulesprivate.h" +#include "gtkintl.h" #include -#include /* For pango_split_file_list */ typedef struct _GtkModuleInfo GtkModuleInfo; struct _GtkModuleInfo @@ -54,8 +53,6 @@ get_module_path (void) { const gchar *module_path_env; const gchar *exe_prefix; - const gchar *home_dir; - gchar *home_gtk_dir = NULL; gchar *module_path; gchar *default_dir; static gchar **result = NULL; @@ -63,32 +60,21 @@ get_module_path (void) if (result) return result; - home_dir = g_get_home_dir(); - if (home_dir) - home_gtk_dir = g_build_filename (home_dir, ".gtk-2.0", NULL); - module_path_env = g_getenv ("GTK_PATH"); exe_prefix = g_getenv ("GTK_EXE_PREFIX"); if (exe_prefix) - default_dir = g_build_filename (exe_prefix, "lib", "gtk-2.0", NULL); + default_dir = g_build_filename (exe_prefix, "lib", "gtk-3.0", NULL); else - default_dir = g_build_filename (GTK_LIBDIR, "gtk-2.0", NULL); + default_dir = g_build_filename (_gtk_get_libdir (), "gtk-3.0", NULL); - if (module_path_env && home_gtk_dir) - module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S, - module_path_env, home_gtk_dir, default_dir, NULL); - else if (module_path_env) + if (module_path_env) module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S, module_path_env, default_dir, NULL); - else if (home_gtk_dir) - module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S, - home_gtk_dir, default_dir, NULL); else module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S, default_dir, NULL); - g_free (home_gtk_dir); g_free (default_dir); result = pango_split_file_list (module_path); @@ -235,8 +221,17 @@ find_module (const gchar *name) module_name = g_module_build_path (NULL, name); } - module = g_module_open (module_name, G_MODULE_BIND_LAZY); - g_free(module_name); + module = g_module_open (module_name, G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY); + + if (_gtk_module_has_mixed_deps (module)) + { + g_warning ("GTK+ module %s cannot be loaded.\n" + "GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported.", module_name); + g_module_close (module); + module = NULL; + } + + g_free (module_name); return module; } @@ -248,11 +243,28 @@ cmp_module (GtkModuleInfo *info, return info->module != module; } +static gboolean +module_is_blacklisted (const gchar *name, + gboolean verbose) +{ + if (g_str_equal (name, "gail") || + g_str_equal (name, "atk-bridge")) + { + if (verbose) + g_message ("Not loading module \"%s\": The functionality is provided by GTK natively. Please try to not load it.", name); + + return TRUE; + } + + return FALSE; +} + static GSList * load_module (GSList *module_list, const gchar *name) { GtkModuleInitFunc modinit_func; + gpointer modinit_func_ptr; GtkModuleInfo *info = NULL; GModule *module = NULL; GSList *l; @@ -263,29 +275,49 @@ load_module (GSList *module_list, for (l = gtk_modules; l; l = l->next) { info = l->data; - if (g_slist_find_custom (info->names, name, + if (g_slist_find_custom (info->names, name, (GCompareFunc)strcmp)) { info->ref_count++; success = TRUE; + break; } + info = NULL; } - if (!success) + if (!success) { module = find_module (name); if (module) { - if (!g_module_symbol (module, "gtk_module_init", (gpointer *) &modinit_func) || - !modinit_func) + /* Do the check this late so we only warn about existing modules, + * not old modules that are still in the modules path. */ + if (module_is_blacklisted (name, TRUE)) + { + modinit_func = NULL; + success = TRUE; + } + else if (g_module_symbol (module, "gtk_module_init", &modinit_func_ptr)) + modinit_func = modinit_func_ptr; + else + modinit_func = NULL; + + if (!modinit_func) g_module_close (module); else { + GSList *temp; + success = TRUE; - info = (GtkModuleInfo *) g_slist_find_custom (gtk_modules, module, - (GCompareFunc)cmp_module); + info = NULL; + + temp = g_slist_find_custom (gtk_modules, module, + (GCompareFunc)cmp_module); + if (temp != NULL) + info = temp->data; + if (!info) { info = g_new0 (GtkModuleInfo, 1); @@ -300,7 +332,7 @@ load_module (GSList *module_list, gtk_modules = g_slist_append (gtk_modules, info); /* display_init == NULL indicates a non-multihead aware module. - * For these, we delay the call to init_func until first display is + * For these, we delay the call to init_func until first display is * opened, see default_display_notify_cb(). * For multihead aware modules, we call init_func immediately, * and also call display_init_func on all opened displays. @@ -333,7 +365,7 @@ load_module (GSList *module_list, } } - if (success) + if (success && info) { if (!g_slist_find (module_list, info)) { @@ -341,8 +373,16 @@ load_module (GSList *module_list, } } else - g_message ("Failed to load module \"%s\": %s", name, g_module_error ()); - + { + if (!module_is_blacklisted (name, FALSE)) + { + const gchar *error = g_module_error (); + + g_message ("Failed to load module \"%s\"%s%s", + name, error ? ": " : "", error ? error : ""); + } + } + return module_list; } @@ -357,7 +397,7 @@ gtk_module_info_unref (GtkModuleInfo *info) if (info->ref_count == 0) { GTK_NOTE (MODULES, - g_print ("Unloading module: %s", g_module_name (info->module))); + g_print ("Unloading module: %s\n", g_module_name (info->module))); gtk_modules = g_slist_remove (gtk_modules, info); g_module_close (info->module); @@ -375,7 +415,7 @@ load_modules (const char *module_str) GSList *module_list = NULL; gint i; - GTK_NOTE (MODULES, g_print ("Loading module list: %s", module_str)); + GTK_NOTE (MODULES, g_print ("Loading module list: %s\n", module_str)); module_names = pango_split_file_list (module_str); for (i = 0; module_names[i]; i++) @@ -428,7 +468,7 @@ display_closed_cb (GdkDisplay *display, settings = gtk_settings_get_for_screen (screen); g_object_set_data_full (G_OBJECT (settings), - g_intern_static_string ("gtk-modules"), + I_("gtk-modules"), NULL, NULL); } } @@ -456,7 +496,7 @@ display_opened_cb (GdkDisplayManager *display_manager, for (i = 0; i < gdk_display_get_n_screens (display); i++) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_STRING); @@ -497,6 +537,7 @@ _gtk_modules_init (gint *argc, } display_manager = gdk_display_manager_get (); + default_display_opened = gdk_display_get_default () != NULL; g_signal_connect (display_manager, "notify::default-display", G_CALLBACK (default_display_notify_cb), NULL); @@ -504,11 +545,13 @@ _gtk_modules_init (gint *argc, G_CALLBACK (display_opened_cb), NULL); - /* Modules specified in the GTK_MODULES environment variable - * or on the command line are always loaded, so we'll just leak - * the refcounts. - */ - g_slist_free (load_modules (gtk_modules_args)); + if (gtk_modules_args) { + /* Modules specified in the GTK_MODULES environment variable + * or on the command line are always loaded, so we'll just leak + * the refcounts. + */ + g_slist_free (load_modules (gtk_modules_args)); + } } static void @@ -530,12 +573,40 @@ _gtk_modules_settings_changed (GtkSettings *settings, { GSList *new_modules = NULL; + GTK_NOTE (MODULES, g_print ("gtk-modules setting changed to: %s\n", modules)); + /* load/ref before unreffing existing */ if (modules && modules[0]) new_modules = load_modules (modules); g_object_set_data_full (G_OBJECT (settings), - g_intern_static_string ("gtk-modules"), + I_("gtk-modules"), new_modules, settings_destroy_notify); } + +/* Return TRUE if module_to_check causes version conflicts. + * If module_to_check is NULL, check the main module. + */ +gboolean +_gtk_module_has_mixed_deps (GModule *module_to_check) +{ + GModule *module; + gpointer func; + gboolean result; + + if (!module_to_check) + module = g_module_open (NULL, 0); + else + module = module_to_check; + + if (g_module_symbol (module, "gtk_progress_get_type", &func)) + result = TRUE; + else + result = FALSE; + + if (!module_to_check) + g_module_close (module); + + return result; +}