]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkmodules.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gtk / gtkmodules.c
index ff4ff921eb5b81f04a95603952908b93b81bdec0..5a15925993be61c7849cf524090b0515b43c4174 100644 (file)
  * 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 <http://www.gnu.org/licenses/>.
  */
 
-#include <config.h>
+#include "config.h"
 
 #include <string.h>
 
 #include "gtkmodules.h"
 #include "gtksettings.h"
 #include "gtkdebug.h"
-#include "gtkprivate.h" /* GTK_LIBDIR */
+#include "gtkprivate.h"
+#include "gtkmodulesprivate.h"
+#include "gtkintl.h"
 
 #include <gmodule.h>
-#include <pango/pango-utils.h> /* 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;
+}