]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkmain.c
Add GtkSpinner::animation-duration style property
[~andy/gtk] / gtk / gtkmain.c
index 20e0e6e181b667f24b1753392eace837c5da76f5..645da6f8f24b0e949f80637987b79818e7316429 100644 (file)
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include "config.h"
+
+#include <glib.h>
 #include "gdkconfig.h"
 
 #include <locale.h>
 
-#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
-#include <libintl.h>
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <gmodule.h>
-#ifdef G_OS_UNIX
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#include <sys/types.h>         /* For uid_t, gid_t */
 #endif
+#include <sys/types.h>         /* For uid_t, gid_t */
+
 #ifdef G_OS_WIN32
 #define STRICT
 #include <windows.h>
 #undef STRICT
 #endif
 
-#include <pango/pango-utils.h> /* For pango_split_file_list */
+#include "gtkintl.h"
 
 #include "gtkaccelmap.h"
 #include "gtkbox.h"
+#include "gtkclipboard.h"
 #include "gtkdnd.h"
 #include "gtkversion.h"
 #include "gtkmain.h"
+#include "gtkmodules.h"
 #include "gtkrc.h"
+#include "gtkrecentmanager.h"
 #include "gtkselection.h"
 #include "gtksettings.h"
 #include "gtkwidget.h"
 #include "gtkwindow.h"
-#include "gtkprivate.h"
-#include "config.h"
+#include "gtktooltip.h"
 #include "gtkdebug.h"
-#include "gtkintl.h"
+#include "gtkalias.h"
+
+#include "gdk/gdkprivate.h" /* for GDK_WINDOW_DESTROYED */
+
+#ifdef G_OS_WIN32
+
+static HMODULE gtk_dll;
+
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+        DWORD     fdwReason,
+        LPVOID    lpvReserved)
+{
+  switch (fdwReason)
+    {
+    case DLL_PROCESS_ATTACH:
+      gtk_dll = (HMODULE) hinstDLL;
+      break;
+    }
+
+  return TRUE;
+}
+
+/* These here before inclusion of gtkprivate.h so that the original
+ * GTK_LIBDIR and GTK_LOCALEDIR definitions are seen. Yeah, this is a
+ * bit sucky.
+ */
+const gchar *
+_gtk_get_libdir (void)
+{
+  static char *gtk_libdir = NULL;
+  if (gtk_libdir == NULL)
+    {
+      gchar *root = g_win32_get_package_installation_directory_of_module (gtk_dll);
+      gchar *slash = strrchr (root, '\\');
+      if (g_ascii_strcasecmp (slash + 1, ".libs") == 0)
+       gtk_libdir = GTK_LIBDIR;
+      else
+       gtk_libdir = g_build_filename (root, "lib", NULL);
+      g_free (root);
+    }
+
+  return gtk_libdir;
+}
+
+const gchar *
+_gtk_get_localedir (void)
+{
+  static char *gtk_localedir = NULL;
+  if (gtk_localedir == NULL)
+    {
+      const gchar *p;
+      gchar *root, *temp;
+      
+      /* GTK_LOCALEDIR ends in either /lib/locale or
+       * /share/locale. Scan for that slash.
+       */
+      p = GTK_LOCALEDIR + strlen (GTK_LOCALEDIR);
+      while (*--p != '/')
+       ;
+      while (*--p != '/')
+       ;
+
+      root = g_win32_get_package_installation_directory_of_module (gtk_dll);
+      temp = g_build_filename (root, p, NULL);
+      g_free (root);
+
+      /* gtk_localedir is passed to bindtextdomain() which isn't
+       * UTF-8-aware.
+       */
+      gtk_localedir = g_win32_locale_filename_from_utf8 (temp);
+      g_free (temp);
+    }
+  return gtk_localedir;
+}
+
+#endif
+
+#include "gtkprivate.h"
 
 /* Private type definitions
  */
@@ -69,7 +148,6 @@ typedef struct _GtkInitFunction               GtkInitFunction;
 typedef struct _GtkQuitFunction                 GtkQuitFunction;
 typedef struct _GtkClosure              GtkClosure;
 typedef struct _GtkKeySnooperData       GtkKeySnooperData;
-typedef struct _GtkModuleInfo            GtkModuleInfo;
 
 struct _GtkInitFunction
 {
@@ -84,14 +162,14 @@ struct _GtkQuitFunction
   GtkCallbackMarshal marshal;
   GtkFunction function;
   gpointer data;
-  GtkDestroyNotify destroy;
+  GDestroyNotify destroy;
 };
 
 struct _GtkClosure
 {
   GtkCallbackMarshal marshal;
   gpointer data;
-  GtkDestroyNotify destroy;
+  GDestroyNotify destroy;
 };
 
 struct _GtkKeySnooperData
@@ -101,12 +179,6 @@ struct _GtkKeySnooperData
   guint id;
 };
 
-struct _GtkModuleInfo
-{
-  GtkModuleInitFunc init_func;
-  GtkModuleDisplayInitFunc display_init_func;
-};
-
 static gint  gtk_quit_invoke_function   (GtkQuitFunction    *quitf);
 static void  gtk_quit_destroy           (GtkQuitFunction    *quitf);
 static gint  gtk_invoke_key_snoopers    (GtkWidget          *grab_widget,
@@ -133,14 +205,8 @@ const guint gtk_micro_version = GTK_MICRO_VERSION;
 const guint gtk_binary_age = GTK_BINARY_AGE;
 const guint gtk_interface_age = GTK_INTERFACE_AGE;
 
-static GSList *gtk_modules;
-
-/* Saved argc,argv for delayed module initialization
- */
-static gint    gtk_argc = 0;
-static gchar **gtk_argv = NULL;
-
 static guint gtk_main_loop_level = 0;
+static gint pre_initialized = FALSE;
 static gint gtk_initialized = FALSE;
 static GList *current_events = NULL;
 
@@ -150,8 +216,6 @@ static GList *init_functions = NULL;           /* A list of init functions.
                                            */
 static GList *quit_functions = NULL;      /* A list of quit functions.
                                            */
-static GMemChunk *quit_mem_chunk = NULL;
-
 static GSList *key_snoopers = NULL;
 
 guint gtk_debug_flags = 0;                /* Global GTK debug flag */
@@ -164,14 +228,50 @@ static const GDebugKey gtk_debug_keys[] = {
   {"tree", GTK_DEBUG_TREE},
   {"updates", GTK_DEBUG_UPDATES},
   {"keybindings", GTK_DEBUG_KEYBINDINGS},
-  {"multihead", GTK_DEBUG_MULTIHEAD}
+  {"multihead", GTK_DEBUG_MULTIHEAD},
+  {"modules", GTK_DEBUG_MODULES},
+  {"geometry", GTK_DEBUG_GEOMETRY},
+  {"icontheme", GTK_DEBUG_ICONTHEME},
+  {"printing", GTK_DEBUG_PRINTING},
+  {"builder", GTK_DEBUG_BUILDER}
 };
-
-static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey);
-
 #endif /* G_ENABLE_DEBUG */
 
-gchar*
+/**
+ * gtk_check_version:
+ * @required_major: the required major version.
+ * @required_minor: the required minor version.
+ * @required_micro: the required micro version.
+ * 
+ * Checks that the GTK+ library in use is compatible with the
+ * given version. Generally you would pass in the constants
+ * #GTK_MAJOR_VERSION, #GTK_MINOR_VERSION, #GTK_MICRO_VERSION
+ * as the three arguments to this function; that produces
+ * a check that the library in use is compatible with
+ * the version of GTK+ the application or module was compiled
+ * against.
+ *
+ * Compatibility is defined by two things: first the version
+ * of the running library is newer than the version
+ * @required_major.required_minor.@required_micro. Second
+ * the running library must be binary compatible with the
+ * version @required_major.required_minor.@required_micro
+ * (same major version.)
+ *
+ * This function is primarily for GTK+ modules; the module
+ * can call this function to check that it wasn't loaded
+ * into an incompatible version of GTK+. However, such a
+ * a check isn't completely reliable, since the module may be
+ * linked against an old version of GTK+ and calling the
+ * old version of gtk_check_version(), but still get loaded
+ * into an application using a newer version of GTK+.
+ *
+ * Return value: %NULL if the GTK+ library is compatible with the
+ *   given version, or a string describing the version mismatch.
+ *   The returned string is owned by GTK+ and should not be modified
+ *   or freed.
+ **/
+const gchar*
 gtk_check_version (guint required_major,
                   guint required_minor,
                   guint required_micro)
@@ -237,28 +337,18 @@ check_setugid (void)
 
 #ifdef G_OS_WIN32
 
-G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)
-
 const gchar *
