[g-a-devel]Re: first cut at acute AtkObjectFactory brokenness workaround



>Subject: first cut at acute AtkObjectFactory brokenness workaround
>From: Michael Meeks <michael ximian com>
>To: Bill Haneman <bill haneman sun com>
>Cc: accessibility mailing list <gnome-accessibility-devel gnome org>, Tim Janik <timj gtk org>
>Content-Transfer-Encoding: 7bit
>Date: 21 Mar 2002 14:09:40 +0000
>
>So,
>
>	Please find attached my first cut at a 'solution' - yes it's ugly - but
>significantly less ugly than what's there currently. I'll be testing it
>out inside libbonoboui - but I'd very much like to move it to gail [
>with appropriate release team API addition approval ] and also provide a
>simpler API for sub-classing existing Gail classes [ as this will be
>used in a good number of places ].


Hi:

I object to this.  What we have is ugly, but it's what we have.  I think that
it's a bad idea to create an alternative solution in the bonoboui namespace
even if it's arguably better.

I am, as usual, quite insulted by the comments.  "acute lack of forethought"
was not the problem here, "acute lack of proofreading resources" is more like it.

The right solution would have been to allow fixing the AtkObjectFactory API.
If you want to lobby for allowing this, please do.

I am fonder of the idea of adding new API to ATK which has the 'correct' 
signature, as you suggest below.  We could do it for ATK 1.0.1.

-Bill



>	Clearly this doesn't fix the underlying problem - perhaps the best way
>to do that is by binning AtkObjectFactory in Gtk+ 2.2 and having
>AtkObjectFactoryWorks (or sim.) that replaces it. Alternatively, we
>could use the 2 extra spare pointers on the class structure - or
>feasibly we could do some nice function casting magic - to allow
>ourselves to pass the AtkFactoryObject * as a (hidden) 2nd / 1st
>parameter of the methods. All of those approaches suck, but less than
>leaving it broken, inefficient and hard to maintain.
>
>	So - here is the patch, untested - comments appreciated. NB. if we fold
>this into Gail we can kill ~4500 line of cut and paste mess.
>
>	Regards,
>
>		Michael.
>
>/**
> * Bonobo accessibility wrappers
> *
> * Author:
> *   Michael Meeks (michael ximian com)
> *
> * Copyright 2002 Sun Microsystems, Inc.
> */
>#ifndef _BONOBO_A11Y_H_
>#define _BONOBO_A11Y_H_
>
>#include <glib-object.h>
>
>void bonobo_a11y_clobber_atk_junk_code (void);
>void bonobo_a11y_register_type_for     (GType atk_object_type,
>					GType gtk_widget_type);
>
>#endif /* _BONOBO_A11Y_H_ */
>
>
>/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
>/**
> * Bonobo accessibility wrappers
> *
> * FIXME: this implementation sucks almost as badly
> *        as the AtkObjectFactory design does.
> *
> * Author:
> *   Michael Meeks (michael ximian com)
> *
> * Copyright 2002 Sun Microsystems, Inc.
> */
>
>#include <bonobo-a11y.h>
>#include <atk/atkobjectfactory.h>
>#include <gtk/gtkwidget.h>
>
>typedef AtkObject * (*BonoboA11YGetAccessible) (GtkWidget *widget);
>
>/* To chain to parent get_accessibles methods */
>static GHashTable *chain_hash = NULL;
>
>/* To map a11y types to GtkWidget types */
>static GHashTable *type_hash = NULL;
>
>static AtkObject *
>bonobo_a11y_get_accessible (GtkWidget *widget)
>{
>	AtkObject *accessible;
>
>	static GQuark quark_accessible_object = 0;
>
>	if (!quark_accessible_object)
>		quark_accessible_object = g_quark_from_static_string (
>			"gtk-accessible-object");
>
>	accessible = g_object_get_qdata (G_OBJECT (widget), 
>					 quark_accessible_object);
>	if (!accessible) {
>		GType t;
>
>		t = (GType) g_hash_table_lookup (
>			type_hash, (gpointer) G_TYPE_FROM_INSTANCE (widget));
>
>		if (t) {
>			accessible = g_object_new (t, NULL);
>
>			atk_object_initialize (accessible, widget);
>
>			g_object_set_qdata (G_OBJECT (widget), 
>					    quark_accessible_object,
>					    accessible);
>		} else {
>			BonoboA11YGetAccessible parent_impl_fn;
>
>			parent_impl_fn = g_hash_table_lookup (
>				chain_hash, (gpointer) G_TYPE_FROM_INSTANCE (widget));
>
>			if (!parent_impl_fn)
>				g_error ("Serious chain hash error '%s'",
>					 g_type_name_from_instance (
>						 (GTypeInstance *) widget));
>			else
>				accessible = parent_impl_fn (widget);
>		}
>	}
>
>	return accessible;
>}
>
>static void
>recursive_a11y_clobber (GType type)
>{
>	guint n_children, i;
>	GType *children;
>	GtkWidgetClass *w_class;
>
>	w_class = g_type_class_peek (type);
>
>	if (!w_class)
>		/* not instantiated yet, no problems */
>		return;
>
>	g_hash_table_insert (chain_hash, (gpointer) type,
>			     w_class->get_accessible);
>
>	w_class->get_accessible = bonobo_a11y_get_accessible;
>
>	children = g_type_children (type, &n_children);
>
>	for (i = 0; i < n_children; i++)
>		recursive_a11y_clobber (children [i]);
>}
>
>/**
> * bonobo_a11y_clobber_atk_junk_code:
> * @void: 
> * 
> *   It seems the only way to work around the acute
> * lack of forethought is to clobber everything
> * derived from GtkWidget so it can't hurt us.
> **/
>void
>bonobo_a11y_clobber_atk_junk_code (void)
>{
>	GType widget_type;
>
>	if (type_hash)
>		return;
>
>	type_hash = g_hash_table_new (NULL, NULL);
>	chain_hash = g_hash_table_new (NULL, NULL);
>
>	widget_type = gtk_widget_get_type ();
>
>	/*
>	 * Leak this - but we need to keep that
>	 * instantiated, since we don't want it
>	 * re-constructed with the original method
>	 */
>	g_type_class_ref (widget_type);
>
>	recursive_a11y_clobber (widget_type);
>}
>
>void
>bonobo_a11y_register_type_for (GType atk_object_type,
>			       GType gtk_widget_type)
>{
>	g_return_if_fail (type_hash != NULL);
>
>	g_hash_table_insert (type_hash,
>			     (gpointer) atk_object_type,
>			     (gpointer) gtk_widget_type);
>}
>
>-- 
> mmeeks gnu org  <><, Pseudo Engineer, itinerant idiot
>

------
Bill Haneman x19279
Gnome Accessibility / Batik SVG Toolkit
Sun Microsystems Ireland 




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