Added implementations for AtkObject:property-change support. Fixed some (but not...
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 19 Oct 2001 16:05:07 +0000 (16:05 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 19 Oct 2001 16:05:07 +0000 (16:05 +0000)
Considerable rework in the event handling in the bridge and elsewhere.
Added Accessibility_Application_registerObjectEventListener(), which is used by the registry.
Worked around a logjam by omitting an unref() in event listeners, which probably means that there is now a memory leak... will keep investigating.
Mostly works but can still sometimes lock up on application exit if one leans on the app hard enough.

git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@79 e2bd861d-eb25-0410-b326-f6ed22b6b98c

33 files changed:
ChangeLog
at-bridge/bridge.c
atk-bridge/bridge.c
cspi/spi-impl.h
cspi/spi-util.c
cspi/spi.c
cspi/spi.h
cspi/spi_accessible.c
cspi/spi_component.c
cspi/spi_selection.c
cspi/spi_table.c
cspi/spi_text.c
idl/Accessibility_Application.idl
idl/Application.idl
libspi/accessible.c
libspi/accessibleeventlistener.c
libspi/action.h
libspi/application.c
libspi/application.h
libspi/component.c
libspi/editabletext.c
libspi/eventlistener.c
libspi/registry.c
libspi/registry.h
libspi/selection.c
libspi/selection.h
libspi/table.c
libspi/text.c
libspi/text.h
registryd/registry.c
registryd/registry.h
test/at.c
test/simple-at.c

index bd9c187..4466084 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,62 @@
+<2001-10-09  Bill Haneman <bill.haneman@sun.com>
+
+       * at-bridge/bridge.c:
+       Re-worked listeners for toolkit events, now we have signal
+       and property listeners. Added a private method
+       register_atk_event_listeners(), which registers with the
+       various atk and gtk signals we need to monitor in order to emit
+       our at-spi events.
+       Added emission hook for AtkObject:property-change events, to
+       support the 'property listeners'.
+       Fixed some alloc()s of Accessibility_Event structs to use CORBA
+       allocation.
+
+       * cspi/spi-util.c: added methods spi_warn_ev and spi_check_ev,
+       which emit warnings and exit, respectively, if CORBA errors occur
+       during remote calls, and we now use these methods to check most of
+       our CORBA calls in the C bindings.
+
+       * cspi/spi_accessible.c:
+       Changed AccessibleSelection_refSelectedChild() to
+       AccessibleSelection_getSelectedChild(), since all our cspi 'gets'
+       now increment refcounts.
+
+       * cspi/spi_component.c:
+       Fixed some long pointer casts (dangerous!) to pass pointers to
+       CORBA_longs of the proper type to the CORBA stubs, and copy the
+       data into the longs that were passed into the C bindings code.
+       
+       * at-bridge/bridge.c:
+       
+       * libspi/accessible.c:
+       Removed ATK_IS_HYPERLINK() query, since AtkObjects are never
+       hyperlinks, AtkHyperlink is an object type.     
+
+       * libspi/application.c:
+       Added various conversions to and from "generic" event types and
+       atk-specific types; this is really part of the 'bridge'
+       implementation but is valid for all AtkObject-based accessibility 
+       implementations.
+
+       * libspi/editabletext.c:
+       Fixed nasty bug wherein editable text's finalize method was
+       unref'ing tha AtkObject reference that the text parent class was
+       about to unref _again_.  There was also a nasty inheritance bug
+       that meant that the AccessibleEditableText class was corrupt.
+
+       * libspi/selection.c:
+       Provided implementations for some selection API that was broken.
+       
+       * idl/Application.idl:
+       Added registerObjectEventListener () method.
+
+       * THROUGHOUT:
+       Fixed a number of return values that were Bonobo_Unknowns from
+       bonobo_object_corba_objref(), which I
+       forgot to dup before returning.  Changed instances of 
+       bonobo_object_corba_objref (bonobo_object(o)) to
+       BONOBO_OBJREF(o), for concision and clarity.
+       
 <2001-10-13  Louise Miller <louise.miller@sun.com>
 
        * idl/Accessible.idl, idl/Application.idl, idl/Desktop.idl,
        of Bonobo.idl
 
 <2001-09-10  Marc Mulcahy <marc.mulcahy@sun.com
-       libspi/component.c libspi/component.h:
-               Fixed typo.  Added assertions for object checks in AccessibleComponent code.
 
-       <2001-10-09  Bill Haneman <bill.haneman@sun.com>
+       * libspi/component.c libspi/component.h:
+               Fixed typo.  Added assertions for object checks in 
+       AccessibleComponent code.
+
+<2001-10-09  Bill Haneman <bill.haneman@sun.com>
 
        * idl/Accessible.idl:
                Added 'isEqual (Accessible *object)' 
index d4e1345..f47d084 100644 (file)
@@ -30,6 +30,8 @@
 #include "accessible.h"
 #include "application.h"
 
+#define APP_STATIC_BUFF_SZ 64
+
 typedef struct _ArgStruct ArgStruct;
 
 struct _ArgStruct {
@@ -44,6 +46,16 @@ static Application *this_app;
 static gboolean bridge_register_app (gpointer p);
 static void bridge_focus_tracker (AtkObject *object);
 static void bridge_exit_func(void);
+static gboolean bridge_register_event_listener ();
+static void register_atk_event_listeners();
+static gboolean bridge_property_event_listener (GSignalInvocationHint *signal_hint,
+                                               guint n_param_values,
+                                               const GValue *param_values,
+                                               gpointer data);
+static gboolean bridge_signal_listener (GSignalInvocationHint *signal_hint,
+                                       guint n_param_values,
+                                       const GValue *param_values,
+                                       gpointer data);
 
 int
 gtk_module_init(gint *argc, gchar **argv[])
@@ -95,21 +107,37 @@ bridge_register_app (gpointer gp)
 
   bonobo_activate ();
 
-  /* Register for focus event notifications, and register app with central registry  */
-  atk_add_focus_tracker (bridge_focus_tracker);
-
   Accessibility_Registry_registerApplication (registry,
-                                              bonobo_object_corba_objref (bonobo_object (this_app)),
+                                              CORBA_Object_duplicate (BONOBO_OBJREF (this_app), &ev),
                                               &ev);
+
+  register_atk_event_listeners ();
+
   return FALSE;
 }
 
+static void
+register_atk_event_listeners ()
+{
+  /* Register for focus event notifications, and register app with central registry  */
+
+/* kludge to make sure the Atk interface types are registered, otherwise
+   the AtkText signal handlers below won't get registered */
+
+  ATK_TYPE_TEXT;
+
+  atk_add_focus_tracker (bridge_focus_tracker);
+  atk_add_global_event_listener (bridge_property_event_listener, "Gtk:AtkObject:property-change");
+/*  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:children-changed");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-changed");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-caret-moved");*/
+}
+
 static void bridge_exit_func()
 {
   fprintf (stderr, "exiting bridge\n");
   Accessibility_Registry_deregisterApplication (registry,
-                                               bonobo_object_corba_objref (
-                                                       bonobo_object (this_app)),
+                                               CORBA_Object_duplicate (BONOBO_OBJREF (this_app), &ev),
                                                &ev);
   fprintf (stderr, "bridge exit func complete.\n");
 }
@@ -118,11 +146,110 @@ static void bridge_focus_tracker (AtkObject *object)
 {
   Accessibility_Event *e = Accessibility_Event__alloc();
   e->type = CORBA_string_dup ("focus:");
-  e->source = bonobo_object_corba_objref (bonobo_object (accessible_new (object)));
+  e->source = CORBA_Object_duplicate (BONOBO_OBJREF (accessible_new (object)), &ev);
+  e->detail1 = 0;
+  e->detail2 = 0;
+  Accessibility_Registry_notifyEvent (registry, e, &ev);
+}
+
+static gboolean
+bridge_property_event_listener (GSignalInvocationHint *signal_hint,
+                               guint n_param_values,
+                               const GValue *param_values,
+                               gpointer data)
+{
+  Accessibility_Event *e = Accessibility_Event__alloc();
+  Bonobo_Unknown source = NULL;
+  AtkObject *aobject;
+  AtkPropertyValues *values;
+  GObject *gobject;
+  GSignalQuery signal_query;
+  gchar *name;
+  char sbuf[APP_STATIC_BUFF_SZ];
+  
+  g_signal_query (signal_hint->signal_id, &signal_query);
+  name = signal_query.signal_name;
+#ifdef SPI_BRIDGE_DEBUG
+  fprintf (stderr, "Received (property) signal %s:%s\n",
+          g_type_name (signal_query.itype), name);
+#endif
+  gobject = g_value_get_object (param_values + 0);
+  values = (AtkPropertyValues*) g_value_get_pointer (param_values + 1);
+
+  /* notify the actual listeners */
+  if (ATK_IS_IMPLEMENTOR (gobject))
+  {
+    aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+    source = CORBA_Object_duplicate (BONOBO_OBJREF (accessible_new (aobject)), &ev);
+    g_object_unref (G_OBJECT(aobject));
+  }
+  else if (ATK_IS_OBJECT (gobject))
+  {
+    aobject = ATK_OBJECT (gobject);
+    source = CORBA_Object_duplicate (BONOBO_OBJREF (accessible_new (aobject)), &ev);
+  }
+  else
+  {
+    g_error("received property-change event from non-AtkImplementor");
+  }
+  
+  snprintf(sbuf, APP_STATIC_BUFF_SZ, "object:property-change:%s", values->property_name);
+  e->type = CORBA_string_dup (sbuf);
+  e->source = source;
+  e->detail1 = 0;
+  e->detail2 = 0;
+  if (source)
+    Accessibility_Registry_notifyEvent (registry, e, &ev);
+  return TRUE;
+}
+
+static gboolean
+bridge_signal_listener (GSignalInvocationHint *signal_hint,
+                       guint n_param_values,
+                       const GValue *param_values,
+                       gpointer data)
+{
+  Accessibility_Event *e = g_new0(Accessibility_Event, 1);
+  AtkObject *aobject;
+  Bonobo_Unknown source;
+  AtkPropertyValues *values;
+  GObject *gobject;
+  GSignalQuery signal_query;
+  gchar *name;
+  char sbuf[APP_STATIC_BUFF_SZ];
+  
+  g_signal_query (signal_hint->signal_id, &signal_query);
+  name = signal_query.signal_name;
+#ifdef SPI_BRIDGE_DEBUG
+  fprintf (stderr, "Received (property) signal %s:%s\n",
+          g_type_name (signal_query.itype), name);
+#endif
+  gobject = g_value_get_object (param_values + 0);
+
+  /* notify the actual listeners */
+  if (ATK_IS_IMPLEMENTOR (gobject))
+  {
+    aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+  }
+  else if (ATK_IS_OBJECT (gobject))
+  {
+    aobject = ATK_OBJECT (gobject);
+    g_object_ref (aobject);
+  }
+  else
+  {
+    g_error("received property-change event from non-AtkImplementor");
+  }
+
+  snprintf(sbuf, APP_STATIC_BUFF_SZ, "%s:%s", name, g_type_name (signal_query.itype));
+  source =  CORBA_Object_duplicate (BONOBO_OBJREF (accessible_new (aobject)), &ev);
+  e->type = CORBA_string_dup (sbuf);
+  e->source = source;
   e->detail1 = 0;
   e->detail2 = 0;
   Accessibility_Registry_notifyEvent (registry, e, &ev);
-  /* CORBA_free (e); */
+  g_object_unref (aobject);
+  return TRUE;
 }
 
 static Accessibility_Registry bridge_get_registry ()
index d4e1345..f47d084 100644 (file)
@@ -30,6 +30,8 @@
 #include "accessible.h"
 #include "application.h"
 
+#define APP_STATIC_BUFF_SZ 64
+
 typedef struct _ArgStruct ArgStruct;
 
 struct _ArgStruct {
@@ -44,6 +46,16 @@ static Application *this_app;
 static gboolean bridge_register_app (gpointer p);
 static void bridge_focus_tracker (AtkObject *object);
 static void bridge_exit_func(void);
+static gboolean bridge_register_event_listener ();
+static void register_atk_event_listeners();
+static gboolean bridge_property_event_listener (GSignalInvocationHint *signal_hint,
+                                               guint n_param_values,
+                                               const GValue *param_values,
+                                               gpointer data);
+static gboolean bridge_signal_listener (GSignalInvocationHint *signal_hint,
+                                       guint n_param_values,
+                                       const GValue *param_values,
+                                       gpointer data);
 
 int
 gtk_module_init(gint *argc, gchar **argv[])
@@ -95,21 +107,37 @@ bridge_register_app (gpointer gp)
 
   bonobo_activate ();
 
-  /* Register for focus event notifications, and register app with central registry  */
-  atk_add_focus_tracker (bridge_focus_tracker);
-
   Accessibility_Registry_registerApplication (registry,
-                                              bonobo_object_corba_objref (bonobo_object (this_app)),
+                                              CORBA_Object_duplicate (BONOBO_OBJREF (this_app), &ev),
                                               &ev);
+
+  register_atk_event_listeners ();
+
   return FALSE;
 }
 
+static void
+register_atk_event_listeners ()
+{
+  /* Register for focus event notifications, and register app with central registry  */
+
+/* kludge to make sure the Atk interface types are registered, otherwise
+   the AtkText signal handlers below won't get registered */
+
+  ATK_TYPE_TEXT;
+
+  atk_add_focus_tracker (bridge_focus_tracker);
+  atk_add_global_event_listener (bridge_property_event_listener, "Gtk:AtkObject:property-change");
+/*  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:children-changed");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-changed");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-caret-moved");*/
+}
+
 static void bridge_exit_func()
 {
   fprintf (stderr, "exiting bridge\n");
   Accessibility_Registry_deregisterApplication (registry,
-                                               bonobo_object_corba_objref (
-                                                       bonobo_object (this_app)),
+                                               CORBA_Object_duplicate (BONOBO_OBJREF (this_app), &ev),
                                                &ev);
   fprintf (stderr, "bridge exit func complete.\n");
 }
@@ -118,11 +146,110 @@ static void bridge_focus_tracker (AtkObject *object)
 {
   Accessibility_Event *e = Accessibility_Event__alloc();
   e->type = CORBA_string_dup ("focus:");
-  e->source = bonobo_object_corba_objref (bonobo_object (accessible_new (object)));
+  e->source = CORBA_Object_duplicate (BONOBO_OBJREF (accessible_new (object)), &ev);
+  e->detail1 = 0;
+  e->detail2 = 0;
+  Accessibility_Registry_notifyEvent (registry, e, &ev);
+}
+
+static gboolean
+bridge_property_event_listener (GSignalInvocationHint *signal_hint,
+                               guint n_param_values,
+                               const GValue *param_values,
+                               gpointer data)
+{
+  Accessibility_Event *e = Accessibility_Event__alloc();
+  Bonobo_Unknown source = NULL;
+  AtkObject *aobject;
+  AtkPropertyValues *values;
+  GObject *gobject;
+  GSignalQuery signal_query;
+  gchar *name;
+  char sbuf[APP_STATIC_BUFF_SZ];
+  
+  g_signal_query (signal_hint->signal_id, &signal_query);
+  name = signal_query.signal_name;
+#ifdef SPI_BRIDGE_DEBUG
+  fprintf (stderr, "Received (property) signal %s:%s\n",
+          g_type_name (signal_query.itype), name);
+#endif
+  gobject = g_value_get_object (param_values + 0);
+  values = (AtkPropertyValues*) g_value_get_pointer (param_values + 1);
+
+  /* notify the actual listeners */
+  if (ATK_IS_IMPLEMENTOR (gobject))
+  {
+    aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+    source = CORBA_Object_duplicate (BONOBO_OBJREF (accessible_new (aobject)), &ev);
+    g_object_unref (G_OBJECT(aobject));
+  }
+  else if (ATK_IS_OBJECT (gobject))
+  {
+    aobject = ATK_OBJECT (gobject);
+    source = CORBA_Object_duplicate (BONOBO_OBJREF (accessible_new (aobject)), &ev);
+  }
+  else
+  {
+    g_error("received property-change event from non-AtkImplementor");
+  }
+  
+  snprintf(sbuf, APP_STATIC_BUFF_SZ, "object:property-change:%s", values->property_name);
+  e->type = CORBA_string_dup (sbuf);
+  e->source = source;
+  e->detail1 = 0;
+  e->detail2 = 0;
+  if (source)
+    Accessibility_Registry_notifyEvent (registry, e, &ev);
+  return TRUE;
+}
+
+static gboolean
+bridge_signal_listener (GSignalInvocationHint *signal_hint,
+                       guint n_param_values,
+                       const GValue *param_values,
+                       gpointer data)
+{
+  Accessibility_Event *e = g_new0(Accessibility_Event, 1);
+  AtkObject *aobject;
+  Bonobo_Unknown source;
+  AtkPropertyValues *values;
+  GObject *gobject;
+  GSignalQuery signal_query;
+  gchar *name;
+  char sbuf[APP_STATIC_BUFF_SZ];
+  
+  g_signal_query (signal_hint->signal_id, &signal_query);
+  name = signal_query.signal_name;
+#ifdef SPI_BRIDGE_DEBUG
+  fprintf (stderr, "Received (property) signal %s:%s\n",
+          g_type_name (signal_query.itype), name);
+#endif
+  gobject = g_value_get_object (param_values + 0);
+
+  /* notify the actual listeners */
+  if (ATK_IS_IMPLEMENTOR (gobject))
+  {
+    aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+  }
+  else if (ATK_IS_OBJECT (gobject))
+  {
+    aobject = ATK_OBJECT (gobject);
+    g_object_ref (aobject);
+  }
+  else
+  {
+    g_error("received property-change event from non-AtkImplementor");
+  }
+
+  snprintf(sbuf, APP_STATIC_BUFF_SZ, "%s:%s", name, g_type_name (signal_query.itype));
+  source =  CORBA_Object_duplicate (BONOBO_OBJREF (accessible_new (aobject)), &ev);
+  e->type = CORBA_string_dup (sbuf);
+  e->source = source;
   e->detail1 = 0;
   e->detail2 = 0;
   Accessibility_Registry_notifyEvent (registry, e, &ev);
-  /* CORBA_free (e); */
+  g_object_unref (aobject);
+  return TRUE;
 }
 
 static Accessibility_Registry bridge_get_registry ()
index 6f8959f..9d34617 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef _SPI_IMPL_H_
 #define _SPI_IMPL_H_
 
+#include <stdlib.h>
 #include <orbit/orbit.h>
 #include "Accessibility.h"
 
index 6cccb40..2c89479 100644 (file)
@@ -4,3 +4,32 @@ spi_freeString (char *s)
   CORBA_free (s);
 }
 
+boolean
+spi_warn_ev (CORBA_Environment *c_ev, char *error_string) {
+
+  if (c_ev->_major != CORBA_NO_EXCEPTION) {
+    fprintf (stderr,
+            "Warning: AT-SPI error: %s: %s\n",
+            error_string,
+             CORBA_exception_id(c_ev));
+        CORBA_exception_init (c_ev);
+        return FALSE;
+  }
+  else
+  {
+        return TRUE;
+  }
+}
+
+void
+spi_check_ev (CORBA_Environment *c_ev, char *error_string) {
+
+  if (c_ev->_major != CORBA_NO_EXCEPTION) {
+    fprintf (stderr,
+            ("AT-SPI error: %s: %s\n"),
+            error_string,
+            CORBA_exception_id(c_ev));
+    CORBA_exception_free(c_ev);
+    exit(-1);
+  }
+}
index e895f90..2fe8f87 100644 (file)
@@ -9,8 +9,12 @@ static Accessible *
 Obj_Add (Accessible object)
 {
   /* TODO: keep list of live object refs */
-  Accessible *oref = g_malloc (sizeof (Accessible));
-  *oref = object;
+  Accessible *oref = NULL;
+  if (!CORBA_Object_is_nil (object, &ev))
+  {
+         oref = g_malloc (sizeof (Accessible));
+         *oref = object;
+  }
   return oref;
 }
 
index 19d1fa3..49a773b 100644 (file)
@@ -1029,7 +1029,7 @@ long
 AccessibleSelection_getNSelectedChildren (AccessibleSelection *obj);
 
 Accessible *
-AccessibleSelection_refSelectedChild (AccessibleSelection *obj,
+AccessibleSelection_getSelectedChild (AccessibleSelection *obj,
                                       long selectedChildIndex);
 
 boolean
index 6707224..f418ba1 100644 (file)
@@ -96,6 +96,7 @@ int
 Accessible_ref (Accessible *obj)
 {
   Accessibility_Accessible_ref (*obj, &ev);
+  spi_check_ev (&ev, "ref");
   return 0;
 }
 
@@ -113,6 +114,7 @@ int
 Accessible_unref (Accessible *obj)
 {
   Accessibility_Accessible_unref (*obj, &ev);
+  spi_check_ev (&ev, "unref");
   return 0;
 }
 
@@ -128,8 +130,11 @@ Accessible_unref (Accessible *obj)
 char *
 Accessible_getName (Accessible *obj)
 {
-  return (char *)
+  char *retval = 
+    (char *)
     Accessibility_Accessible__get_name (*obj, &ev);
+  spi_check_ev (&ev, "getName"); 
+  return retval;
 }
 
 /**
@@ -144,8 +149,10 @@ Accessible_getName (Accessible *obj)
 char *
 Accessible_getDescription (Accessible *obj)
 {
-  return (char *)
+  char *retval = (char *)
     Accessibility_Accessible__get_description (*obj, &ev);
+  spi_check_ev (&ev, "getDescription");
+  return retval;
 }
 
 /**
@@ -154,14 +161,17 @@ Accessible_getDescription (Accessible *obj)
  *
  * Get an #Accessible object's parent container.
  *
- * Returns: a pointer to the #Accessible object which contains the given
+ * Returns: a pointer tothe #Accessible object which contains the given
  *          #Accessible instance, or NULL if the @obj has no parent container.
  *
  **/
 Accessible *
 Accessible_getParent (Accessible *obj)
 {
-  return Obj_Add (Accessibility_Accessible__get_parent (*obj, &ev));
+  Accessible *retval = 
+      Obj_Add (Accessibility_Accessible__get_parent (*obj, &ev));
+  spi_check_ev (&ev, "getParent");
+  return retval;
 }
 
 /**
@@ -178,7 +188,9 @@ Accessible_getParent (Accessible *obj)
 long
 Accessible_getChildCount (Accessible *obj)
 {
-  return Accessibility_Accessible__get_childCount (*obj, &ev);
+  long retval = (long) Accessibility_Accessible__get_childCount (*obj, &ev);
+  spi_check_ev (&ev, "getChildCount");
+  return retval;
 }
 
 /**
@@ -197,7 +209,9 @@ Accessible *
 Accessible_getChildAtIndex (Accessible *obj,
                             long childIndex)
 {
-  return Obj_Add (Accessibility_Accessible_getChildAtIndex (*obj, childIndex, &ev));
+  Accessible *retval = Obj_Add (Accessibility_Accessible_getChildAtIndex (*obj, childIndex, &ev));
+  spi_check_ev (&ev, "getChildAtIndex");
+  return retval;
 }
 
 /**
@@ -215,7 +229,9 @@ Accessible_getChildAtIndex (Accessible *obj,
 long
 Accessible_getIndexInParent (Accessible *obj)
 {
-  return Accessibility_Accessible_getIndexInParent (*obj, &ev);
+  long retval = (long) Accessibility_Accessible_getIndexInParent (*obj, &ev);
+  spi_check_ev (&ev, "getIndexInParent");
+  return retval;
 }
 
 /**
@@ -244,8 +260,10 @@ Accessible_getRelationSet (Accessible *obj)
 char *
 Accessible_getRole (Accessible *obj)
 {
-  return Accessible_Role_getName (
+  char *retval = Accessible_Role_getName (
                  Accessibility_Accessible_getRole (*obj, &ev));
+  spi_check_ev (&ev, "getRole");
+  return retval;
 }
 
 /**
@@ -280,7 +298,9 @@ Accessible_isAction (Accessible *obj)
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Action:1.0",
                                              &ev);
-  return (iface != NULL) ? TRUE : FALSE;
+  spi_warn_ev (&ev, "isAction");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
 }
 
 /**
@@ -299,7 +319,9 @@ Accessible_isComponent (Accessible *obj)
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Component:1.0",
                                              &ev);
-  return (iface != NULL) ? TRUE : FALSE;
+  spi_warn_ev (&ev, "isComponent");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
 }
 
 /**
@@ -319,7 +341,9 @@ Accessible_isEditableText (Accessible *obj)
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/EditableText:1.0",
                                              &ev);
-  return (iface != NULL) ? TRUE : FALSE;
+  spi_check_ev (&ev, "isEditableText");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
 }
 
 /**
@@ -339,7 +363,10 @@ Accessible_isHypertext (Accessible *obj)
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Hypertext:1.0",
                                              &ev);
-  return (iface != NULL) ? TRUE : FALSE;
+
+  spi_check_ev (&ev, "isHypertext");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
 }
 
 /**
@@ -359,7 +386,9 @@ Accessible_isImage (Accessible *obj)
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Image:1.0",
                                              &ev);
-  return (iface != NULL) ? TRUE : FALSE;
+  spi_check_ev (&ev, "isImage");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
 }
 
 /**
@@ -379,7 +408,10 @@ Accessible_isSelection (Accessible *obj)
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Selection:1.0",
                                              &ev);
-  return (iface != NULL) ? TRUE : FALSE;
+  spi_warn_ev (&ev, "isSelection");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
+
 }
 
 /**
@@ -399,7 +431,10 @@ Accessible_isTable (Accessible *obj)
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Table:1.0",
                                              &ev);
-  return (iface != NULL) ? TRUE : FALSE;
+  spi_check_ev (&ev, "isTable");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
+
 }
 
 /**
@@ -419,7 +454,31 @@ Accessible_isText (Accessible *obj)
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Text:1.0",
                                              &ev);
-  return (iface != NULL) ? TRUE : FALSE;
+  spi_warn_ev (&ev, "isText");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
+}
+
+/**
+ * Accessible_isValue:
+ * @obj: a pointer to the #Accessible instance to query.
+ *
+ * Query whether the specified #Accessible implements #AccessibleValue.
+ * Not Yet Implemented.
+ *
+ * Returns: #TRUE if @obj implements the #AccessibleValue interface,
+ *          #FALSE otherwise.
+**/
+boolean
+Accessible_isValue (Accessible *obj)
+{
+  Bonobo_Unknown iface =
+    Accessibility_Accessible_queryInterface (*obj,
+                                             "IDL:Accessibility/Value:1.0",
+                                             &ev);
+  spi_check_ev (&ev, "isValue");
+
+  return (CORBA_Object_is_nil (iface, &ev)) ? FALSE : TRUE;
 }
 
 /**
@@ -431,11 +490,14 @@ Accessible_isText (Accessible *obj)
 AccessibleAction *
 Accessible_getAction (Accessible *obj)
 {
-  AccessibleComponent iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Action:1.0",
                                              &ev);
-  return Obj_Add (iface);
+  spi_check_ev (&ev, "getAction");
+
+  return (AccessibleAction *)
+         ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
 }
 
 /**
@@ -450,21 +512,26 @@ Accessible_getAction (Accessible *obj)
 AccessibleComponent *
 Accessible_getComponent (Accessible *obj)
 {
-  AccessibleComponent iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Component:1.0",
                                              &ev);
-  return Obj_Add (iface);
+  spi_check_ev (&ev, "getComponent");
+
+  return (AccessibleComponent *) ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
 }
 
 AccessibleEditableText *
 Accessible_getEditableText (Accessible *obj)
 {
-  AccessibleComponent iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/EditableText:1.0",
                                              &ev);
-  return Obj_Add (iface);
+  spi_check_ev (&ev, "getEditableText");
+
+  return (AccessibleEditableText *)
+         ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
 }
 
 
@@ -472,11 +539,14 @@ Accessible_getEditableText (Accessible *obj)
 AccessibleHypertext *
 Accessible_getHypertext (Accessible *obj)
 {
-  AccessibleComponent iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Hypertext:1.0",
                                              &ev);
-  return Obj_Add (iface);
+  spi_check_ev (&ev, "getHypertext");
+
+  return (AccessibleHypertext *)
+         ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
 }
 
 
@@ -484,11 +554,14 @@ Accessible_getHypertext (Accessible *obj)
 AccessibleImage *
 Accessible_getImage (Accessible *obj)
 {
-  AccessibleImage iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Image:1.0",
                                              &ev);
-  return Obj_Add (iface);
+  spi_check_ev (&ev, "getImage");
+
+  return (AccessibleImage *)
+         ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
 }
 
 
@@ -496,11 +569,14 @@ Accessible_getImage (Accessible *obj)
 AccessibleSelection *
 Accessible_getSelection (Accessible *obj)
 {
-  AccessibleSelection iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Selection:1.0",
                                              &ev);
-  return Obj_Add (iface);
+  spi_warn_ev (&ev, "getSelection");
+
+  return (AccessibleSelection *)
+         ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
 }
 
 
@@ -508,23 +584,28 @@ Accessible_getSelection (Accessible *obj)
 AccessibleTable *
 Accessible_getTable (Accessible *obj)
 {
-  AccessibleTable iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Table:1.0",
                                              &ev);
-  return Obj_Add (iface);
-}
-
+  spi_check_ev (&ev, "getTable");
 
+  return (AccessibleTable *)
+         ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
+}
 
 AccessibleText *
 Accessible_getText (Accessible *obj)
 {
-  AccessibleText iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Text:1.0",
                                              &ev);
-  return Obj_Add (iface);
+
+  spi_check_ev (&ev, "getText"); 
+
+  return (AccessibleText *)
+         ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
 }
 
 
@@ -532,11 +613,12 @@ Accessible_getText (Accessible *obj)
 AccessibleValue *
 Accessible_getValue (Accessible *obj)
 {
-  AccessibleComponent iface =
+  Bonobo_Unknown iface =
     Accessibility_Accessible_queryInterface (*obj,
                                              "IDL:Accessibility/Value:1.0",
                                              &ev);
-  return Obj_Add (iface);
+  return (AccessibleValue *)
+         ((CORBA_Object_is_nil (iface, &ev)) ? 0 : Obj_Add (iface));
 }
 
 
index c695fc4..247a810 100644 (file)
@@ -109,14 +109,19 @@ AccessibleComponent_getExtents (AccessibleComponent *obj,
                                 long *height,
                                 AccessibleCoordType ctype)
 {
-  /* TODO: remove assumption that CORBA_long == long in typecast */
+  CORBA_long cx, cy, cw, ch;   
   Accessibility_Component_getExtents (*obj,
-                                     (CORBA_long *) x,
-                                     (CORBA_long *) y,
-                                     (CORBA_long *) width,
-                                     (CORBA_long *) height,
-                                     ctype,
-                                     &ev);
+                                      &cx,
+                                      &cy,
+                                      &cw,
+                                      &ch,
+                                     ctype,
+                                     &ev);
+  spi_warn_ev (&ev, "AccessibleComponent_getExtents");
+  *x = (long) cx;
+  *y = (long) cy;
+  *width = (long) cw;
+  *height = (long) ch;
 }
 
 /**
index fdd12f7..dbef7ef 100644 (file)
@@ -29,12 +29,13 @@ Accessible *
 AccessibleSelection_getSelectedChild (AccessibleSelection *obj,
                                       long selectedChildIndex)
 {
-  return (Accessible *)
+  Accessibility_Accessible child = 
     Accessibility_Selection_getSelectedChild (*obj,
                                              (CORBA_long) selectedChildIndex, &ev);
-}
-
+  spi_warn_ev (&ev, "getSelectedChild");
 
+  return (Accessible *) ((CORBA_Object_is_nil (child, &ev)) ? NULL : Obj_Add (child));
+}
 
 boolean
 AccessibleSelection_selectChild (AccessibleSelection *obj,
index cf96701..91d9f76 100644 (file)
@@ -184,7 +184,7 @@ AccessibleTable_getSelectedRows (AccessibleTable *obj,
 
   i = rows->_buffer;
   length = (long) rows->_length;
-  j = *selectedRows = malloc (sizeof(long)*length);
+  j = *selectedRows = (long *) malloc (sizeof(long)*length);
   
   while (length--)
     *j++ = (CORBA_long) (*i++);
@@ -215,7 +215,7 @@ AccessibleTable_getSelectedColumns (AccessibleTable *obj,
 
   i = columns->_buffer;
   length = (long) columns->_length;
-  j = *selectedColumns = malloc (sizeof(long)*length);
+  j = *selectedColumns = (long *) malloc (sizeof(long)*length);
   
   while (length--)
     *j++ = (CORBA_long) (*i++);
index 28bd5bd..4c9ed87 100644 (file)
@@ -19,8 +19,15 @@ AccessibleText_unref (AccessibleText *obj)
 long
 AccessibleText_getCharacterCount (AccessibleText *obj)
 {
-  return (long)
+  long retval;
+
+  CORBA_exception_init (&ev);
+  retval = (long)
     Accessibility_Text__get_characterCount (*obj, &ev);
+
+  spi_check_ev (&ev, "AccessibleText_getCharacterCount");
+
+  return retval;
 }
 
 
@@ -101,9 +108,9 @@ AccessibleText_getTextBeforeOffset (AccessibleText *obj,
 
 char *
 AccessibleText_getTextAtOffset (AccessibleText *obj,
-                                    long offset,
-                                    TEXT_BOUNDARY_TYPE type,
-                                   long *startOffset, long *endOffset)
+                               long offset,
+                               TEXT_BOUNDARY_TYPE type,
+                               long *startOffset, long *endOffset)
 {
   CORBA_long corbaStartOffset;
   CORBA_long corbaEndOffset;
index 05139bc..01deff3 100644 (file)
@@ -51,12 +51,19 @@ module Accessibility {
     attribute long id;
 
     /**
-     * Register with this application's toolkit for "toolkit" event notifications.
+     * Register with this application's toolkit for "toolkit-specific" event notifications.
      *
      **/
     void registerToolkitEventListener (in EventListener listener, in string eventName);
 
     /**
+     * Register with this application's toolkit for "Accessibility::Accessible" 
+     * event notifications.
+     *
+     **/
+    void registerObjectEventListener (in EventListener listener, in string eventName);
+
+    /**
      * pause:
      * Returns: %true if the request succeeded, %false otherwise.
      *
index 05139bc..01deff3 100644 (file)
@@ -51,12 +51,19 @@ module Accessibility {
     attribute long id;
 
     /**
-     * Register with this application's toolkit for "toolkit" event notifications.
+     * Register with this application's toolkit for "toolkit-specific" event notifications.
      *
      **/
     void registerToolkitEventListener (in EventListener listener, in string eventName);
 
     /**
+     * Register with this application's toolkit for "Accessibility::Accessible" 
+     * event notifications.
+     *
+     **/
+    void registerObjectEventListener (in EventListener listener, in string eventName);
+
+    /**
      * pause:
      * Returns: %true if the request succeeded, %false otherwise.
      *
index 3777145..ad5a89f 100644 (file)
@@ -67,7 +67,8 @@ accessible_object_finalize (GObject *object)
         Accessible *accessible = ACCESSIBLE (object);
 
         printf("accessible_object_finalize called\n");
-        g_object_unref (accessible->atko);
+       ATK_OBJECT (accessible->atko); /* assertion */
+        g_object_unref (G_OBJECT(accessible->atko));
         accessible->atko = NULL;
 
         printf("atko freed, calling parent finalize\n");