-_gtk_get_libdir (void)
+_gtk_get_datadir (void)
 {
-  static char *gtk_libdir = NULL;
-  if (gtk_libdir == NULL)
-    gtk_libdir = g_win32_get_package_installation_subdirectory
-      (GETTEXT_PACKAGE, dll_name, "lib");
-
-  return gtk_libdir;
-}
-
-const gchar *
-_gtk_get_localedir (void)
-{
-  static char *gtk_localedir = NULL;
-  if (gtk_localedir == NULL)
-    gtk_localedir = g_win32_get_package_installation_subdirectory
-      (GETTEXT_PACKAGE, dll_name, "lib\\locale");
+  static char *gtk_datadir = NULL;
+  if (gtk_datadir == NULL)
+    {
+      gchar *root = g_win32_get_package_installation_directory_of_module (gtk_dll);
+      gtk_datadir = g_build_filename (root, "share", NULL);
+      g_free (root);
+    }
 
-  return gtk_localedir;
+  return gtk_datadir;
 }
 
 const gchar *
@@ -266,8 +356,11 @@ _gtk_get_sysconfdir (void)
 {
   static char *gtk_sysconfdir = NULL;
   if (gtk_sysconfdir == NULL)
-    gtk_sysconfdir = g_win32_get_package_installation_subdirectory
-      (GETTEXT_PACKAGE, dll_name, "etc");
+    {
+      gchar *root = g_win32_get_package_installation_directory_of_module (gtk_dll);
+      gtk_sysconfdir = g_build_filename (root, "etc", NULL);
+      g_free (root);
+    }
 
   return gtk_sysconfdir;
 }
@@ -277,347 +370,527 @@ _gtk_get_data_prefix (void)
 {
   static char *gtk_data_prefix = NULL;
   if (gtk_data_prefix == NULL)
-    gtk_data_prefix = g_win32_get_package_installation_directory
-      (GETTEXT_PACKAGE, dll_name);
+    gtk_data_prefix = g_win32_get_package_installation_directory_of_module (gtk_dll);
 
   return gtk_data_prefix;
 }
 
 #endif /* G_OS_WIN32 */
 
-static gchar **
-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;
-
-  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);
+static gboolean do_setlocale = TRUE;
 
-  module_path_env = g_getenv ("GTK_PATH");
-  exe_prefix = g_getenv ("GTK_EXE_PREFIX");
+/**
+ * gtk_disable_setlocale:
+ * 
+ * Prevents gtk_init(), gtk_init_check(), gtk_init_with_args() and
+ * gtk_parse_args() from automatically
+ * calling <literal>setlocale (LC_ALL, "")</literal>. You would 
+ * want to use this function if you wanted to set the locale for 
+ * your program to something other than the user's locale, or if 
+ * you wanted to set different values for different locale categories.
+ *
+ * Most programs should not need to call this function.
+ **/
+void
+gtk_disable_setlocale (void)
+{
+  if (pre_initialized)
+    g_warning ("gtk_disable_setlocale() must be called before gtk_init()");
+    
+  do_setlocale = FALSE;
+}
 
-  if (exe_prefix)
-    default_dir = g_build_filename (exe_prefix, "lib", "gtk-2.0", NULL);
-  else
-    default_dir = g_build_filename (GTK_LIBDIR, "gtk-2.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)
-    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);
+#ifdef G_PLATFORM_WIN32
+#undef gtk_init_check
+#endif
 
-  g_free (home_gtk_dir);
-  g_free (default_dir);
+static GString *gtk_modules_string = NULL;
+static gboolean g_fatal_warnings = FALSE;
 
-  result = pango_split_file_list (module_path);
-  g_free (module_path);
+#ifdef G_ENABLE_DEBUG
+static gboolean
+gtk_arg_debug_cb (const char *key, const char *value, gpointer user_data)
+{
+  gtk_debug_flags |= g_parse_debug_string (value,
+                                          gtk_debug_keys,
+                                          G_N_ELEMENTS (gtk_debug_keys));
 
-  return result;
+  return TRUE;
 }
 
-/**
- * _gtk_get_module_path:
- * @type: the type of the module, for instance 'modules', 'engines', immodules'
- * 
- * Determines the search path for a particular type of module.
- * 
- * Return value: the search path for the module type. Free with g_strfreev().
- **/
-gchar **
-_gtk_get_module_path (const gchar *type)
+static gboolean
+gtk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data)
 {
-  gchar **paths = get_module_path();
-  gchar **path;
-  gchar **result;
-  gint count = 0;
-
-  for (path = paths; *path; path++)
-    count++;
+  gtk_debug_flags &= ~g_parse_debug_string (value,
+                                           gtk_debug_keys,
+                                           G_N_ELEMENTS (gtk_debug_keys));
 
-  result = g_new (gchar *, count * 4 + 1);
+  return TRUE;
+}
+#endif /* G_ENABLE_DEBUG */
 
-  count = 0;
-  for (path = get_module_path (); *path; path++)
+static gboolean
+gtk_arg_module_cb (const char *key, const char *value, gpointer user_data)
+{
+  if (value && *value)
     {
-      gint use_version, use_host;
+      if (gtk_modules_string)
+       g_string_append_c (gtk_modules_string, G_SEARCHPATH_SEPARATOR);
+      else
+       gtk_modules_string = g_string_new (NULL);
       
-      for (use_version = TRUE; use_version >= FALSE; use_version--)
-       for (use_host = TRUE; use_host >= FALSE; use_host--)
-         {
-           gchar *tmp_dir;
-           
-           if (use_version && use_host)
-             tmp_dir = g_build_filename (*path, GTK_BINARY_VERSION, GTK_HOST, type, NULL);
-           else if (use_version)
-             tmp_dir = g_build_filename (*path, GTK_BINARY_VERSION, type, NULL);
-           else if (use_host)
-             tmp_dir = g_build_filename (*path, GTK_HOST, type, NULL);
-           else
-             tmp_dir = g_build_filename (*path, type, NULL);
-
-           result[count++] = tmp_dir;
-         }
+      g_string_append (gtk_modules_string, value);
     }
 
-  result[count++] = NULL;
-
-  return result;
+  return TRUE;
 }
 
-/* Like g_module_path, but use .la as the suffix
- */
-static gchar*
-module_build_la_path (const gchar *directory,
-                     const gchar *module_name)
+static const GOptionEntry gtk_args[] = {
+  { "gtk-module",       0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_module_cb,   
+    /* Description of --gtk-module=MODULES in --help output */ N_("Load additional GTK+ modules"), 
+    /* Placeholder in --gtk-module=MODULES in --help output */ N_("MODULES") },
+  { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, 
+    /* Description of --g-fatal-warnings in --help output */   N_("Make all warnings fatal"), NULL },
+#ifdef G_ENABLE_DEBUG
+  { "gtk-debug",        0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_debug_cb,    
+    /* Description of --gtk-debug=FLAGS in --help output */    N_("GTK+ debugging flags to set"), 
+    /* Placeholder in --gtk-debug=FLAGS in --help output */    N_("FLAGS") },
+  { "gtk-no-debug",     0, 0, G_OPTION_ARG_CALLBACK, gtk_arg_no_debug_cb, 
+    /* Description of --gtk-no-debug=FLAGS in --help output */ N_("GTK+ debugging flags to unset"), 
+    /* Placeholder in --gtk-no-debug=FLAGS in --help output */ N_("FLAGS") },
+#endif 
+  { NULL }
+};
+
+#ifdef G_OS_WIN32
+
+static char *iso639_to_check = NULL;
+static char *iso3166_to_check = NULL;
+static char *script_to_check = NULL;
+static gboolean setlocale_called = FALSE;
+
+static BOOL CALLBACK
+enum_locale_proc (LPTSTR locale)
 {
-       gchar *filename;
-       gchar *result;
-       
-       if (strncmp (module_name, "lib", 3) == 0)
-               filename = (gchar *)module_name;
-       else
-               filename =  g_strconcat ("lib", module_name, ".la", NULL);
+  LCID lcid;
+  char iso639[10];
+  char iso3166[10];
+  char *endptr;
+
+
+  lcid = strtoul (locale, &endptr, 16);
+  if (*endptr == '\0' &&
+      GetLocaleInfo (lcid, LOCALE_SISO639LANGNAME, iso639, sizeof (iso639)) &&
+      GetLocaleInfo (lcid, LOCALE_SISO3166CTRYNAME, iso3166, sizeof (iso3166)))
+    {
+      if (strcmp (iso639, iso639_to_check) == 0 &&
+         ((iso3166_to_check != NULL &&
+           strcmp (iso3166, iso3166_to_check) == 0) ||
+          (iso3166_to_check == NULL &&
+           SUBLANGID (LANGIDFROMLCID (lcid)) == SUBLANG_DEFAULT)))
+       {
+         char language[100], country[100];
+         char locale[300];
+
+         if (script_to_check != NULL)
+           {
+             /* If lcid is the "other" script for this language,
+              * return TRUE, i.e. continue looking.
+              */
+             if (strcmp (script_to_check, "Latn") == 0)
+               {
+                 switch (LANGIDFROMLCID (lcid))
+                   {
+                   case MAKELANGID (LANG_AZERI, SUBLANG_AZERI_CYRILLIC):
+                     return TRUE;
+                   case MAKELANGID (LANG_UZBEK, SUBLANG_UZBEK_CYRILLIC):
+                     return TRUE;
+                   case MAKELANGID (LANG_SERBIAN, SUBLANG_SERBIAN_CYRILLIC):
+                     return TRUE;
+                   case MAKELANGID (LANG_SERBIAN, 0x07):
+                     /* Serbian in Bosnia and Herzegovina, Cyrillic */
+                     return TRUE;
+                   }
+               }
+             else if (strcmp (script_to_check, "Cyrl") == 0)
+               {
+                 switch (LANGIDFROMLCID (lcid))
+                   {
+                   case MAKELANGID (LANG_AZERI, SUBLANG_AZERI_LATIN):
+                     return TRUE;
+                   case MAKELANGID (LANG_UZBEK, SUBLANG_UZBEK_LATIN):
+                     return TRUE;
+                   case MAKELANGID (LANG_SERBIAN, SUBLANG_SERBIAN_LATIN):
+                     return TRUE;
+                   case MAKELANGID (LANG_SERBIAN, 0x06):
+                     /* Serbian in Bosnia and Herzegovina, Latin */
+                     return TRUE;
+                   }
+               }
+           }
 
-       if (directory && *directory)
-               result = g_build_filename (directory, filename, NULL);
-       else
-               result = g_strdup (filename);
+         SetThreadLocale (lcid);
 
-       if (filename != module_name)
-               g_free (filename);
+         if (GetLocaleInfo (lcid, LOCALE_SENGLANGUAGE, language, sizeof (language)) &&
+             GetLocaleInfo (lcid, LOCALE_SENGCOUNTRY, country, sizeof (country)))
+           {
+             strcpy (locale, language);
+             strcat (locale, "_");
+             strcat (locale, country);
+
+             if (setlocale (LC_ALL, locale) != NULL)
+               setlocale_called = TRUE;
+           }
 
-       return result;
+         return FALSE;
+       }
+    }
+
+  return TRUE;
 }
