📄 gtkmain.c
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <X11/Xlocale.h> /* so we get the right setlocale */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <gmodule.h>#include "gtkbutton.h"#include "gtkdnd.h"#include "gtkfeatures.h"#include "gtkhscrollbar.h"#include "gtkhseparator.h"#include "gtkmain.h"#include "gtkpreview.h"#include "gtkrc.h"#include "gtkscrolledwindow.h"#include "gtkselection.h"#include "gtksignal.h"#include "gtktable.h"#include "gtktext.h"#include "gtkvbox.h"#include "gtkvscrollbar.h"#include "gtkwidget.h"#include "gtkwindow.h"#include "gtkprivate.h"#include "gdk/gdki18n.h"#include "config.h"#include "gtkdebug.h"#include "gtkintl.h"/* Private type definitions */typedef struct _GtkInitFunction GtkInitFunction;typedef struct _GtkQuitFunction GtkQuitFunction;typedef struct _GtkClosure GtkClosure;typedef struct _GtkKeySnooperData GtkKeySnooperData;struct _GtkInitFunction{ GtkFunction function; gpointer data;};struct _GtkQuitFunction{ guint id; guint main_level; GtkCallbackMarshal marshal; GtkFunction function; gpointer data; GtkDestroyNotify destroy;};struct _GtkClosure{ GtkCallbackMarshal marshal; gpointer data; GtkDestroyNotify destroy;};struct _GtkKeySnooperData{ GtkKeySnoopFunc func; gpointer func_data; guint id;};static void gtk_exit_func (void);static gint gtk_quit_invoke_function (GtkQuitFunction *quitf);static void gtk_quit_destroy (GtkQuitFunction *quitf);static gint gtk_invoke_key_snoopers (GtkWidget *grab_widget, GdkEvent *event);static void gtk_destroy_closure (gpointer data);static gboolean gtk_invoke_idle_timeout (gpointer data);static void gtk_invoke_input (gpointer data, gint source, GdkInputCondition condition);#if 0static void gtk_error (gchar *str);static void gtk_warning (gchar *str);static void gtk_message (gchar *str);static void gtk_print (gchar *str);#endifconst 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 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 GMemChunk *quit_mem_chunk = NULL;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_DEBUGstatic const GDebugKey gtk_debug_keys[] = { {"objects", GTK_DEBUG_OBJECTS}, {"misc", GTK_DEBUG_MISC}, {"signals", GTK_DEBUG_SIGNALS}, {"dnd", GTK_DEBUG_DND}, {"plugsocket", GTK_DEBUG_PLUGSOCKET}};static const guint gtk_ndebug_keys = sizeof (gtk_debug_keys) / sizeof (GDebugKey);#endif /* G_ENABLE_DEBUG */gchar*gtk_check_version (guint required_major, guint required_minor, guint 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) return "Gtk+ version too new (micro mismatch)"; if (required_micro > GTK_MICRO_VERSION) return "Gtk+ version too old (micro mismatch)"; return NULL;}gbooleangtk_init_check (int *argc, char ***argv){ extern void gtk_object_post_arg_parsing_init (void); GSList *gtk_modules = NULL; GSList *slist; gchar *env_string = NULL; if (gtk_initialized) return TRUE;#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 /* 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_event_handler_set ((GdkEventFunc)gtk_main_do_event, NULL, NULL); #ifdef G_ENABLE_DEBUG env_string = 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 = getenv ("GTK_MODULES"); if (env_string) { gchar **modules, **as; modules = g_strsplit (env_string, ":", -1); 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; } 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) gtk_modules = g_slist_prepend (gtk_modules, g_strdup (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; } } } /* load gtk modules */ gtk_modules = g_slist_reverse (gtk_modules); for (slist = gtk_modules; slist; slist = slist->next) { gchar *module_name; GModule *module = NULL; GtkModuleInitFunc modinit_func = NULL; module_name = slist->data; slist->data = NULL; if (!(module_name[0] == '/' || (module_name[0] == 'l' && module_name[1] == 'i' && module_name[2] == 'b'))) { gchar *old = module_name; module_name = g_strconcat ("lib", module_name, ".so", NULL); g_free (old); } 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_warning ("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); }#ifdef ENABLE_NLS bindtextdomain("gtk+", GTK_LOCALEDIR);#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 (); gtk_object_post_arg_parsing_init (); gtk_signal_init (); gtk_rc_init (); /* Register an exit function to make sure we are able to cleanup. */ g_atexit (gtk_exit_func); /* Set the 'initialized' flag. */ gtk_initialized = TRUE; /* initialize gtk modules */ for (slist = gtk_modules; slist; slist = slist->next) { if (slist->data) { GtkModuleInitFunc modinit; modinit = slist->data; modinit (argc, argv); } } g_slist_free (gtk_modules); return TRUE;}voidgtk_init (int *argc, char ***argv){ if (!gtk_init_check (argc, argv)) { g_warning ("cannot open display: %s", gdk_get_display ()); exit(1); }}voidgtk_exit (int errorcode){ /* 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);}gchar*gtk_set_locale (void){ return gdk_set_locale ();}voidgtk_main (void){ GList *tmp_list; GList *functions; GtkInitFunction *init; GMainLoop *loop; gtk_main_loop_level++; loop = g_main_new (TRUE); main_loops = g_slist_prepend (main_loops, loop); tmp_list = functions = init_functions; init_functions = NULL; while (tmp_list) { init = tmp_list->data; tmp_list = tmp_list->next; (* init->function) (init->data); g_free (init); } g_list_free (functions); if (g_main_is_running (main_loops->data)) { GDK_THREADS_LEAVE (); g_main_run (loop); GDK_THREADS_ENTER (); gdk_flush ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -