Re: [g-a-devel]Re: at-poke patch for interactive refresh and Java compat



On Tue, 2002-05-14 at 17:34, Michael Meeks wrote:
> Hi Bill,
> 
> 	I have a few, entirely stylistic comments, to your nice patch.
...

> 	Apart from that it looks really great. Thanks for fixing that up Bill -
> it's starting to look nice.

Thanks Michael.

I attach a revised patch; if you want to ignore it for now I will just
commit in the morning, but I made a couple of changes other than fixing
your comments above (I tried to be stylistically consistent, much of the
trouble comes from working in multiple languages/modules at the same
time :-)

The changes:  

* the brute force "update everything on notify" was/is really
inefficient of course, so I introduced a second signal on the
AccessibleListener, "text-update", so we can update only the
AccessibleText info on text-caret-moved and text-changed events.  I
think another couple of signals might be appropriate later on, to keep
the amount of unnecessary pounding on the API to a minimum.

* I added a primitive display of attributes at the current text caret
position; for now I did this by hand-editing the .glade2 file, perhaps
you will want to run glade2 and clean this up but at the moment there
are two GtkLabels, one which says "Attributes at Caret" and an adjacent
one that displays the attributes as a semicolon-delimited string.

> 	I just need to totally re-write the tree model to try and synchronize
> the tree model on both sides of the link in a reliable way and make that
> jive with the tree model at some stage, and then we'll have a rock-solid
> beast :-)

Yes, that will really be great!  

I have some minor concerns about efficiency; although at-poke is clearly
a test tool and not a demo ;-) it does a lot of API calling which makes
things appear quite slow when compared, for instance, with AT demos
which make a more selective use of the API.  When using the Java bridge
for instance, which has to use IIOP over IP, the time taken to refresh
is quite apparent.

Best regards, and thanks for letting me hack away at your nifty utility
:-)

Bill
 

> 	So please do commit, with those fixes,
> 
> 	Regards,
> 
> 		Michael.
> 
> -- 
>  mmeeks gnu org  <><, Pseudo Engineer, itinerant idiot
> 
> _______________________________________________
> Gnome-accessibility-devel mailing list
> Gnome-accessibility-devel gnome org
> http://mail.gnome.org/mailman/listinfo/gnome-accessibility-devel

? config.h.in
? at-poke.diff
? icons/Makefile.in
? icons/Makefile
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/at-poke/ChangeLog,v
retrieving revision 1.20
diff -u -r1.20 ChangeLog
--- ChangeLog	22 Apr 2002 16:08:40 -0000	1.20
+++ ChangeLog	14 May 2002 18:50:25 -0000
@@ -1,3 +1,49 @@
+2002-05-14  Bill Haneman <bill haneman sun com>
+
+	* glade/at-poke.glade2:
+	* src/poke.c:
+	Changed spelling of "carret" to "caret".
+
+	* src/accessible-tree-model.c:
+	Added a compile-time guard, JAVA_ENABLED.
+	Disable runtime assertions for
+	g_assert (accessible_is_base_accessible (root))
+
+	* src/main.c:
+	Put #ifdef JAVA_ENABLED guards around assertion
+	(aa == accessible), instead we use g_message in that
+	case to print a warning.
+	
+	* src/poke.c:
+	Create an AccessibleListener (See added files below) and connect
+	to its "object-update" signal; keep the listener informed of
+	changes to the selected object in the tree view.
+	When fired we update the object-specific data.
+	Block the text caret signal handler 
+	(as well as the text change handler) for the duration of a text 
+	update.
+	Added method "poker_selection_object_update() and 
+	poker_window_activate_cb()".  This second function is a callback
+	which we use to block the "object-update" signal handler 
+	when the at-poke UI is active, to help avoid collisions
+	between the poke UI (which changes the Accessible) and the
+	listener which notifies at-poke of those changes.	
+
+	* src/graphics.c:
+	Associated role types LAYERED_PANE and 
+	ROOT_PANE with existing graphics "viewport_xpm".
+
+	* src/poke.c:
+	Changed the default coordinate type in poker-ctype to
+	SPI_COORD_TYPE_SCREEN.
+
+	* src/accessible-listener.c:
+	* src/accessible-listener.h:
+	New files.
+
+	* src/Makefile.am:
+	Include above new files in SOURCES.
+	
 2002-04-22  jacob berkman  <jacob ximian com>
 
 	* configure.in: fix some confusion between make and m4