+  
+#endif
 
-/**
- * _gtk_find_module:
- * @name: the name of the module
- * @type: the type of the module, for instance 'modules', 'engines', immodules'
- * 
- * Looks for a dynamically module named @name of type @type in the standard GTK+
- *  module search path.
- * 
- * Return value: the pathname to the found module, or %NULL if it wasn't found.
- *  Free with g_free().
- **/
-gchar *
-_gtk_find_module (const gchar *name,
-                 const gchar *type)
+static void
+setlocale_initialization (void)
 {
-  gchar **paths;
-  gchar **path;
-  gchar *module_name = NULL;
+  static gboolean initialized = FALSE;
 
-  if (g_path_is_absolute (name))
-    return g_strdup (name);
+  if (initialized)
+    return;
+  initialized = TRUE;
 
-  paths = _gtk_get_module_path (type);
-  for (path = paths; *path; path++)
+  if (do_setlocale)
     {
-      gchar *tmp_name;
+#ifdef G_OS_WIN32
+      /* If some of the POSIXish environment variables are set, set
+       * the Win32 thread locale correspondingly.
+       */ 
+      char *p = getenv ("LC_ALL");
+      if (p == NULL)
+       p = getenv ("LANG");
 
-      tmp_name = g_module_build_path (*path, name);
-      if (g_file_test (tmp_name, G_FILE_TEST_EXISTS))
+      if (p != NULL)
        {
-         module_name = tmp_name;
-         goto found;
-       }
-      g_free(tmp_name);
+         p = g_strdup (p);
+         if (strcmp (p, "C") == 0)
+           SetThreadLocale (LOCALE_SYSTEM_DEFAULT);
+         else
+           {
+             /* Check if one of the supported locales match the
+              * environment variable. If so, use that locale.
+              */
+             iso639_to_check = p;
+             iso3166_to_check = strchr (iso639_to_check, '_');
+             if (iso3166_to_check != NULL)
+               {
+                 *iso3166_to_check++ = '\0';
 
-      tmp_name = module_build_la_path (*path, name);
-      if (g_file_test (tmp_name, G_FILE_TEST_EXISTS))
-       {
-         module_name = tmp_name;
-         goto found;
+                 script_to_check = strchr (iso3166_to_check, '@');
+                 if (script_to_check != NULL)
+                   *script_to_check++ = '\0';
+
+                 /* Handle special cases. */
+                 
+                 /* The standard code for Serbia and Montenegro was
+                  * "CS", but MSFT uses for some reason "SP". By now
+                  * (October 2006), SP has split into two, "RS" and
+                  * "ME", but don't bother trying to handle those
+                  * yet. Do handle the even older "YU", though.
+                  */
+                 if (strcmp (iso3166_to_check, "CS") == 0 ||
+                     strcmp (iso3166_to_check, "YU") == 0)
+                   iso3166_to_check = "SP";
+               }
+             else
+               {
+                 script_to_check = strchr (iso639_to_check, '@');
+                 if (script_to_check != NULL)
+                   *script_to_check++ = '\0';
+                 /* LANG_SERBIAN == LANG_CROATIAN, recognize just "sr" */
+                 if (strcmp (iso639_to_check, "sr") == 0)
+                   iso3166_to_check = "SP";
+               }
+
+             EnumSystemLocales (enum_locale_proc, LCID_SUPPORTED);
+           }
+         g_free (p);
        }
-      g_free(tmp_name);
+      if (!setlocale_called)
+       setlocale (LC_ALL, "");
+#else
+      if (!setlocale (LC_ALL, ""))
+       g_warning ("Locale not supported by C library.\n\tUsing the fallback 'C' locale.");
+#endif
     }
-
- found:
-  g_strfreev (paths);
-  return module_name;
 }
 
-static GModule *
-find_module (const gchar *name)
+static void
+do_pre_parse_initialization (int    *argc,
+                            char ***argv)
 {
-  GModule *module;
-  gchar *module_name;
+  const gchar *env_string;
+  
+#if    0
+  g_set_error_handler (gtk_error);
+  g_set_warning_handler (gtk_warning);
+  g_set_message_handler (gtk_message);
+  g_set_print_handler (gtk_print);
+#endif
+
+  if (pre_initialized)
+    return;
+
+  pre_initialized = TRUE;
 
-  module_name = _gtk_find_module (name, "modules");
-  if (!module_name)
+  gdk_pre_parse_libgtk_only ();
+  gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL);
+  
+#ifdef G_ENABLE_DEBUG
+  env_string = g_getenv ("GTK_DEBUG");
+  if (env_string != NULL)
     {
-      /* As last resort, try loading without an absolute path (using system
-       * library path)
-       */
-      module_name = g_module_build_path (NULL, name);
+      gtk_debug_flags = g_parse_debug_string (env_string,
+                                             gtk_debug_keys,
+                                             G_N_ELEMENTS (gtk_debug_keys));
+      env_string = NULL;
     }
-  
-  module = g_module_open (module_name, G_MODULE_BIND_LAZY);
-  g_free(module_name);
+#endif /* G_ENABLE_DEBUG */
 
-  return module;
+  env_string = g_getenv ("GTK_MODULES");
+  if (env_string)
+    gtk_modules_string = g_string_new (env_string);
 }
 
-static GSList *
-load_module (GSList      *module_list,
-            const gchar *name)
+static void
+gettext_initialization (void)
 {
-  GtkModuleInitFunc modinit_func = NULL;
-  GtkModuleInfo *info;
-  GModule *module = NULL;
-  
-  if (g_module_supported ())
+  setlocale_initialization ();
+
+#ifdef ENABLE_NLS
+  bindtextdomain (GETTEXT_PACKAGE, GTK_LOCALEDIR);
+  bindtextdomain (GETTEXT_PACKAGE "-properties", GTK_LOCALEDIR);
+#    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+  bind_textdomain_codeset (GETTEXT_PACKAGE "-properties", "UTF-8");
+#    endif
+#endif  
+}
+
+static void
+do_post_parse_initialization (int    *argc,
+                             char ***argv)
+{
+  if (gtk_initialized)
+    return;
+
+  gettext_initialization ();
+
+#ifdef SIGPIPE
+  signal (SIGPIPE, SIG_IGN);
+#endif
+
+  if (g_fatal_warnings)
     {
-      module = find_module (name);
-      if (module &&
-         g_module_symbol (module, "gtk_module_init", (gpointer *) &modinit_func) &&
-         modinit_func)
-       {
-         if (!g_slist_find (module_list, (gconstpointer) modinit_func))
-           {
-             g_module_make_resident (module);
-             info = g_new (GtkModuleInfo, 1);
+      GLogLevelFlags fatal_mask;
 
-             info->init_func = modinit_func;
-             g_module_symbol (module, "gtk_module_display_init",
-                              (gpointer *) &info->display_init_func);
-             
-             module_list = g_slist_prepend (module_list, info);
-           }
-         else
-           {
-             g_module_close (module);
-             module = NULL;
-           }
-       }
+      fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+      fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+      g_log_set_always_fatal (fatal_mask);
     }
-  if (!modinit_func)
+
+  if (gtk_debug_flags & GTK_DEBUG_UPDATES)
+    gdk_window_set_debug_updates (TRUE);
+
+  {
+  /* Translate to default:RTL if you want your widgets
+   * to be RTL, otherwise translate to default:LTR.
+   * Do *not* translate it to "predefinito:LTR", if it
+   * it isn't default:LTR or default:RTL it will not work 
+   */
+    char *e = _("default:LTR");
+    if (strcmp (e, "default:RTL")==0) 
+      gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
+    else if (strcmp (e, "default:LTR"))
+      g_warning ("Whoever translated default:LTR did so wrongly.\n");
+  }
+
+  /* do what the call to gtk_type_init() used to do */
+  g_type_init ();
+  gtk_object_get_type ();
+
+  _gtk_accel_map_init ();
+  _gtk_rc_init ();
+
+  /* Set the 'initialized' flag.
+   */
+  gtk_initialized = TRUE;
+
+  /* load gtk modules */
+  if (gtk_modules_string)
     {
-      g_message ("Failed to load module \"%s\": %s",
-                module ? g_module_name (module) : name,
-                g_module_error ());
-      if (module)
-       g_module_close (module);
+      _gtk_modules_init (argc, argv, gtk_modules_string->str);
+      g_string_free (gtk_modules_string, TRUE);
+    }
+  else
+    {
+      _gtk_modules_init (argc, argv, NULL);
     }
-  
-  return module_list;
 }
 
