X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fgdk.c;h=87d12ea46931ef4d0908544cdc61611d59d416f8;hb=2fb74b135baeeb7b2363e099d61ac953c1467404;hp=5ac0af1a819dc0294ea7a5642d69c1897c38e2c1;hpb=85224117f45c25841fb50ab46ae8047e83a65479;p=~andy%2Fgtk diff --git a/gdk/gdk.c b/gdk/gdk.c index 5ac0af1a8..87d12ea46 100644 --- a/gdk/gdk.c +++ b/gdk/gdk.c @@ -37,7 +37,6 @@ #endif typedef struct _GdkPredicate GdkPredicate; -typedef struct _GdkErrorTrap GdkErrorTrap; struct _GdkPredicate { @@ -45,43 +44,38 @@ struct _GdkPredicate gpointer data; }; -struct _GdkErrorTrap -{ - gint error_warnings; - gint error_code; -}; - -/* - * Private function declarations - */ - -GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev, - GdkEvent *event, - gpointer data); - /* Private variable declarations */ static int gdk_initialized = 0; /* 1 if the library is initialized, * 0 otherwise. */ -static GSList *gdk_error_traps = NULL; /* List of error traps */ -static GSList *gdk_error_trap_free_list = NULL; /* Free list */ +static gchar *gdk_progclass = NULL; +static gint gdk_argc = 0; +static gchar **gdk_argv = NULL; #ifdef G_ENABLE_DEBUG static const GDebugKey gdk_debug_keys[] = { {"events", GDK_DEBUG_EVENTS}, {"misc", GDK_DEBUG_MISC}, {"dnd", GDK_DEBUG_DND}, - {"color-context", GDK_DEBUG_COLOR_CONTEXT}, - {"xim", GDK_DEBUG_XIM} + {"xim", GDK_DEBUG_XIM}, + {"nograbs", GDK_DEBUG_NOGRABS}, + {"colormap", GDK_DEBUG_COLORMAP}, + {"gdkrgb", GDK_DEBUG_GDKRGB}, + {"gc", GDK_DEBUG_GC}, + {"pixmap", GDK_DEBUG_PIXMAP}, + {"image", GDK_DEBUG_IMAGE}, + {"input", GDK_DEBUG_INPUT}, + {"cursor", GDK_DEBUG_CURSOR}, + {"multihead", GDK_DEBUG_MULTIHEAD}, }; -static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey); +static const int gdk_ndebug_keys = G_N_ELEMENTS (gdk_debug_keys); #endif /* G_ENABLE_DEBUG */ -GdkArgContext * +static GdkArgContext * gdk_arg_context_new (gpointer cb_data) { GdkArgContext *result = g_new (GdkArgContext, 1); @@ -91,20 +85,20 @@ gdk_arg_context_new (gpointer cb_data) return result; } -void +static void gdk_arg_context_destroy (GdkArgContext *context) { g_ptr_array_free (context->tables, TRUE); g_free (context); } -void +static void gdk_arg_context_add_table (GdkArgContext *context, GdkArgDesc *table) { g_ptr_array_add (context->tables, table); } -void +static void gdk_arg_context_parse (GdkArgContext *context, gint *argc, gchar ***argv) { int i, j, k; @@ -142,7 +136,7 @@ gdk_arg_context_parse (GdkArgContext *context, gint *argc, gchar ***argv) int len = strlen (table[k].name); if (strncmp (arg, table[k].name, len) == 0 && - (arg[len] == '=' || argc[len] == 0)) + (arg[len] == '=' || arg[len] == 0)) { char *value = NULL; @@ -215,20 +209,26 @@ gdk_arg_context_parse (GdkArgContext *context, gint *argc, gchar ***argv) static void gdk_arg_debug_cb (const char *key, const char *value, gpointer user_data) { - gdk_debug_flags |= g_parse_debug_string (value, - (GDebugKey *) gdk_debug_keys, - gdk_ndebug_keys); + _gdk_debug_flags |= g_parse_debug_string (value, + (GDebugKey *) gdk_debug_keys, + gdk_ndebug_keys); } static void gdk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data) { - gdk_debug_flags &= ~g_parse_debug_string (value, - (GDebugKey *) gdk_debug_keys, - gdk_ndebug_keys); + _gdk_debug_flags &= ~g_parse_debug_string (value, + (GDebugKey *) gdk_debug_keys, + gdk_ndebug_keys); } #endif /* G_ENABLE_DEBUG */ +static void +gdk_arg_class_cb (const char *key, const char *value, gpointer user_data) +{ + gdk_set_program_class (value); +} + static void gdk_arg_name_cb (const char *key, const char *value, gpointer user_data) { @@ -236,7 +236,11 @@ gdk_arg_name_cb (const char *key, const char *value, gpointer user_data) } static GdkArgDesc gdk_args[] = { - { "name", GDK_ARG_STRING, NULL, gdk_arg_name_cb }, + { "class" , GDK_ARG_CALLBACK, NULL, gdk_arg_class_cb }, + { "name", GDK_ARG_CALLBACK, NULL, gdk_arg_name_cb }, + { "display", GDK_ARG_STRING, &_gdk_display_name, (GdkArgFunc)NULL }, + { "screen", GDK_ARG_INT, &_gdk_screen_number, (GdkArgFunc)NULL }, + #ifdef G_ENABLE_DEBUG { "gdk-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_debug_cb }, { "gdk-no-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_no_debug_cb }, @@ -244,52 +248,60 @@ static GdkArgDesc gdk_args[] = { { NULL } }; -/* - *-------------------------------------------------------------- - * gdk_init_check - * - * Initialize the library for use. + +/** + * _gdk_get_command_line_args: + * @argv: location to store argv pointer + * @argc: location + * + * Retrieve the command line arguments passed to gdk_init(). + * The returned argv pointer points to static storage ; no + * copy is made. + **/ +void +_gdk_get_command_line_args (int *argc, + char ***argv) +{ + *argc = gdk_argc; + *argv = gdk_argv; +} + +/** + * gdk_parse_args: + * @argc: the number of command line arguments. + * @argv: the array of command line arguments. + * + * Parse command line arguments, and store for future + * use by calls to gdk_display_open(). * - * Arguments: - * "argc" is the number of arguments. - * "argv" is an array of strings. + * Any arguments used by GDK are removed from the array and @argc and @argv are + * updated accordingly. * - * Results: - * "argc" and "argv" are modified to reflect any arguments - * which were not handled. (Such arguments should either - * be handled by the application or dismissed). If initialization - * fails, returns FALSE, otherwise TRUE. + * You shouldn't call this function explicitely if you are using + * gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check(). * - * Side effects: - * The library is initialized. - * - *-------------------------------------------------------------- - */ - -gboolean -gdk_init_check (int *argc, + * Since: 2.2 + **/ +void +gdk_parse_args (int *argc, char ***argv) { - gchar **argv_orig = NULL; - gint argc_orig = 0; GdkArgContext *arg_context; - gboolean result; - int i; - + gint i; + if (gdk_initialized) - return TRUE; + return; + + gdk_initialized = TRUE; - if (g_thread_supported ()) - gdk_threads_mutex = g_mutex_new (); - if (argc && argv) { - argc_orig = *argc; + gdk_argc = *argc; - argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*)); - for (i = 0; i < argc_orig; i++) - argv_orig[i] = g_strdup ((*argv)[i]); - argv_orig[argc_orig] = NULL; + gdk_argv = g_malloc ((gdk_argc + 1) * sizeof (char*)); + for (i = 0; i < gdk_argc; i++) + gdk_argv[i] = g_strdup ((*argv)[i]); + gdk_argv[gdk_argc] = NULL; if (*argc > 0) { @@ -302,13 +314,23 @@ gdk_init_check (int *argc, g_set_prgname ((*argv)[0]); } } + else + { + g_set_prgname (""); + } + /* We set the fallback program class here, rather than lazily in + * gdk_get_program_class, since we don't want -name to override it. + */ + gdk_progclass = g_strdup (g_get_prgname ()); + if (gdk_progclass[0]) + gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]); #ifdef G_ENABLE_DEBUG { gchar *debug_string = getenv("GDK_DEBUG"); if (debug_string != NULL) - gdk_debug_flags = g_parse_debug_string (debug_string, + _gdk_debug_flags = g_parse_debug_string (debug_string, (GDebugKey *) gdk_debug_keys, gdk_ndebug_keys); } @@ -323,26 +345,106 @@ gdk_init_check (int *argc, GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ())); g_type_init (); + + /* Do any setup particular to the windowing system + */ + _gdk_windowing_init (argc, argv); +} + +/** + * gdk_get_display_arg_name: + * + * Gets the display name specified in the command line arguments passed + * to gdk_init() or gdk_parse_args(), if any. + * + * Returns: the display name, if specified explicitely, otherwise %NULL + * this string is owned by GTK+ and must not be modified or freed. + * + * Since: 2.2 + */ +G_CONST_RETURN gchar * +gdk_get_display_arg_name (void) +{ + if (!_gdk_display_arg_name) + { + if (_gdk_screen_number >= 0) + _gdk_display_arg_name = _gdk_windowing_substitute_screen_number (_gdk_display_name, _gdk_screen_number); + else + _gdk_display_arg_name = g_strdup (_gdk_display_name); + } + + return _gdk_display_arg_name; +} + +/** + * gdk_display_open_default_libgtk_only: + * + * Opens the default display specified by command line arguments or + * environment variables, sets it as the default display, and returns + * it. gdk_parse_args must have been called first. If the default + * display has previously been set, simply returns that. An internal + * function that should not be used by applications. + * + * Return value: the default display, if it could be opened, + * otherwise %NULL. + **/ +GdkDisplay * +gdk_display_open_default_libgtk_only (void) +{ + GdkDisplay *display; + + g_return_val_if_fail (gdk_initialized, NULL); - result = _gdk_windowing_init_check (argc_orig, argv_orig); + display = gdk_display_get_default (); + if (display) + return display; - for (i = 0; i < argc_orig; i++) - g_free(argv_orig[i]); - g_free(argv_orig); + display = gdk_display_open (gdk_get_display_arg_name ()); - if (!result) - return FALSE; + if (!display && _gdk_screen_number >= 0) + { + g_free (_gdk_display_arg_name); + _gdk_display_arg_name = g_strdup (_gdk_display_name); + + display = gdk_display_open (_gdk_display_name); + } - gdk_visual_init (); - _gdk_windowing_window_init (); - _gdk_windowing_image_init (); - gdk_events_init (); - gdk_input_init (); - gdk_dnd_init (); + if (display) + gdk_display_manager_set_default_display (gdk_display_manager_get (), + display); + + return display; +} + +/* + *-------------------------------------------------------------- + * gdk_init_check + * + * Initialize the library for use. + * + * Arguments: + * "argc" is the number of arguments. + * "argv" is an array of strings. + * + * Results: + * "argc" and "argv" are modified to reflect any arguments + * which were not handled. (Such arguments should either + * be handled by the application or dismissed). If initialization + * fails, returns FALSE, otherwise TRUE. + * + * Side effects: + * The library is initialized. + * + *-------------------------------------------------------------- + */ - gdk_initialized = 1; +gboolean +gdk_init_check (int *argc, + char ***argv) +{ + gdk_parse_args (argc, argv); - return TRUE; + return gdk_display_open_default_libgtk_only () != NULL; } void @@ -350,7 +452,7 @@ gdk_init (int *argc, char ***argv) { if (!gdk_init_check (argc, argv)) { - g_warning ("cannot open display: %s", gdk_get_display ()); + g_warning ("cannot open display: %s", gdk_get_display_arg_name ()); exit(1); } } @@ -377,141 +479,51 @@ gdk_init (int *argc, char ***argv) void gdk_exit (gint errorcode) { - /* de-initialisation is done by the gdk_exit_funct(), - no need to do this here (Alex J.) */ exit (errorcode); } -#if 0 - -/* This is disabled, but the code isn't removed, because we might - * want to have some sort of explicit way to shut down GDK cleanly - * at some point in the future. - */ - -/* - *-------------------------------------------------------------- - * gdk_exit_func - * - * This is the "atexit" function that makes sure the - * library gets a chance to cleanup. - * - * Arguments: - * - * Results: - * - * Side effects: - * The library is un-initialized and the program exits. - * - *-------------------------------------------------------------- - */ - -static void -gdk_exit_func (void) +void +gdk_threads_enter () { - static gboolean in_gdk_exit_func = FALSE; - - /* This is to avoid an infinite loop if a program segfaults in - an atexit() handler (and yes, it does happen, especially if a program - has trounced over memory too badly for even g_message to work) */ - if (in_gdk_exit_func == TRUE) - return; - in_gdk_exit_func = TRUE; - - if (gdk_initialized) - { - gdk_image_exit (); - gdk_input_exit (); - gdk_key_repeat_restore (); - - gdk_windowing_exit (); - - gdk_initialized = 0; - } + GDK_THREADS_ENTER (); } -#endif - -/************************************************************* - * gdk_error_trap_push: - * Push an error trap. X errors will be trapped until - * the corresponding gdk_error_pop(), which will return - * the error code, if any. - * arguments: - * - * results: - *************************************************************/ - void -gdk_error_trap_push (void) +gdk_threads_leave () { - GSList *node; - GdkErrorTrap *trap; - - if (gdk_error_trap_free_list) - { - node = gdk_error_trap_free_list; - gdk_error_trap_free_list = gdk_error_trap_free_list->next; - } - else - { - node = g_slist_alloc (); - node->data = g_new (GdkErrorTrap, 1); - } - - node->next = gdk_error_traps; - gdk_error_traps = node; - - trap = node->data; - trap->error_code = gdk_error_code; - trap->error_warnings = gdk_error_warnings; - - gdk_error_code = 0; - gdk_error_warnings = 0; + GDK_THREADS_LEAVE (); } -/************************************************************* - * gdk_error_trap_pop: - * Pop an error trap added with gdk_error_push() - * arguments: - * - * results: - * 0, if no error occured, otherwise the error code. - *************************************************************/ - -gint -gdk_error_trap_pop (void) +/** + * gdk_threads_init: + * + * Initializes GDK so that it can be used from multiple threads + * in conjunction with gdk_threads_enter() and gdk_threads_leave(). + * g_thread_init() must be called previous to this function. + * + * This call must be made before any use of the main loop from + * GTK+; to be safe, call it before gtk_init(). + **/ +void +gdk_threads_init () { - GSList *node; - GdkErrorTrap *trap; - gint result; - - g_return_val_if_fail (gdk_error_traps != NULL, 0); - - node = gdk_error_traps; - gdk_error_traps = gdk_error_traps->next; + if (!g_thread_supported ()) + g_error ("g_thread_init() must be called before gdk_threads_init()"); - node->next = gdk_error_trap_free_list; - gdk_error_trap_free_list = node; - - result = gdk_error_code; - - trap = node->data; - gdk_error_code = trap->error_code; - gdk_error_warnings = trap->error_warnings; - - return result; + gdk_threads_mutex = g_mutex_new (); } -void -gdk_threads_enter () +G_CONST_RETURN char * +gdk_get_program_class (void) { - GDK_THREADS_ENTER (); + return gdk_progclass; } void -gdk_threads_leave () +gdk_set_program_class (const char *program_class) { - GDK_THREADS_LEAVE (); -} + if (gdk_progclass) + g_free (gdk_progclass); + gdk_progclass = g_strdup (program_class); +}