Index: glade/at-poke.glade2
===================================================================
RCS file: /cvs/gnome/at-poke/glade/at-poke.glade2,v
retrieving revision 1.10
diff -u -r1.10 at-poke.glade2
--- glade/at-poke.glade2	21 Mar 2002 20:16:04 -0000	1.10
+++ glade/at-poke.glade2	14 May 2002 18:50:27 -0000
@@ -1083,7 +1083,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label2795">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Carret Offset</property>
+			      <property name="label" translatable="yes">Caret Offset</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -1102,7 +1102,7 @@
 			  </child>
 
 			  <child>
-			    <widget class="GtkSpinButton" id="text_if_carret">
+			    <widget class="GtkSpinButton" id="text_if_caret">
 			      <property name="visible">True</property>
 			      <property name="can_focus">True</property>
 			      <property name="climb_rate">1</property>
@@ -1128,6 +1128,60 @@
 			  <property name="x_options">fill</property>
 			</packing>
 		      </child>
+		      <child>
+			<widget class="GtkVBox" id="foo">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">0</property>
+		          <child>
+			    <widget class="GtkLabel" id="attribute-label">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Attributes at Caret</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">4</property>
+			      <property name="ypad">0</property>
+		            </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>    
+			  <child>    
+			    <widget class="GtkLabel" id="attribute_label">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="no">&lt;i&gt;(none)&lt;/i&gt;</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">True</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">1</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">4</property>
+			      <property name="ypad">0</property>
+		            </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+                        </widget>			    
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="x_options">fill</property>
+			</packing>
+		      </child>
 
 		      <child>
 			<widget class="GtkFrame" id="poker_editable_text_frame">
@@ -1439,8 +1493,8 @@
 			<packing>
 			  <property name="left_attach">0</property>
 			  <property name="right_attach">1</property>
-			  <property name="top_attach">2</property>
-			  <property name="bottom_attach">3</property>
+			  <property name="top_attach">3</property>
+			  <property name="bottom_attach">4</property>
 			  <property name="x_options">fill</property>
 			</packing>
 		      </child>
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/at-poke/src/Makefile.am,v
retrieving revision 1.3
diff -u -r1.3 Makefile.am
--- src/Makefile.am	21 Mar 2002 20:16:04 -0000	1.3
+++ src/Makefile.am	14 May 2002 18:50:27 -0000
@@ -7,6 +7,8 @@
 at_poke_SOURCES =		\
 	child-listener.c	\
 	child-listener.h	\
+	accessible-listener.c	\
+	accessible-listener.h	\
 	main.c			\
 	poke.c			\
 	graphics.c		\
Index: src/accessible-tree-model.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/accessible-tree-model.c,v
retrieving revision 1.11
diff -u -r1.11 accessible-tree-model.c
--- src/accessible-tree-model.c	17 Apr 2002 23:55:22 -0000	1.11
+++ src/accessible-tree-model.c	14 May 2002 18:50:28 -0000
@@ -16,6 +16,9 @@
 
 #undef DEBUG_TREE
 
+/* Java requires disabling lots of sanity checks :-( */
+#define JAVA_ENABLED
+
 /* FIXME: leaks references like a sieve ! */
 
 static GObjectClass *parent_class;
@@ -132,6 +135,8 @@
 		 tree_model->root_node,
 		 Accessible_getRoleName (tree_model->root_node),
 		 Accessible_getName (tree_model->root_node));