-static GSList *
-load_modules (const char *module_str)
+
+typedef struct
+{
+  gboolean open_default_display;
+} OptionGroupInfo;
+
+static gboolean
+pre_parse_hook (GOptionContext *context,
+               GOptionGroup   *group,
+               gpointer        data,
+               GError        **error)
 {
-  gchar **module_names = pango_split_file_list (module_str);
-  GSList *module_list = NULL;
-  gint i;
+  do_pre_parse_initialization (NULL, NULL);
   
-  for (i = 0; module_names[i]; i++)
-    module_list = load_module (module_list, module_names[i]);
+  return TRUE;
+}
+
+static gboolean
+post_parse_hook (GOptionContext *context,
+                GOptionGroup   *group,
+                gpointer       data,
+                GError        **error)
+{
+  OptionGroupInfo *info = data;
+
   
-  module_list = g_slist_reverse (module_list);
+  do_post_parse_initialization (NULL, NULL);
   
-  g_strfreev (module_names);
+  if (info->open_default_display)
+    {
+      if (gdk_display_open_default_libgtk_only () == NULL)
+       {
+         const char *display_name = gdk_get_display_arg_name ();
+         g_set_error (error, 
+                      G_OPTION_ERROR, 
+                      G_OPTION_ERROR_FAILED,
+                      _("Cannot open display: %s"),
+                      display_name ? display_name : "" );
+         
+         return FALSE;
+       }
+    }
 
-  return module_list;
+  return TRUE;
 }
 
-static gboolean do_setlocale = TRUE;
 
 /**
- * gtk_disable_setlocale:
+ * gtk_get_option_group:
+ * @open_default_display: whether to open the default display 
+ *    when parsing the commandline arguments
  * 
- * Prevents gtk_init() and gtk_init_check() from automatically
- * calling <literal>setlocale (LC_ALL, "")</literal>. You would 
- * want to use this function if you wanted to set the locale for 
- * your program to something other than the user's locale, or if 
- * you wanted to set different values for different locale categories.
+ * Returns a #GOptionGroup for the commandline arguments recognized
+ * by GTK+ and GDK. You should add this group to your #GOptionContext 
+ * with g_option_context_add_group(), if you are using 
+ * g_option_context_parse() to parse your commandline arguments.
  *
- * Most programs should not need to call this function.
- **/
-void
-gtk_disable_setlocale (void)
+ * Returns: a #GOptionGroup for the commandline arguments recognized
+ *   by GTK+
+ *
+ * Since: 2.6
+ */
+GOptionGroup *
+gtk_get_option_group (gboolean open_default_display)
 {
-  if (gtk_initialized)
-    g_warning ("gtk_disable_setlocale() must be called before gtk_init()");
-    
-  do_setlocale = FALSE;
-}
+  GOptionGroup *group;
+  OptionGroupInfo *info;
 
-#undef gtk_init_check
+  gettext_initialization ();
 
-static void
-default_display_notify_cb (GdkDisplayManager *display_manager)
-{
-  GSList *slist;
+  info = g_new0 (OptionGroupInfo, 1);
+  info->open_default_display = open_default_display;
+  
+  group = g_option_group_new ("gtk", _("GTK+ Options"), _("Show GTK+ Options"), info, g_free);
+  g_option_group_set_parse_hooks (group, pre_parse_hook, post_parse_hook);
 
-  /* Initialize non-multihead-aware modules when the
-   * default display is first set to a non-NULL value.
-   */
-  static gboolean initialized = FALSE;
+  gdk_add_option_entries_libgtk_only (group);
+  g_option_group_add_entries (group, gtk_args);
+  g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
+  
+  return group;
+}
 
-  if (!gdk_display_get_default () || initialized)
-    return;
+/**
+ * gtk_init_with_args:
+ * @argc: a pointer to the number of command line arguments.
+ * @argv: a pointer to the array of command line arguments.
+ * @parameter_string: a string which is displayed in
+ *    the first line of <option>--help</option> output, after 
+ *    <literal><replaceable>programname</replaceable> [OPTION...]</literal>
+ * @entries: a %NULL-terminated array of #GOptionEntry<!-- -->s
+ *    describing the options of your program
+ * @translation_domain: a translation domain to use for translating
+ *    the <option>--help</option> output for the options in @entries
+ *    with gettext(), or %NULL
+ * @error: a return location for errors 
+ *
+ * This function does the same work as gtk_init_check(). 
+ * Additionally, it allows you to add your own commandline options, 
+ * and it automatically generates nicely formatted 
+ * <option>--help</option> output. Note that your program will
+ * be terminated after writing out the help output.
+ *
+ * Returns: %TRUE if the GUI has been successfully initialized, 
+ *               %FALSE otherwise.
+ * 
+ * Since: 2.6
+ */
+gboolean
+gtk_init_with_args (int            *argc,
+                   char         ***argv,
+                   char           *parameter_string,  
+                   GOptionEntry   *entries,
+                   char           *translation_domain,
+                   GError        **error)
+{
+  GOptionContext *context;
+  GOptionGroup *gtk_group;
+  gboolean retval;
 
-  initialized = TRUE;
+  if (gtk_initialized)
+    return gdk_display_open_default_libgtk_only () != NULL;
 
-  for (slist = gtk_modules; slist; slist = slist->next)
-    {
-      if (slist->data)
-       {
-         GtkModuleInfo *info = slist->data;
+  gettext_initialization ();
 
-         if (!info->display_init_func)
-           info->init_func (&gtk_argc, &gtk_argv);
-       }
-    }
-}
+  if (!check_setugid ())
+    return FALSE;
 
-static void
-display_opened_cb (GdkDisplayManager *display_manager,
-                  GdkDisplay        *display)
-{
-  GSList *slist;
+  gtk_group = gtk_get_option_group (TRUE);
+  
+  context = g_option_context_new (parameter_string);
+  g_option_context_add_group (context, gtk_group);
   
-  for (slist = gtk_modules; slist; slist = slist->next)
-    {
-      if (slist->data)
-       {
-         GtkModuleInfo *info = slist->data;
+  if (entries)
+    g_option_context_add_main_entries (context, entries, translation_domain);
+  retval = g_option_context_parse (context, argc, argv, error);
+  
+  g_option_context_free (context);
 
-         if (info->display_init_func)
-           info->display_init_func (display);
-       }
-    }
+  return retval;
 }
 
