Back to index

unity  6.0.0
panel-a11y.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Canonical Ltd
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License version 3 as
00006  * published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Authored by: Rodrigo Moya <rodrigo.moya@canonical.com>
00017  */
00018 
00019 #include <gio/gio.h>
00020 
00021 #include "panel-a11y.h"
00022 #include "panel-util-accessible.h"
00023 
00024 static gboolean a11y_initialized = FALSE;
00025 
00026 #define INIT_METHOD "gnome_accessibility_module_init"
00027 #define DESKTOP_SCHEMA "org.gnome.desktop.interface"
00028 #define ACCESSIBILITY_ENABLED_KEY "toolkit-accessibility"
00029 #define AT_SPI_SCHEMA "org.a11y.atspi"
00030 #define ATK_BRIDGE_LOCATION_KEY "atk-bridge-location"
00031 
00032 
00033 /* This method is required because g_setting_new abort if the schema
00034    is not present. */
00035 static gboolean
00036 has_gsettings_schema (const gchar *schema)
00037 {
00038   const char * const *list_schemas = NULL;
00039   gboolean found = FALSE;
00040   int i = 0;
00041 
00042   list_schemas = g_settings_list_schemas ();
00043   for (i = 0; list_schemas [i]; i++)
00044     {
00045       if (!g_strcmp0 (list_schemas[i], schema))
00046         {
00047           found = TRUE;
00048           break;
00049         }
00050     }
00051 
00052   return found;
00053 }
00054 
00055 static gboolean
00056 should_enable_a11y (void)
00057 {
00058   GSettings *desktop_settings = NULL;
00059   gboolean value = FALSE;
00060 
00061   if (!has_gsettings_schema (DESKTOP_SCHEMA))
00062     return FALSE;
00063 
00064   desktop_settings = g_settings_new (DESKTOP_SCHEMA);
00065   value = g_settings_get_boolean (desktop_settings, ACCESSIBILITY_ENABLED_KEY);
00066 
00067   g_object_unref (desktop_settings);
00068 
00069   return value;
00070 }
00071 
00072 static gchar*
00073 get_atk_bridge_path (void)
00074 {
00075   GSettings *atspi_settings = NULL;
00076   GVariant *variant = NULL;
00077   char *value = NULL;
00078 
00079   if (!has_gsettings_schema (AT_SPI_SCHEMA))
00080     return NULL;
00081 
00082   atspi_settings = g_settings_new(AT_SPI_SCHEMA);
00083   variant = g_settings_get_value (atspi_settings, ATK_BRIDGE_LOCATION_KEY);
00084   value = g_variant_dup_bytestring (variant, NULL);
00085 
00086   g_variant_unref (variant);
00087   g_object_unref (atspi_settings);
00088 
00089   return value;
00090 }
00091 
00092 static gboolean
00093 a11y_invoke_module (const char *module_path)
00094 {
00095   GModule    *handle;
00096   void      (*invoke_fn) (void);
00097 
00098   if (!module_path)
00099     {
00100       g_warning ("Accessibility: invalid module path (NULL)");
00101 
00102       return FALSE;
00103     }
00104 
00105   if (!(handle = g_module_open (module_path, (GModuleFlags)0)))
00106     {
00107       g_warning ("Accessibility: failed to load module '%s': '%s'",
00108                  module_path, g_module_error ());
00109 
00110       return FALSE;
00111     }
00112 
00113   if (!g_module_symbol (handle, INIT_METHOD, (gpointer *)&invoke_fn))
00114     {
00115       g_warning ("Accessibility: error library '%s' does not include "
00116                  "method '%s' required for accessibility support",
00117                  module_path, INIT_METHOD);
00118       g_module_close (handle);
00119 
00120       return FALSE;
00121     }
00122 
00123   invoke_fn ();
00124 
00125   return TRUE;
00126 }
00127 
00128 void
00129 panel_a11y_init (void)
00130 {
00131   gchar *bridge_path = NULL;
00132 
00133   if (a11y_initialized)
00134     return;
00135 
00136   /* Restore environment to load AT bridge */
00137   g_unsetenv ("NO_AT_BRIDGE");
00138   g_unsetenv ("NO_GAIL");
00139 
00140   if (!should_enable_a11y ())
00141     return;
00142 
00143   /* Load PanelUtilAccessible class */
00144   g_type_class_unref (g_type_class_ref (PANEL_TYPE_UTIL_ACCESSIBLE));
00145 
00146   bridge_path = get_atk_bridge_path ();
00147   if (a11y_invoke_module (bridge_path))
00148     {
00149       g_debug ("Unity accessibility started, using bridge on %s", bridge_path);
00150     }
00151 
00152   g_free (bridge_path);
00153   atk_get_root ();
00154 
00155   a11y_initialized = TRUE;
00156 }