+	if (node == tree_model->root_node) 
+		fprintf (stderr, "node is root node\n");
 #endif
 
 	while (node != tree_model->root_node && node != NULL) {
@@ -367,9 +372,9 @@
 	g_return_val_if_fail (root != NULL, NULL);
 	
 	model = g_object_new (ACCESSIBLE_TYPE_TREE_MODEL, NULL);
-
-	g_assert (accessible_is_base_accessible (root));
-
+#ifndef JAVA_ENABLED
+	g_assert (accessible_is_base_accessible (root)); 
+#endif
 	ACCESSIBLE_TREE_MODEL (model)->root_node = root;
 
 	make_root_path_iter (
Index: src/graphics.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/graphics.c,v
retrieving revision 1.4
diff -u -r1.4 graphics.c
--- src/graphics.c	28 Mar 2002 20:45:35 -0000	1.4
+++ src/graphics.c	14 May 2002 18:50:28 -0000
@@ -69,7 +69,7 @@
 	{ SPI_ROLE_IMAGE, image_xpm },
 	{ SPI_ROLE_INTERNAL_FRAME, NULL },
 	{ SPI_ROLE_LABEL, label_xpm },
-	{ SPI_ROLE_LAYERED_PANE, NULL },
+	{ SPI_ROLE_LAYERED_PANE, viewport_xpm },
 	{ SPI_ROLE_LIST, NULL },
 	{ SPI_ROLE_LIST_ITEM, NULL },
 	{ SPI_ROLE_MENU, menuitem_xpm },
@@ -85,7 +85,7 @@
 	{ SPI_ROLE_PUSH_BUTTON, button_xpm },
 	{ SPI_ROLE_RADIO_BUTTON, NULL },
 	{ SPI_ROLE_RADIO_MENU_ITEM, NULL },
-	{ SPI_ROLE_ROOT_PANE, NULL },
+	{ SPI_ROLE_ROOT_PANE, viewport_xpm },
 	{ SPI_ROLE_ROW_HEADER, NULL },
 	{ SPI_ROLE_SCROLL_BAR, vscrollbar_xpm },
 	{ SPI_ROLE_SCROLL_PANE, scrolledwindow_xpm },
@@ -107,7 +107,7 @@
 	{ SPI_ROLE_TREE, tree_xpm },
 	{ SPI_ROLE_TREE_TABLE, tree_xpm },
 	{ SPI_ROLE_UNKNOWN, unknown_xpm },
-	{ SPI_ROLE_VIEWPORT, NULL },
+	{ SPI_ROLE_VIEWPORT, viewport_xpm },
 	{ SPI_ROLE_WINDOW, window_xpm },
 	{ SPI_ROLE_EXTENDED, NULL },
 	{ 0xffffff, NULL}
Index: src/main.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/main.c,v
retrieving revision 1.9
diff -u -r1.9 main.c
--- src/main.c	21 Mar 2002 21:08:47 -0000	1.9
+++ src/main.c	14 May 2002 18:50:29 -0000
@@ -26,6 +26,9 @@
 #include "graphics.h"
 #include "child-listener.h"
 
+/* Java requires disabling lots of sanity checks :-( */
+#define JAVA_ENABLED
+
 extern void poke (Accessible *accessible);
 
 #define APP_COL_NAME   0
@@ -105,15 +108,22 @@
 	Accessible *parent;
 
 	aa = Accessible_queryInterface (accessible, "IDL:Accessibility/Accessible:1.0");
+#ifndef JAVA_ENABLED	
 	g_assert (aa == accessible);
-
+#else
+        if (aa != accessible) {
+		g_message ("aa == accessible failed");
+		fprintf (stderr,"cmp %p %p\n", aa, accessible);
+	}
+#endif
 	child = Accessible_getChildAtIndex (accessible, 0);
 	if (!child)
 		return;
 
 	parent = Accessible_getParent (child);
-
+#ifndef JAVA_ENABLED
 	g_assert (parent == accessible);
+#endif
 }
 
 static void
Index: src/poke.c
===================================================================
RCS file: /cvs/gnome/at-poke/src/poke.c,v
retrieving revision 1.19
diff -u -r1.19 poke.c
--- src/poke.c	17 Apr 2002 23:55:22 -0000	1.19
+++ src/poke.c	14 May 2002 18:50:30 -0000
@@ -18,6 +18,8 @@
  *    + AccessibleHypertext
  *    + AccessibleHyperlink
  *    + editable text
+ *    + sync text caret spinbutton with text entry field, and changes to
+ *      length of text string.
  */
 
 #include <config.h>
@@ -31,6 +33,7 @@
 
 #include "graphics.h"
 #include "child-listener.h"
+#include "accessible-listener.h"
 #include "accessible-tree-model.h"
 
 extern void poke (Accessible *accessible);
@@ -57,8 +60,10 @@
 	GtkWidget    *action_take;
 
 	GtkWidget    *text;
-	GtkWidget    *text_carret;
+	GtkWidget    *text_caret;
+	GtkWidget    *attribute_label;
 	gulong        text_changed_id;
+	gulong        caret_changed_id;
 
 	GtkWidget    *value_minimum;
 	GtkWidget    *value_current;
@@ -74,6 +79,9 @@
 	GtkWidget    *selection_clear;
 	gulong        selection_changed_id;
 
+	gulong        update_id;
+	gulong        text_update_id;
+
 	Accessible   *selected;
 
 	AccessibleCoordType ctype;
@@ -262,7 +270,8 @@
 	gtk_list_store_clear (poker->state_set_store);
 	state_set = Accessible_getStateSet (accessible);
 	for (i = 0; state_names [i].name; i++) {
-		if (AccessibleStateSet_contains (state_set, state_names [i].state)) {
+		if (AccessibleStateSet_contains (state_set,
+						 state_names [i].state)) {
 			GtkTreeIter iter;
 			gtk_list_store_append (poker->state_set_store, &iter);
 			gtk_list_store_set (poker->state_set_store, &iter,
@@ -409,7 +418,8 @@
 		SPI_freeString (name);
 	}
 
-	if (gtk_tree_model_get_iter_root (GTK_TREE_MODEL (poker->action_store), &iter)) {
+	if (gtk_tree_model_get_iter_root (GTK_TREE_MODEL (poker->action_store),
+					  &iter)) {
 		gtk_tree_selection_select_iter (
 			gtk_tree_view_get_selection (
 				GTK_TREE_VIEW (poker->action_view)), &iter);
@@ -422,8 +432,13 @@
 update_if_text (Poker *poker, AccessibleText *text)
 {
 	char *txt;
+	gint caret_pos;
+	long int startOffset = 0, endOffset = 0;
+	char *attributes;
+	gchar *attribute_label_string;
 
 	g_signal_handler_block (poker->text, poker->text_changed_id);
+	g_signal_handler_block (poker->text_caret, poker->caret_changed_id);
 
 	txt = AccessibleText_getText (text, 0, -1);
 	gtk_entry_set_text (GTK_ENTRY (poker->text), txt);
@@ -434,12 +449,32 @@
 
 	g_signal_handler_unblock (poker->text, poker->text_changed_id);
 
-	gtk_spin_button_set_value (
-		GTK_SPIN_BUTTON (poker->text_carret),
-		AccessibleText_getCaretOffset (text));
 	gtk_spin_button_set_range (
-		GTK_SPIN_BUTTON (poker->text_carret),
+		GTK_SPIN_BUTTON (poker->text_caret),
 		0, AccessibleText_getCharacterCount (text));
+
+	caret_pos = AccessibleText_getCaretOffset (text);
+	gtk_spin_button_set_value (
+		GTK_SPIN_BUTTON (poker->text_caret),
+		caret_pos);
+	
+	attributes = AccessibleText_getAttributes (text,
+						   caret_pos,
+						   &startOffset,
+						   &endOffset);
+
+	attribute_label_string = g_strconcat ("<i>",
+		(strlen (g_strstrip (attributes)) ?
+		 attributes : "(none)"), "</i>", NULL);
+
+	gtk_label_set_markup (GTK_LABEL (poker->attribute_label),
+			      attribute_label_string);
+	if (attributes != NULL)
+		SPI_freeString (attributes);
+	
+	g_free (attribute_label_string);
+	
+	g_signal_handler_unblock (poker->text_caret, poker->caret_changed_id);
 }
 
 static void
@@ -462,7 +497,7 @@
 }
 
 static void
-text_carret_changed_cb (GtkSpinButton *spin_button,
+text_caret_changed_cb (GtkSpinButton *spin_button,
 			Poker         *poker)
 {
 	AccessibleText *text;
@@ -803,7 +838,7 @@
 update_frame_visibility (Poker *poker, Accessible *accessible)
 {
 	int i;
-
+	
 	for (i = 0; poker_widget_names [i].interface_name; i++) {
 		GtkWidget *frame;
 		AccessibleUnknown *unknown;
@@ -832,6 +867,20 @@
 }
 
 static void
+poker_selected_object_update (AccessibleListener *listener,
+			      Poker              *poker)
+{
+	update_frame_visibility (poker, poker->selected);
+}
+
+static void
+poker_selected_object_text_update (AccessibleListener *listener,
+				   Poker              *poker)
+{
+	update_text (poker);
+}
+
+
 poker_tree_selection_changed (GtkTreeSelection *selection,
 			      Poker            *poker)
 {
@@ -847,6 +896,9 @@
 
 	poker->selected = accessible;
 
+	accessible_listener_set_target (accessible_listener_get (),
+					accessible);
+	
 	update_frame_visibility (poker, accessible);
 }
 
@@ -877,6 +929,37 @@
 }
 
 static void
+poker_window_activate_cb (GtkWindow     *window,
+			  GdkEventFocus *event,
+			  Poker         *poker)
+{
+	static gint local_changes_blocked = 0;
+	if (event->in) {
+		g_signal_handler_block (accessible_listener_get(),
+					poker->update_id);
+		g_signal_handler_block (accessible_listener_get(),
+					poker->text_update_id);
+		if (local_changes_blocked) {
+			g_signal_handler_unblock (poker->text,
+						  poker->text_changed_id);
+			g_signal_handler_unblock (poker->text_caret,
+						  poker->caret_changed_id);
+			--local_changes_blocked;
+		}
+	} else {
+		++local_changes_blocked;
+		g_signal_handler_block (poker->text,
+					poker->text_changed_id);
+		g_signal_handler_block (poker->text_caret,
+					poker->caret_changed_id);
+		g_signal_handler_unblock (accessible_listener_get(),
+					  poker->update_id);
+		g_signal_handler_unblock (accessible_listener_get(),
+					  poker->text_update_id);
+	}
+}
+
+static void
 add_pix_name_column (GtkTreeView *tree_view,
 		     int          icon_col,
 		     int          name_col)
@@ -971,9 +1054,9 @@
 	GtkWidget *widget;
 
 	poker = g_new0 (Poker, 1);
-
+	
 	/* FIXME: need a toggle for this */
-	poker->ctype = SPI_COORD_TYPE_WINDOW;
+	poker->ctype = SPI_COORD_TYPE_SCREEN;
 
 	poker->root_node = accessible;
 	poker->xml = get_glade_xml ();
@@ -1059,12 +1142,16 @@
 			g_signal_connect (poker->text, "changed",
 					  G_CALLBACK (editable_text_changed_cb),
 					  poker);
-		poker->text_carret = glade_xml_get_widget (
-			poker->xml, "text_if_carret");
-		g_signal_connect (poker->text_carret,
+
+		poker->text_caret = glade_xml_get_widget (
+			poker->xml, "text_if_caret");
+		poker->caret_changed_id =
+			g_signal_connect (poker->text_caret,
 				  "value_changed",
-				  G_CALLBACK (text_carret_changed_cb),
+				  G_CALLBACK (text_caret_changed_cb),
 				  poker);
+		poker->attribute_label = glade_xml_get_widget (
+			poker->xml, "attribute_label");
 	}
 
 	{ /* editable text interface */
@@ -1180,6 +1267,29 @@
 			child_listener_get (), "root_died", closure, FALSE);
 
 		child_listener_add_root (child_listener_get (), poker->root_node);
+		poker->update_id = g_signal_connect (
+			accessible_listener_get (),
+			"object-update",
+			G_CALLBACK (poker_selected_object_update),
+			poker);
+		
+		poker->text_update_id = g_signal_connect (
+			accessible_listener_get (),
+			"text-update",
+			G_CALLBACK (poker_selected_object_text_update),
+			poker);
+
+		g_signal_connect (
+			poker->window,
+			"focus_in_event",
+			G_CALLBACK (poker_window_activate_cb),
+			poker);
+
+		g_signal_connect (
+			poker->window,
+			"focus_out_event",
+			G_CALLBACK (poker_window_activate_cb),
+			poker);
 	}
 
 	init_accessible_tree (poker, accessible);
@@ -1190,7 +1300,7 @@
 	child_listener_remove_root (child_listener_get (), poker->root_node);
 
 	gtk_widget_destroy (poker->window);
-
+	
 	g_object_unref (poker->xml);
 	g_free (poker);
 }
/*
 * selection-listener.c: listens to selected at-spi events
 *                       and calls into the at-poke API.
 *
 * Author:
 *    Bill Haneman
 *
 * Copyright 2002 Sun Microsystems, Inc.
 */
#include "accessible-listener.h"
#include <libgnome/gnome-macros.h>

enum {
	UPDATE,
	UPDATE_TEXT,
	LAST_SIGNAL
};

static guint signals [LAST_SIGNAL];
static GObjectClass *parent_class;
static gchar *event_names[8] = {
	"object:text-changed",
	"object:text-caret-moved",
	"object:text-selection-changed",
	"object:selection-changed",
	"object:property-change",
	"object:visible-data-changed",
	"object:state-changed",
	NULL
};

GType accessible_listener_get_type (void);

GNOME_CLASS_BOILERPLATE (AccessibleListener,
			 accessible_listener,
			 GObject,
			 G_TYPE_OBJECT);

static void
accessible_listener_global_event (const AccessibleEvent *event,
				  void                  *user_data)
{
	AccessibleListener *al = user_data;
	if (event->source == al->target)
		g_signal_emit (al, signals [UPDATE], 0);
}

static void
accessible_listener_global_text_event (const AccessibleEvent *event,
				       void                  *user_data)
{
	AccessibleListener *al = user_data;
	if (event->source == al->target)
		g_signal_emit (al, signals [UPDATE_TEXT], 0);
}

static void
accessible_listener_instance_init (AccessibleListener *al)
{
	gint i;
	al->el = SPI_createAccessibleEventListener (
		accessible_listener_global_event, al);

	al->tel = SPI_createAccessibleEventListener (
		accessible_listener_global_text_event, al);
	
	for (i = 0; event_names[i]; ++i) {
		if (strstr (event_names[i], "text"))
			SPI_registerGlobalEventListener (al->tel,
							 event_names[i]);
		else
			SPI_registerGlobalEventListener (al->el,
							 event_names[i]);
	}
	/* TODO: listen to various table events also */
}

static void
accessible_listener_dispose (GObject *object)
{
	AccessibleListener *al = (AccessibleListener *) object;

	if (al->el) {
		SPI_deregisterGlobalEventListenerAll (al->el);
		AccessibleEventListener_unref (al->el);
		al->el = NULL;
	}
	if (al->tel) {
		SPI_deregisterGlobalEventListenerAll (al->tel);
		AccessibleEventListener_unref (al->tel);
		al->tel = NULL;
	}

	parent_class->dispose (object);
}

static void
accessible_listener_class_init (AccessibleListenerClass *klass)
{
	GObjectClass *gobject_class = (GObjectClass *) klass;

	parent_class = g_type_class_peek_parent (klass);

	gobject_class->dispose = accessible_listener_dispose;
	
	signals [UPDATE] =
		g_signal_new ("object-update",
			      G_TYPE_FROM_CLASS (gobject_class),
			      G_SIGNAL_RUN_LAST,
			      0,
			      NULL, NULL,
			      g_cclosure_marshal_VOID__VOID,
			      G_TYPE_NONE, 0);

	signals [UPDATE_TEXT] =
		g_signal_new ("text-update",
			      G_TYPE_FROM_CLASS (gobject_class),
			      G_SIGNAL_RUN_LAST,
			      0,
			      NULL, NULL,
			      g_cclosure_marshal_VOID__VOID,
			      G_TYPE_NONE, 0);
}


AccessibleListener *
accessible_listener_get (void)
{
	static AccessibleListener *listener = NULL;

	if (!listener)
		listener = g_object_new (
			accessible_listener_get_type (), NULL);

	return listener;
}

void
accessible_listener_set_target (AccessibleListener *al,
				Accessible *accessible)
{
	al->target = accessible;
}
/*
 * accessible-listener.h: listens to at-spi events and
 *                       emits a signal if their source matches
 *                       the currently selected target.
 *
 * Author:
 *    Bill Haneman
 *
 * Copyright 2002 Sun Microsystems, Inc.
 */
#ifndef ACCESSIBLE_LISTENER_H
#define ACCESSIBLE_LISTENER_H

#include <cspi/spi.h>
#include <glib-object.h>

typedef struct {
	GObject parent;
	Accessible *target;
	AccessibleEventListener *el;
	AccessibleEventListener *tel;
} AccessibleListener;

typedef struct {
	GObjectClass parent_class;

	/* signals */
	void (*update) (AccessibleListener *listener, void *user_data);
} AccessibleListenerClass;

AccessibleListener *accessible_listener_get         (void);
void accessible_listener_set_target (AccessibleListener *al,
				     Accessible *accessible);

#endif /* ACCESSIBLE_LISTENER_H */


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