@@ -88,7 +89,7 @@ impl_accessibility_accessible_get_name (PortableServer_Servant servant,
     retval = CORBA_string_dup (retval);
   else
     retval = CORBA_string_dup ("");
-  fprintf (stderr, "Accessible get_name called: %s\n", retval);
+
   return retval;
 }
 
@@ -115,7 +116,7 @@ impl_accessibility_accessible_get_description (PortableServer_Servant servant,
   CORBA_char * retval;
   Accessible *accessible = ACCESSIBLE (bonobo_object_from_servant (servant));
   retval = CORBA_string_dup (atk_object_get_description (accessible->atko));
-  fprintf (stderr, "Accessible get_description called: %s\n", retval);
+
   return retval;
 }
 
@@ -143,9 +144,9 @@ impl_accessibility_accessible_get_parent (PortableServer_Servant servant,
   Accessible *accessible = ACCESSIBLE (bonobo_object_from_servant (servant));
   AtkObject *parent;
   parent = atk_object_get_parent (accessible->atko);
-  retval = bonobo_object_corba_objref (bonobo_object (accessible_new (parent)));
+  retval = BONOBO_OBJREF (accessible_new (parent));
   printf ("Accessible get_parent called\n");
-  return retval;
+  return CORBA_Object_duplicate (retval, &ev);
 }
 
 /*
@@ -187,9 +188,9 @@ impl_accessibility_accessible_get_child_at_index (PortableServer_Servant servant
   Accessibility_Accessible retval;
   Accessible *accessible = ACCESSIBLE (bonobo_object_from_servant (servant));
   AtkObject *child = atk_object_ref_accessible_child (accessible->atko, (gint) index);
-  retval = bonobo_object_corba_objref ( bonobo_object (accessible_new (child)));
+  retval = BONOBO_OBJREF (accessible_new (child));
   printf ("Accessible get_child_at_index called.\n");
-  return retval;
+  return CORBA_Object_duplicate (retval, &ev);
 }
 
 /*
@@ -213,7 +214,6 @@ impl_accessibility_accessible_get_state (PortableServer_Servant servant,
  */
 static Accessibility_RelationSet *
 impl_accessibility_accessible_get_relation_set (PortableServer_Servant servant,
-                                               const CORBA_long      index,
                                                CORBA_Environment     *ev)
 {
   Accessibility_RelationSet *retval;
@@ -233,7 +233,6 @@ impl_accessibility_accessible_get_relation_set (PortableServer_Servant servant,
  */
 static Accessibility_Role
 impl_accessibility_accessible_get_role (PortableServer_Servant servant,
-                                       const CORBA_long      index,
                                        CORBA_Environment     *ev)
 {
   Accessibility_Role retval;
@@ -313,6 +312,8 @@ accessible_new (AtkObject *o)
 {
     Accessible *retval =
                ACCESSIBLE (g_object_new (accessible_get_type (), NULL));
+    CORBA_Environment ev;
+    CORBA_exception_init (&ev);
     g_object_ref (o);
     retval->atko = ATK_OBJECT (o);
 
@@ -328,7 +329,7 @@ accessible_new (AtkObject *o)
         bonobo_object_add_interface (bonobo_object (retval),
                                      BONOBO_OBJECT (action_interface_new (o)));
       }
-
+      
     if (ATK_IS_COMPONENT (o))
       {
         bonobo_object_add_interface (bonobo_object (retval),
@@ -353,12 +354,6 @@ accessible_new (AtkObject *o)
                                      BONOBO_OBJECT (text_interface_new (o)));
       }
 
-    if (ATK_IS_HYPERLINK (o))
-      {
-       bonobo_object_add_interface (bonobo_object (retval),
-                                    BONOBO_OBJECT (hyperlink_interface_new(o)));
-      }
-
     if (ATK_IS_IMAGE (o))
       {
         bonobo_object_add_interface (bonobo_object (retval),
@@ -383,6 +378,5 @@ accessible_new (AtkObject *o)
                                      BONOBO_OBJECT (value_interface_new (o)));
       }
 
-
     return retval;
 }
index 2a3bc4f..9de4519 100644 (file)
@@ -85,7 +85,7 @@ impl_accessible_event_notify_event (PortableServer_Servant     servant,
           (*cb) (e);
         }
     }
-  Accessibility_Accessible_unref (e->source, ev);
+  /* Accessibility_Accessible_unref (e->source, ev); */
 }
 
 static void
