1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gdkinternals.h"
35 #ifndef HAVE_XCONVERTCASE
36 #include "gdkkeysyms.h"
39 typedef struct _GdkPredicate GdkPredicate;
47 /* Private variable declarations
49 static int gdk_initialized = 0; /* 1 if the library is initialized,
53 static gchar *gdk_progclass = NULL;
56 static const GDebugKey gdk_debug_keys[] = {
57 {"events", GDK_DEBUG_EVENTS},
58 {"misc", GDK_DEBUG_MISC},
59 {"dnd", GDK_DEBUG_DND},
60 {"xim", GDK_DEBUG_XIM},
61 {"nograbs", GDK_DEBUG_NOGRABS},
64 static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey);
66 #endif /* G_ENABLE_DEBUG */
68 static GdkArgContext *
69 gdk_arg_context_new (gpointer cb_data)
71 GdkArgContext *result = g_new (GdkArgContext, 1);
72 result->tables = g_ptr_array_new ();
73 result->cb_data = cb_data;
79 gdk_arg_context_destroy (GdkArgContext *context)
81 g_ptr_array_free (context->tables, TRUE);
86 gdk_arg_context_add_table (GdkArgContext *context, GdkArgDesc *table)
88 g_ptr_array_add (context->tables, table);
92 gdk_arg_context_parse (GdkArgContext *context, gint *argc, gchar ***argv)
96 /* Save a copy of the original argc and argv */
99 for (i = 1; i < *argc; i++)
103 if (!(*argv)[i][0] == '-' && (*argv)[i][1] == '-')
106 arg = (*argv)[i] + 2;
108 /* '--' terminates list of arguments */
115 for (j = 0; j < context->tables->len; j++)
117 GdkArgDesc *table = context->tables->pdata[j];
118 for (k = 0; table[k].name; k++)
120 switch (table[k].type)
123 case GDK_ARG_CALLBACK:
126 int len = strlen (table[k].name);
128 if (strncmp (arg, table[k].name, len) == 0 &&
129 (arg[len] == '=' || arg[len] == 0))
136 value = arg + len + 1;
137 else if (i < *argc - 1)
139 value = (*argv)[i + 1];
146 switch (table[k].type)
149 *(gchar **)table[k].location = g_strdup (value);
152 *(gint *)table[k].location = atoi (value);
154 case GDK_ARG_CALLBACK:
155 (*table[k].callback)(table[k].name, value, context->cb_data);
167 if (strcmp (arg, table[k].name) == 0)
171 *(gboolean *)table[k].location = (table[k].type == GDK_ARG_BOOL) ? TRUE : FALSE;
181 for (i = 1; i < *argc; i++)
183 for (k = i; k < *argc; k++)
184 if ((*argv)[k] != NULL)
190 for (j = i + k; j < *argc; j++)
191 (*argv)[j-k] = (*argv)[j];
198 #ifdef G_ENABLE_DEBUG
200 gdk_arg_debug_cb (const char *key, const char *value, gpointer user_data)
202 _gdk_debug_flags |= g_parse_debug_string (value,
203 (GDebugKey *) gdk_debug_keys,
208 gdk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data)
210 _gdk_debug_flags &= ~g_parse_debug_string (value,
211 (GDebugKey *) gdk_debug_keys,
214 #endif /* G_ENABLE_DEBUG */
217 gdk_arg_class_cb (const char *key, const char *value, gpointer user_data)
219 gdk_set_program_class (value);
223 gdk_arg_name_cb (const char *key, const char *value, gpointer user_data)
225 g_set_prgname (value);
228 static GdkArgDesc gdk_args[] = {
229 { "class" , GDK_ARG_CALLBACK, NULL, gdk_arg_class_cb },
230 { "name", GDK_ARG_CALLBACK, NULL, gdk_arg_name_cb },
231 #ifdef G_ENABLE_DEBUG
232 { "gdk-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_debug_cb },
233 { "gdk-no-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_no_debug_cb },
234 #endif /* G_ENABLE_DEBUG */
239 *--------------------------------------------------------------
242 * Initialize the library for use.
245 * "argc" is the number of arguments.
246 * "argv" is an array of strings.
249 * "argc" and "argv" are modified to reflect any arguments
250 * which were not handled. (Such arguments should either
251 * be handled by the application or dismissed). If initialization
252 * fails, returns FALSE, otherwise TRUE.
255 * The library is initialized.
257 *--------------------------------------------------------------
261 gdk_init_check (int *argc,
264 gchar **argv_orig = NULL;
266 GdkArgContext *arg_context;
277 argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*));
278 for (i = 0; i < argc_orig; i++)
279 argv_orig[i] = g_strdup ((*argv)[i]);
280 argv_orig[argc_orig] = NULL;
286 d = strrchr((*argv)[0], G_DIR_SEPARATOR);
288 g_set_prgname (d + 1);
290 g_set_prgname ((*argv)[0]);
295 g_set_prgname ("<unknown>");
298 #ifdef G_ENABLE_DEBUG
300 gchar *debug_string = getenv("GDK_DEBUG");
301 if (debug_string != NULL)
302 _gdk_debug_flags = g_parse_debug_string (debug_string,
303 (GDebugKey *) gdk_debug_keys,
306 #endif /* G_ENABLE_DEBUG */
308 arg_context = gdk_arg_context_new (NULL);
309 gdk_arg_context_add_table (arg_context, gdk_args);
310 gdk_arg_context_add_table (arg_context, _gdk_windowing_args);
311 gdk_arg_context_parse (arg_context, argc, argv);
312 gdk_arg_context_destroy (arg_context);
314 GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ()));
318 result = _gdk_windowing_init_check (argc_orig, argv_orig);
320 for (i = 0; i < argc_orig; i++)
321 g_free(argv_orig[i]);
328 _gdk_windowing_window_init ();
329 _gdk_windowing_image_init ();
340 gdk_init (int *argc, char ***argv)
342 if (!gdk_init_check (argc, argv))
344 g_warning ("cannot open display: %s", gdk_get_display ());
350 *--------------------------------------------------------------
353 * Restores the library to an un-itialized state and exits
354 * the program using the "exit" system call.
357 * "errorcode" is the error value to pass to "exit".
360 * Allocated structures are freed and the program exits
365 *--------------------------------------------------------------
369 gdk_exit (gint errorcode)
371 /* de-initialisation is done by the gdk_exit_funct(),
372 no need to do this here (Alex J.) */
378 /* This is disabled, but the code isn't removed, because we might
379 * want to have some sort of explicit way to shut down GDK cleanly
380 * at some point in the future.
384 *--------------------------------------------------------------
387 * This is the "atexit" function that makes sure the
388 * library gets a chance to cleanup.
395 * The library is un-initialized and the program exits.
397 *--------------------------------------------------------------
403 static gboolean in_gdk_exit_func = FALSE;
405 /* This is to avoid an infinite loop if a program segfaults in
406 an atexit() handler (and yes, it does happen, especially if a program
407 has trounced over memory too badly for even g_message to work) */
408 if (in_gdk_exit_func == TRUE)
410 in_gdk_exit_func = TRUE;
417 _gdk_windowing_exit ();
428 GDK_THREADS_ENTER ();
434 GDK_THREADS_LEAVE ();
440 * Initializes GDK so that it can be used from multiple threads
441 * in conjunction with gdk_threads_enter() and gdk_threads_leave().
442 * g_thread_init() must be called previous to this function.
444 * This call must be made before any use of the main loop from
445 * GTK+; to be safe, call it before gtk_init().
450 if (!g_thread_supported ())
451 g_error ("g_thread_init() must be called before gdk_threads_init()");
453 gdk_threads_mutex = g_mutex_new ();
456 G_CONST_RETURN char *
457 gdk_get_program_class (void)
459 if (gdk_progclass == NULL)
461 gdk_progclass = g_strdup (g_get_prgname ());
462 gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]);
465 return gdk_progclass;
469 gdk_set_program_class (const char *program_class)
472 g_free (gdk_progclass);
474 gdk_progclass = g_strdup (program_class);