diff options
Diffstat (limited to '')
-rw-r--r-- | chooser/chooser-main.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/chooser/chooser-main.c b/chooser/chooser-main.c new file mode 100644 index 0000000..6f94c62 --- /dev/null +++ b/chooser/chooser-main.c @@ -0,0 +1,250 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include <stdlib.h> +#include <libintl.h> +#include <locale.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> + +#include <glib/gi18n.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> + +#include "gdm-common.h" +#include "gdm-log.h" + +#include "gdm-chooser-session.h" + +#define ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility" + +static Atom AT_SPI_IOR; + + +static gboolean +assistive_registry_launch (void) +{ + GPid pid; + GError *error; + const char *command; + char **argv; + gboolean res; + + command = AT_SPI_REGISTRYD_DIR "/at-spi-registryd"; + + argv = NULL; + error = NULL; + res = g_shell_parse_argv (command, NULL, &argv, &error); + if (! res) { + g_warning ("Unable to parse command: %s", error->message); + return FALSE; + } + + error = NULL; + res = g_spawn_async (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH + | G_SPAWN_STDOUT_TO_DEV_NULL + | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, + NULL, + &pid, + &error); + g_strfreev (argv); + + if (! res) { + g_warning ("Unable to run command %s: %s", command, error->message); + return FALSE; + } + + if (kill (pid, 0) < 0) { + g_warning ("at-spi-registryd not running"); + return FALSE; + } + + return TRUE; +} + +static GdkFilterReturn +filter_watch (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + XEvent *xev = (XEvent *)xevent; + + if (xev->xany.type == PropertyNotify + && xev->xproperty.atom == AT_SPI_IOR) { + gtk_main_quit (); + + return GDK_FILTER_REMOVE; + } + + return GDK_FILTER_CONTINUE; +} + +static gboolean +filter_timeout (gpointer data) +{ + g_warning ("The accessibility registry was not found."); + + gtk_main_quit (); + + return FALSE; +} + +static void +assistive_registry_start (void) +{ + GdkWindow *root; + guint tid; + + root = gdk_get_default_root_window (); + + if ( ! AT_SPI_IOR) { + AT_SPI_IOR = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "AT_SPI_IOR", False); + } + + gdk_window_set_events (root, GDK_PROPERTY_CHANGE_MASK); + + if ( ! assistive_registry_launch ()) { + g_warning ("The accessibility registry could not be started."); + return; + } + + gdk_window_add_filter (root, filter_watch, NULL); + tid = g_timeout_add_seconds (5, filter_timeout, NULL); + + gtk_main (); + + gdk_window_remove_filter (root, filter_watch, NULL); + g_source_remove (tid); +} + +static void +at_set_gtk_modules (void) +{ + GSList *modules_list; + GSList *l; + const char *old; + char **modules; + gboolean found_gail; + gboolean found_atk_bridge; + int n; + + n = 0; + modules_list = NULL; + found_gail = FALSE; + found_atk_bridge = FALSE; + + if ((old = g_getenv ("GTK_MODULES")) != NULL) { + modules = g_strsplit (old, ":", -1); + for (n = 0; modules[n]; n++) { + if (!strcmp (modules[n], "gail")) { + found_gail = TRUE; + } else if (!strcmp (modules[n], "atk-bridge")) { + found_atk_bridge = TRUE; + } + + modules_list = g_slist_prepend (modules_list, modules[n]); + modules[n] = NULL; + } + g_free (modules); + } + + if (!found_gail) { + modules_list = g_slist_prepend (modules_list, "gail"); + ++n; + } + + if (!found_atk_bridge) { + modules_list = g_slist_prepend (modules_list, "atk-bridge"); + ++n; + } + + modules = g_new (char *, n + 1); + modules[n--] = NULL; + for (l = modules_list; l; l = l->next) { + modules[n--] = g_strdup (l->data); + } + + g_setenv ("GTK_MODULES", g_strjoinv (":", modules), TRUE); + g_strfreev (modules); + g_slist_free (modules_list); +} + +static void +load_a11y (void) +{ + assistive_registry_start (); + at_set_gtk_modules (); +} + +int +main (int argc, char *argv[]) +{ + GdmChooserSession *session; + gboolean res; + GError *error; + + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + setlocale (LC_ALL, ""); + + gdm_log_init (); + gdm_log_set_debug (TRUE); + + g_debug ("Chooser for display %s xauthority:%s", + g_getenv ("DISPLAY"), + g_getenv ("XAUTHORITY")); + + gdk_init (&argc, &argv); + + load_a11y (); + + gtk_init (&argc, &argv); + + session = gdm_chooser_session_new (); + if (session == NULL) { + g_critical ("Unable to create chooser session"); + exit (EXIT_FAILURE); + } + + error = NULL; + res = gdm_chooser_session_start (session, &error); + if (! res) { + g_warning ("Unable to start chooser session: %s", error->message); + g_error_free (error); + exit (EXIT_FAILURE); + } + + gtk_main (); + + if (session != NULL) { + g_object_unref (session); + } + + return 0; +} |