[g-a-devel]libgnome accessibility ...



Hi Jody,

	Appended is the start of my scheme for getting the accessibility module
loading working in gail/libgail-gnome/at-spi and hooking it into every
gnome program - without the evilness of GTK_MODULE hacks - oh and
enabling it at runtime.

	It is unfinished, unpolished, needs release team approval, and for some
reason the GConf callback doesn't happen when you toggle the
accessibility boolean.

	I think it's prolly the right way to go though - and might form the
foundation of any 'AccessX' type thing from the POV of dynamic
enablement. We already have the GConf key setup, and the public symbol
hooks added to gail, at-spi ( but not libgail-gnome yet ).

	Anders is also happy with this general approach AFAIR.

	Can you take it on ?

		Michael. 


Index: libgnome/gnome-program.c
===================================================================
RCS file: /cvs/gnome/libgnome/libgnome/gnome-program.c,v
retrieving revision 1.51
diff -u -p -u -r1.51 gnome-program.c
--- libgnome/gnome-program.c	2002/01/25 20:08:02	1.51
+++ libgnome/gnome-program.c	2002/02/06 19:12:08
@@ -27,6 +27,9 @@
 
 #undef TIME_INIT
 
+#define GNOME_ACCESSIBILITY_ENV "GNOME_ACCESSIBILITY_ON"
+#define GNOME_ACCESSIBILITY_KEY "/desktop/gnome/interface/accessibility"
+
 /* This module takes care of handling application and library
    initialization and command line parsing */
 
@@ -38,6 +41,9 @@
 #include <string.h>
 #include <unistd.h>
 #include <gmodule.h>
+#include <gconf/gconf.h>
+#include <gconf/gconf-value.h>
+#include <gconf/gconf-client.h>
 
 #include "gnome-i18nP.h"
 
@@ -84,6 +90,7 @@ struct _GnomeProgramPrivate {
 
     /* valid-while: state == APP_PREINIT_DONE */
     GArray *top_options_table;
+    GSList *accessibility_modules;
 };
 
 enum {
@@ -1424,6 +1431,102 @@ gnome_program_parse_args (GnomeProgram *
     }
 }
 
+static void
+accessibility_setup_module_list (GnomeProgram *program)
+{
+	int i;
+	GSList *list = NULL;
+
+	/* Seek the module list we need */
+	for (i = 0; i < program_modules->len; i++) {
+		GnomeModuleInfo *module = g_ptr_array_index (program_modules, i);
+		
+		if (!module)
+			continue;
+
+		if (!strcmp (module->name, "gtk"))
+			list = g_slist_prepend (list, module);
+
+		else if (!strcmp (module->name, "libgnomeui"))
+			list = g_slist_prepend (list, module);
+	}
+
+	program->_priv->accessibility_modules = list;
+}
+
+static gboolean
+accessibility_invoke_module (GnomeProgram *program, const char *fname, gboolean init)
+{
+	GModule    *handle;
+	void      (*invoke_fn) (void);
+	const char *method;
+
+	/* FIXME: need to store the handle on the Program
+	 * FIXME: need to use gnome_program_locate_file */
+
+	if (init)
+		method = "gnome_accessibility_module_init";
+	else
+		method = "gnome_accessibility_module_shutdown";
+
+	if (!(handle = g_module_open (fname, G_MODULE_BIND_LAZY))) {
+		g_warning ("Failed to load '%s': '%s'", fname,
+			   g_module_error ());
+		return FALSE;
+	}
+
+	else if (!g_module_symbol (handle, method, (gpointer *)&invoke_fn)) {
+		g_warning ("accessibility library '%s' has no method '%s'",
+			   fname, method);
+		g_module_close (handle);
+
+		return FALSE;
+	} else
+		invoke_fn ();
+
+	return TRUE;
+}
+
+static gboolean
+accessibility_invoke (GnomeProgram *program, gboolean init)
+{
+	GSList *l;
+
+	if (!program->_priv->accessibility_modules)
+		return FALSE;
+
+	for (l = program->_priv->accessibility_modules; l; l = l->next) {
+		GnomeModuleInfo *module = l->data;
+		
+		if (!strcmp (module->name, "gtk"))
+			accessibility_invoke_module (program, "libgail", init);
+
+		else if (!strcmp (module->name, "libgnomeui"))
+			accessibility_invoke_module (program, "libgail-gnome", init);
+	}
+
+	accessibility_invoke_module (program, "libatk-bridge", init);
+
+	return TRUE;
+}
+
+static void
+accessibility_changed_cb (GConfClient *client,
+			  guint        cnxn_id,
+			  GConfEntry  *entry,
+			  gpointer     user_data)
+{
+	gboolean on;
+	GnomeProgram *program = user_data;
+
+	on = (g_getenv (GNOME_ACCESSIBILITY_ENV) ||
+	      gconf_value_get_bool (entry->value));
+
+	g_warning ("Accessibility changed to %d", on);
+
+	accessibility_invoke (program, on);
+}
+
 /**
  * gnome_program_postinit:
  * @program: Application object
@@ -1460,6 +1563,21 @@ gnome_program_postinit (GnomeProgram *pr
 	}
     }
 
+    /* Accessibility magic */
+    accessibility_setup_module_list (program);
+
+    if (g_getenv (GNOME_ACCESSIBILITY_ENV) ||
+	gconf_client_get_bool (gconf_client_get_default (),
+			       GNOME_ACCESSIBILITY_KEY, NULL))
+	    accessibility_invoke (program, TRUE);
+
+    gconf_client_notify_add (
+	    gconf_client_get_default (),
+	    GNOME_ACCESSIBILITY_KEY,
+	    accessibility_changed_cb,
+	    program, NULL, NULL);
+
+
     /* Free up stuff we don't need to keep around for the lifetime of the app */
 
     /* Note! we cannot kill the program_modules array as that
@@ -1590,7 +1708,6 @@ gnome_program_initv (GType type,
 	/*
 	 * Load all the modules.
 	 */
-
 	for (i = 0; i < program_module_list->len; i++) {
 	    gchar *modname = g_ptr_array_index (program_module_list, i);
 
Index: libgnome/gnome-program.h
===================================================================
RCS file: /cvs/gnome/libgnome/libgnome/gnome-program.h,v
retrieving revision 1.26
diff -u -p -u -r1.26 gnome-program.h
--- libgnome/gnome-program.h	2002/01/03 19:10:26	1.26
+++ libgnome/gnome-program.h	2002/02/06 19:12:10
@@ -203,7 +203,8 @@ struct _GnomeModuleInfo {
 
     GnomeModuleClassInitHook class_init;
 
-    gpointer expansion1, expansion2;
+    const char *opt_prefix;
+    gpointer    expansion1;
 };
 
 /* This function should be called before gnomelib_preinit() - it's an
-- 
 mmeeks gnu org  <><, Pseudo Engineer, itinerant idiot




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]