index 50a8d10..8b4f013 100644 (file)
@@ -32,7 +32,7 @@ extern "C" {
 #define ACTION_TYPE        (action_get_type ())
 #define ACTION(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), ACTION_TYPE, Action))
 #define ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), ACTION_TYPE, ActionClass))
-#define IS_ACTION(obj)       (G_TYPE_CHECK__INSTANCE_TYPE ((obj), ACTION_TYPE))
+#define IS_ACTION(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ACTION_TYPE))
 #define IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ACTION_TYPE))
 
 typedef struct _Action Action;
index 8c31dd7..9d9d93c 100644 (file)
@@ -24,6 +24,7 @@
  * application.c: implements Application.idl
  *
  */
+#include <string.h>
 #include <config.h>
 #include <bonobo/Bonobo.h>
 #include <atk/atkutil.h>
  */
 static AccessibleClass *application_parent_class;
 
-Accessibility_EventListener the_toolkit_listener;
+static Application *the_app;
+
+/* static methods */
+
+static void notify_listeners (GList *listeners,
+                             Accessibility_Event *e,
+                             CORBA_Environment *ev);
+
+static char* lookup_toolkit_event_for_name (char *generic_name);
+
+static char* reverse_lookup_name_for_toolkit_event (char *toolkit_name);
 
 /*
  * Implemented GObject::finalize
@@ -57,12 +68,7 @@ static void
 accessible_application_finalize (GObject *object)
 {
   /* TODO: any necessary cleanup */
-  Accessible *accessible = ACCESSIBLE (object);
-
-  g_object_unref (accessible->atko);
-  accessible->atko = NULL;
-
-  /* TODO: chain to parent class instead */
+  (G_OBJECT_CLASS (application_parent_class))->finalize (object);
 }
 
 static CORBA_string
