#include "gtkrc.h"
#include "gtkselection.h"
#include "gtksettings.h"
-#include "gtksignal.h"
#include "gtkwidget.h"
#include "gtkwindow.h"
#include "gtkprivate.h"
typedef struct _GtkQuitFunction GtkQuitFunction;
typedef struct _GtkClosure GtkClosure;
typedef struct _GtkKeySnooperData GtkKeySnooperData;
+typedef struct _GtkModuleInfo GtkModuleInfo;
struct _GtkInitFunction
{
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,
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;
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;
}
}
static GSList *
-load_module (GSList *gtk_modules,
+load_module (GSList *module_list,
const gchar *name)
{
GtkModuleInitFunc modinit_func = NULL;
+ GtkModuleInfo *info;
GModule *module = NULL;
if (g_module_supported ())
g_module_symbol (module, "gtk_module_init", (gpointer *) &modinit_func) &&
modinit_func)
{
- if (!g_slist_find (gtk_modules, (gconstpointer) modinit_func))
+ if (!g_slist_find (module_list, (gconstpointer) modinit_func))
{
g_module_make_resident (module);
- gtk_modules = g_slist_prepend (gtk_modules,
- (gpointer) modinit_func);
+ 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);
}
- return gtk_modules;
+ return module_list;
}
static GSList *
load_modules (const char *module_str)
{
gchar **module_names = pango_split_file_list (module_str);
- GSList *gtk_modules = NULL;
+ GSList *module_list = NULL;
gint i;
for (i = 0; module_names[i]; i++)
- gtk_modules = load_module (gtk_modules, module_names[i]);
+ module_list = load_module (module_list, module_names[i]);
- gtk_modules = g_slist_reverse (gtk_modules);
+ module_list = g_slist_reverse (module_list);
g_strfreev (module_names);
- return gtk_modules;
+ return module_list;
}
static gboolean do_setlocale = TRUE;
#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)
{
GString *gtk_modules_string = NULL;
- GSList *gtk_modules = NULL;
GSList *slist;
+ GdkDisplayManager *display_manager;
const gchar *env_string;
if (gtk_initialized)
if (!setlocale (LC_ALL, ""))
g_warning ("Locale not supported by C library.\n\tUsing the fallback 'C' locale.");
}
-
- /* 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;
+ gdk_parse_args (argc, argv);
gdk_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL);
#ifdef G_ENABLE_DEBUG
*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)
*/
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 = (GtkModuleInitFunc) slist->data;
- modinit (argc, argv);
+ GtkModuleInfo *info = slist->data;
+
+ if (info->display_init_func)
+ info->init_func (argc, argv);
}
}
- g_slist_free (gtk_modules);
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)
+{
+ if (!gtk_parse_args (argc, argv))
+ return FALSE;
+
+ return gdk_display_open_default_libgtk_only () != NULL;
+}
+
#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))
{
- char *display_name_arg = gdk_get_display_arg_name ();
+ const 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,\n"
- "or that you are using an unsupported compiler.");
+ "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
"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 switch,\n"
- "or that you are using an unsupported compiler.");
+ "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
void
gtk_exit (gint errorcode)
{
- /* Only if "gtk" has been initialized should we de-initialize.
- */
- gdk_exit (errorcode);
+ exit (errorcode);
}
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';
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;
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;
}
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;
}
if (next_event)
gdk_event_free (next_event);
+ if (event->type == GDK_SETTING)
+ {
+ _gtk_settings_handle_event (&event->setting);
+ return;
+ }
+
/* Find the widget which got the event. We store the widget
* in the user_data field of GdkWindow's.
* Ignore the event if we don't have a widget for it, except
* them specially
*/
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);
+ _gtk_selection_incr_event (event->any.window,
+ &event->property);
return;
}
break;
case GDK_DELETE:
- gtk_widget_ref (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_WIDGET_REALIZED (event_widget))
gtk_widget_destroy (event_widget);
- gtk_widget_unref (event_widget);
+ g_object_unref (event_widget);
}
break;
if (was_grabbed != is_grabbed)
{
- g_object_ref (G_OBJECT (child));
+ g_object_ref (child);
- gtk_signal_emit_by_name (GTK_OBJECT (child), "grab_notify", was_grabbed);
+ 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 (G_OBJECT (child));
+ g_object_unref (child);
}
}
was_grabbed = (group->grabs != NULL);
- gtk_widget_ref (widget);
+ g_object_ref (widget);
group->grabs = g_slist_prepend (group->grabs, widget);
gtk_grab_notify (group, widget, FALSE);
group = gtk_main_get_window_group (widget);
group->grabs = g_slist_remove (group->grabs, widget);
- gtk_widget_unref (widget);
+ g_object_unref (widget);
gtk_grab_notify (group, widget, TRUE);
}
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
GtkArg args[1];
gint ret_val = FALSE;
args[0].name = NULL;
- args[0].type = GTK_TYPE_BOOL;
+ args[0].type = G_TYPE_BOOLEAN;
args[0].d.pointer_data = &ret_val;
closure->marshal (NULL, closure->data, 0, args);
return ret_val;
GtkClosure *closure = data;
GtkArg args[3];
- args[0].type = GTK_TYPE_INT;
+ args[0].type = G_TYPE_INT;
args[0].name = NULL;
GTK_VALUE_INT (args[0]) = source;
args[1].type = GDK_TYPE_INPUT_CONDITION;
args[1].name = NULL;
GTK_VALUE_FLAGS (args[1]) = condition;
- args[2].type = GTK_TYPE_NONE;
+ args[2].type = G_TYPE_NONE;
args[2].name = NULL;
closure->marshal (NULL, closure->data, 2, args);
gint ret_val = FALSE;
args[0].name = NULL;
- args[0].type = GTK_TYPE_BOOL;
+ args[0].type = G_TYPE_BOOLEAN;
args[0].d.pointer_data = &ret_val;
((GtkCallbackMarshal) quitf->marshal) (NULL,
quitf->data,
handled_event = FALSE;
- gtk_widget_ref (widget);
+ g_object_ref (widget);
if ((event->type == GDK_KEY_PRESS) ||
(event->type == GDK_KEY_RELEASE))
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