/* CALLY - The Clutter Accessibility Implementation Library * * Copyright (C) 2009 Igalia, S.L. * * Author: Alejandro PiƱeiro Iglesias * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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. */ #include #include #include #include "cally-examples-util.h" /* Checking the at-spi sources, the module directory is * $(libdir)/gtk-2.0/modules * * It is supposed cally would be installed on the same libdir. * * You could use the option atk-bridge-dir to use other directory. */ #define ATK_BRIDGE_DEFAULT_MODULE_DIRECTORY PREFIXDIR"/gtk-2.0/modules" /* Convenient default directory (debug purposes) */ #define CALLY_DEFAULT_MODULE_DIRECTORY "../cally/.libs" static gchar ** _get_clutter_module_paths (void) { gchar **retval; GPtrArray *paths; const gchar *modules_dir; paths = g_ptr_array_new (); /* CLUTTER_[API/ABI]_VERSION_S not provided by clutter */ /* g_ptr_array_add (paths, */ /* g_build_filename (g_get_home_dir (), */ /* ".clutter-" CLUTTER_API_VERSION_S, */ /* CLUTTER_ABI_VERSION_S, */ /* "modules", */ /* NULL)); */ /* g_ptr_array_add (paths, */ /* g_build_filename (CLUTTER_LIBDIR, */ /* "clutter-" CLUTTER_API_VERSION_S, */ /* CLUTTER_ABI_VERSION_S, */ /* "modules", */ /* NULL)); */ g_ptr_array_add (paths, g_strdup (CALLY_DEFAULT_MODULE_DIRECTORY)); modules_dir = g_getenv ("CLUTTER_MODULES_PATH"); if (modules_dir) g_ptr_array_add (paths, g_strdup (modules_dir)); g_ptr_array_add (paths, NULL); retval = (gchar **) paths->pdata; g_ptr_array_free (paths, FALSE); return retval; } static gchar * _search_for_clutter_module (const gchar *module_name) { gchar **paths, **path; gchar *module_path = NULL; paths = _get_clutter_module_paths (); for (path = paths; *path; path++) { gchar *tmp_name; tmp_name = g_module_build_path (*path, module_name); if (g_file_test (tmp_name, G_FILE_TEST_EXISTS)) { module_path = tmp_name; break; } g_free (tmp_name); } g_strfreev (paths); return module_path; } static gchar * _search_for_bridge_module (const gchar *module_name) { /* We simplify the search for the atk bridge, see see the definition * of the macro for more information*/ return g_strdup (ATK_BRIDGE_DEFAULT_MODULE_DIRECTORY); } static gchar* _a11y_check_custom_bridge (int *argc, char ***argv) { GError *error = NULL; GOptionContext *context; static gchar *bridge_dir = NULL; static GOptionEntry entries [] = { {"atk-bridge-dir", 'd', 0, G_OPTION_ARG_STRING, &bridge_dir, "atk-bridge module directory", NULL} }; context = g_option_context_new ("- cally examples"); g_option_context_add_main_entries (context, entries, NULL); if (!g_option_context_parse (context, argc, argv, &error)) { g_print ("%s\n", error->message); g_print ("Use --help for more information.\n"); exit (0); } return bridge_dir; } static gboolean _a11y_invoke_module (const gchar *module_path, gboolean init) { GModule *handle; void (*invoke_fn) (void); const char *method; if (init) method = "gnome_accessibility_module_init"; else method = "gnome_accessibility_module_shutdown"; if (!module_path) return FALSE; if (!(handle = g_module_open (module_path, G_MODULE_BIND_LAZY))) { g_warning ("Accessibility: failed to load module '%s': '%s'", module_path, g_module_error ()); return FALSE; } if (!g_module_symbol (handle, method, (gpointer *)&invoke_fn)) { g_warning ("Accessibility: error library '%s' does not include " "method '%s' required for accessibility support", module_path, method); g_module_close (handle); return FALSE; } g_debug ("Module %s loaded successfully", module_path); invoke_fn (); return TRUE; } /** * This method will initialize the accessibility support provided by cally. * * Basically it will load the cally module using gmodule functions. * */ void cally_util_a11y_init (int *argc, char ***argv) { gchar *bridge_dir = NULL; gchar *cally_path = NULL; gchar *bridge_path = NULL; cally_path = _search_for_clutter_module ("cally-1.0"); if (cally_path == NULL) { g_warning ("Accessibility: failed to find module 'cally-1.0' " "which is needed to make this application accessible"); return; } bridge_dir = _a11y_check_custom_bridge (argc, argv); if (bridge_dir == NULL) bridge_dir = _search_for_bridge_module ("atk-bridge"); bridge_path = g_module_build_path (bridge_dir, "libatk-bridge"); _a11y_invoke_module (cally_path, TRUE); _a11y_invoke_module (bridge_path, TRUE); g_free (bridge_dir); g_free (bridge_path); g_free (cally_path); }