@@ -107,14 +113,81 @@ impl_accessibility_application_set_id (PortableServer_Servant servant,
 #define APP_STATIC_BUFF_SZ 64
 
 static gboolean
-application_toolkit_listener (GSignalInvocationHint *signal_hint,
-                              guint n_param_values,
-                              const GValue *param_values,
-                              gpointer data)
+application_object_event_listener (GSignalInvocationHint *signal_hint,
+                                  guint n_param_values,
+                                  const GValue *param_values,
+                                  gpointer data)
+{
+  Accessibility_Event *e = Accessibility_Event__alloc();
+  AtkObject *aobject;
+  GObject *gobject;
+  Accessible *source;
+  CORBA_Environment ev;
+  GSignalQuery signal_query;
+  gchar *name;
+  char sbuf[APP_STATIC_BUFF_SZ];
+  char *generic_name;
+  
+  g_signal_query (signal_hint->signal_id, &signal_query);
+  name = signal_query.signal_name;
+  fprintf (stderr, "Received (object) signal %s:%s\n",
+          g_type_name (signal_query.itype), name);
+
+  /* TODO: move GTK dependency out of app.c into bridge */
+  snprintf(sbuf, APP_STATIC_BUFF_SZ, "Gtk:%s:%s", g_type_name (signal_query.itype), name);
+
+  generic_name = reverse_lookup_name_for_toolkit_event (sbuf);
+  gobject = g_value_get_object (param_values + 0);
+
+  /* notify the actual listeners */
+  if (ATK_IS_IMPLEMENTOR (gobject))
+  {
+    aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+  }
+  else if (ATK_IS_OBJECT (gobject))
+  {
+    aobject = ATK_OBJECT (gobject);
+    g_object_ref (G_OBJECT (aobject));
+  }
+  else
+  {
+    g_error("received event from non-AtkImplementor");
+  }
+
+  g_return_val_if_fail (generic_name, FALSE);
+  if (generic_name)
+    {
+        source = accessible_new (aobject);
+       e->type = CORBA_string_dup (generic_name);
+       e->source = BONOBO_OBJREF (source);
+        /*
+        * no need to dup this ref, since it's inprocess               
+        * and will be dup'ed by (inprocess) notify_listeners() call below
+        */
+       e->detail1 = 0;
+       e->detail2 = 0;
+       if (the_app) notify_listeners (the_app->toolkit_listeners, e, &ev);
+        /* unref because the in-process notify has called b_o_dup_ref (e->source) */
+        bonobo_object_release_unref (e->source, &ev); 
+    }
+  /* and, decrement the refcount on atkobject, incremented moments ago:
+   *  the call to accessible_new() above should have added an extra ref */
+  g_object_unref (G_OBJECT (aobject));
+
+  return TRUE;
+}
+
+
+static gboolean
+application_toolkit_event_listener (GSignalInvocationHint *signal_hint,
+                                   guint n_param_values,
+                                   const GValue *param_values,
+                                   gpointer data)
 {
-  Accessibility_Event *e = g_new0(Accessibility_Event, 1);
+  Accessibility_Event *e = Accessibility_Event__alloc();
   AtkObject *aobject;
   GObject *gobject;
+  Accessible *source;
   CORBA_Environment ev;
   GSignalQuery signal_query;
   gchar *name;
@@ -127,32 +200,34 @@ application_toolkit_listener (GSignalInvocationHint *signal_hint,
   /* TODO: move GTK dependency out of app.c into bridge */
   snprintf(sbuf, APP_STATIC_BUFF_SZ, "Gtk:%s:%s", g_type_name (signal_query.itype), name);
 
-
   gobject = g_value_get_object (param_values + 0);
   /* notify the actual listeners */
   if (ATK_IS_IMPLEMENTOR (gobject))
     {
       aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+      source = accessible_new (aobject);
       e->type = CORBA_string_dup (sbuf);
-      e->source = bonobo_object_corba_objref (bonobo_object (accessible_new (aobject)));
+      e->source = BONOBO_OBJREF (source);
       e->detail1 = 0;
       e->detail2 = 0;
-      Accessibility_EventListener_notifyEvent (the_toolkit_listener, e, &ev);
-      g_object_unref (aobject);
+      if (the_app) notify_listeners (the_app->toolkit_listeners, e, &ev);
+      bonobo_object_unref (source);
+      g_object_unref (G_OBJECT (aobject));
     }
   return TRUE;
 }
 
 static void
 impl_accessibility_application_register_toolkit_event_listener (PortableServer_Servant servant,
-                                                                Accessibility_EventListener listener,
+                                                               Accessibility_EventListener listener,
                                                                 const CORBA_char *event_name,
                                                                 CORBA_Environment *ev)
 {
   guint listener_id;
   listener_id =
-     atk_add_global_event_listener (application_toolkit_listener, event_name);
-  the_toolkit_listener = CORBA_Object_duplicate (listener, ev);
+     atk_add_global_event_listener (application_toolkit_event_listener, event_name);
+  the_app->toolkit_listeners = g_list_append (the_app->toolkit_listeners,
+                                             CORBA_Object_duplicate (listener, ev));
 #ifdef SPI_DEBUG
   fprintf (stderr, "registered %d for toolkit events named: %s\n",
            listener_id,
@@ -161,6 +236,96 @@ impl_accessibility_application_register_toolkit_event_listener (PortableServer_S
 }
 
 static void
+impl_accessibility_application_register_object_event_listener (PortableServer_Servant servant,
+                                                              Accessibility_EventListener listener,
+                                                              const CORBA_char *event_name,
+                                                              CORBA_Environment *ev)
+{
+  guint listener_id;
+  char *toolkit_specific_event_name = lookup_toolkit_event_for_name (event_name);
+  if (toolkit_specific_event_name)
+  {
+    listener_id =
+       atk_add_global_event_listener (application_object_event_listener,
+                                     CORBA_string_dup (toolkit_specific_event_name));
+    the_app->toolkit_listeners = g_list_append (the_app->toolkit_listeners,
+                                             CORBA_Object_duplicate (listener, ev));
+  }
+#ifdef SPI_DEBUG
+  fprintf (stderr, "registered %d for object events named: %s\n",
+           listener_id,
+           event_name);
+#endif
+}
+
+static void
+notify_listeners (GList *listeners, Accessibility_Event *e, CORBA_Environment *ev)
+{
+    int n_listeners=0;
+    int i;
+    if (listeners) n_listeners = g_list_length (listeners);
+
+    for (i=0; i<n_listeners; ++i) {
+        Accessibility_EventListener listener;
+       e->source = bonobo_object_dup_ref (e->source, ev); 
+       listener = (Accessibility_EventListener) g_list_nth_data (listeners, i);
+       Accessibility_EventListener_notifyEvent (listener, e, ev);
+       /*
+        * when this (oneway) call completes, the CORBA refcount and
+        * Bonobo_Unknown refcount will be decremented by the recipient
+        */
+    }
+}
+
+static char *
+lookup_toolkit_event_for_name (char *generic_name)
+{
+    char *toolkit_specific_name;
+    ApplicationClass *klass = g_type_class_peek (APPLICATION_TYPE);
+#ifdef SPI_DEBUG
+    fprintf (stderr, "looking for %s in hash table.\n", generic_name);
+#endif
+    toolkit_specific_name =
+           (char *) g_hash_table_lookup (klass->toolkit_event_names, generic_name);
+#ifdef SPI_DEBUG
+    fprintf (stderr, "generic event %s converted to %s\n", generic_name, toolkit_specific_name);
+#endif
+    return toolkit_specific_name;
+}
+
+static char *
+reverse_lookup_name_for_toolkit_event (char *toolkit_specific_name)
+{
+    char *generic_name;
+    ApplicationClass *klass = g_type_class_peek (APPLICATION_TYPE);
+#ifdef SPI_DEBUG
+    fprintf (stderr, "(reverse lookup) looking for %s in hash table.\n", toolkit_specific_name);
+#endif
+    generic_name =
+           (char *) g_hash_table_lookup (klass->generic_event_names, toolkit_specific_name);
+#ifdef SPI_DEBUG
+    fprintf (stderr, "toolkit event %s converted to %s\n", toolkit_specific_name, generic_name);
+#endif
+    return generic_name;
+}
+
+static void
+init_toolkit_names (GHashTable **generic_event_names, GHashTable **toolkit_event_names)
+{
+       *toolkit_event_names = g_hash_table_new (g_str_hash, g_str_equal);
+       *generic_event_names = g_hash_table_new (g_str_hash, g_str_equal);
+       g_hash_table_insert (*toolkit_event_names,
+                            "object:property-change",
+                            "Gtk:AtkObject:property-change");
+       g_hash_table_insert (*generic_event_names,
+                            "Gtk:AtkObject:property-change",
+                            "object:property-change");
+#ifdef SPI_DEBUG
+       fprintf (stderr, "inserted selection_changed hash\n");
+#endif
+}
+
+static void
 application_class_init (ApplicationClass *klass)
 {
   GObjectClass * object_class = (GObjectClass *) klass;
@@ -175,12 +340,15 @@ application_class_init (ApplicationClass *klass)
   epv->_get_id = impl_accessibility_application_get_id;
   epv->_set_id = impl_accessibility_application_set_id;
   epv->registerToolkitEventListener = impl_accessibility_application_register_toolkit_event_listener;
+  init_toolkit_names (&klass->generic_event_names, &klass->toolkit_event_names);
 }
 
 static void
 application_init (Application  *application)
 {
   ACCESSIBLE (application)->atko = g_object_new (atk_object_get_type(), NULL);
+  application->toolkit_listeners = (GList *) NULL;
+  the_app = application;
 }
 
 GType
@@ -224,5 +392,6 @@ application_new (AtkObject *app_root)
     Application *retval =
                APPLICATION (g_object_new (application_get_type (), NULL));
     ACCESSIBLE (retval)->atko = app_root;
+    g_object_ref (G_OBJECT (app_root));
     return retval;
 }
index 110cdda..5886d95 100644 (file)
@@ -41,11 +41,14 @@ extern "C" {
 typedef struct {
         Accessible parent;
         long id;
+       GList *toolkit_listeners;
 } Application;
 
 typedef struct {
         AccessibleClass parent_class;
         POA_Accessibility_Application__epv epv;
+       GHashTable *toolkit_event_names;
+       GHashTable *generic_event_names;
 } ApplicationClass;
 
 GType               application_get_type           (void);
index efd22c9..5e679d9 100644 (file)
@@ -62,7 +62,7 @@ accessibility_component_object_finalize (GObject *object)
         g_object_unref (component->atko);
        component->atko = NULL;
 
-        printf("atko freed, calling parent finalize\n");
+        printf("component atko freed, calling parent finalize\n");
         component_parent_class->finalize (object);
 }
 
@@ -113,7 +113,7 @@ impl_accessibility_component_get_accessible_at_point (PortableServer_Servant ser
                                                   (gint) x, (gint) y,
                                                   (AtkCoordType) coord_type);
   retval = bonobo_object_corba_objref (bonobo_object (accessible_new (child)));
-  return retval;
+  return CORBA_Object_duplicate (retval, ev);
 }
 
 /*
@@ -253,5 +253,5 @@ component_interface_new (AtkObject *o)
                COMPONENT (g_object_new (accessibility_component_get_type (), NULL));
     retval->atko = o;
     g_object_ref (o);
-return retval;
+    return retval;
 }
index b2a1808..17856ae 100644 (file)
@@ -124,10 +124,15 @@ editable_text_class_init (EditableTextClass *klass)
 {
   GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_EditableText__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
+  parent_class = g_type_interface_peek_parent (klass);
 
   object_class->finalize = editable_text_finalize;
-
+  
+/* */
+  fprintf(stderr, "INITIALIZING editabletext class!\n");
+  
+  fprintf (stderr, "EditableText: get-character-count is at %p\n",
+          ((TEXT_CLASS(klass))->epv._get_characterCount));
 
   /* Initialize epv table */
 
@@ -148,10 +153,6 @@ editable_text_init (EditableText *editable)
 static void
 editable_text_finalize (GObject *obj)
 {
-  EditableText *editable = EDITABLE_TEXT(obj);
-  Text *text = TEXT(obj);
-  g_object_unref (text->atko);
-  text->atko = NULL;
   parent_class->finalize (obj);
 }
 
@@ -160,9 +161,9 @@ editable_text_interface_new (AtkObject *obj)
 {
   EditableText *new_editable =
     EDITABLE_TEXT(g_object_new (EDITABLE_TEXT_TYPE, NULL));
-  TEXT (new_editable)->atko = obj;
+  (TEXT (new_editable))->atko = obj;
   g_object_ref (obj);
-return new_editable;
+  return new_editable;
 }
 
 
index 2a3bc4f..9de4519 100644 (file)
@@ -85,7 +85,7 @@ impl_accessible_event_notify_event (PortableServer_Servant     servant,
           (*cb) (e);
         }
     }
-  Accessibility_Accessible_unref (e->source, ev);
+  /* Accessibility_Accessible_unref (e->source, ev); */
 }
 
 static void
