790d2165f3
http://bugzilla.clutter-project.org/show_bug.cgi?id=2099 Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
217 lines
5.8 KiB
C
217 lines
5.8 KiB
C
/* CALLY - The Clutter Accessibility Implementation Library
|
|
*
|
|
* Copyright (C) 2009 Igalia, S.L.
|
|
*
|
|
* Author: Alejandro Piñeiro Iglesias <apinheiro@igalia.com>
|
|
*
|
|
* 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 <gmodule.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <clutter/clutter.h>
|
|
|
|
#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);
|
|
}
|