+
 /**
- * gdk_parse_args:
- * @argc: the number of command line arguments.
- * @argv: the array of command line arguments.
+ * gtk_parse_args:
+ * @argc: a pointer to the number of command line arguments.
+ * @argv: a pointer to the array of command line arguments.
  * 
  * Parses command line arguments, and initializes global
  * attributes of GTK+, but does not actually open a connection
  * to a display. (See gdk_display_open(), gdk_get_display_arg_name())
  *
- * Any arguments used by GTK or GDK are removed from the array and
+ * Any arguments used by GTK+ or GDK are removed from the array and
  * @argc and @argv are updated accordingly.
  *
  * You shouldn't call this function explicitely if you are using
@@ -629,228 +902,44 @@ gboolean
 gtk_parse_args (int    *argc,
                char ***argv)
 {
-  GString *gtk_modules_string = NULL;
-  GSList *slist;
-  GdkDisplayManager *display_manager;
-  const gchar *env_string;
-
+  GOptionContext *option_context;
+  GOptionGroup *gtk_group;
+  GError *error = NULL;
+  
   if (gtk_initialized)
     return TRUE;
 
+  gettext_initialization ();
+
   if (!check_setugid ())
     return FALSE;
-  
-#if    0
-  g_set_error_handler (gtk_error);
-  g_set_warning_handler (gtk_warning);
-  g_set_message_handler (gtk_message);
-  g_set_print_handler (gtk_print);
-#endif
-
-  if (do_setlocale)
-    {
-      if (!setlocale (LC_ALL, ""))
-       g_warning ("Locale not supported by C library.\n\tUsing the fallback 'C' locale.");
-    }
-
-  gdk_parse_args (argc, argv);
-  gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL);
-  
-#ifdef G_ENABLE_DEBUG
-  env_string = g_getenv ("GTK_DEBUG");
-  if (env_string != NULL)
-    {
-      gtk_debug_flags = g_parse_debug_string (env_string,
-                                             gtk_debug_keys,
-                                             gtk_ndebug_keys);
-      env_string = NULL;
-    }
-#endif /* G_ENABLE_DEBUG */
-
-  env_string = g_getenv ("GTK_MODULES");
-  if (env_string)
-    gtk_modules_string = g_string_new (env_string);
-
-  if (argc && argv)
-    {
-      gint i, j, k;
-      
-      for (i = 1; i < *argc;)
-       {
-         if (strcmp ("--gtk-module", (*argv)[i]) == 0 ||
-             strncmp ("--gtk-module=", (*argv)[i], 13) == 0)
-           {
-             gchar *module_name = (*argv)[i] + 12;
-             
-             if (*module_name == '=')
-               module_name++;
-             else if (i + 1 < *argc)
-               {
-                 (*argv)[i] = NULL;
-                 i += 1;
-                 module_name = (*argv)[i];
-               }
-             (*argv)[i] = NULL;
-
-             if (module_name && *module_name)
-               {
-                 if (gtk_modules_string)
-                   g_string_append_c (gtk_modules_string, G_SEARCHPATH_SEPARATOR);
-                 else
-                   gtk_modules_string = g_string_new (NULL);
-
-                 g_string_append (gtk_modules_string, module_name);
-               }
-           }
-         else if (strcmp ("--g-fatal-warnings", (*argv)[i]) == 0)
-           {
-             GLogLevelFlags fatal_mask;
-             
-             fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
-             fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
-              g_log_set_always_fatal (fatal_mask);
-             (*argv)[i] = NULL;
-           }
-#ifdef G_ENABLE_DEBUG
-         else if ((strcmp ("--gtk-debug", (*argv)[i]) == 0) ||
-                  (strncmp ("--gtk-debug=", (*argv)[i], 12) == 0))
-           {
-             gchar *equal_pos = strchr ((*argv)[i], '=');
-             
-             if (equal_pos != NULL)
-               {
-                 gtk_debug_flags |= g_parse_debug_string (equal_pos+1,
-                                                          gtk_debug_keys,
-                                                          gtk_ndebug_keys);
-               }
-             else if ((i + 1) < *argc && (*argv)[i + 1])
-               {
-                 gtk_debug_flags |= g_parse_debug_string ((*argv)[i+1],
-                                                          gtk_debug_keys,
-                                                          gtk_ndebug_keys);
-                 (*argv)[i] = NULL;
-                 i += 1;
-               }
-             (*argv)[i] = NULL;
-           }
-         else if ((strcmp ("--gtk-no-debug", (*argv)[i]) == 0) ||
-                  (strncmp ("--gtk-no-debug=", (*argv)[i], 15) == 0))
-           {
-             gchar *equal_pos = strchr ((*argv)[i], '=');
-             
-             if (equal_pos != NULL)
-               {
-                 gtk_debug_flags &= ~g_parse_debug_string (equal_pos+1,
-                                                           gtk_debug_keys,
-                                                           gtk_ndebug_keys);
-               }
-             else if ((i + 1) < *argc && (*argv)[i + 1])
-               {
-                 gtk_debug_flags &= ~g_parse_debug_string ((*argv)[i+1],
-                                                           gtk_debug_keys,
-                                                           gtk_ndebug_keys);
-                 (*argv)[i] = NULL;
-                 i += 1;
-               }
-             (*argv)[i] = NULL;
-           }
-#endif /* G_ENABLE_DEBUG */
-         i += 1;
-       }
-      
-      for (i = 1; i < *argc; i++)
-       {
-         for (k = i; k < *argc; k++)
-           if ((*argv)[k] != NULL)
-             break;
-         
-         if (k > i)
-           {
-             k -= i;
-             for (j = i + k; j < *argc; j++)
-               (*argv)[j-k] = (*argv)[j];
-             *argc -= k;
-           }
-       }
-
-      gtk_argv = g_malloc ((gtk_argc + 1) * sizeof (char*));
-      for (i = 0; i < gtk_argc; i++)
-       gtk_argv[i] = g_strdup ((*argv)[i]);
-      gtk_argv[gtk_argc] = NULL;
-    }
-
-  if (gtk_debug_flags & GTK_DEBUG_UPDATES)
-    gdk_window_set_debug_updates (TRUE);
 
-  /* load gtk modules */
-  if (gtk_modules_string)
+  option_context = g_option_context_new (NULL);
+  g_option_context_set_ignore_unknown_options (option_context, TRUE);
+  g_option_context_set_help_enabled (option_context, FALSE);
+  gtk_group = gtk_get_option_group (FALSE);
+  g_option_context_set_main_group (option_context, gtk_group);
+  if (!g_option_context_parse (option_context, argc, argv, &error))
     {
-      gtk_modules = load_modules (gtk_modules_string->str);
-      g_string_free (gtk_modules_string, TRUE);
-    }
-
-#ifdef ENABLE_NLS
-  bindtextdomain (GETTEXT_PACKAGE, GTK_LOCALEDIR);
-#    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
-  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-#    endif
-#endif  
-
-  {
-  /* Translate to default:RTL if you want your widgets
-   * to be RTL, otherwise translate to default:LTR.
-   * Do *not* translate it to "predefinito:LTR", if it
-   * it isn't default:LTR or default:RTL it will not work 
-   */
-    char *e = _("default:LTR");
-    if (strcmp (e, "default:RTL")==0) {
-      gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
-    } else if (strcmp (e, "default:LTR")) {
-      g_warning ("Whoever translated default:LTR did so wrongly.\n");
+      g_warning ("%s", error->message);
+      g_error_free (error);
     }
-  }
-
-  gtk_type_init (0);
-  _gtk_accel_map_init ();  
-  _gtk_rc_init ();
-  
-  /* Set the 'initialized' flag.
-   */
-  gtk_initialized = TRUE;
 
-  display_manager = gdk_display_manager_get ();
-  g_signal_connect (display_manager, "notify::default-display",
-                   G_CALLBACK (default_display_notify_cb), NULL);
-  g_signal_connect (display_manager, "display-opened",
-                   G_CALLBACK (display_opened_cb), NULL);
+  g_option_context_free (option_context);
 
-  /* initialize multhead aware gtk modules; for other modules,
-   * we wait until we have a display open;
-   */
-  for (slist = gtk_modules; slist; slist = slist->next)
-    {
-      if (slist->data)
-       {
-         GtkModuleInfo *info = slist->data;
-
-         if (info->display_init_func)
-           info->init_func (argc, argv);
-       }
-    }
-  
   return TRUE;
 }
 
+#ifdef G_PLATFORM_WIN32
 #undef gtk_init_check
+#endif
 
 /**
  * gtk_init_check:
  * @argc: Address of the <parameter>argc</parameter> parameter of your 
- *   <function>main()</function> function. Changed if any arguments were 
- *   handled.
- * @argv: Address of the <parameter>argv</parameter> parameter of 
- *   <function>main()</function>. Any parameters understood by gtk_init() 
- *   are stripped before return.
+ *   main() function. Changed if any arguments were handled.
+ * @argv: Address of the <parameter>argv</parameter> parameter of main(). 
+ *   Any parameters understood by gtk_init() are stripped before return.
  * 
  * This function does the same work as gtk_init() with only 
  * a single change: It does not terminate the program if the GUI can't be 
@@ -872,28 +961,43 @@ gtk_init_check (int        *argc,
   return gdk_display_open_default_libgtk_only () != NULL;
 }
 
+#ifdef G_PLATFORM_WIN32
 #undef gtk_init
+#endif
 
 /**
  * gtk_init:
  * @argc: Address of the <parameter>argc</parameter> parameter of your 
- *   <function>main()</function> function. Changed if any arguments were 
- *   handled.
- * @argv: Address of the <parameter>argv</parameter> parameter of 
- *   <function>main()</function>. Any parameters understood by gtk_init() 
- *   are stripped before return.
+ *   main() function. Changed if any arguments were handled.
+ * @argv: Address of the <parameter>argv</parameter> parameter of main(). 
+ *   Any parameters understood by gtk_init() are stripped before return.
  * 
  * Call this function before using any other GTK+ functions in your GUI
- * applications.  It will initialize everything needed to operate the toolkit and
- * parses some standard command line options. @argc and 
+ * applications.  It will initialize everything needed to operate the 
+ * toolkit and parses some standard command line options. @argc and 
  * @argv are adjusted accordingly so your own code will 
- * never see those standard arguments.
+ * never see those standard arguments. 
+ *
+ * Note that there are some alternative ways to initialize GTK+: 
+ * if you are calling gtk_parse_args(), gtk_init_check(), 
+ * gtk_init_with_args() or g_option_context_parse() with 
+ * the option group returned by gtk_get_option_group(), you 
+ * <emphasis>don't</emphasis> have to call gtk_init().
  *
  * <note><para>
  * This function will terminate your program if it was unable to initialize 
  * the GUI for some reason. If you want your program to fall back to a 
  * textual interface you want to call gtk_init_check() instead.
  * </para></note>
+ *
+ * <note><para>
+ * Since 2.18, GTK+ calls <literal>signal (SIGPIPE, SIG_IGN)</literal>
+ * during initialization, to ignore SIGPIPE signals, since these are
+ * almost never wanted in graphical applications. If you do need to
+ * handle SIGPIPE for some reason, reset the handler after gtk_init(),
+ * but notice that other libraries (e.g. libdbus or gvfs) might do
+ * similar things.
+ * </para></note>
  **/
 void
 gtk_init (int *argc, char ***argv)