index 208cab5..14622fd 100644 (file)
@@ -60,6 +60,8 @@ static ListenerClass *registry_parent_class;
 
 typedef enum {
   ETYPE_FOCUS,
+  ETYPE_OBJECT,
+  ETYPE_PROPERTY,
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
   ETYPE_LAST_DEFINED
@@ -122,7 +124,7 @@ impl_accessibility_registry_register_application (PortableServer_Servant servant
   fprintf (stderr, "registering app %p\n", application);
 #endif
   registry->desktop->applications = g_list_append (registry->desktop->applications,
-                                                   CORBA_Object_duplicate (application, ev));
+                                                   bonobo_object_dup_ref (application, ev));
 
   /* TODO: create unique string here (with libuuid call ?) and hash ? */
   Accessibility_Application__set_id (application, _get_unique_id(), ev);
@@ -157,7 +159,7 @@ register_with_toolkits (Registry *registry_bonobo_object, EventTypeStruct *etype
   Accessibility_Desktop desktop;
   Accessibility_Application app;
   Accessibility_Registry registry;
-  registry  = bonobo_object_corba_objref (bonobo_object (registry_bonobo_object));
+  registry  = BONOBO_OBJREF (registry_bonobo_object);
 
   /* for each app in each desktop, call ...Application_registerToolkitEventListener */
 
@@ -172,11 +174,11 @@ register_with_toolkits (Registry *registry_bonobo_object, EventTypeStruct *etype
           app = (Accessibility_Application) Accessibility_Desktop_getChildAtIndex (desktop,
                                                                                    j,
                                                                                    ev);
-          /* TODO: should we be ref-ing the registry object before each call ? */
-          Accessibility_Application_registerToolkitEventListener (app,
-                                                                  registry,
-                                                                  CORBA_string_dup (etype->event_name),
-                                                                  ev);
+         Accessibility_Application_registerToolkitEventListener (app,
+                                                                 registry,
+                                                                 CORBA_string_dup (etype->event_name),
+                                                                 
+                                                                 ev);
         }
     }
 }
@@ -200,6 +202,10 @@ parse_event_type (EventTypeStruct *etype, char *event_name)
     {
       etype->type_cat = ETYPE_FOCUS;
     }
