* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#ifdef GDK_WINDOWING_X11
-#include <X11/Xlocale.h> /* so we get the right setlocale */
-#else
+#include "gdkconfig.h"
+
#include <locale.h>
-#endif
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
#include <libintl.h>
#include <stdlib.h>
#include <string.h>
#include <gmodule.h>
+#ifdef G_OS_UNIX
+#include <unistd.h>
+#include <sys/types.h> /* For uid_t, gid_t */
+#endif
+#ifdef G_OS_WIN32
+#define STRICT
+#include <windows.h>
+#undef STRICT
+#endif
+
+#include <pango/pango-utils.h> /* For pango_split_file_list */
+
+#include "gtkaccelmap.h"
+#include "gtkbox.h"
#include "gtkdnd.h"
-#include "gtkcompat.h"
+#include "gtkversion.h"
#include "gtkmain.h"
#include "gtkrc.h"
#include "gtkselection.h"
-#include "gtksignal.h"
+#include "gtksettings.h"
#include "gtkwidget.h"
#include "gtkwindow.h"
#include "gtkprivate.h"
-#include "gdk/gdki18n.h"
#include "config.h"
#include "gtkdebug.h"
#include "gtkintl.h"
typedef struct _GtkQuitFunction GtkQuitFunction;
typedef struct _GtkClosure GtkClosure;
typedef struct _GtkKeySnooperData GtkKeySnooperData;
+typedef struct _GtkModuleInfo GtkModuleInfo;
struct _GtkInitFunction
{
guint id;
};
-static void gtk_exit_func (void);
+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,
static void gtk_print (gchar *str);
#endif
+static GtkWindowGroup *gtk_main_get_window_group (GtkWidget *widget);
+
const guint gtk_major_version = GTK_MAJOR_VERSION;
const guint gtk_minor_version = GTK_MINOR_VERSION;
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 gtk_initialized = FALSE;
static GList *current_events = NULL;
static GSList *main_loops = NULL; /* stack of currently executing main loops */
-static GSList *grabs = NULL; /* A stack of unique grabs. The grabbing
- * widget is the first one on the list.
- */
static GList *init_functions = NULL; /* A list of init functions.
*/
static GList *quit_functions = NULL; /* A list of quit functions.
static GSList *key_snoopers = NULL;
-static GdkVisual *gtk_visual; /* The visual to be used in creating new
- * widgets.
- */
-static GdkColormap *gtk_colormap; /* The colormap to be used in creating new
- * widgets.
- */
-
guint gtk_debug_flags = 0; /* Global GTK debug flag */
#ifdef G_ENABLE_DEBUG
static const GDebugKey gtk_debug_keys[] = {
{"misc", GTK_DEBUG_MISC},
- {"dnd", GTK_DEBUG_DND},
{"plugsocket", GTK_DEBUG_PLUGSOCKET},
{"text", GTK_DEBUG_TEXT},
{"tree", GTK_DEBUG_TREE},
- {"updates", GTK_DEBUG_UPDATES}
+ {"updates", GTK_DEBUG_UPDATES},
+ {"keybindings", GTK_DEBUG_KEYBINDINGS},
+ {"multihead", GTK_DEBUG_MULTIHEAD}
};
static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey);
guint required_minor,
guint required_micro)
{
+ gint gtk_effective_micro = 100 * GTK_MINOR_VERSION + GTK_MICRO_VERSION;
+ gint required_effective_micro = 100 * required_minor + required_micro;
+
if (required_major > GTK_MAJOR_VERSION)
return "Gtk+ version too old (major mismatch)";
if (required_major < GTK_MAJOR_VERSION)
return "Gtk+ version too new (major mismatch)";
- if (required_minor > GTK_MINOR_VERSION)
- return "Gtk+ version too old (minor mismatch)";
- if (required_minor < GTK_MINOR_VERSION)
- return "Gtk+ version too new (minor mismatch)";
- if (required_micro < GTK_MICRO_VERSION - GTK_BINARY_AGE)
+ if (required_effective_micro < gtk_effective_micro - GTK_BINARY_AGE)
return "Gtk+ version too new (micro mismatch)";
- if (required_micro > GTK_MICRO_VERSION)
+ if (required_effective_micro > gtk_effective_micro)
return "Gtk+ version too old (micro mismatch)";
return NULL;
}
-#ifdef __EMX__
-static gchar *add_dll_suffix(gchar *module_name)
-{
- gchar *suffix = strrchr(module_name, '.');
-
- if (!suffix || stricmp(suffix, ".dll"))
- {
- gchar *old = module_name;
-
- module_name = g_strconcat (module_name, ".dll", NULL);
- g_free (old);
- }
- return (module_name);
-}
-#endif
-
-#undef gtk_init_check
-
/* This checks to see if the process is running suid or sgid
* at the current time. If so, we don't allow GTK+ to be initialized.
* This is meant to be a mild check - we only error out if we
static gboolean
check_setugid (void)
{
-/* this isn't at all relevant on Windoze and doesn't compile ... --hb */
+/* this isn't at all relevant on MS Windows and doesn't compile ... --hb */
#ifndef G_OS_WIN32
uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
return TRUE;
}
+#ifdef G_OS_WIN32
+
+G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)
+
+const gchar *
+_gtk_get_libdir (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");
+
+ return gtk_localedir;
+}
+
+const gchar *
+_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");
+
+ return gtk_sysconfdir;
+}
+
+const gchar *
+_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);
+
+ 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);
+
+ 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);
+ 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);
+
+ g_free (home_gtk_dir);
+ g_free (default_dir);
+
+ result = pango_split_file_list (module_path);
+ g_free (module_path);
+
+ return result;
+}
+
+/**
+ * _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)
+{
+ gchar **paths = get_module_path();
+ gchar **path;
+ gchar **result;
+ gint count = 0;
+
+ for (path = paths; *path; path++)
+ count++;
+
+ result = g_new (gchar *, count * 4 + 1);
+
+ count = 0;
+ for (path = get_module_path (); *path; path++)
+ {
+ gint use_version, use_host;
+
+ 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;
+ }
+ }
+
+ result[count++] = NULL;
+
+ return result;
+}
+
+/* Like g_module_path, but use .la as the suffix
+ */
+static gchar*
+module_build_la_path (const gchar *directory,
+ const gchar *module_name)
+{
+ gchar *filename;
+ gchar *result;
+
+ if (strncmp (module_name, "lib", 3) == 0)
+ filename = (gchar *)module_name;
+ else
+ filename = g_strconcat ("lib", module_name, ".la", NULL);
+
+ if (directory && *directory)
+ result = g_build_filename (directory, filename, NULL);
+ else
+ result = g_strdup (filename);
+
+ if (filename != module_name)
+ g_free (filename);
+
+ return result;
+}
+
+/**
+ * _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)
+{
+ gchar **paths;
+ gchar **path;
+ gchar *module_name = NULL;
+
+ if (g_path_is_absolute (name))
+ return g_strdup (name);
+
+ paths = _gtk_get_module_path (type);
+ for (path = paths; *path; path++)
+ {
+ gchar *tmp_name;
+
+ tmp_name = g_module_build_path (*path, name);
+ if (g_file_test (tmp_name, G_FILE_TEST_EXISTS))
+ {
+ module_name = tmp_name;
+ goto found;
+ }
+ g_free(tmp_name);
+
+ tmp_name = module_build_la_path (*path, name);
+ if (g_file_test (tmp_name, G_FILE_TEST_EXISTS))
+ {
+ module_name = tmp_name;
+ goto found;
+ }
+ g_free(tmp_name);
+ }
+
+ found:
+ g_strfreev (paths);
+ return module_name;
+}
+
+static GModule *
+find_module (const gchar *name)
+{
+ GModule *module;
+ gchar *module_name;
+
+ module_name = _gtk_find_module (name, "modules");
+ if (!module_name)
+ {
+ /* As last resort, try loading without an absolute path (using system
+ * library path)
+ */
+ module_name = g_module_build_path (NULL, name);
+ }
+
+ module = g_module_open (module_name, G_MODULE_BIND_LAZY);
+ g_free(module_name);
+
+ return module;
+}
+
+static GSList *
+load_module (GSList *module_list,
+ const gchar *name)
+{
+ GtkModuleInitFunc modinit_func = NULL;
+ GtkModuleInfo *info;
+ GModule *module = NULL;
+
+ if (g_module_supported ())
+ {
+ 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);
+
+ 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;
+ }
+ }
+ }
+ if (!modinit_func)
+ {
+ g_message ("Failed to load module \"%s\": %s",
+ module ? g_module_name (module) : name,
+ g_module_error ());
+ if (module)
+ g_module_close (module);
+ }
+
+ return module_list;
+}
+
+static GSList *
+load_modules (const char *module_str)
+{
+ gchar **module_names = pango_split_file_list (module_str);
+ GSList *module_list = NULL;
+ gint i;
+
+ for (i = 0; module_names[i]; i++)
+ module_list = load_module (module_list, module_names[i]);
+
+ module_list = g_slist_reverse (module_list);
+
+ g_strfreev (module_names);
+
+ return module_list;
+}
+
+static gboolean do_setlocale = TRUE;
+
+/**
+ * gtk_disable_setlocale:
+ *
+ * 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.
+ *
+ * Most programs should not need to call this function.
+ **/
+void
+gtk_disable_setlocale (void)
+{
+ if (gtk_initialized)
+ g_warning ("gtk_disable_setlocale() must be called before gtk_init()");
+
+ do_setlocale = FALSE;
+}
+
+#undef gtk_init_check
+
+static void
+default_display_notify_cb (GdkDisplayManager *display_manager)
+{
+ GSList *slist;
+
+ /* Initialize non-multihead-aware modules when the
+ * default display is first set to a non-NULL value.
+ */
+ static gboolean initialized = FALSE;
+
+ if (!gdk_display_get_default () || initialized)
+ return;
+
+ initialized = TRUE;
+
+ for (slist = gtk_modules; slist; slist = slist->next)
+ {
+ if (slist->data)
+ {
+ GtkModuleInfo *info = slist->data;
+
+ if (!info->display_init_func)
+ info->init_func (>k_argc, >k_argv);
+ }
+ }
+}
+
+static void
+display_opened_cb (GdkDisplayManager *display_manager,
+ GdkDisplay *display)
+{
+ GSList *slist;
+
+ for (slist = gtk_modules; slist; slist = slist->next)
+ {
+ if (slist->data)
+ {
+ GtkModuleInfo *info = slist->data;
+
+ if (info->display_init_func)
+ info->display_init_func (display);
+ }
+ }
+}
+
+/**
+ * gdk_parse_args:
+ * @argc: the number of command line arguments.
+ * @argv: 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
+ * @argc and @argv are updated accordingly.
+ *
+ * You shouldn't call this function explicitely if you are using
+ * gtk_init(), or gtk_init_check().
+ *
+ * Return value: %TRUE if initialization succeeded, otherwise %FALSE.
+ **/
gboolean
-gtk_init_check (int *argc,
- char ***argv)
+gtk_parse_args (int *argc,
+ char ***argv)
{
- GSList *gtk_modules = NULL;
+ GString *gtk_modules_string = NULL;
GSList *slist;
- gchar *env_string = NULL;
+ GdkDisplayManager *display_manager;
+ const gchar *env_string;
if (gtk_initialized)
return TRUE;
g_set_message_handler (gtk_message);
g_set_print_handler (gtk_print);
#endif
-
- /* Initialize "gdk". We pass along the 'argc' and 'argv'
- * parameters as they contain information that GDK uses
- */
- if (!gdk_init_check (argc, argv))
- return FALSE;
+ 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 = getenv ("GTK_DEBUG");
+ env_string = g_getenv ("GTK_DEBUG");
if (env_string != NULL)
{
gtk_debug_flags = g_parse_debug_string (env_string,
}
#endif /* G_ENABLE_DEBUG */
- env_string = getenv ("GTK_MODULES");
+ env_string = g_getenv ("GTK_MODULES");
if (env_string)
- {
- gchar **modules, **as;
-
-#ifndef __EMX__
- modules = g_strsplit (env_string, G_SEARCHPATH_SEPARATOR_S, -1);
-#else
- modules = g_strsplit (env_string, ";", -1);
-#endif
- for (as = modules; *as; as++)
- {
- if (**as)
- gtk_modules = g_slist_prepend (gtk_modules, *as);
- else
- g_free (*as);
- }
- g_free (modules);
- env_string = NULL;
- }
+ gtk_modules_string = g_string_new (env_string);
if (argc && argv)
{
(*argv)[i] = NULL;
if (module_name && *module_name)
- gtk_modules = g_slist_prepend (gtk_modules, g_strdup (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)
{
*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 */
- gtk_modules = g_slist_reverse (gtk_modules);
- for (slist = gtk_modules; slist; slist = slist->next)
+ if (gtk_modules_string)
{
- gchar *module_name;
- GModule *module = NULL;
- GtkModuleInitFunc modinit_func = NULL;
-
- module_name = slist->data;
- slist->data = NULL;
-#ifndef __EMX__
- if (!g_path_is_absolute (module_name))
- {
- gchar *old = module_name;
-
- module_name = g_module_build_path (NULL, module_name);
- g_free (old);
- }
-#else
- module_name = add_dll_suffix(module_name);
-#endif
- if (g_module_supported ())
- {
- module = g_module_open (module_name, G_MODULE_BIND_LAZY);
- if (module &&
- g_module_symbol (module, "gtk_module_init", (gpointer*) &modinit_func) &&
- modinit_func)
- {
- if (!g_slist_find (gtk_modules, modinit_func))
- {
- g_module_make_resident (module);
- slist->data = modinit_func;
- }
- else
- {
- g_module_close (module);
- module = NULL;
- }
- }
- }
- if (!modinit_func)
- {
- g_message ("Failed to load module \"%s\": %s",
- module ? g_module_name (module) : module_name,
- g_module_error ());
- if (module)
- g_module_close (module);
- }
- g_free (module_name);
+ gtk_modules = load_modules (gtk_modules_string->str);
+ g_string_free (gtk_modules_string, TRUE);
}
#ifdef ENABLE_NLS
-# ifndef G_OS_WIN32
- bindtextdomain(GETTEXT_PACKAGE, GTK_LOCALEDIR);
+ bindtextdomain (GETTEXT_PACKAGE, GTK_LOCALEDIR);
# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
# endif
-# else /* !G_OS_WIN32 */
- {
- bindtextdomain (GETTEXT_PACKAGE,
- g_win32_get_package_installation_subdirectory (GETTEXT_PACKAGE,
- g_strdup_printf ("gtk-%d.%d.dll", GTK_MAJOR_VERSION, GTK_MINOR_VERSION),
- "locale"));
- }
-#endif
#endif
{
}
}
- /* Initialize the default visual and colormap to be
- * used in creating widgets. (We want to use the system
- * defaults so as to be nice to the colormap).
- */
- gtk_visual = gdk_visual_get_system ();
- gtk_colormap = gdk_colormap_get_system ();
-
gtk_type_init (0);
- gtk_rc_init ();
-
-
- /* Register an exit function to make sure we are able to cleanup.
- */
- g_atexit (gtk_exit_func);
+ _gtk_accel_map_init ();
+ _gtk_rc_init ();
/* Set the 'initialized' flag.
*/
gtk_initialized = TRUE;
- /* initialize gtk modules
+ 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);
+
+ /* 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)
{
- GtkModuleInitFunc modinit;
-
- modinit = slist->data;
- modinit (argc, argv);
+ GtkModuleInfo *info = slist->data;
+
+ if (info->display_init_func)
+ info->init_func (argc, argv);
}
}
- g_slist_free (gtk_modules);
-#ifndef G_OS_WIN32
- /* No use warning on Win32, there aren't any non-devel versions anyhow... */
- g_message ("" "YOU ARE USING THE DEVEL BRANCH 1.3.x OF GTK+ WHICH IS CURRENTLY\n"
- " UNDER HEAVY DEVELOPMENT AND FREQUENTLY INTRODUCES INSTABILITIES.\n"
- " if you don't know why you are getting this, you probably want to\n"
- " use the stable branch which can be retrived from\n"
- " ftp://ftp.gtk.org/pub/gtk/v1.2/ or via CVS with\n"
- " cvs checkout -r glib-1-2 glib; cvs checkout -r gtk-1-2 gtk+");
-#endif
-
return TRUE;
}
+#undef gtk_init_check
+
+/**
+ * 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.
+ *
+ * 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
+ * initialized. Instead it returns %FALSE on failure.
+ *
+ * This way the application can fall back to some other means of communication
+ * with the user - for example a curses or command line interface.
+ *
+ * Return value: %TRUE if the GUI has been successfully initialized,
+ * %FALSE otherwise.
+ **/
+gboolean
+gtk_init_check (int *argc,
+ char ***argv)
+{
+ GdkDisplay *display;
+
+ if (!gtk_parse_args (argc, argv))
+ return FALSE;
+
+ if (gdk_display_get_default ())
+ return TRUE;
+
+ display = gdk_display_open (gdk_get_display_arg_name ());
+
+ if (display)
+ {
+ gdk_display_manager_set_default_display (gdk_display_manager_get (),
+ display);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
#undef gtk_init
+/**
+ * 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.
+ *
+ * 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
+ * @argv are adjusted accordingly so your own code will
+ * never see those standard arguments.
+ *
+ * <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>
+ **/
void
gtk_init (int *argc, char ***argv)
{
if (!gtk_init_check (argc, argv))
{
- g_warning ("cannot open display: %s", gdk_get_display ());
- exit(1);
+ char *display_name_arg = gdk_get_display_arg_name ();
+ g_warning ("cannot open display: %s", display_name_arg ? display_name_arg : " ");
+ exit (1);
}
}
-#ifdef G_OS_WIN32
+#ifdef G_PLATFORM_WIN32
static void
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 switch.");
+ "your code with gcc without the -fnative-struct\n"
+ "(or -mms-bitfields) switch, or that you are using\n"
+ "an unsupported compiler.");
+}
+
+/* In GTK+ 2.0 the GtkWindow struct actually is the same size in
+ * gcc-compiled code on Win32 whether compiled with -fnative-struct or
+ * not. Unfortunately this wan't noticed until after GTK+ 2.0.1. So,
+ * from GTK+ 2.0.2 on, check some other struct, too, where the use of
+ * -fnative-struct still matters. GtkBox is one such.
+ */
+static void
+check_sizeof_GtkBox (size_t sizeof_GtkBox)
+{
+ if (sizeof_GtkBox != sizeof (GtkBox))
+ g_error ("Incompatible build!\n"
+ "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.");
}
/* These two functions might get more checks added later, thus pass
* in the number of extra args.
*/
void
-gtk_init_abi_check (int *argc, char ***argv, int num_checks, size_t sizeof_GtkWindow)
+gtk_init_abi_check (int *argc, char ***argv, int num_checks, size_t sizeof_GtkWindow, size_t sizeof_GtkBox)
{
check_sizeof_GtkWindow (sizeof_GtkWindow);
+ if (num_checks >= 2)
+ check_sizeof_GtkBox (sizeof_GtkBox);
gtk_init (argc, argv);
}
gboolean
-gtk_init_check_abi_check (int *argc, char ***argv, int num_checks, size_t sizeof_GtkWindow)
+gtk_init_check_abi_check (int *argc, char ***argv, int num_checks, size_t sizeof_GtkWindow, size_t sizeof_GtkBox)
{
check_sizeof_GtkWindow (sizeof_GtkWindow);
+ if (num_checks >= 2)
+ check_sizeof_GtkBox (sizeof_GtkBox);
return gtk_init_check (argc, argv);
}
{
/* Only if "gtk" has been initialized should we de-initialize.
*/
- /* de-initialisation is done by the gtk_exit_funct(),
- * no need to do this here (Alex J.)
- */
- gdk_exit(errorcode);
+ gdk_exit (errorcode);
}
+
+/**
+ * gtk_set_locale:
+ *
+ * Initializes internationalization support for GTK+. gtk_init()
+ * automatically does this, so there is typically no point
+ * in calling this function.
+ *
+ * If you are calling this function because you changed the locale
+ * after GTK+ is was initialized, then calling this function
+ * may help a bit. (Note, however, that changing the locale
+ * after GTK+ is initialized may produce inconsistent results and
+ * is not really supported.)
+ *
+ * In detail - sets the current locale according to the
+ * program environment. This is the same as calling the C library function
+ * <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>.
+ **/
gchar*
gtk_set_locale (void)
{
*
* Return value: the default language as an allocated string, must be freed
**/
-gchar*
+PangoLanguage *
gtk_get_default_language (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
+ * 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.)
+ */
+ 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 ();
+ }
+ }
+#else
lang = g_strdup (setlocale (LC_CTYPE, NULL));
+#endif
p = strchr (lang, '.');
if (p)
*p = '\0';
if (p)
*p = '\0';
- return lang;
+ result = pango_language_from_string (lang);
+ g_free (lang);
+
+ return result;
}
void
gtk_main_loop_level++;
- loop = g_main_new (TRUE);
+ loop = g_main_loop_new (NULL, TRUE);
main_loops = g_slist_prepend (main_loops, loop);
tmp_list = functions = init_functions;
}
g_list_free (functions);
- if (g_main_is_running (main_loops->data))
+ if (g_main_loop_is_running (main_loops->data))
{
GDK_THREADS_LEAVE ();
- g_main_run (loop);
+ g_main_loop_run (loop);
GDK_THREADS_ENTER ();
gdk_flush ();
}
main_loops = g_slist_remove (main_loops, loop);
- g_main_destroy (loop);
+ g_main_loop_unref (loop);
gtk_main_loop_level--;
}
{
g_return_if_fail (main_loops != NULL);
- g_main_quit (main_loops->data);
+ g_main_loop_quit (main_loops->data);
}
gint
gboolean result;
GDK_THREADS_LEAVE ();
- result = g_main_pending();
+ result = g_main_context_pending (NULL);
GDK_THREADS_ENTER ();
return result;
}
-gint
+gboolean
gtk_main_iteration (void)
{
GDK_THREADS_LEAVE ();
- g_main_iteration (TRUE);
+ g_main_context_iteration (NULL, TRUE);
GDK_THREADS_ENTER ();
if (main_loops)
- return !g_main_is_running (main_loops->data);
+ return !g_main_loop_is_running (main_loops->data);
else
return TRUE;
}
-gint
+gboolean
gtk_main_iteration_do (gboolean blocking)
{
GDK_THREADS_LEAVE ();
- g_main_iteration (blocking);
+ g_main_context_iteration (NULL, blocking);
GDK_THREADS_ENTER ();
if (main_loops)
- return !g_main_is_running (main_loops->data);
+ return !g_main_loop_is_running (main_loops->data);
else
return TRUE;
}
+/* private libgtk to libgdk interfaces
+ */
+gboolean gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
+ GdkWindow **grab_window,
+ gboolean *owner_events);
+gboolean gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
+ GdkWindow **grab_window,
+ gboolean *owner_events);
+
+static void
+rewrite_events_translate (GdkWindow *old_window,
+ GdkWindow *new_window,
+ gdouble *x,
+ gdouble *y)
+{
+ gint old_origin_x, old_origin_y;
+ gint new_origin_x, new_origin_y;
+
+ gdk_window_get_origin (old_window, &old_origin_x, &old_origin_y);
+ gdk_window_get_origin (new_window, &new_origin_x, &new_origin_y);
+
+ *x += old_origin_x - new_origin_x;
+ *y += old_origin_y - new_origin_y;
+}
+
+static GdkEvent *
+rewrite_event_for_window (GdkEvent *event,
+ GdkWindow *new_window)
+{
+ event = gdk_event_copy (event);
+
+ switch (event->type)
+ {
+ case GDK_SCROLL:
+ rewrite_events_translate (event->any.window,
+ new_window,
+ &event->scroll.x, &event->scroll.y);
+ break;
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ rewrite_events_translate (event->any.window,
+ new_window,
+ &event->button.x, &event->button.y);
+ break;
+ case GDK_MOTION_NOTIFY:
+ rewrite_events_translate (event->any.window,
+ new_window,
+ &event->motion.x, &event->motion.y);
+ break;
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ case GDK_PROXIMITY_IN:
+ case GDK_PROXIMITY_OUT:
+ break;
+
+ default:
+ return event;
+ }
+
+ g_object_unref (event->any.window);
+ event->any.window = g_object_ref (new_window);
+
+ return event;
+}
+
+/* If there is a pointer or keyboard grab in effect with owner_events = TRUE,
+ * then what X11 does is deliver the event normally if it was going to this
+ * client, otherwise, delivers it in terms of the grab window. This function
+ * rewrites events to the effect that events going to the same window group
+ * are delivered normally, otherwise, the event is delivered in terms of the
+ * grab window.
+ */
+static GdkEvent *
+rewrite_event_for_grabs (GdkEvent *event)
+{
+ GdkWindow *grab_window;
+ GtkWidget *event_widget, *grab_widget;
+ gboolean owner_events;
+ GdkDisplay *display;
+
+ switch (event->type)
+ {
+ case GDK_SCROLL:
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_MOTION_NOTIFY:
+ case GDK_PROXIMITY_IN:
+ case GDK_PROXIMITY_OUT:
+ display = gdk_drawable_get_display (event->proximity.window);
+ if (!gdk_pointer_grab_info_libgtk_only (display, &grab_window, &owner_events) ||
+ !owner_events)
+ return NULL;
+ break;
+
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ display = gdk_drawable_get_display (event->key.window);
+ if (!gdk_keyboard_grab_info_libgtk_only (display, &grab_window, &owner_events) ||
+ !owner_events)
+ return NULL;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ event_widget = gtk_get_event_widget (event);
+ gdk_window_get_user_data (grab_window, (void**) &grab_widget);
+
+ if (grab_widget &&
+ gtk_main_get_window_group (grab_widget) != gtk_main_get_window_group (event_widget))
+ return rewrite_event_for_window (event, grab_window);
+ else
+ return NULL;
+}
+
void
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.
* them specially
*/
if (event->type == GDK_PROPERTY_NOTIFY)
- gtk_selection_incr_event (event->any.window,
- &event->property);
-
+ _gtk_selection_incr_event (event->any.window,
+ &event->property);
+ else if (event->type == GDK_SETTING)
+ _gtk_settings_handle_event (&event->setting);
+
return;
}
+
+ /* If pointer or keyboard grabs are in effect, munge the events
+ * so that each window group looks like a separate app.
+ */
+ rewritten_event = rewrite_event_for_grabs (event);
+ if (rewritten_event)
+ {
+ event = rewritten_event;
+ event_widget = gtk_get_event_widget (event);
+ }
+ window_group = gtk_main_get_window_group (event_widget);
+
/* Push the event onto a stack of current events for
* gtk_current_event_get().
*/
current_events = g_list_prepend (current_events, event);
-
+
/* If there is a grab in effect...
*/
- if (grabs)
+ if (window_group->grabs)
{
- grab_widget = grabs->data;
+ grab_widget = window_group->grabs->data;
/* If the grab widget is an ancestor of the event widget
* then we send the event to the original event widget.
break;
case GDK_DELETE:
- gtk_widget_ref (event_widget);
- if ((!grabs || gtk_widget_get_toplevel (grabs->data) == event_widget) &&
+ g_object_ref (event_widget);
+ if ((!window_group->grabs || gtk_widget_get_toplevel (window_group->grabs->data) == event_widget) &&
!gtk_widget_event (event_widget, event))
gtk_widget_destroy (event_widget);
- gtk_widget_unref (event_widget);
+ g_object_unref (event_widget);
break;
case GDK_DESTROY:
*/
if (!event_widget->parent)
{
- gtk_widget_ref (event_widget);
+ g_object_ref (event_widget);
if (!gtk_widget_event (event_widget, event) &&
- !GTK_OBJECT_DESTROYED (event_widget))
+ GTK_WIDGET_REALIZED (event_widget))
gtk_widget_destroy (event_widget);
- gtk_widget_unref (event_widget);
+ g_object_unref (event_widget);
}
break;
case GDK_EXPOSE:
if (event->any.window && GTK_WIDGET_DOUBLE_BUFFERED (event_widget))
- gdk_window_begin_paint_region (event->any.window, event->expose.region);
-
- gtk_widget_send_expose (event_widget, event);
-
- if (event->any.window && GTK_WIDGET_DOUBLE_BUFFERED (event_widget))
- gdk_window_end_paint (event->any.window);
+ {
+ gdk_window_begin_paint_region (event->any.window, event->expose.region);
+ gtk_widget_send_expose (event_widget, event);
+ gdk_window_end_paint (event->any.window);
+ }
+ else
+ gtk_widget_send_expose (event_widget, event);
break;
case GDK_PROPERTY_NOTIFY:
case GDK_ENTER_NOTIFY:
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);
}
break;
case GDK_DRAG_STATUS:
case GDK_DROP_FINISHED:
- gtk_drag_source_handle_event (event_widget, event);
+ _gtk_drag_source_handle_event (event_widget, event);
break;
case GDK_DRAG_ENTER:
case GDK_DRAG_LEAVE:
case GDK_DRAG_MOTION:
case GDK_DROP_START:
- gtk_drag_dest_handle_event (event_widget, event);
+ _gtk_drag_dest_handle_event (event_widget, event);
+ break;
+ default:
+ g_assert_not_reached ();
break;
}
tmp_list = current_events;
current_events = g_list_remove_link (current_events, tmp_list);
g_list_free_1 (tmp_list);
+
+ if (rewritten_event)
+ gdk_event_free (rewritten_event);
}
-gint
+gboolean
gtk_true (void)
{
return TRUE;
}
-gint
+gboolean
gtk_false (void)
{
return FALSE;
}
+static GtkWindowGroup *
+gtk_main_get_window_group (GtkWidget *widget)
+{
+ GtkWidget *toplevel = NULL;
+
+ if (widget)
+ toplevel = gtk_widget_get_toplevel (widget);
+
+ if (toplevel && GTK_IS_WINDOW (toplevel))
+ return _gtk_window_get_group (GTK_WINDOW (toplevel));
+ else
+ return _gtk_window_get_group (NULL);
+}
+
+typedef struct
+{
+ GtkWidget *old_grab_widget;
+ GtkWidget *new_grab_widget;
+} 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);
+
+ if (was_grabbed != is_grabbed)
+ {
+ 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);
+ }
+}
+
+static void
+gtk_grab_notify (GtkWindowGroup *group,
+ GtkWidget *grab_widget,
+ gboolean was_grabbed)
+{
+ 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;
+ }
+
+ g_object_ref (group);
+ g_object_ref (grab_widget);
+
+ toplevels = gtk_window_list_toplevels ();
+ g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
+
+ while (toplevels)
+ {
+ 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);
+ g_object_unref (toplevel);
+ }
+
+ g_object_unref (group);
+ g_object_unref (grab_widget);
+}
+
void
gtk_grab_add (GtkWidget *widget)
{
+ GtkWindowGroup *group;
+ gboolean was_grabbed;
+
g_return_if_fail (widget != NULL);
- if (!GTK_WIDGET_HAS_GRAB (widget))
+ if (!GTK_WIDGET_HAS_GRAB (widget) && GTK_WIDGET_IS_SENSITIVE (widget))
{
GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_GRAB);
- grabs = g_slist_prepend (grabs, widget);
- gtk_widget_ref (widget);
+ group = gtk_main_get_window_group (widget);
+
+ was_grabbed = (group->grabs != NULL);
+
+ g_object_ref (widget);
+ group->grabs = g_slist_prepend (group->grabs, widget);
+
+ gtk_grab_notify (group, widget, FALSE);
}
}
GtkWidget*
gtk_grab_get_current (void)
{
- if (grabs)
- return GTK_WIDGET (grabs->data);
+ GtkWindowGroup *group;
+
+ group = gtk_main_get_window_group (NULL);
+
+ if (group->grabs)
+ return GTK_WIDGET (group->grabs->data);
return NULL;
}
void
gtk_grab_remove (GtkWidget *widget)
{
+ GtkWindowGroup *group;
+
g_return_if_fail (widget != NULL);
if (GTK_WIDGET_HAS_GRAB (widget))
{
GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_GRAB);
+
+ group = gtk_main_get_window_group (widget);
+ group->grabs = g_slist_remove (group->grabs, widget);
- grabs = g_slist_remove (grabs, widget);
- gtk_widget_unref (widget);
+ g_object_unref (widget);
+
+ gtk_grab_notify (group, widget, TRUE);
}
}
GtkObject **object_p;
g_return_if_fail (main_level > 0);
- g_return_if_fail (object != NULL);
g_return_if_fail (GTK_IS_OBJECT (object));
object_p = g_new (GtkObject*, 1);
*object_p = object;
- gtk_signal_connect (object,
- "destroy",
- GTK_SIGNAL_FUNC (gtk_widget_destroyed),
- object_p);
+ g_signal_connect (object,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ object_p);
gtk_quit_add (main_level, (GtkFunction) gtk_quit_destructor, object_p);
}
gtk_idle_add (GtkFunction function,
gpointer data)
{
- return g_idle_add_full (GTK_PRIORITY_DEFAULT, function, data, NULL);
+ return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
}
guint
-gtk_idle_add_priority (gint priority,
- GtkFunction function,
- gpointer data)
+gtk_idle_add_priority (gint priority,
+ GtkFunction function,
+ gpointer data)
{
return g_idle_add_full (priority, function, data, NULL);
}
GtkArg args[3];
args[0].type = GTK_TYPE_INT;
args[0].name = NULL;
- GTK_VALUE_INT(args[0]) = source;
- args[1].type = GTK_TYPE_GDK_INPUT_CONDITION;
+ GTK_VALUE_INT (args[0]) = source;
+ args[1].type = GDK_TYPE_INPUT_CONDITION;
args[1].name = NULL;
- GTK_VALUE_FLAGS(args[1]) = condition;
+ GTK_VALUE_FLAGS (args[1]) = condition;
args[2].type = GTK_TYPE_NONE;
args[2].name = NULL;
return widget;
}
-static void
-gtk_exit_func (void)
-{
- if (gtk_initialized)
- {
- gtk_initialized = FALSE;
- }
-}
-
-
static gint
gtk_quit_invoke_function (GtkQuitFunction *quitf)
{
{
gint handled_event;
- g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (event != NULL);
handled_event = FALSE;
- gtk_widget_ref (widget);
+ g_object_ref (widget);
if ((event->type == GDK_KEY_PRESS) ||
(event->type == GDK_KEY_RELEASE))
*/
GtkWidget *window;
- window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
-
- if (window)
+ window = gtk_widget_get_toplevel (widget);
+ if (window && GTK_IS_WINDOW (window))
{
/* If there is a grab within the window, give the grab widget
* a first crack at the key event
if (!handled_event)
{
- window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
- if (window)
+ window = gtk_widget_get_toplevel (widget);
+ if (window && GTK_IS_WINDOW (window))
{
if (GTK_WIDGET_IS_SENSITIVE (window))
gtk_widget_event (window, event);
handled_event = !GTK_WIDGET_IS_SENSITIVE (widget) || gtk_widget_event (widget, event);
tmp = widget->parent;
- gtk_widget_unref (widget);
+ g_object_unref (widget);
widget = tmp;
if (!handled_event && widget)
- gtk_widget_ref (widget);
+ g_object_ref (widget);
else
break;
}
}
else
- gtk_widget_unref (widget);
+ g_object_unref (widget);
}
#if 0
gtk_widget_show (window);
}
#endif
+
+gboolean
+_gtk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
+ GValue *return_accu,
+ const GValue *handler_return,
+ gpointer dummy)
+{
+ gboolean continue_emission;
+ gboolean signal_handled;
+
+ signal_handled = g_value_get_boolean (handler_return);
+ g_value_set_boolean (return_accu, signal_handled);
+ continue_emission = !signal_handled;
+
+ return continue_emission;
+}