@@ -901,7 +1005,9 @@ gtk_init (int *argc, char ***argv)
   if (!gtk_init_check (argc, argv))
     {
       const char *display_name_arg = gdk_get_display_arg_name ();
-      g_warning ("cannot open display: %s", display_name_arg ? display_name_arg : " ");
+      if (display_name_arg == NULL)
+        display_name_arg = getenv("DISPLAY");
+      g_warning ("cannot open display: %s", display_name_arg ? display_name_arg : "");
       exit (1);
     }
 }
@@ -916,9 +1022,8 @@ check_sizeof_GtkWindow (size_t sizeof_GtkWindow)
             "The code using GTK+ thinks GtkWindow is of different\n"
              "size than it actually is in this build of GTK+.\n"
             "On Windows, this probably means that you have compiled\n"
-            "your code with gcc without the -fnative-struct\n"
-            "(or -mms-bitfields) switch, or that you are using\n"
-            "an unsupported compiler.");
+            "your code with gcc without the -mms-bitfields switch,\n"
+            "or that you are using an unsupported compiler.");
 }
 
 /* In GTK+ 2.0 the GtkWindow struct actually is the same size in
@@ -935,9 +1040,8 @@ check_sizeof_GtkBox (size_t sizeof_GtkBox)
             "The code using GTK+ thinks GtkBox is of different\n"
              "size than it actually is in this build of GTK+.\n"
             "On Windows, this probably means that you have compiled\n"
-            "your code with gcc without the -fnative-struct\n"
-            "(or -mms-bitfields) switch, or that you are using\n"
-            "an unsupported compiler.");
+            "your code with gcc without the -mms-bitfields switch,\n"
+            "or that you are using an unsupported compiler.");
 }
 
 /* These two functions might get more checks added later, thus pass
@@ -988,75 +1092,98 @@ gtk_exit (gint errorcode)
  * <literal>setlocale (LC_ALL, "")</literal> but also takes care of the 
  * locale specific setup of the windowing system used by GDK.
  * 
- * Return value: a string corresponding to the locale set, as with the
- * C library function <function>setlocale()</function>.
+ * Returns: a string corresponding to the locale set, typically in the
+ * form lang_COUNTRY, where lang is an ISO-639 language code, and
+ * COUNTRY is an ISO-3166 country code. On Unix, this form matches the
+ * result of the setlocale(); it is also used on other machines, such as 
+ * Windows, where the C library returns a different result. The string is 
+ * owned by GTK+ and should not be modified or freed.
  **/
-gchar*
+gchar *
 gtk_set_locale (void)
 {
   return gdk_set_locale ();
 }
 
 /**
- * gtk_get_default_language:
+ * _gtk_get_lc_ctype:
  *
- * Returns the ISO language code for the default language currently in
- * effect. (Note that this can change over the life of an
- * application.)  The default language is derived from the current
- * locale. It determines, for example, whether GTK+ uses the
- * right-to-left or left-to-right text direction.
+ * Return the Unix-style locale string for the language currently in
+ * effect. On Unix systems, this is the return value from
+ * <literal>setlocale(LC_CTYPE, NULL)</literal>, and the user can
+ * affect this through the environment variables LC_ALL, LC_CTYPE or
+ * LANG (checked in that order). The locale strings typically is in
+ * the form lang_COUNTRY, where lang is an ISO-639 language code, and
+ * COUNTRY is an ISO-3166 country code. For instance, sv_FI for
+ * Swedish as written in Finland or pt_BR for Portuguese as written in
+ * Brazil.
  * 
- * Return value: the default language as an allocated string, must be freed
- **/
-PangoLanguage *
-gtk_get_default_language (void)
+ * On Windows, the C library doesn't use any such environment
+ * variables, and setting them won't affect the behaviour of functions
+ * like ctime(). The user sets the locale through the Regional Options 
+ * in the Control Panel. The C library (in the setlocale() function) 
+ * does not use country and language codes, but country and language 
+ * names spelled out in English. 
+ * However, this function does check the above environment
+ * variables, and does return a Unix-style locale string based on
+ * either said environment variables or the thread's current locale.
+ *
+ * Return value: a dynamically allocated string, free with g_free().
+ */
+
+gchar *
+_gtk_get_lc_ctype (void)
 {
-  gchar *lang;
-  PangoLanguage *result;
-  gchar *p;
-  
 #ifdef G_OS_WIN32
   /* Somebody might try to set the locale for this process using the
    * LANG or LC_ environment variables. The Microsoft C library
    * doesn't know anything about them. You set the locale in the
    * Control Panel. Setting these env vars won't have any affect on
-   * locale-dependent C library functions like ctime. But just for
-   * kicks, do obey LC_ALL, LANG and LC_CTYPE in GTK. (This also makes
+   * locale-dependent C library functions like ctime(). But just for
+   * kicks, do obey LC_ALL, LC_CTYPE and LANG in GTK. (This also makes
    * it easier to test GTK and Pango in various default languages, you
    * don't have to clickety-click in the Control Panel, you can simply
    * start the program with LC_ALL=something on the command line.)
    */
+  gchar *p;
+
   p = getenv ("LC_ALL");
   if (p != NULL)
-    lang = g_strdup (p);
-  else
-    {
-      p = getenv ("LANG");
-      if (p != NULL)
-       lang = g_strdup (p);
-      else
-       {
-         p = getenv ("LC_CTYPE");
-         if (p != NULL)
-           lang = g_strdup (p);
-         else
-           lang = g_win32_getlocale ();
-       }
-    }
+    return g_strdup (p);
+
+  p = getenv ("LC_CTYPE");
+  if (p != NULL)
+    return g_strdup (p);
+
+  p = getenv ("LANG");
+  if (p != NULL)
+    return g_strdup (p);
+
+  return g_win32_getlocale ();
 #else
-  lang = g_strdup (setlocale (LC_CTYPE, NULL));
+  return g_strdup (setlocale (LC_CTYPE, NULL));
 #endif
-  p = strchr (lang, '.');
-  if (p)
-    *p = '\0';
-  p = strchr (lang, '@');
-  if (p)
-    *p = '\0';
-
-  result = pango_language_from_string (lang);
-  g_free (lang);
-  
-  return result;
+}
+
+/**
+ * gtk_get_default_language:
+ *
+ * Returns the #PangoLanguage for the default language currently in
+ * effect. (Note that this can change over the life of an
+ * application.)  The default language is derived from the current
+ * locale. It determines, for example, whether GTK+ uses the
+ * right-to-left or left-to-right text direction.
+ *
+ * This function is equivalent to pango_language_get_default().  See
+ * that function for details.
+ * 
+ * Return value: the default language as a #PangoLanguage, must not be
+ * freed
+ **/
+PangoLanguage *
+gtk_get_default_language (void)
+{
+  return pango_language_get_default ();
 }
 
 void
@@ -1129,12 +1256,21 @@ gtk_main (void)
 
       gdk_flush ();
     }
-             
+    
   main_loops = g_slist_remove (main_loops, loop);
 
   g_main_loop_unref (loop);
 
   gtk_main_loop_level--;
+
+  if (gtk_main_loop_level == 0)
+    {
+      /* Try storing all clipboard data we have */
+      _gtk_clipboard_store_all ();
+
+      /* Synchronize the recent manager singleton */
+      _gtk_recent_manager_sync ();
+    }
 }
 
 guint
@@ -1151,7 +1287,7 @@ gtk_main_quit (void)
   g_main_loop_quit (main_loops->data);
 }
 