+  else if (!g_ascii_strncasecmp (event_name, "object:", 7))
+    {
+      etype->type_cat = ETYPE_OBJECT;
+    }
   else if (!g_ascii_strncasecmp (event_name, "window:", 7))
     {
       etype->type_cat = ETYPE_WINDOW;
@@ -296,6 +302,7 @@ impl_accessibility_registry_register_global_event_listener (
   Registry *registry = REGISTRY (bonobo_object_from_servant (servant));
   ListenerStruct *ls = g_malloc (sizeof (ListenerStruct));
   EventTypeStruct etype;
+  gboolean is_toolkit_specific = TRUE;
 
   fprintf(stderr, "registering for events of type %s\n", event_name);
 
@@ -307,9 +314,11 @@ impl_accessibility_registry_register_global_event_listener (
   switch (etype.type_cat)
     {
     case (ETYPE_FOCUS) :
+    case (ETYPE_OBJECT) :
+    case (ETYPE_PROPERTY) :
       ls->listener = CORBA_Object_duplicate (listener, ev);
-      registry->focus_listeners =
-        g_list_append (registry->focus_listeners, ls);
+      registry->object_listeners =
+        g_list_append (registry->object_listeners, ls);
       break;
     case (ETYPE_WINDOW) :
       /* Support for Window Manager Events is not yet implemented */
@@ -335,7 +344,7 @@ impl_accessibility_registry_deregister_global_event_listener_all (
                                                     CORBA_Environment      *ev)
 {
   Registry *registry = REGISTRY (bonobo_object_from_servant (servant));
-  GList *list = g_list_find_custom (registry->focus_listeners, listener, compare_corba_objects);
+  GList *list = g_list_find_custom (registry->object_listeners, listener, compare_corba_objects);
 
   /*
    * TODO : de-register with toolkit if the last instance of a listener
@@ -345,8 +354,8 @@ impl_accessibility_registry_deregister_global_event_listener_all (
   while (list)
     {
       fprintf (stderr, "deregistering listener\n");
-      registry->focus_listeners = g_list_delete_link (registry->focus_listeners, list);
-      list = g_list_find_custom (registry->focus_listeners, listener, compare_corba_objects);
+      registry->object_listeners = g_list_delete_link (registry->object_listeners, list);
+      list = g_list_find_custom (registry->object_listeners, listener, compare_corba_objects);
     }
   list = g_list_find_custom (registry->toolkit_listeners, listener, compare_corba_objects);
   while (list)
@@ -376,8 +385,10 @@ impl_accessibility_registry_deregister_global_event_listener (
   parse_event_type (&etype, event_name);
   switch (etype.type_cat)
     {
+    case (ETYPE_OBJECT) :
+    case (ETYPE_PROPERTY) :
     case (ETYPE_FOCUS) :
-      listeners = &registry->focus_listeners;
+      listeners = &registry->object_listeners;
       break;
     case (ETYPE_WINDOW) :
       /* Support for Window Manager Events is not yet implemented */
@@ -438,8 +449,7 @@ impl_accessibility_registry_get_desktop (PortableServer_Servant servant,
   if (n == 0)
     {
       return (Accessibility_Desktop)
-        CORBA_Object_duplicate (
-             bonobo_object_corba_objref (bonobo_object (registry->desktop)), ev);
+        CORBA_Object_duplicate (BONOBO_OBJREF (registry->desktop), ev);
     }
   else
     {
@@ -470,9 +480,7 @@ impl_accessibility_registry_get_device_event_controller (PortableServer_Servant
   Registry *registry = REGISTRY (bonobo_object_from_servant (servant));
   if (!registry->device_event_controller)
     registry->device_event_controller = g_object_new (DEVICE_EVENT_CONTROLLER_TYPE, NULL);
-  return CORBA_Object_duplicate (
-         bonobo_object_corba_objref (
-                 bonobo_object (registry->device_event_controller)), ev);
+  return CORBA_Object_duplicate (BONOBO_OBJREF (registry->device_event_controller), ev);
 }
 
 static void
@@ -487,19 +495,21 @@ impl_registry_notify_event (PortableServer_Servant servant,
 
   switch (etype.type_cat)
     {
+    case (ETYPE_OBJECT) :
+    case (ETYPE_PROPERTY) :
     case (ETYPE_FOCUS) :
-      _registry_notify_listeners (registry->focus_listeners, e, ev);
+      _registry_notify_listeners (registry->object_listeners, e, ev); 
       break;
     case (ETYPE_WINDOW) :
       _registry_notify_listeners (registry->window_listeners, e, ev);
       break;
     case (ETYPE_TOOLKIT) :
-      _registry_notify_listeners (registry->toolkit_listeners, e, ev);
+      _registry_notify_listeners (registry->toolkit_listeners, e, ev); 
       break;
     default:
       break;
     }
- Accessibility_Accessible_unref (e->source, ev);
+  /* Accessibility_Accessible_unref (e->source, ev);*/ /* This should be here! */
 }
 
 static long
@@ -526,7 +536,7 @@ _registry_notify_listeners ( GList *listeners,
   for (n=0; n<len; ++n)
     {
       ls =  (ListenerStruct *) g_list_nth_data (listeners, n);
-#ifdef SPI_DEBUG
+#ifdef SPI_LISTENER_DEBUG
       fprintf(stderr, "event hashes: %lx %lx %lx\n", ls->event_type_hash, etype.hash, minor_hash);
       fprintf(stderr, "event name: %s\n", etype.event_name);
 #endif
@@ -534,8 +544,9 @@ _registry_notify_listeners ( GList *listeners,
         {
 #ifdef SPI_DEBUG
           fprintf(stderr, "notifying listener #%d\n", n);
-          fprintf(stderr, "event name %s\n", Accessibility_Accessible__get_name(e->source, ev));
+          fprintf(stderr, "event source name %s\n", Accessibility_Accessible__get_name(e->source, ev));
 #endif
+         e->source = CORBA_Object_duplicate (e->source, ev);
           Accessibility_Accessible_ref ( e->source, ev);
           Accessibility_EventListener_notifyEvent ((Accessibility_EventListener) ls->listener,
                                                    e,
@@ -585,7 +596,7 @@ registry_class_init (RegistryClass *klass)
 static void
 registry_init (Registry *registry)
 {
-  registry->focus_listeners = NULL;
+  registry->object_listeners = NULL;
   registry->window_listeners = NULL;
   registry->toolkit_listeners = NULL;
   registry->applications = NULL;
index 7622fe2..ca5a2fe 100644 (file)
@@ -41,7 +41,7 @@ extern "C" {
 
 typedef struct {
   Listener parent;
-  GList *focus_listeners;
+  GList *object_listeners;
   GList *window_listeners;
   GList *toolkit_listeners;
   GList *applications;
index f80af59..bf33ecf 100644 (file)
@@ -33,6 +33,7 @@
  * This pulls the CORBA definitions for the "Accessibility::Accessible" server
  */
 #include <libspi/Accessibility.h>
+#include "accessible.h"
 
 /*
  * This pulls the definition of the selection bonobo object
@@ -165,12 +166,17 @@ static CORBA_long
 impl__get_nSelectedChildren (PortableServer_Servant _servant,
                             CORBA_Environment * ev)
 {
-  Selection *selection = SELECTION (bonobo_object_from_servant (_servant));
+  BonoboObject *obj = bonobo_object_from_servant (_servant);
+  Selection *selection;
+#ifdef SPI_DEBUG
+  fprintf (stderr, "calling impl__get_nSelectedChildren\n");
+#endif
+  g_return_val_if_fail (IS_SELECTION (obj), 0);
+  selection = SELECTION (obj);
+  g_return_val_if_fail (ATK_IS_SELECTION (selection->atko), 0);
   return (CORBA_long)
     atk_selection_get_selection_count (ATK_SELECTION(selection->atko));
-} 
-
-
+}
 
 
 static Accessibility_Accessible
@@ -178,13 +184,27 @@ impl_getSelectedChild (PortableServer_Servant _servant,
                       const CORBA_long selectedChildIndex,
                       CORBA_Environment * ev)
 {
-  Selection *selection = SELECTION (bonobo_object_from_servant (_servant));
+  BonoboObject *obj = bonobo_object_from_servant (_servant);
+  Selection
+         *selection;
   AtkObject *atk_object;
   Accessibility_Accessible rv;
-
-  atk_object = atk_selection_ref_selection (ATK_SELECTION(selection->atko), (gint) selectedChildIndex);
-  rv = bonobo_object_corba_objref (BONOBO_OBJECT(accessible_new(atk_object)));
-  return rv;
+#ifdef SPI_DEBUG
+  fprintf (stderr, "calling impl_getSelectedChild\n");
+#endif
+  g_return_val_if_fail (IS_SELECTION (obj), 0);
+  selection = SELECTION (obj);
+  g_return_val_if_fail (ATK_IS_SELECTION (selection->atko), 0);
+
+  atk_object = atk_selection_ref_selection (ATK_SELECTION (selection->atko),
+                                           (gint) selectedChildIndex);
+  g_return_val_if_fail (ATK_IS_OBJECT (atk_object), NULL);
+#ifdef SPI_DEBUG
+  fprintf (stderr, "child type is %s\n", g_type_name (G_OBJECT_TYPE (atk_object)));
+#endif
+  rv = bonobo_object_corba_objref (bonobo_object (accessible_new (atk_object)));
+  g_object_unref (atk_object);
+  return CORBA_Object_duplicate (rv, ev);
 }
 
 
index 02c2882..97cb807 100644 (file)
@@ -32,7 +32,7 @@ extern "C" {
 #define SELECTION_TYPE        (selection_get_type ())
 #define SELECTION(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SELECTION_TYPE, Selection))
 #define SELECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SELECTION_TYPE, SelectionClass))
-#define IS_SELECTION(obj)       (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SELECTION_TYPE))
+#define IS_SELECTION(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SELECTION_TYPE))
 #define IS_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SELECTION_TYPE))
 
 typedef struct _Selection Selection;
index 593522e..17172a9 100644 (file)
@@ -235,7 +235,7 @@ impl__get_caption (PortableServer_Servant _servant,
 
   atk_object = atk_table_get_caption (ATK_TABLE(table-> atko));
   rv = bonobo_object_corba_objref (BONOBO_OBJECT(accessible_new(atk_object)));
-  return rv;
+  return CORBA_Object_duplicate (rv, ev);
 }
 
 
@@ -250,7 +250,7 @@ impl__get_summary (PortableServer_Servant _servant,
 
   atk_object = atk_table_get_summary (ATK_TABLE(table->atko));
   rv = bonobo_object_corba_objref (BONOBO_OBJECT(accessible_new(atk_object)));
-  return rv;
+  return CORBA_Object_duplicate (rv, ev);
 }
 
 
@@ -290,7 +290,7 @@ impl_getAccessibleAt (PortableServer_Servant _servant,
   atk_object = atk_table_ref_at (ATK_TABLE(table->atko),
                                             (gint) row, (gint) column);
   rv = bonobo_object_corba_objref (BONOBO_OBJECT(accessible_new(atk_object)));
-  return rv;
+  return CORBA_Object_duplicate (rv, ev);
 }
 
 
@@ -405,7 +405,7 @@ impl_getRowHeader (PortableServer_Servant _servant,
 
   header = atk_table_get_row_header (ATK_TABLE(table->atko), (gint) row);
   rv = bonobo_object_corba_objref (BONOBO_OBJECT(accessible_new(header)));
-  return rv;
+  return CORBA_Object_duplicate (rv, ev);
 }
 
 
@@ -421,7 +421,7 @@ impl_getColumnHeader (PortableServer_Servant _servant,
 
   header = atk_table_get_column_header (ATK_TABLE(table->atko), (gint) column);
   rv = bonobo_object_corba_objref (BONOBO_OBJECT(accessible_new(header)));
-  return rv;
+  return CORBA_Object_duplicate (rv, ev);
 }
 
 
index 7b369a7..f7302fc 100644 (file)
 #include "text.h"
 
 /*
+ * Our parent Gtk object type
+ */
+#define PARENT_TYPE BONOBO_OBJECT_TYPE
+
+
+/*
+ * A pointer to our parent object class
+ */
+static GObjectClass *text_parent_class;
+
+/*
  * Static function declarations
  */
 
 static void
-text_class_init (TextClass *klass);
+accessibility_text_class_init (TextClass *klass);
+
 static void
-text_init (Text *text);
+accessibility_text_init (Text *text);
+
 static void
-text_finalize (GObject *obj);
+accessibility_text_object_finalize (GObject *obj);
+
 static CORBA_string
 impl_getText (PortableServer_Servant _servant,
              const CORBA_long startOffset,
              const CORBA_long endOffset,
              CORBA_Environment * ev);
-CORBA_string
+
+static CORBA_string
 impl_getTextAfterOffset (PortableServer_Servant _servant,
                         const CORBA_long offset,
                         const
@@ -75,6 +90,7 @@ static CORBA_unsigned_long
 impl_getCharacterAtOffset (PortableServer_Servant _servant,
                           const CORBA_long offset,
                           CORBA_Environment * ev);
+
 static CORBA_string
 impl_getTextBeforeOffset (PortableServer_Servant _servant,
                          const CORBA_long offset,
@@ -83,15 +99,18 @@ impl_getTextBeforeOffset (PortableServer_Servant _servant,
                          type, CORBA_long * startOffset,
                          CORBA_long * endOffset,
                          CORBA_Environment * ev);
+
 static CORBA_long
 impl__get_caretOffset (PortableServer_Servant _servant,
                     CORBA_Environment * ev);
+
 static CORBA_string
 impl_getAttributes (PortableServer_Servant _servant,
                       const CORBA_long offset,
                       CORBA_long * startOffset,
                       CORBA_long * endOffset,
                       CORBA_Environment * ev);
+
 static void 
 impl_getCharacterExtents (PortableServer_Servant _servant,
                          const CORBA_long offset, CORBA_long * x,
@@ -99,48 +118,52 @@ impl_getCharacterExtents (PortableServer_Servant _servant,
                          CORBA_long * height,
                          const CORBA_short coordType,
                          CORBA_Environment * ev);
+
 static CORBA_long
 impl__get_characterCount (PortableServer_Servant _servant,
                        CORBA_Environment * ev);
+
 static CORBA_long
 impl_getOffsetAtPoint (PortableServer_Servant _servant,
                       const CORBA_long x, const CORBA_long y,
                       const CORBA_short coordType,
                       CORBA_Environment * ev);
+
 static CORBA_long
 impl_getNSelections (PortableServer_Servant _servant,
                     CORBA_Environment * ev);
+
 static void 
 impl_getSelection (PortableServer_Servant _servant,
                   const CORBA_long selectionNum,
                   CORBA_long * startOffset, CORBA_long * endOffset,
                   CORBA_Environment * ev);
+
 static CORBA_boolean
 impl_addSelection (PortableServer_Servant _servant,
                   const CORBA_long startOffset,
                   const CORBA_long endOffset,
                   CORBA_Environment * ev);
+
 static CORBA_boolean
 impl_removeSelection (PortableServer_Servant _servant,
                      const CORBA_long selectionNum,
                      CORBA_Environment * ev);
+
 static CORBA_boolean
 impl_setSelection (PortableServer_Servant _servant,
                   const CORBA_long selectionNum,
                   const CORBA_long startOffset,
                   const CORBA_long endOffset,
                   CORBA_Environment * ev);
+
 static CORBA_boolean
 impl_setCaretOffset (PortableServer_Servant _servant,
                     const CORBA_long value,
-                    CORBA_Environment * ev);
-  
-
-static GObjectClass *parent_class;
+                    CORBA_Environment * ev); 
 
 GType
-text_get_type (void)
+accessibility_text_get_type (void)
 {
   static GType type = 0;
 
@@ -149,13 +172,13 @@ text_get_type (void)
       sizeof (TextClass),
       (GBaseInitFunc) NULL,
       (GBaseFinalizeFunc) NULL,
-      (GClassInitFunc) text_class_init,
+      (GClassInitFunc) accessibility_text_class_init,
       (GClassFinalizeFunc) NULL,
       NULL, /* class data */
       sizeof (Text),
       0, /* n preallocs */
-      (GInstanceInitFunc) text_init,
-                        NULL /* value table */
+      (GInstanceInitFunc) accessibility_text_init,
+      NULL /* value table */
     };
 
     /*
@@ -164,7 +187,7 @@ text_get_type (void)
      * use bonobo_type_unique.
      */
     type = bonobo_type_unique (
-                              BONOBO_OBJECT_TYPE,
+                              PARENT_TYPE,
                               POA_Accessibility_Text__init,
                               NULL,
                               G_STRUCT_OFFSET (TextClass, epv),
@@ -176,14 +199,13 @@ text_get_type (void)
 }
 
 static void
-text_class_init (TextClass *klass)
+accessibility_text_class_init (TextClass *klass)
 {
   GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Text__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = text_finalize;
+  text_parent_class = g_type_class_peek_parent (klass);
 
+  object_class->finalize = accessibility_text_object_finalize;
 
   /* Initialize epv table */
 
@@ -206,24 +228,24 @@ text_class_init (TextClass *klass)
 }
 
 static void
-text_init (Text *text)
+accessibility_text_init (Text *text)
 {
 }
 
 static void
-text_finalize (GObject *obj)
+accessibility_text_object_finalize (GObject *obj)
 {
   Text *text = TEXT (obj);
   g_object_unref (text->atko);
   text->atko = NULL;
-  parent_class->finalize (obj);
+  text_parent_class->finalize (obj);
 }
 
 Text *
 text_interface_new (AtkObject *obj)
 {
   Text *new_text = 
-    TEXT(g_object_new (TEXT_TYPE, NULL));
+    TEXT (g_object_new (accessibility_text_get_type (), NULL));
   new_text->atko = obj;
   g_object_ref (obj);
   return new_text;
@@ -239,7 +261,7 @@ impl_getText (PortableServer_Servant _servant,
 {
   Text *text;
   gchar *txt;
-  CORBA_char *rv;
+  CORBA_string rv;
   BonoboObject *obj;
   
   obj = (bonobo_object_from_servant (_servant));
@@ -456,13 +478,16 @@ impl__get_characterCount (PortableServer_Servant _servant,
 {
   Text *text;
   BonoboObject *obj;
+  CORBA_long retval;
 
   obj = (bonobo_object_from_servant (_servant));
   g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)0);
   text = TEXT (obj);
 
-  return (CORBA_long)
+  retval = (CORBA_long)
     atk_text_get_character_count (ATK_TEXT(text->atko));
+
+  return retval;
 }
 
 
index 53f4817..4c79eec 100644 (file)
@@ -30,7 +30,7 @@ extern "C" {
 #include <libspi/Accessibility.h>
 #include "accessible.h"
 
-#define TEXT_TYPE        (text_get_type ())
+#define TEXT_TYPE        (accessibility_text_get_type ())
 #define TEXT(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEXT_TYPE, Text))
 #define TEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), TEXT_TYPE, TextClass))
 #define IS_TEXT(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEXT_TYPE))
@@ -50,7 +50,7 @@ struct _TextClass {
 };
 
 GType
-text_get_type   (void);
+accessibility_text_get_type   (void);
 
 Text *
 text_interface_new       (AtkObject *obj);
index 208cab5..14622fd 100644 (file)
@@ -60,6 +60,8 @@ static ListenerClass *registry_parent_class;
 
 typedef enum {
   ETYPE_FOCUS,
+  ETYPE_OBJECT,
+  ETYPE_PROPERTY,
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
   ETYPE_LAST_DEFINED
@@ -122,7 +124,7 @@ impl_accessibility_registry_register_application (PortableServer_Servant servant
   fprintf (stderr, "registering app %p\n", application);
 #endif
   registry->desktop->applications = g_list_append (registry->desktop->applications,
-                                                   CORBA_Object_duplicate (application, ev));
+                                                   bonobo_object_dup_ref (application, ev));
 
   /* TODO: create unique string here (with libuuid call ?) and hash ? */
   Accessibility_Application__set_id (application, _get_unique_id(), ev);
@@ -157,7 +159,7 @@ register_with_toolkits (Registry *registry_bonobo_object, EventTypeStruct *etype
   Accessibility_Desktop desktop;
   Accessibility_Application app;
   Accessibility_Registry registry;
-  registry  = bonobo_object_corba_objref (bonobo_object (registry_bonobo_object));
+  registry  = BONOBO_OBJREF (registry_bonobo_object);
 
   /* for each app in each desktop, call ...Application_registerToolkitEventListener */
 
@@ -172,11 +174,11 @@ register_with_toolkits (Registry *registry_bonobo_object, EventTypeStruct *etype
           app = (Accessibility_Application) Accessibility_Desktop_getChildAtIndex (desktop,
                                                                                    j,
                                                                                    ev);
-          /* TODO: should we be ref-ing the registry object before each call ? */
-          Accessibility_Application_registerToolkitEventListener (app,
-                                                                  registry,
-                                                                  CORBA_string_dup (etype->event_name),
-                                                                  ev);
+         Accessibility_Application_registerToolkitEventListener (app,
+                                                                 registry,
+                                                                 CORBA_string_dup (etype->event_name),
+                                                                 
+                                                                 ev);
         }
     }
 }
@@ -200,6 +202,10 @@ parse_event_type (EventTypeStruct *etype, char *event_name)
     {
       etype->type_cat = ETYPE_FOCUS;
     }
+  else if (!g_ascii_strncasecmp (event_name, "object:", 7))
+    {
+      etype->type_cat = ETYPE_OBJECT;
+    }
   else if (!g_ascii_strncasecmp (event_name, "window:", 7))
     {
       etype->type_cat = ETYPE_WINDOW;
@@ -296,6 +302,7 @@ impl_accessibility_registry_register_global_event_listener (
   Registry *registry = REGISTRY (bonobo_object_from_servant (servant));
   ListenerStruct *ls = g_malloc (sizeof (ListenerStruct));
   EventTypeStruct etype;
+  gboolean is_toolkit_specific = TRUE;
 
   fprintf(stderr, "registering for events of type %s\n", event_name);
 
@@ -307,9 +314,11 @@ impl_accessibility_registry_register_global_event_listener (
   switch (etype.type_cat)
     {
     case (ETYPE_FOCUS) :
+    case (ETYPE_OBJECT) :
+    case (ETYPE_PROPERTY) :
       ls->listener = CORBA_Object_duplicate (listener, ev);
-      registry->focus_listeners =
-        g_list_append (registry->focus_listeners, ls);
+      registry->object_listeners =
+        g_list_append (registry->object_listeners, ls);
       break;
     case (ETYPE_WINDOW) :
       /* Support for Window Manager Events is not yet implemented */
@@ -335,7 +344,7 @@ impl_accessibility_registry_deregister_global_event_listener_all (
                                                     CORBA_Environment      *ev)
 {
   Registry *registry = REGISTRY (bonobo_object_from_servant (servant));
-  GList *list = g_list_find_custom (registry->focus_listeners, listener, compare_corba_objects);
+  GList *list = g_list_find_custom (registry->object_listeners, listener, compare_corba_objects);
 
   /*
    * TODO : de-register with toolkit if the last instance of a listener
@@ -345,8 +354,8 @@ impl_accessibility_registry_deregister_global_event_listener_all (
   while (list)
     {
       fprintf (stderr, "deregistering listener\n");
-      registry->focus_listeners = g_list_delete_link (registry->focus_listeners, list);
-      list = g_list_find_custom (registry->focus_listeners, listener, compare_corba_objects);
+      registry->object_listeners = g_list_delete_link (registry->object_listeners, list);
+      list = g_list_find_custom (registry->object_listeners, listener, compare_corba_objects);
     }
   list = g_list_find_custom (registry->toolkit_listeners, listener, compare_corba_objects);
   while (list)
@@ -376,8 +385,10 @@ impl_accessibility_registry_deregister_global_event_listener (
   parse_event_type (&etype, event_name);
   switch (etype.type_cat)
     {
+    case (ETYPE_OBJECT) :
+    case (ETYPE_PROPERTY) :
     case (ETYPE_FOCUS) :
-      listeners = &registry->focus_listeners;
+      listeners = &registry->object_listeners;
       break;
     case (ETYPE_WINDOW) :
       /* Support for Window Manager Events is not yet implemented */
@@ -438,8 +449,7 @@ impl_accessibility_registry_get_desktop (PortableServer_Servant servant,
   if (n == 0)
     {
       return (Accessibility_Desktop)
-        CORBA_Object_duplicate (
-             bonobo_object_corba_objref (bonobo_object (registry->desktop)), ev);
+        CORBA_Object_duplicate (BONOBO_OBJREF (registry->desktop), ev);
     }
   else
     {
@@ -470,9 +480,7 @@ impl_accessibility_registry_get_device_event_controller (PortableServer_Servant
   Registry *registry = REGISTRY (bonobo_object_from_servant (servant));
   if (!registry->device_event_controller)
     registry->device_event_controller = g_object_new (DEVICE_EVENT_CONTROLLER_TYPE, NULL);
-  return CORBA_Object_duplicate (
-         bonobo_object_corba_objref (
-                 bonobo_object (registry->device_event_controller)), ev);
+  return CORBA_Object_duplicate (BONOBO_OBJREF (registry->device_event_controller), ev);
 }
 
 static void
@@ -487,19 +495,21 @@ impl_registry_notify_event (PortableServer_Servant servant,
 
   switch (etype.type_cat)
     {
+    case (ETYPE_OBJECT) :
+    case (ETYPE_PROPERTY) :
     case (ETYPE_FOCUS) :
-      _registry_notify_listeners (registry->focus_listeners, e, ev);
+      _registry_notify_listeners (registry->object_listeners, e, ev); 
       break;
     case (ETYPE_WINDOW) :
       _registry_notify_listeners (registry->window_listeners, e, ev);
       break;
     case (ETYPE_TOOLKIT) :
-      _registry_notify_listeners (registry->toolkit_listeners, e, ev);
+      _registry_notify_listeners (registry->toolkit_listeners, e, ev); 
       break;
     default:
       break;
     }
- Accessibility_Accessible_unref (e->source, ev);
+  /* Accessibility_Accessible_unref (e->source, ev);*/ /* This should be here! */
 }
 
 static long
@@ -526,7 +536,7 @@ _registry_notify_listeners ( GList *listeners,
   for (n=0; n<len; ++n)
     {
       ls =  (ListenerStruct *) g_list_nth_data (listeners, n);
-#ifdef SPI_DEBUG
+#ifdef SPI_LISTENER_DEBUG
       fprintf(stderr, "event hashes: %lx %lx %lx\n", ls->event_type_hash, etype.hash, minor_hash);
       fprintf(stderr, "event name: %s\n", etype.event_name);
 #endif
@@ -534,8 +544,9 @@ _registry_notify_listeners ( GList *listeners,
         {
 #ifdef SPI_DEBUG
           fprintf(stderr, "notifying listener #%d\n", n);
-          fprintf(stderr, "event name %s\n", Accessibility_Accessible__get_name(e->source, ev));
+          fprintf(stderr, "event source name %s\n", Accessibility_Accessible__get_name(e->source, ev));
 #endif
+         e->source = CORBA_Object_duplicate (e->source, ev);
           Accessibility_Accessible_ref ( e->source, ev);
           Accessibility_EventListener_notifyEvent ((Accessibility_EventListener) ls->listener,
                                                    e,
@@ -585,7 +596,7 @@ registry_class_init (RegistryClass *klass)
 static void
 registry_init (Registry *registry)
 {
-  registry->focus_listeners = NULL;
+  registry->object_listeners = NULL;
   registry->window_listeners = NULL;
   registry->toolkit_listeners = NULL;
   registry->applications = NULL;
index 7622fe2..ca5a2fe 100644 (file)
@@ -41,7 +41,7 @@ extern "C" {
 
 typedef struct {
   Listener parent;
-  GList *focus_listeners;
+  GList *object_listeners;
   GList *window_listeners;
   GList *toolkit_listeners;
   GList *applications;
index 5a57be6..b4a555e 100644 (file)
--- a/test/at.c
+++ b/test/at.c
@@ -101,7 +101,6 @@ main(int argc, char **argv)
         check_ev (&ev, "register:button_press");
         fprintf (stderr, "AT callback registered.\n");
 
-
             n_desktops = Accessibility_Registry_getDesktopCount (registry, &ev);
 
             for (i=0; i<n_desktops; ++i)
index c06b527..749bcf1 100644 (file)
@@ -28,6 +28,7 @@
 static void report_focus_event (void *fp);
 static void report_button_press (void *fp);
 static boolean report_key_event (void *fp);
+static void check_property_change (void *fp);
 static void get_environment_vars (void);
 
 static int _festival_init ();
@@ -47,6 +48,7 @@ main(int argc, char **argv)
   Accessible *desktop;
   Accessible *application;
   AccessibleEventListener *focus_listener;
+  AccessibleEventListener *property_listener;
   AccessibleEventListener *button_listener;
   KeystrokeListener *key_listener;
 
@@ -60,11 +62,11 @@ main(int argc, char **argv)
   SPI_init();
 
   focus_listener = createEventListener (report_focus_event);
+  property_listener = createEventListener (check_property_change); 
   button_listener = createEventListener (report_button_press);
-
   registerGlobalEventListener (focus_listener, "focus:");
+  registerGlobalEventListener (property_listener, "object:property-change:accessible-selection"); 
   registerGlobalEventListener (button_listener, "Gtk:GtkWidget:button-press-event");
-
   n_desktops = getDesktopCount ();
 
   for (i=0; i<n_desktops; ++i)
@@ -76,6 +78,7 @@ main(int argc, char **argv)
         {
           application = Accessible_getChildAtIndex (desktop, j);
           fprintf (stderr, "app %d name: %s\n", j, Accessible_getName (application));
+         Accessible_unref (application);
         }
     }
 
@@ -106,25 +109,23 @@ get_environment_vars()
 }
 
 void
-report_focus_event (void *p)
+report_focussed_accessible (Accessible *obj, boolean shutup_previous_speech)
 {
-  AccessibleEvent *ev = (AccessibleEvent *) p;
-  fprintf (stderr, "%s event from %s\n", ev->type,
-           Accessible_getName (&ev->source));
-  
   if (use_festival)
     {
     if (festival_chatty)           
       {
-        _festival_say (Accessible_getRole (&ev->source), "voice_don_diphone", TRUE);
+        _festival_say (Accessible_getRole (obj), "voice_don_diphone", shutup_previous_speech);
       }
-      _festival_say (Accessible_getName (&ev->source), "voice_kal_diphone", festival_chatty==FALSE);
+      fprintf (stderr, "getting Name\n");
+      _festival_say (Accessible_getName (obj), "voice_kal_diphone",
+                    shutup_previous_speech || festival_chatty);
     }
   
-  if (Accessible_isComponent (&ev->source))
+  if (Accessible_isComponent (obj))
     {
       long x, y, width, height;
-      AccessibleComponent *component = Accessible_getComponent (&ev->source);
+      AccessibleComponent *component = Accessible_getComponent (obj);
       AccessibleComponent_getExtents (component, &x, &y, &width, &height,
                                       COORD_TYPE_SCREEN);
       fprintf (stderr, "Bounding box: (%ld, %ld) ; (%ld, %ld)\n",
@@ -133,20 +134,31 @@ report_focus_event (void *p)
              magnifier_set_roi (x, y, width, height);        
       }
     }
-  if (Accessible_isText(&ev->source))
-    /* if this is a text object, speak the first sentence. */
+  /* if this is a text object, speak the first sentence. */
+  if (Accessible_isText(obj))
   {
-     AccessibleText *text_interface = Accessible_getText (&ev->source);
+     AccessibleText *text_interface;
      long start_offset, end_offset;
-     char *first_sentence = "";
+     char *first_sentence = "empty";
+     text_interface = Accessible_getText (obj);
+     fprintf (stderr, "isText...%p %p\n", text_interface, (void *)*text_interface);
      first_sentence = AccessibleText_getTextAtOffset (
-            text_interface, (long) 0, TEXT_BOUNDARY_WORD_END,
-            &start_offset, &end_offset); 
-     _festival_say(first_sentence, "voice_don_diphone", festival_chatty==FALSE);
+              text_interface, (long) 0, TEXT_BOUNDARY_SENTENCE_START, &start_offset, &end_offset);
+     if (first_sentence) _festival_say(first_sentence, "voice_don_diphone", FALSE);
+     fprintf (stderr, "done reporting on focussed object\n");
   }
 }
 
 void
+report_focus_event (void *p)
+{
+  AccessibleEvent *ev = (AccessibleEvent *) p;
+  fprintf (stderr, "%s event from %s\n", ev->type,
+           Accessible_getName (&ev->source));
+  report_focussed_accessible (&ev->source, TRUE);
+}
+
+void
 report_button_press (void *p)
 {
   AccessibleEvent *ev = (AccessibleEvent *) p;
@@ -154,6 +166,30 @@ report_button_press (void *p)
            Accessible_getName (&ev->source));
 }
 
+
+void
+check_property_change (void *p)
+{
+  AccessibleEvent *ev = (AccessibleEvent *) p;
+  AccessibleSelection *selection = Accessible_getSelection (&ev->source);
+  int n_selections;
+  int i;
+  if (selection)
+  {
+    n_selections = (int) AccessibleSelection_getNSelectedChildren (selection);
+    fprintf (stderr, "(Property) %s event from %s, %d selected children\n", ev->type,
+           Accessible_getName (&ev->source), n_selections);
+  /* for now, speak entire selection set */
+    for (i=0; i<n_selections; ++i)
+    {
+         Accessible *obj = AccessibleSelection_getSelectedChild (selection, (long) i);
+         g_return_if_fail (obj);
+          fprintf (stderr, "Child %d, name=%s\n", i, Accessible_getName (obj));
+         report_focussed_accessible (obj, i==0);
+    }
+  }
+}
+
 static boolean
 report_key_event (void *p)
 {