Blame gtk/gtkmodules.c

Packit 98cdb6
/* GTK - The GIMP Toolkit
Packit 98cdb6
 * Copyright 1998-2002 Tim Janik, Red Hat, Inc., and others.
Packit 98cdb6
 * Copyright (C) 2003 Alex Graveley
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include "config.h"
Packit 98cdb6
Packit 98cdb6
#include <string.h>
Packit 98cdb6
Packit 98cdb6
#include "gtkmodules.h"
Packit 98cdb6
#include "gtkmain.h"
Packit 98cdb6
#include "gtksettings.h"
Packit 98cdb6
#include "gtkdebug.h"
Packit 98cdb6
#include "gtkprivate.h" /* GTK_LIBDIR */
Packit 98cdb6
#include "gtkintl.h" 
Packit 98cdb6
#include "gtkalias.h"
Packit 98cdb6
Packit 98cdb6
#include <gmodule.h>
Packit 98cdb6
Packit 98cdb6
typedef struct _GtkModuleInfo GtkModuleInfo;
Packit 98cdb6
struct _GtkModuleInfo
Packit 98cdb6
{
Packit 98cdb6
  GModule                 *module;
Packit 98cdb6
  gint                     ref_count;
Packit 98cdb6
  GtkModuleInitFunc        init_func;
Packit 98cdb6
  GtkModuleDisplayInitFunc display_init_func;
Packit 98cdb6
  GSList                  *names;
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
static GSList *gtk_modules = NULL;
Packit 98cdb6
Packit 98cdb6
static gboolean default_display_opened = FALSE;
Packit 98cdb6
Packit 98cdb6
/* Saved argc, argv for delayed module initialization
Packit 98cdb6
 */
Packit 98cdb6
static gint    gtk_argc = 0;
Packit 98cdb6
static gchar **gtk_argv = NULL;
Packit 98cdb6
Packit 98cdb6
static gchar **
Packit 98cdb6
get_module_path (void)
Packit 98cdb6
{
Packit 98cdb6
  const gchar *module_path_env;
Packit 98cdb6
  const gchar *exe_prefix;
Packit 98cdb6
  const gchar *home_dir;
Packit 98cdb6
  gchar *home_gtk_dir = NULL;
Packit 98cdb6
  gchar *module_path;
Packit 98cdb6
  gchar *default_dir;
Packit 98cdb6
  static gchar **result = NULL;
Packit 98cdb6
Packit 98cdb6
  if (result)
Packit 98cdb6
    return result;
Packit 98cdb6
Packit 98cdb6
  home_dir = g_get_home_dir();
Packit 98cdb6
  if (home_dir)
Packit 98cdb6
    home_gtk_dir = g_build_filename (home_dir, ".gtk-2.0", NULL);
Packit 98cdb6
Packit 98cdb6
  module_path_env = g_getenv ("GTK_PATH");
Packit 98cdb6
  exe_prefix = g_getenv ("GTK_EXE_PREFIX");
Packit 98cdb6
Packit 98cdb6
  if (exe_prefix)
Packit 98cdb6
    default_dir = g_build_filename (exe_prefix, "lib", "gtk-2.0", NULL);
Packit 98cdb6
  else
Packit 98cdb6
    default_dir = g_build_filename (GTK_LIBDIR, "gtk-2.0", NULL);
Packit 98cdb6
Packit 98cdb6
  if (module_path_env && home_gtk_dir)
Packit 98cdb6
    module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S,
Packit 98cdb6
				module_path_env, home_gtk_dir, default_dir, NULL);
Packit 98cdb6
  else if (module_path_env)
Packit 98cdb6
    module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S,
Packit 98cdb6
				module_path_env, default_dir, NULL);
Packit 98cdb6
  else if (home_gtk_dir)
Packit 98cdb6
    module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S,
Packit 98cdb6
				home_gtk_dir, default_dir, NULL);
Packit 98cdb6
  else
Packit 98cdb6
    module_path = g_build_path (G_SEARCHPATH_SEPARATOR_S,
Packit 98cdb6
				default_dir, NULL);
Packit 98cdb6
Packit 98cdb6
  g_free (home_gtk_dir);
Packit 98cdb6
  g_free (default_dir);