-gint
+gboolean
 gtk_events_pending (void)
 {
   gboolean result;
@@ -1268,6 +1404,7 @@ rewrite_event_for_grabs (GdkEvent *event)
 {
   GdkWindow *grab_window;
   GtkWidget *event_widget, *grab_widget;
+  gpointer grab_widget_ptr;
   gboolean owner_events;
   GdkDisplay *display;
 
@@ -1300,7 +1437,8 @@ rewrite_event_for_grabs (GdkEvent *event)
     }
 
   event_widget = gtk_get_event_widget (event);
-  gdk_window_get_user_data (grab_window, (void**) &grab_widget);
+  gdk_window_get_user_data (grab_window, &grab_widget_ptr);
+  grab_widget = grab_widget_ptr;
 
   if (grab_widget &&
       gtk_main_get_window_group (grab_widget) != gtk_main_get_window_group (event_widget))
@@ -1315,41 +1453,20 @@ gtk_main_do_event (GdkEvent *event)
   GtkWidget *event_widget;
   GtkWidget *grab_widget;
   GtkWindowGroup *window_group;
-  GdkEvent *next_event;
   GdkEvent *rewritten_event = NULL;
   GList *tmp_list;
 
-  /* If there are any events pending then get the next one.
-   */
-  next_event = gdk_event_peek ();
-  
-  /* Try to compress enter/leave notify events. These event
-   *  pairs occur when the mouse is dragged quickly across
-   *  a window with many buttons (or through a menu). Instead
-   *  of highlighting and de-highlighting each widget that
-   *  is crossed it is better to simply de-highlight the widget
-   *  which contained the mouse initially and highlight the
-   *  widget which ends up containing the mouse.
-   */
-  if (next_event)
-    if (((event->type == GDK_ENTER_NOTIFY) ||
-        (event->type == GDK_LEAVE_NOTIFY)) &&
-       ((next_event->type == GDK_ENTER_NOTIFY) ||
-        (next_event->type == GDK_LEAVE_NOTIFY)) &&
-       (next_event->type != event->type) &&
-       (next_event->any.window == event->any.window))
-      {
-       /* Throw both the peeked copy and the queued copy away 
-        */
-       gdk_event_free (next_event);
-       next_event = gdk_event_get ();
-       gdk_event_free (next_event);
-       
-       return;
-      }
-
-  if (next_event)
-    gdk_event_free (next_event);
+  if (event->type == GDK_SETTING)
+    {
+      _gtk_settings_handle_event (&event->setting);
+      return;
+    }
+
+  if (event->type == GDK_OWNER_CHANGE)
+    {
+      _gtk_clipboard_handle_event (&event->owner_change);
+      return;
+    }
 
   /* Find the widget which got the event. We store the widget
    *  in the user_data field of GdkWindow's.
@@ -1370,8 +1487,6 @@ gtk_main_do_event (GdkEvent *event)
       if (event->type == GDK_PROPERTY_NOTIFY)
        _gtk_selection_incr_event (event->any.window,
                                   &event->property);
-      else if (event->type == GDK_SETTING)
-       _gtk_settings_handle_event (&event->setting);
 
       return;
     }
@@ -1457,7 +1572,15 @@ gtk_main_do_event (GdkEvent *event)
          gdk_window_end_paint (event->any.window);
        }
       else
-       gtk_widget_send_expose (event_widget, event);
+       {
+         /* The app may paint with a previously allocated cairo_t,
+            which will draw directly to the window. We can't catch cairo
+            drap operatoins to automatically flush the window, thus we
+            need to explicitly flush any outstanding moves or double
+            buffering */
+         gdk_window_flush (event->any.window);
+         gtk_widget_send_expose (event_widget, event);
+       }
       break;
 
     case GDK_PROPERTY_NOTIFY:
@@ -1472,6 +1595,8 @@ gtk_main_do_event (GdkEvent *event)
     case GDK_CLIENT_EVENT:
     case GDK_VISIBILITY_NOTIFY:
     case GDK_WINDOW_STATE:
+    case GDK_GRAB_BROKEN:
+    case GDK_DAMAGE:
       gtk_widget_event (event_widget, event);
       break;
 
@@ -1498,25 +1623,15 @@ gtk_main_do_event (GdkEvent *event)
       break;
       
     case GDK_ENTER_NOTIFY:
+      GTK_PRIVATE_SET_FLAG (event_widget, GTK_HAS_POINTER);
+      _gtk_widget_set_pointer_window (event_widget, event->any.window);
       if (GTK_WIDGET_IS_SENSITIVE (grab_widget))
-       {
-         g_object_ref (event_widget);
-         
-         gtk_widget_event (grab_widget, event);
-         if (event_widget == grab_widget)
-           GTK_PRIVATE_SET_FLAG (event_widget, GTK_LEAVE_PENDING);
-         
-         g_object_unref (event_widget);
-       }
+       gtk_widget_event (grab_widget, event);
       break;
       
     case GDK_LEAVE_NOTIFY:
-      if (GTK_WIDGET_LEAVE_PENDING (event_widget))
-       {
-         GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_LEAVE_PENDING);
-         gtk_widget_event (event_widget, event);
-       }
-      else if (GTK_WIDGET_IS_SENSITIVE (grab_widget))
+      GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_HAS_POINTER);
+      if (GTK_WIDGET_IS_SENSITIVE (grab_widget))
        gtk_widget_event (grab_widget, event);
       break;
       
@@ -1534,6 +1649,20 @@ gtk_main_do_event (GdkEvent *event)
       g_assert_not_reached ();
       break;
     }
+
+  if (event->type == GDK_ENTER_NOTIFY
+      || event->type == GDK_LEAVE_NOTIFY
+      || event->type == GDK_BUTTON_PRESS
+      || event->type == GDK_2BUTTON_PRESS
+      || event->type == GDK_3BUTTON_PRESS
+      || event->type == GDK_KEY_PRESS
+      || event->type == GDK_DRAG_ENTER
+      || event->type == GDK_GRAB_BROKEN
+      || event->type == GDK_MOTION_NOTIFY
+      || event->type == GDK_SCROLL)
+    {
+      _gtk_tooltip_handle_event (event);
+    }
   
   tmp_list = current_events;
   current_events = g_list_remove_link (current_events, tmp_list);
@@ -1563,71 +1692,88 @@ gtk_main_get_window_group (GtkWidget   *widget)
   if (widget)
     toplevel = gtk_widget_get_toplevel (widget);
 
-  if (toplevel && GTK_IS_WINDOW (toplevel))
-    return _gtk_window_get_group (GTK_WINDOW (toplevel));
+  if (GTK_IS_WINDOW (toplevel))
+    return gtk_window_get_group (GTK_WINDOW (toplevel));
   else
-    return _gtk_window_get_group (NULL);
+    return gtk_window_get_group (NULL);
 }
 
 typedef struct
 {
   GtkWidget *old_grab_widget;
   GtkWidget *new_grab_widget;
+  gboolean   was_grabbed;
+  gboolean   is_grabbed;
+  gboolean   from_grab;
 } GrabNotifyInfo;
 
-static gboolean
-check_is_grabbed (GtkWidget *widget,
-                 GtkWidget *grab_widget)
-{
-  if (grab_widget)
-    return !(widget == grab_widget || gtk_widget_is_ancestor (widget, grab_widget));
-  else
-    return FALSE;
-}
-
 static void
 gtk_grab_notify_foreach (GtkWidget *child,
                         gpointer   data)
                         
 {
   GrabNotifyInfo *info = data;
-  gboolean was_grabbed = check_is_grabbed (child, info->old_grab_widget);
-  gboolean is_grabbed = check_is_grabbed (child, info->new_grab_widget);
+  gboolean was_grabbed, is_grabbed, was_shadowed, is_shadowed;
+
+  was_grabbed = info->was_grabbed;
+  is_grabbed = info->is_grabbed;
+
+  info->was_grabbed = info->was_grabbed || (child == info->old_grab_widget);
+  info->is_grabbed = info->is_grabbed || (child == info->new_grab_widget);
+
+  was_shadowed = info->old_grab_widget && !info->was_grabbed;
+  is_shadowed = info->new_grab_widget && !info->is_grabbed;
 
-  if (was_grabbed != is_grabbed)
+  g_object_ref (child);
+
+  if ((was_shadowed || is_shadowed) && GTK_IS_CONTAINER (child))
+    gtk_container_forall (GTK_CONTAINER (child), gtk_grab_notify_foreach, info);
+  
+  if (is_shadowed)
     {
-      g_object_ref (child);
-      
-      g_signal_emit_by_name (child, "grab_notify", was_grabbed);
-      
-      if (GTK_IS_CONTAINER (child))
-       gtk_container_foreach (GTK_CONTAINER (child), gtk_grab_notify_foreach, info);
-      
-      g_object_unref (child);
+      GTK_PRIVATE_SET_FLAG (child, GTK_SHADOWED);
+      if (!was_shadowed && GTK_WIDGET_HAS_POINTER (child)
+         && GTK_WIDGET_IS_SENSITIVE (child))
+       _gtk_widget_synthesize_crossing (child, info->new_grab_widget,
+                                        GDK_CROSSING_GTK_GRAB);
+    }
+  else
+    {
+      GTK_PRIVATE_UNSET_FLAG (child, GTK_SHADOWED);
+      if (was_shadowed && GTK_WIDGET_HAS_POINTER (child)
+         && GTK_WIDGET_IS_SENSITIVE (child))
+       _gtk_widget_synthesize_crossing (info->old_grab_widget, child,
+                                        info->from_grab ? GDK_CROSSING_GTK_GRAB
+                                        : GDK_CROSSING_GTK_UNGRAB);
     }
+
+  if (was_shadowed != is_shadowed)
+    _gtk_widget_grab_notify (child, was_shadowed);
+  
+  g_object_unref (child);
+  
+  info->was_grabbed = was_grabbed;
+  info->is_grabbed = is_grabbed;
 }
 
 static void
 gtk_grab_notify (GtkWindowGroup *group,
-                GtkWidget      *grab_widget,
-                gboolean        was_grabbed)
+                GtkWidget      *old_grab_widget,
+                GtkWidget      *new_grab_widget,
+                gboolean        from_grab)
 {
   GList *toplevels;
   GrabNotifyInfo info;
 
-  if (was_grabbed)
-    {
-      info.old_grab_widget = grab_widget;
-      info.new_grab_widget = group->grabs ? group->grabs->data : NULL;
-    }
-  else
-    {
-      info.old_grab_widget = (group->grabs && group->grabs->next) ? group->grabs->next->data : NULL;
-      info.new_grab_widget = grab_widget;
-    }
+  if (old_grab_widget == new_grab_widget)
+    return;
+
+  info.old_grab_widget = old_grab_widget;
+  info.new_grab_widget = new_grab_widget;
+  info.from_grab = from_grab;
 
   g_object_ref (group);
-  g_object_ref (grab_widget);
 
   toplevels = gtk_window_list_toplevels ();
   g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
@@ -1637,20 +1783,22 @@ gtk_grab_notify (GtkWindowGroup *group,
       GtkWindow *toplevel = toplevels->data;
       toplevels = g_list_delete_link (toplevels, toplevels);
 
-      if (group == _gtk_window_get_group (toplevel))
-       gtk_container_foreach (GTK_CONTAINER (toplevel), gtk_grab_notify_foreach, &info);
+      info.was_grabbed = FALSE;
+      info.is_grabbed = FALSE;
+
+      if (group == gtk_window_get_group (toplevel))
+       gtk_grab_notify_foreach (GTK_WIDGET (toplevel), &info);
       g_object_unref (toplevel);
     }
 
   g_object_unref (group);
-  g_object_unref (grab_widget);
 }
 
 void
 gtk_grab_add (GtkWidget *widget)
 {
   GtkWindowGroup *group;
-  gboolean was_grabbed;
+  GtkWidget *old_grab_widget;
   
   g_return_if_fail (widget != NULL);
   
@@ -1660,12 +1808,15 @@ gtk_grab_add (GtkWidget *widget)
       
       group = gtk_main_get_window_group (widget);
 
-      was_grabbed = (group->grabs != NULL);
-      
+      if (group->grabs)
+       old_grab_widget = (GtkWidget *)group->grabs->data;
+      else
+       old_grab_widget = NULL;
+
       g_object_ref (widget);
       group->grabs = g_slist_prepend (group->grabs, widget);
 
-      gtk_grab_notify (group, widget, FALSE);
+      gtk_grab_notify (group, old_grab_widget, widget, TRUE);
     }
 }
 
@@ -1685,6 +1836,7 @@ void
 gtk_grab_remove (GtkWidget *widget)
 {
   GtkWindowGroup *group;
+  GtkWidget *new_grab_widget;
   
   g_return_if_fail (widget != NULL);
   
@@ -1695,9 +1847,14 @@ gtk_grab_remove (GtkWidget *widget)
       group = gtk_main_get_window_group (widget);
       group->grabs = g_slist_remove (group->grabs, widget);
       
-      g_object_unref (widget);
+      if (group->grabs)
+       new_grab_widget = (GtkWidget *)group->grabs->data;
+      else
+       new_grab_widget = NULL;
 
-      gtk_grab_notify (group, widget, TRUE);
+      gtk_grab_notify (group, widget, new_grab_widget, FALSE);
+      
+      g_object_unref (widget);
     }
 }
 
@@ -1733,7 +1890,7 @@ gtk_key_snooper_install (GtkKeySnoopFunc snooper,
 }
 
 void
-gtk_key_snooper_remove (guint           snooper_id)
+gtk_key_snooper_remove (guint snooper_id)
 {
   GtkKeySnooperData *data = NULL;
   GSList *slist;
@@ -1749,7 +1906,10 @@ gtk_key_snooper_remove (guint             snooper_id)
       data = NULL;
     }
   if (data)
-    key_snoopers = g_slist_remove (key_snoopers, data);
+    {
+      key_snoopers = g_slist_remove (key_snoopers, data);
+      g_free (data);
+    }
 }
 
 static gint
@@ -1777,18 +1937,14 @@ gtk_quit_add_full (guint                main_level,
                   GtkFunction          function,
                   GtkCallbackMarshal   marshal,
                   gpointer             data,
-                  GtkDestroyNotify     destroy)
+                  GDestroyNotify       destroy)
 {
   static guint quit_id = 1;
   GtkQuitFunction *quitf;
   
   g_return_val_if_fail ((function != NULL) || (marshal != NULL), 0);
 
-  if (!quit_mem_chunk)
-    quit_mem_chunk = g_mem_chunk_new ("quit mem chunk", sizeof (GtkQuitFunction),
-                                     512, G_ALLOC_AND_FREE);
-  
-  quitf = g_chunk_new (GtkQuitFunction, quit_mem_chunk);
+  quitf = g_slice_new (GtkQuitFunction);
   
   quitf->id = quit_id++;
   quitf->main_level = main_level;
@@ -1807,7 +1963,7 @@ gtk_quit_destroy (GtkQuitFunction *quitf)
 {
   if (quitf->destroy)
     quitf->destroy (quitf->data);
-  g_mem_chunk_free (quit_mem_chunk, quitf);
+  g_slice_free (GtkQuitFunction, quitf);
 }
 
 static gint
@@ -1899,7 +2055,7 @@ gtk_timeout_add_full (guint32              interval,
                      GtkFunction        function,
                      GtkCallbackMarshal marshal,
                      gpointer           data,
-                     GtkDestroyNotify   destroy)
+                     GDestroyNotify     destroy)
 {
   if (marshal)
     {
@@ -1938,7 +2094,7 @@ gtk_idle_add_full (gint                   priority,
                   GtkFunction          function,
                   GtkCallbackMarshal   marshal,
                   gpointer             data,
-                  GtkDestroyNotify     destroy)
+                  GDestroyNotify       destroy)
 {
   if (marshal)
     {
@@ -1992,7 +2148,7 @@ gtk_input_add_full (gint          source,
                    GdkInputFunction    function,
                    GtkCallbackMarshal  marshal,
                    gpointer            data,
-                   GtkDestroyNotify    destroy)
+                   GDestroyNotify      destroy)
 {
   if (marshal)
     {
@@ -2007,7 +2163,7 @@ gtk_input_add_full (gint          source,
                                 condition,
                                 (GdkInputFunction) gtk_invoke_input,
                                 closure,
-                                (GdkDestroyNotify) gtk_destroy_closure);
+                                (GDestroyNotify) gtk_destroy_closure);
     }
   else
     return gdk_input_add_full (source, condition, function, data, destroy);
@@ -2138,10 +2294,15 @@ GtkWidget*
 gtk_get_event_widget (GdkEvent *event)
 {
   GtkWidget *widget;
+  gpointer widget_ptr;
 
   widget = NULL;
-  if (event && event->any.window)
-    gdk_window_get_user_data (event->any.window, (void**) &widget);
+  if (event && event->any.window && 
+      (event->type == GDK_DESTROY || !GDK_WINDOW_DESTROYED (event->any.window)))
+    {
+      gdk_window_get_user_data (event->any.window, &widget_ptr);
+      widget = widget_ptr;
+    }
   
   return widget;
 }
@@ -2213,7 +2374,7 @@ gtk_propagate_event (GtkWidget *widget,
       GtkWidget *window;
 
       window = gtk_widget_get_toplevel (widget);
-      if (window && GTK_IS_WINDOW (window))
+      if (GTK_IS_WINDOW (window))
        {
          /* If there is a grab within the window, give the grab widget
           * a first crack at the key event
@@ -2224,7 +2385,7 @@ gtk_propagate_event (GtkWidget *widget,
          if (!handled_event)
            {
              window = gtk_widget_get_toplevel (widget);
-             if (window && GTK_IS_WINDOW (window))
+             if (GTK_IS_WINDOW (window))
                {
                  if (GTK_WIDGET_IS_SENSITIVE (window))
                    gtk_widget_event (window, event);
@@ -2244,8 +2405,17 @@ gtk_propagate_event (GtkWidget *widget,
       while (TRUE)
        {
          GtkWidget *tmp;
-         
-         handled_event = !GTK_WIDGET_IS_SENSITIVE (widget) || gtk_widget_event (widget, event);
+
+         /* Scroll events are special cased here because it
+          * feels wrong when scrolling a GtkViewport, say,
+          * to have children of the viewport eat the scroll
+          * event
+          */
+         if (!GTK_WIDGET_IS_SENSITIVE (widget))
+           handled_event = event->type != GDK_SCROLL;
+         else
+           handled_event = gtk_widget_event (widget, event);
+             
          tmp = widget->parent;
          g_object_unref (widget);
 
@@ -2306,7 +2476,7 @@ gtk_print (gchar *str)
       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
       
       gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                         (GtkSignalFunc) gtk_widget_destroyed,
+                         G_CALLBACK (gtk_widget_destroyed),
                          &window);
       
       gtk_window_set_title (GTK_WINDOW (window), "Messages");
@@ -2357,7 +2527,7 @@ gtk_print (gchar *str)
       
       button = gtk_button_new_with_label ("close");
       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                                (GtkSignalFunc) gtk_widget_hide,
+                                G_CALLBACK (gtk_widget_hide),
                                 GTK_OBJECT (window));
       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
@@ -2389,3 +2559,6 @@ _gtk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
   
   return continue_emission;
 }
+
+#define __GTK_MAIN_C__
+#include "gtkaliasdef.c"