Packit 98cdb6
Packit 98cdb6
  result = pango_split_file_list (module_path);
Packit 98cdb6
  g_free (module_path);
Packit 98cdb6
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gtk_get_module_path:
Packit 98cdb6
 * @type: the type of the module, for instance 'modules', 'engines', immodules'
Packit 98cdb6
 * 
Packit 98cdb6
 * Determines the search path for a particular type of module.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the search path for the module type. Free with g_strfreev().
Packit 98cdb6
 **/
Packit 98cdb6
gchar **
Packit 98cdb6
_gtk_get_module_path (const gchar *type)
Packit 98cdb6
{
Packit 98cdb6
  gchar **paths = get_module_path();
Packit 98cdb6
  gchar **path;
Packit 98cdb6
  gchar **result;
Packit 98cdb6
  gint count = 0;
Packit 98cdb6
Packit 98cdb6
  for (path = paths; *path; path++)
Packit 98cdb6
    count++;
Packit 98cdb6
Packit 98cdb6
  result = g_new (gchar *, count * 4 + 1);
Packit 98cdb6
Packit 98cdb6
  count = 0;
Packit 98cdb6
  for (path = get_module_path (); *path; path++)
Packit 98cdb6
    {
Packit 98cdb6
      gint use_version, use_host;
Packit 98cdb6
      
Packit 98cdb6
      for (use_version = TRUE; use_version >= FALSE; use_version--)
Packit 98cdb6
	for (use_host = TRUE; use_host >= FALSE; use_host--)
Packit 98cdb6
	  {
Packit 98cdb6
	    gchar *tmp_dir;
Packit 98cdb6
	    
Packit 98cdb6
	    if (use_version && use_host)
Packit 98cdb6
	      tmp_dir = g_build_filename (*path, GTK_BINARY_VERSION, GTK_HOST, type, NULL);
Packit 98cdb6
	    else if (use_version)
Packit 98cdb6
	      tmp_dir = g_build_filename (*path, GTK_BINARY_VERSION, type, NULL);
Packit 98cdb6
	    else if (use_host)
Packit 98cdb6
	      tmp_dir = g_build_filename (*path, GTK_HOST, type, NULL);
Packit 98cdb6
	    else
Packit 98cdb6
	      tmp_dir = g_build_filename (*path, type, NULL);
Packit 98cdb6
Packit 98cdb6
	    result[count++] = tmp_dir;
Packit 98cdb6
	  }
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  result[count++] = NULL;
Packit 98cdb6
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Like g_module_path, but use .la as the suffix
Packit 98cdb6
 */
Packit 98cdb6
static gchar*
Packit 98cdb6
module_build_la_path (const gchar *directory,
Packit 98cdb6
		      const gchar *module_name)
Packit 98cdb6
{
Packit 98cdb6
  gchar *filename;
Packit 98cdb6
  gchar *result;
Packit 98cdb6
	
Packit 98cdb6
  if (strncmp (module_name, "lib", 3) == 0)
Packit 98cdb6
    filename = (gchar *)module_name;
Packit 98cdb6
  else
Packit 98cdb6
    filename =  g_strconcat ("lib", module_name, ".la", NULL);
Packit 98cdb6
Packit 98cdb6
  if (directory && *directory)
Packit 98cdb6
    result = g_build_filename (directory, filename, NULL);
Packit 98cdb6
  else
Packit 98cdb6
    result = g_strdup (filename);
Packit 98cdb6
Packit 98cdb6
  if (filename != module_name)
Packit 98cdb6
    g_free (filename);
Packit 98cdb6
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * _gtk_find_module:
Packit 98cdb6
 * @name: the name of the module
Packit 98cdb6
 * @type: the type of the module, for instance 'modules', 'engines', immodules'
Packit 98cdb6
 * 
Packit 98cdb6
 * Looks for a dynamically module named @name of type @type in the standard GTK+
Packit 98cdb6
 *  module search path.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the pathname to the found module, or %NULL if it wasn't found.
Packit 98cdb6
 *  Free with g_free().
Packit 98cdb6
 **/
Packit 98cdb6
gchar *
Packit 98cdb6
_gtk_find_module (const gchar *name,
Packit 98cdb6
		  const gchar *type)
Packit 98cdb6
{
Packit 98cdb6
  gchar **paths;
Packit 98cdb6
  gchar **path;
Packit 98cdb6
  gchar *module_name = NULL;
Packit 98cdb6
Packit 98cdb6
  if (g_path_is_absolute (name))
Packit 98cdb6
    return g_strdup (name);
Packit 98cdb6
Packit 98cdb6
  paths = _gtk_get_module_path (type);
Packit 98cdb6
  for (path = paths; *path; path++)
Packit 98cdb6
    {
Packit 98cdb6
      gchar *tmp_name;
Packit 98cdb6
Packit 98cdb6
      tmp_name = g_module_build_path (*path, name);
Packit 98cdb6
      if (g_file_test (tmp_name, G_FILE_TEST_EXISTS))
Packit 98cdb6
	{
Packit 98cdb6
	  module_name = tmp_name;
Packit 98cdb6
	  goto found;
Packit 98cdb6
	}
Packit 98cdb6
      g_free(tmp_name);
Packit 98cdb6
Packit 98cdb6
      tmp_name = module_build_la_path (*path, name);
Packit 98cdb6
      if (g_file_test (tmp_name, G_FILE_TEST_EXISTS))
Packit 98cdb6
	{
Packit 98cdb6
	  module_name = tmp_name;
Packit 98cdb6
	  goto found;
Packit 98cdb6
	}
Packit 98cdb6
      g_free(tmp_name);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
 found:
Packit 98cdb6
  g_strfreev (paths);
Packit 98cdb6
  return module_name;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GModule *
Packit 98cdb6
find_module (const gchar *name)
Packit 98cdb6
{
Packit 98cdb6
  GModule *module;
Packit 98cdb6
  gchar *module_name;
Packit 98cdb6
Packit 98cdb6
  module_name = _gtk_find_module (name, "modules");
Packit 98cdb6
  if (!module_name)
Packit 98cdb6
    {
Packit 98cdb6
      /* As last resort, try loading without an absolute path (using system
Packit 98cdb6
       * library path)
Packit 98cdb6
       */
Packit 98cdb6
      module_name = g_module_build_path (NULL, name);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  module = g_module_open (module_name, G_MODULE_BIND_LOCAL | G_MODULE_BIND_LAZY);
Packit 98cdb6
Packit 98cdb6
  if (_gtk_module_has_mixed_deps (module))
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("GTK+ module %s cannot be loaded.\n"
Packit 98cdb6
                 "GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported.", module_name);
Packit 98cdb6
      g_module_close (module);
Packit 98cdb6
      module = NULL;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  g_free (module_name);
Packit 98cdb6
Packit 98cdb6
  return module;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gint
Packit 98cdb6
cmp_module (GtkModuleInfo *info,
Packit 98cdb6
	    GModule       *module)
Packit 98cdb6
{
Packit 98cdb6
  return info->module != module;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GSList *
Packit 98cdb6
load_module (GSList      *module_list,
Packit 98cdb6
	     const gchar *name)
Packit 98cdb6
{
Packit 98cdb6
  GtkModuleInitFunc modinit_func;
Packit 98cdb6
  gpointer modinit_func_ptr;
Packit 98cdb6
  GtkModuleInfo *info = NULL;
Packit 98cdb6
  GModule *module = NULL;
Packit 98cdb6
  GSList *l;
Packit 98cdb6
  gboolean success = FALSE;
Packit 98cdb6
  
Packit 98cdb6
  if (g_module_supported ())
Packit 98cdb6
    {
Packit 98cdb6
      for (l = gtk_modules; l; l = l->next)
Packit 98cdb6
	{
Packit 98cdb6
	  info = l->data;
Packit 98cdb6
	  if (g_slist_find_custom (info->names, name, 
Packit 98cdb6
				   (GCompareFunc)strcmp))
Packit 98cdb6
	    {
Packit 98cdb6
	      info->ref_count++;
Packit 98cdb6
	      
Packit 98cdb6
	      success = TRUE;
Packit 98cdb6
              break;
Packit 98cdb6
	    }
Packit 98cdb6
	}
Packit 98cdb6
Packit 98cdb6
      if (!success) 
Packit 98cdb6
	{
Packit 98cdb6
	  module = find_module (name);
Packit 98cdb6
Packit 98cdb6
	  if (module)
Packit 98cdb6
	    {
Packit 98cdb6
	      if (g_module_symbol (module, "gtk_module_init", &modinit_func_ptr))
Packit 98cdb6
		modinit_func = modinit_func_ptr;
Packit 98cdb6
	      else
Packit 98cdb6
		modinit_func = NULL;
Packit 98cdb6
Packit 98cdb6
	      if (!modinit_func)
Packit 98cdb6
		g_module_close (module);
Packit 98cdb6
	      else
Packit 98cdb6
		{
Packit 98cdb6
		  GSList *temp;
Packit 98cdb6
Packit 98cdb6
		  success = TRUE;
Packit 98cdb6
		  info = NULL;
Packit 98cdb6
Packit 98cdb6
		  temp = g_slist_find_custom (gtk_modules, module,
Packit 98cdb6
			(GCompareFunc)cmp_module);
Packit 98cdb6
		  if (temp != NULL)
Packit 98cdb6
			info = temp->data;
Packit 98cdb6
Packit 98cdb6
		  if (!info)
Packit 98cdb6
		    {
Packit 98cdb6
		      info = g_new0 (GtkModuleInfo, 1);
Packit 98cdb6
		      
Packit 98cdb6
		      info->names = g_slist_prepend (info->names, g_strdup (name));
Packit 98cdb6
		      info->module = module;
Packit 98cdb6
		      info->ref_count = 1;
Packit 98cdb6
		      info->init_func = modinit_func;
Packit 98cdb6
		      g_module_symbol (module, "gtk_module_display_init",
Packit 98cdb6
				       (gpointer *) &info->display_init_func);
Packit 98cdb6
		      
Packit 98cdb6
		      gtk_modules = g_slist_append (gtk_modules, info);
Packit 98cdb6
		      
Packit 98cdb6
		      /* display_init == NULL indicates a non-multihead aware module.
Packit 98cdb6
		       * For these, we delay the call to init_func until first display is 
Packit 98cdb6
		       * opened, see default_display_notify_cb().
Packit 98cdb6
		       * For multihead aware modules, we call init_func immediately,
Packit 98cdb6
		       * and also call display_init_func on all opened displays.
Packit 98cdb6
		       */
Packit 98cdb6
		      if (default_display_opened || info->display_init_func)
Packit 98cdb6
			(* info->init_func) (&gtk_argc, &gtk_argv);
Packit 98cdb6
		      
Packit 98cdb6
		      if (info->display_init_func) 
Packit 98cdb6
			{
Packit 98cdb6
			  GSList *displays, *iter; 		  
Packit 98cdb6
			  displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
Packit 98cdb6
			  for (iter = displays; iter; iter = iter->next)
Packit 98cdb6
			    {
Packit 98cdb6
			      GdkDisplay *display = iter->data;
Packit 98cdb6
			  (* info->display_init_func) (display);
Packit 98cdb6
			    }
Packit 98cdb6
			  g_slist_free (displays);
Packit 98cdb6
			}
Packit 98cdb6
		    }
Packit 98cdb6
		  else
Packit 98cdb6
		    {
Packit 98cdb6
		      GTK_NOTE (MODULES, g_print ("Module already loaded, ignoring: %s\n", name));
Packit 98cdb6
		      info->names = g_slist_prepend (info->names, g_strdup (name));
Packit 98cdb6
		      info->ref_count++;
Packit 98cdb6
		      /* remove new reference count on module, we already have one */
Packit 98cdb6
		      g_module_close (module);
Packit 98cdb6
		    }
Packit 98cdb6
		}
Packit 98cdb6
	    }
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (success)
Packit 98cdb6
    {
Packit 98cdb6
      if (!g_slist_find (module_list, info))
Packit 98cdb6
	{
Packit 98cdb6
	  module_list = g_slist_prepend (module_list, info);
Packit 98cdb6
	}
Packit 98cdb6
      else
Packit 98cdb6
        info->ref_count--;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
   {
Packit 98cdb6
      const gchar *error = g_module_error ();
Packit 98cdb6
Packit 98cdb6
      g_message ("Failed to load module \"%s\"%s%s",
Packit 98cdb6
                 name, error ? ": " : "", error ? error : "");
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return module_list;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gtk_module_info_unref (GtkModuleInfo *info)
Packit 98cdb6
{
Packit 98cdb6
  GSList *l;
Packit 98cdb6
Packit 98cdb6
  info->ref_count--;
Packit 98cdb6
Packit 98cdb6
  if (info->ref_count == 0) 
Packit 98cdb6
    {
Packit 98cdb6
      GTK_NOTE (MODULES, 
Packit 98cdb6
		g_print ("Unloading module: %s\n", g_module_name (info->module)));
Packit 98cdb6
Packit 98cdb6
      gtk_modules = g_slist_remove (gtk_modules, info);
Packit 98cdb6
      g_module_close (info->module);
Packit 98cdb6
      for (l = info->names; l; l = l->next)
Packit 98cdb6
	g_free (l->data);
Packit 98cdb6
      g_slist_free (info->names);
Packit 98cdb6
      g_free (info);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GSList *
Packit 98cdb6
load_modules (const char *module_str)
Packit 98cdb6
{
Packit 98cdb6
  gchar **module_names;
Packit 98cdb6
  GSList *module_list = NULL;
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  GTK_NOTE (MODULES, g_print ("Loading module list: %s\n", module_str));
Packit 98cdb6
Packit 98cdb6
  module_names = pango_split_file_list (module_str);
Packit 98cdb6
  for (i = 0; module_names[i]; i++) 
Packit 98cdb6
    module_list = load_module (module_list, module_names[i]);
Packit 98cdb6
Packit 98cdb6
  module_list = g_slist_reverse (module_list);
Packit 98cdb6
  g_strfreev (module_names);
Packit 98cdb6
Packit 98cdb6
  return module_list;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
default_display_notify_cb (GdkDisplayManager *display_manager)
Packit 98cdb6
{
Packit 98cdb6
  GSList *slist;
Packit 98cdb6
Packit 98cdb6
  /* Initialize non-multihead-aware modules when the
Packit 98cdb6
   * default display is first set to a non-NULL value.
Packit 98cdb6
   */
Packit 98cdb6
Packit 98cdb6
  if (!gdk_display_get_default () || default_display_opened)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  default_display_opened = TRUE;
Packit 98cdb6
Packit 98cdb6
  for (slist = gtk_modules; slist; slist = slist->next)
Packit 98cdb6
    {
Packit 98cdb6
      if (slist->data)
Packit 98cdb6
	{
Packit 98cdb6
	  GtkModuleInfo *info = slist->data;
Packit 98cdb6
Packit 98cdb6
	  if (!info->display_init_func)
Packit 98cdb6
	    (* info->init_func) (&gtk_argc, &gtk_argv);
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
display_closed_cb (GdkDisplay *display,
Packit 98cdb6
		   gboolean    is_error)
Packit 98cdb6
{
Packit 98cdb6
  GdkScreen *screen;
Packit 98cdb6
  GtkSettings *settings;
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  for (i = 0; i < gdk_display_get_n_screens (display); i++)
Packit 98cdb6
    {
Packit 98cdb6
      screen = gdk_display_get_screen (display, i);
Packit 98cdb6
Packit 98cdb6
      settings = gtk_settings_get_for_screen (screen);
Packit 98cdb6
Packit 98cdb6
      g_object_set_data_full (G_OBJECT (settings),
Packit 98cdb6
			      I_("gtk-modules"),
Packit 98cdb6
			      NULL, NULL);
Packit 98cdb6
    }  
Packit 98cdb6
}
Packit 98cdb6
		   
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
display_opened_cb (GdkDisplayManager *display_manager,
Packit 98cdb6
		   GdkDisplay        *display)
Packit 98cdb6
{
Packit 98cdb6
  GSList *slist;
Packit 98cdb6
  GdkScreen *screen;
Packit 98cdb6
  GtkSettings *settings;
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  for (slist = gtk_modules; slist; slist = slist->next)
Packit 98cdb6
    {
Packit 98cdb6
      if (slist->data)
Packit 98cdb6
	{
Packit 98cdb6
	  GtkModuleInfo *info = slist->data;
Packit 98cdb6
Packit 98cdb6
	  if (info->display_init_func)
Packit 98cdb6
	    (* info->display_init_func) (display);
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  for (i = 0; i < gdk_display_get_n_screens (display); i++)
Packit 98cdb6
    {
Packit 98cdb6
      GValue value = { 0, };
Packit 98cdb6
Packit 98cdb6
      g_value_init (&value, G_TYPE_STRING);
Packit 98cdb6
Packit 98cdb6
      screen = gdk_display_get_screen (display, i);
Packit 98cdb6
Packit 98cdb6
      if (gdk_screen_get_setting (screen, "gtk-modules", &value))
Packit 98cdb6
	{
Packit 98cdb6
	  settings = gtk_settings_get_for_screen (screen);
Packit 98cdb6
	  _gtk_modules_settings_changed (settings, g_value_get_string (&value));
Packit 98cdb6
	  g_value_unset (&value);
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* Since closing display doesn't actually release the resources yet,
Packit 98cdb6
   * we have to connect to the ::closed signal.
Packit 98cdb6
   */
Packit 98cdb6
  g_signal_connect (display, "closed", G_CALLBACK (display_closed_cb), NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_modules_init (gint        *argc, 
Packit 98cdb6
		   gchar     ***argv, 
Packit 98cdb6
		   const gchar *gtk_modules_args)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplayManager *display_manager;
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  g_assert (gtk_argv == NULL);
Packit 98cdb6
Packit 98cdb6
  if (argc && argv) 
Packit 98cdb6
    {
Packit 98cdb6
      /* store argc and argv for later use in mod initialization */
Packit 98cdb6
      gtk_argc = *argc;
Packit 98cdb6
      gtk_argv = g_new (gchar *, *argc + 1);
Packit 98cdb6
      for (i = 0; i < gtk_argc; i++)
Packit 98cdb6
	gtk_argv [i] = g_strdup ((*argv) [i]);
Packit 98cdb6
      gtk_argv [*argc] = NULL;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  display_manager = gdk_display_manager_get ();
Packit 98cdb6
  default_display_opened = gdk_display_get_default () != NULL;
Packit 98cdb6
  g_signal_connect (display_manager, "notify::default-display",
Packit 98cdb6
		    G_CALLBACK (default_display_notify_cb), 
Packit 98cdb6
		    NULL);
Packit 98cdb6
  g_signal_connect (display_manager, "display-opened",
Packit 98cdb6
		    G_CALLBACK (display_opened_cb), 
Packit 98cdb6
		    NULL);
Packit 98cdb6
Packit 98cdb6
  if (gtk_modules_args) {
Packit 98cdb6
    /* Modules specified in the GTK_MODULES environment variable
Packit 98cdb6
     * or on the command line are always loaded, so we'll just leak 
Packit 98cdb6
     * the refcounts.
Packit 98cdb6
     */
Packit 98cdb6
    g_slist_free (load_modules (gtk_modules_args));
Packit 98cdb6
  }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
settings_destroy_notify (gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  GSList *iter, *modules = data;
Packit 98cdb6
Packit 98cdb6
  for (iter = modules; iter; iter = iter->next) 
Packit 98cdb6
    {
Packit 98cdb6
      GtkModuleInfo *info = iter->data;
Packit 98cdb6
      gtk_module_info_unref (info);
Packit 98cdb6
    }
Packit 98cdb6
  g_slist_free (modules);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gtk_modules_settings_changed (GtkSettings *settings, 
Packit 98cdb6
			       const gchar *modules)
Packit 98cdb6
{
Packit 98cdb6
  GSList *new_modules = NULL;
Packit 98cdb6
Packit 98cdb6
  GTK_NOTE (MODULES, g_print ("gtk-modules setting changed to: %s\n", modules));
Packit 98cdb6
Packit 98cdb6
  /* load/ref before unreffing existing */
Packit 98cdb6
  if (modules && modules[0])
Packit 98cdb6
    new_modules = load_modules (modules);
Packit 98cdb6
Packit 98cdb6
  g_object_set_data_full (G_OBJECT (settings),
Packit 98cdb6
			  I_("gtk-modules"),
Packit 98cdb6
			  new_modules,
Packit 98cdb6
			  settings_destroy_notify);
Packit 98cdb6
}