2001-12-07 Michael Meeks <michael@ximian.com>
authormichael <michael@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 7 Dec 2001 16:43:33 +0000 (16:43 +0000)
committermichael <michael@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 7 Dec 2001 16:43:33 +0000 (16:43 +0000)
* libspi/component.c
(impl_accessibility_component_get_extents): make it match
it's sig.

* libspi/registry.c (_registry_notify_listeners):
re-remove X headers & reconcile conflicts.
(spi_listener_struct_free): bad conflict resolve.
(impl_accessibility_registry_register_application):
more bad merging fixed.
(impl_accessibility_registry_deregister_application): ditto.
(spi_registry_new): ditto.
(spi_registry_init): don't have an applications field.

[ merge fixups2 branch to here ]

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

80 files changed:
cspi/bonobo/cspi-bonobo-listener.c
cspi/bonobo/cspi-bonobo-listener.h
cspi/spi-listener-impl.c
cspi/spi-listener-impl.h
cspi/spi-listener.h
cspi/spi-private.h
cspi/spi-roletypes.h
cspi/spi-util.c
cspi/spi-util.h [deleted file]
cspi/spi.h
cspi/spi_accessible.c
cspi/spi_component.c
cspi/spi_editabletext.c
cspi/spi_event.c
cspi/spi_main.c
cspi/spi_registry.c
cspi/spi_selection.c
docs/reference/cspi/tmpl/spi_event.sgml
docs/reference/cspi/tmpl/spi_image.sgml
docs/reference/cspi/tmpl/spi_main.sgml
docs/reference/cspi/tmpl/spi_registry.sgml
idl/Accessibility_Accessible.idl
idl/Accessibility_Event.idl
idl/Accessible.idl
idl/Event.idl
libspi/Makefile.am
libspi/accessible.c
libspi/accessible.h
libspi/accessibleeventlistener.c
libspi/accessibleeventlistener.h
libspi/action.c
libspi/action.h
libspi/application.c
libspi/application.h
libspi/base.c
libspi/base.h
libspi/component.c
libspi/component.h
libspi/desktop.c
libspi/desktop.h
libspi/deviceeventcontroller.h
libspi/editabletext.c
libspi/editabletext.h
libspi/eventlistener.c
libspi/eventlistener.h
libspi/hyperlink.c
libspi/hyperlink.h
libspi/hypertext.c
libspi/hypertext.h
libspi/image.c
libspi/image.h
libspi/keystrokelistener.c
libspi/keystrokelistener.h
libspi/libspi.h
libspi/listener.c
libspi/listener.h
libspi/registry.c
libspi/registry.h
libspi/relation.c
libspi/relation.h
libspi/selection.c
libspi/selection.h
libspi/table.c
libspi/table.h
libspi/text.c
libspi/text.h
libspi/value.c
libspi/value.h
registryd/desktop.c
registryd/desktop.h
registryd/deviceeventcontroller.h
registryd/registry-main.c
registryd/registry.c
registryd/registry.h
registryd/registryd.c
test/Makefile.am
test/accessx-gui.c
test/keysynth-demo.c
test/simple-at.c
test/test-simple.c [new file with mode: 0644]

index e05e855..d4bd31b 100644 (file)
@@ -1,6 +1,59 @@
 #include <cspi/spi-private.h>
 #include <cspi/spi-listener-impl.h>
 
+typedef struct
+{
+  union
+    {
+      AccessibleEventListenerCB     event;
+      AccessibleKeystrokeListenerCB key_event;
+      gpointer                      method;
+    } cb;
+  gpointer user_data;
+} EventHandler;
+
+GObjectClass *event_parent_class;
+GObjectClass *keystroke_parent_class;
+
+/*
+ * Misc. helpers.
+ */
+
+static EventHandler *
+event_handler_new (gpointer method, gpointer user_data)
+{
+  EventHandler *eh = g_new0 (EventHandler, 1);
+
+  eh->cb.method = method;
+  eh->user_data = user_data;
+
+  return eh;
+}
+
+static void
+event_handler_free (EventHandler *handler)
+{
+  g_free (handler);
+}
+
+static GList *
+event_list_remove_by_callback (GList *list, gpointer callback)
+{
+  GList *l, *next;
+       
+  for (l = list; l; l = next)
+    {
+      EventHandler *eh = l->data;
+      next = l->next;
+      
+      list = g_list_delete_link (list, l);
+      
+      event_handler_free (eh);
+    }
+
+  return list;
+}
+
 /*
  * Standard event dispatcher
  */
@@ -12,21 +65,23 @@ static void
 cspi_event (SpiEventListener    *listener,
            Accessibility_Event *event)
 {
-  GSList *l;
+  GList *l;
   CSpiEventListener *clistener = (CSpiEventListener *) listener;
   AccessibleEvent aevent;
 
   aevent.type    = event->type;
-  aevent.source  = cspi_object_add (event->source);
+  aevent.source  = cspi_object_add_check (bonobo_object_dup_ref (event->source, cspi_ev ()));
   aevent.detail1 = event->detail1;
   aevent.detail2 = event->detail2;
 
+  /* FIXME: re-enterancy hazard on this list */
   for (l = clistener->callbacks; l; l = l->next)
     {
-      AccessibleEventListenerCB cb = l->data;
-      cb (&aevent);
+      EventHandler *eh = l->data;
+
+      eh->cb.event (&aevent, eh->user_data);
     }
-  
+
   cspi_object_unref (aevent.source);
 }
 
@@ -36,8 +91,29 @@ cspi_event_listener_instance_init (CSpiEventListener *listener)
 }
 
 static void
+cspi_event_listener_finalize (GObject *object)
+{
+  CSpiEventListener *listener = (CSpiEventListener *) object;
+  GList *l;
+  
+  for (l = listener->callbacks; l; l = l->next)
+    {
+      event_handler_free (l->data);
+    }
+  
+  g_list_free (listener->callbacks);
+
+  event_parent_class->finalize (object);
+}
+
+static void
 cspi_event_listener_class_init (CSpiEventListenerClass *klass)
 {
+  GObjectClass *object_class = (GObjectClass *) klass;
+
+  event_parent_class = g_type_class_peek_parent (klass);
+  object_class->finalize = cspi_event_listener_finalize;
+
   klass->event = cspi_event;
 }
 
@@ -49,18 +125,20 @@ cspi_event_listener_new (void)
 
 void
 cspi_event_listener_add_callback (CSpiEventListener        *listener,
-                                 AccessibleEventListenerCB callback)
+                                 AccessibleEventListenerCB callback,
+                                 void                     *user_data)
 {
-  g_return_if_fail (IS_SPI_ACCESSIBLE_EVENT_SPI_LISTENER (listener));
-  listener->callbacks = g_slist_prepend (listener->callbacks, callback);
+  g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener));
+  listener->callbacks = g_list_prepend (listener->callbacks,
+                                       event_handler_new (callback, user_data));
 }
 
 void
 cspi_event_listener_remove_callback (CSpiEventListener        *listener,
                                     AccessibleEventListenerCB callback)
 {
-  g_return_if_fail (IS_CSPI_KEYSTROKE_LISTENER (listener));
-  listener->callbacks = g_slist_remove (listener->callbacks, callback);
+  g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener));
+  listener->callbacks = event_list_remove_by_callback (listener->callbacks, callback);
 }
 
 /*
@@ -71,11 +149,24 @@ static gboolean
 cspi_key_event (SpiKeystrokeListener          *listener,
                const Accessibility_KeyStroke *keystroke)
 {
-  GSList *l;
+  GList *l;
   CSpiKeystrokeListener *clistener = (CSpiKeystrokeListener *) listener;
   AccessibleKeystroke akeystroke;
   gboolean handled = FALSE;
 
+#ifdef SPI_KEYEVENT_DEBUG
+  fprintf (stderr, "%s%c",
+          (keystroke->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
+          ((keystroke->modifiers & SPI_KEYMASK_SHIFT)^(keystroke->modifiers & SPI_KEYMASK_SHIFTLOCK))?
+          (char) toupper((int) keystroke->keyID) : (char) tolower((int) keystroke->keyID));
+  
+  fprintf (stderr, "Key:\tsym %ld\n\tmods %x\n\tcode %d\n\ttime %ld\n",
+          (long) keystroke->keyID,
+          (unsigned int) keystroke->modifiers,
+          (int) keystroke->keycode,
+          (long int) keystroke->timestamp);
+#endif
+
   switch (keystroke->type)
     {
       case Accessibility_KEY_PRESSED:
@@ -93,10 +184,12 @@ cspi_key_event (SpiKeystrokeListener          *listener,
   akeystroke.timestamp = keystroke->timestamp;
   akeystroke.modifiers = keystroke->modifiers;
 
+  /* FIXME: re-enterancy hazard on this list */
   for (l = clistener->callbacks; l; l = l->next)
     {
-      AccessibleKeystrokeListenerCB cb = l->data;
-      if ((handled = cb (&akeystroke)))
+      EventHandler *eh = l->data;
+
+      if ((handled = eh->cb.key_event (&akeystroke, eh->user_data)))
         {
          break;
        }
@@ -110,9 +203,31 @@ cspi_keystroke_listener_init (CSpiKeystrokeListener *listener)
 {
 }
 
+
+static void
+cspi_keystroke_listener_finalize (GObject *object)
+{
+  CSpiKeystrokeListener *listener = (CSpiKeystrokeListener *) object;
+  GList *l;
+  
+  for (l = listener->callbacks; l; l = l->next)
+    {
+      event_handler_free (l->data);
+    }
+  
+  g_list_free (listener->callbacks);
+
+  keystroke_parent_class->finalize (object);
+}
+
 static void
 cspi_keystroke_listener_class_init (CSpiKeystrokeListenerClass *klass)
 {
+  GObjectClass *object_class = (GObjectClass *) klass;
+
+  keystroke_parent_class = g_type_class_peek_parent (klass);
+  object_class->finalize = cspi_keystroke_listener_finalize;
+
   klass->key_event = cspi_key_event;
 }
 
@@ -128,16 +243,18 @@ cspi_keystroke_listener_new (void)
 
 void
 cspi_keystroke_listener_add_callback (CSpiKeystrokeListener        *listener,
-                                     AccessibleKeystrokeListenerCB callback)
+                                     AccessibleKeystrokeListenerCB callback,
+                                     void                         *user_data)
 {
-  g_return_if_fail (IS_CSPI_KEYSTROKE_LISTENER (listener));
-  listener->callbacks = g_slist_prepend (listener->callbacks, callback);
+  g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
+  listener->callbacks = g_list_prepend (listener->callbacks,
+                                       event_handler_new (callback, user_data));
 }
 
 void
 cspi_keystroke_listener_remove_callback (CSpiKeystrokeListener        *listener,
                                         AccessibleKeystrokeListenerCB callback)
 {
-  g_return_if_fail (IS_CSPI_KEYSTROKE_LISTENER (listener));
-  listener->callbacks = g_slist_remove (listener->callbacks, callback);
+  g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
+  listener->callbacks = event_list_remove_by_callback (listener->callbacks, callback);
 }
index 9316ac6..a533879 100644 (file)
@@ -1,46 +1,52 @@
 #ifndef __SPI_LISTENER_IMPL_H__
 #define __SPI_LISTENER_IMP_H__
 
-#include <libspi/Accessibility.h>
-#include <libspi/accessibleeventlistener.h>
+#include <libspi/eventlistener.h>
 #include <libspi/keystrokelistener.h>
 #include <cspi/spi-impl.h>
 #include <cspi/spi-listener.h>
 
 G_BEGIN_DECLS
 
-#define CSPI_KEYSTROKE_LISTENER_TYPE        (cspi_keystroke_listener_get_type ())
-#define CSPI_KEYSTROKE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListener))
-#define CSPI_KEYSTROKE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListenerClass))
-#define IS_CSPI_KEYSTROKE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_KEYSTROKE_LISTENER_TYPE))
-#define IS_CSPI_KEYSTROKE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_KEYSTROKE_LISTENER_TYPE))
+#define CSPI_EVENT_LISTENER_TYPE        (cspi_event_listener_get_type ())
+#define CSPI_EVENT_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_EVENT_LISTENER_TYPE, CSpiEventListener))
+#define CSPI_EVENT_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), CSPI_EVENT_LISTENER_TYPE, CSpiEventListenerClass))
+#define CSPI_IS_EVENT_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_EVENT_LISTENER_TYPE))
+#define CSPI_IS_EVENT_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_EVENT_LISTENER_TYPE))
 
 typedef struct _CSpiEventListener CSpiEventListener;
 struct _CSpiEventListener {
        SpiEventListener parent;
-       GSList          *callbacks;
+       GList           *callbacks;
 };
-
 typedef SpiEventListenerClass CSpiEventListenerClass;
 
 GType              cspi_event_listener_get_type        (void);
 CSpiEventListener *cspi_event_listener_new             (void);
 void               cspi_event_listener_add_callback    (CSpiEventListener        *listener,
-                                                       AccessibleEventListenerCB callback);
+                                                       AccessibleEventListenerCB callback,
+                                                       void                     *user_data);
 void               cspi_event_listener_remove_callback (CSpiEventListener        *listener,
                                                        AccessibleEventListenerCB callback);
 
+#define CSPI_KEYSTROKE_LISTENER_TYPE        (cspi_keystroke_listener_get_type ())
+#define CSPI_KEYSTROKE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListener))
+#define CSPI_KEYSTROKE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListenerClass))
+#define CSPI_IS_KEYSTROKE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_KEYSTROKE_LISTENER_TYPE))
+#define CSPI_IS_KEYSTROKE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_KEYSTROKE_LISTENER_TYPE))
+
 typedef struct _CSpiKeystrokeListener CSpiKeystrokeListener;
 struct _CSpiKeystrokeListener {
        SpiKeystrokeListener parent;
-       GSList              *callbacks;
+       GList               *callbacks;
 };
 typedef SpiKeystrokeListenerClass CSpiKeystrokeListenerClass;
 
 GType                  cspi_keystroke_listener_get_type        (void);
 CSpiKeystrokeListener *cspi_keystroke_listener_new             (void);
 void                   cspi_keystroke_listener_add_callback    (CSpiKeystrokeListener        *listener,
-                                                               AccessibleKeystrokeListenerCB callback);
+                                                               AccessibleKeystrokeListenerCB callback,
+                                                               void                         *user_data);
 void                   cspi_keystroke_listener_remove_callback (CSpiKeystrokeListener        *listener,
                                                                AccessibleKeystrokeListenerCB callback);
 
index e05e855..d4bd31b 100644 (file)
@@ -1,6 +1,59 @@
 #include <cspi/spi-private.h>
 #include <cspi/spi-listener-impl.h>
 
+typedef struct
+{
+  union
+    {
+      AccessibleEventListenerCB     event;
+      AccessibleKeystrokeListenerCB key_event;
+      gpointer                      method;
+    } cb;
+  gpointer user_data;
+} EventHandler;
+
+GObjectClass *event_parent_class;
+GObjectClass *keystroke_parent_class;
+
+/*
+ * Misc. helpers.
+ */
+
+static EventHandler *
+event_handler_new (gpointer method, gpointer user_data)
+{
+  EventHandler *eh = g_new0 (EventHandler, 1);
+
+  eh->cb.method = method;
+  eh->user_data = user_data;
+
+  return eh;
+}
+
+static void
+event_handler_free (EventHandler *handler)
+{
+  g_free (handler);
+}
+
+static GList *
+event_list_remove_by_callback (GList *list, gpointer callback)
+{
+  GList *l, *next;
+       
+  for (l = list; l; l = next)
+    {
+      EventHandler *eh = l->data;
+      next = l->next;
+      
+      list = g_list_delete_link (list, l);
+      
+      event_handler_free (eh);
+    }
+
+  return list;
+}
+
 /*
  * Standard event dispatcher
  */
@@ -12,21 +65,23 @@ static void
 cspi_event (SpiEventListener    *listener,
            Accessibility_Event *event)
 {
-  GSList *l;
+  GList *l;
   CSpiEventListener *clistener = (CSpiEventListener *) listener;
   AccessibleEvent aevent;
 
   aevent.type    = event->type;
-  aevent.source  = cspi_object_add (event->source);
+  aevent.source  = cspi_object_add_check (bonobo_object_dup_ref (event->source, cspi_ev ()));
   aevent.detail1 = event->detail1;
   aevent.detail2 = event->detail2;
 
+  /* FIXME: re-enterancy hazard on this list */
   for (l = clistener->callbacks; l; l = l->next)
     {
-      AccessibleEventListenerCB cb = l->data;
-      cb (&aevent);
+      EventHandler *eh = l->data;
+
+      eh->cb.event (&aevent, eh->user_data);
     }
-  
+
   cspi_object_unref (aevent.source);
 }
 
@@ -36,8 +91,29 @@ cspi_event_listener_instance_init (CSpiEventListener *listener)
 }
 
 static void
+cspi_event_listener_finalize (GObject *object)
+{
+  CSpiEventListener *listener = (CSpiEventListener *) object;
+  GList *l;
+  
+  for (l = listener->callbacks; l; l = l->next)
+    {
+      event_handler_free (l->data);
+    }
+  
+  g_list_free (listener->callbacks);
+
+  event_parent_class->finalize (object);
+}
+
+static void
 cspi_event_listener_class_init (CSpiEventListenerClass *klass)
 {
+  GObjectClass *object_class = (GObjectClass *) klass;
+
+  event_parent_class = g_type_class_peek_parent (klass);
+  object_class->finalize = cspi_event_listener_finalize;
+
   klass->event = cspi_event;
 }
 
@@ -49,18 +125,20 @@ cspi_event_listener_new (void)
 
 void
 cspi_event_listener_add_callback (CSpiEventListener        *listener,
-                                 AccessibleEventListenerCB callback)
+                                 AccessibleEventListenerCB callback,
+                                 void                     *user_data)
 {
-  g_return_if_fail (IS_SPI_ACCESSIBLE_EVENT_SPI_LISTENER (listener));
-  listener->callbacks = g_slist_prepend (listener->callbacks, callback);
+  g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener));
+  listener->callbacks = g_list_prepend (listener->callbacks,
+                                       event_handler_new (callback, user_data));
 }
 
 void
 cspi_event_listener_remove_callback (CSpiEventListener        *listener,
                                     AccessibleEventListenerCB callback)
 {
-  g_return_if_fail (IS_CSPI_KEYSTROKE_LISTENER (listener));
-  listener->callbacks = g_slist_remove (listener->callbacks, callback);
+  g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener));
+  listener->callbacks = event_list_remove_by_callback (listener->callbacks, callback);
 }
 
 /*
@@ -71,11 +149,24 @@ static gboolean
 cspi_key_event (SpiKeystrokeListener          *listener,
                const Accessibility_KeyStroke *keystroke)
 {
-  GSList *l;
+  GList *l;
   CSpiKeystrokeListener *clistener = (CSpiKeystrokeListener *) listener;
   AccessibleKeystroke akeystroke;
   gboolean handled = FALSE;
 
+#ifdef SPI_KEYEVENT_DEBUG
+  fprintf (stderr, "%s%c",
+          (keystroke->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
+          ((keystroke->modifiers & SPI_KEYMASK_SHIFT)^(keystroke->modifiers & SPI_KEYMASK_SHIFTLOCK))?
+          (char) toupper((int) keystroke->keyID) : (char) tolower((int) keystroke->keyID));
+  
+  fprintf (stderr, "Key:\tsym %ld\n\tmods %x\n\tcode %d\n\ttime %ld\n",
+          (long) keystroke->keyID,
+          (unsigned int) keystroke->modifiers,
+          (int) keystroke->keycode,
+          (long int) keystroke->timestamp);
+#endif
+
   switch (keystroke->type)
     {
       case Accessibility_KEY_PRESSED:
@@ -93,10 +184,12 @@ cspi_key_event (SpiKeystrokeListener          *listener,
   akeystroke.timestamp = keystroke->timestamp;
   akeystroke.modifiers = keystroke->modifiers;
 
+  /* FIXME: re-enterancy hazard on this list */
   for (l = clistener->callbacks; l; l = l->next)
     {
-      AccessibleKeystrokeListenerCB cb = l->data;
-      if ((handled = cb (&akeystroke)))
+      EventHandler *eh = l->data;
+
+      if ((handled = eh->cb.key_event (&akeystroke, eh->user_data)))
         {
          break;
        }
@@ -110,9 +203,31 @@ cspi_keystroke_listener_init (CSpiKeystrokeListener *listener)
 {
 }
 
+
+static void
+cspi_keystroke_listener_finalize (GObject *object)
+{
+  CSpiKeystrokeListener *listener = (CSpiKeystrokeListener *) object;
+  GList *l;
+  
+  for (l = listener->callbacks; l; l = l->next)
+    {
+      event_handler_free (l->data);
+    }
+  
+  g_list_free (listener->callbacks);
+
+  keystroke_parent_class->finalize (object);
+}
+
 static void
 cspi_keystroke_listener_class_init (CSpiKeystrokeListenerClass *klass)
 {
+  GObjectClass *object_class = (GObjectClass *) klass;
+
+  keystroke_parent_class = g_type_class_peek_parent (klass);
+  object_class->finalize = cspi_keystroke_listener_finalize;
+
   klass->key_event = cspi_key_event;
 }
 
@@ -128,16 +243,18 @@ cspi_keystroke_listener_new (void)
 
 void
 cspi_keystroke_listener_add_callback (CSpiKeystrokeListener        *listener,
-                                     AccessibleKeystrokeListenerCB callback)
+                                     AccessibleKeystrokeListenerCB callback,
+                                     void                         *user_data)
 {
-  g_return_if_fail (IS_CSPI_KEYSTROKE_LISTENER (listener));
-  listener->callbacks = g_slist_prepend (listener->callbacks, callback);
+  g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
+  listener->callbacks = g_list_prepend (listener->callbacks,
+                                       event_handler_new (callback, user_data));
 }
 
 void
 cspi_keystroke_listener_remove_callback (CSpiKeystrokeListener        *listener,
                                         AccessibleKeystrokeListenerCB callback)
 {
-  g_return_if_fail (IS_CSPI_KEYSTROKE_LISTENER (listener));
-  listener->callbacks = g_slist_remove (listener->callbacks, callback);
+  g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
+  listener->callbacks = event_list_remove_by_callback (listener->callbacks, callback);
 }
index 9316ac6..a533879 100644 (file)
@@ -1,46 +1,52 @@
 #ifndef __SPI_LISTENER_IMPL_H__
 #define __SPI_LISTENER_IMP_H__
 
-#include <libspi/Accessibility.h>
-#include <libspi/accessibleeventlistener.h>
+#include <libspi/eventlistener.h>
 #include <libspi/keystrokelistener.h>
 #include <cspi/spi-impl.h>
 #include <cspi/spi-listener.h>
 
 G_BEGIN_DECLS
 
-#define CSPI_KEYSTROKE_LISTENER_TYPE        (cspi_keystroke_listener_get_type ())
-#define CSPI_KEYSTROKE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListener))
-#define CSPI_KEYSTROKE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListenerClass))
-#define IS_CSPI_KEYSTROKE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_KEYSTROKE_LISTENER_TYPE))
-#define IS_CSPI_KEYSTROKE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_KEYSTROKE_LISTENER_TYPE))
+#define CSPI_EVENT_LISTENER_TYPE        (cspi_event_listener_get_type ())
+#define CSPI_EVENT_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_EVENT_LISTENER_TYPE, CSpiEventListener))
+#define CSPI_EVENT_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), CSPI_EVENT_LISTENER_TYPE, CSpiEventListenerClass))
+#define CSPI_IS_EVENT_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_EVENT_LISTENER_TYPE))
+#define CSPI_IS_EVENT_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_EVENT_LISTENER_TYPE))
 
 typedef struct _CSpiEventListener CSpiEventListener;
 struct _CSpiEventListener {
        SpiEventListener parent;
-       GSList          *callbacks;
+       GList           *callbacks;
 };
-
 typedef SpiEventListenerClass CSpiEventListenerClass;
 
 GType              cspi_event_listener_get_type        (void);
 CSpiEventListener *cspi_event_listener_new             (void);
 void               cspi_event_listener_add_callback    (CSpiEventListener        *listener,
-                                                       AccessibleEventListenerCB callback);
+                                                       AccessibleEventListenerCB callback,
+                                                       void                     *user_data);
 void               cspi_event_listener_remove_callback (CSpiEventListener        *listener,
                                                        AccessibleEventListenerCB callback);
 
+#define CSPI_KEYSTROKE_LISTENER_TYPE        (cspi_keystroke_listener_get_type ())
+#define CSPI_KEYSTROKE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListener))
+#define CSPI_KEYSTROKE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListenerClass))
+#define CSPI_IS_KEYSTROKE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_KEYSTROKE_LISTENER_TYPE))
+#define CSPI_IS_KEYSTROKE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_KEYSTROKE_LISTENER_TYPE))
+
 typedef struct _CSpiKeystrokeListener CSpiKeystrokeListener;
 struct _CSpiKeystrokeListener {
        SpiKeystrokeListener parent;
-       GSList              *callbacks;
+       GList               *callbacks;
 };
 typedef SpiKeystrokeListenerClass CSpiKeystrokeListenerClass;
 
 GType                  cspi_keystroke_listener_get_type        (void);
 CSpiKeystrokeListener *cspi_keystroke_listener_new             (void);
 void                   cspi_keystroke_listener_add_callback    (CSpiKeystrokeListener        *listener,
-                                                               AccessibleKeystrokeListenerCB callback);
+                                                               AccessibleKeystrokeListenerCB callback,
+                                                               void                         *user_data);
 void                   cspi_keystroke_listener_remove_callback (CSpiKeystrokeListener        *listener,
                                                                AccessibleKeystrokeListenerCB callback);
 
index a9677dc..0f9e600 100644 (file)
@@ -9,24 +9,24 @@ G_BEGIN_DECLS
  * Structure used to encapsulate event information
  */
 typedef struct {
-       const char  *type;
-       Accessible  *source;
-       long         detail1;
-       long         detail2;
+  const char  *type;
+  Accessible  *source;
+  long         detail1;
+  long         detail2;
 } AccessibleEvent;
 
 typedef enum {
-       SPI_KEY_PRESSED  = 1<<0,
-       SPI_KEY_RELEASED = 1<<1
+  SPI_KEY_PRESSED  = 1<<0,
+  SPI_KEY_RELEASED = 1<<1
 } AccessibleKeyEventType;
 
 
 typedef struct {
-       long                   keyID;
-       short                  keycode;
-       long                   timestamp;
-       AccessibleKeyEventType type;
-       unsigned short         modifiers;
+  long                   keyID;
+  short                  keycode;
+  long                   timestamp;
+  AccessibleKeyEventType type;
+  unsigned short         modifiers;
 } AccessibleKeystroke;
 
 /*
@@ -38,8 +38,10 @@ typedef struct {
  *
  * SPIBoolean (*AccessibleKeystrokeListenerCB) (AccessibleKeystrokeEvent *Event);
  */
-typedef void    (*AccessibleEventListenerCB)     (AccessibleEvent     *event);
-typedef SPIBoolean (*AccessibleKeystrokeListenerCB) (AccessibleKeystroke *stroke);
+typedef void       (*AccessibleEventListenerCB)     (AccessibleEvent     *event,
+                                                    void                *user_data);
+typedef SPIBoolean (*AccessibleKeystrokeListenerCB) (AccessibleKeystroke *stroke,
+                                                    void                *user_data);
 
 G_END_DECLS
 
index 7f564a0..118171e 100644 (file)
@@ -18,15 +18,18 @@ struct _Accessible {
 
 #define CSPI_OBJREF(a) (((Accessible *)(a))->objref)
 
-CORBA_Environment     *cspi_ev           (void);
-SPIBoolean             cspi_exception    (void);
-Accessibility_Registry cspi_registry     (void);
-Accessible            *cspi_object_add   (CORBA_Object         corba_object);
-void                   cspi_object_ref   (Accessible          *accessible);
-void                   cspi_object_unref (Accessible          *accessible);
-SPIBoolean             cspi_warn_ev      (CORBA_Environment   *ev,
-                                         const char          *error_string);
-void                   cspi_check_ev     (CORBA_Environment   *ev,
-                                         const char          *error_string);
+CORBA_Environment     *cspi_ev               (void);
+SPIBoolean             cspi_exception        (void);
+Accessibility_Registry cspi_registry         (void);
+Accessible            *cspi_object_add       (CORBA_Object         corba_object);
+Accessible            *cspi_object_add_check (CORBA_Object         corba_object);
+void                   cspi_object_ref       (Accessible          *accessible);
+void                   cspi_object_unref     (Accessible          *accessible);
+SPIBoolean             cspi_accessible_is_a  (Accessible          *obj,
+                                             const char          *interface_name);
+SPIBoolean             cspi_warn_ev          (CORBA_Environment   *ev,
+                                             const char          *error_string);
+void                   cspi_check_ev         (CORBA_Environment   *ev,
+                                             const char          *error_string);
 
 #endif /* _SPI_PRIVATE_H_ */
index 28d778e..843064b 100644 (file)
@@ -146,7 +146,7 @@ typedef enum
   SPI_ROLE_LAST_DEFINED
 } AccessibleRole;
 
-char* AccessibleRole_getName (AccessibleRole role);
+const char* AccessibleRole_getName (AccessibleRole role);
 
 G_END_DECLS
 
index 64a52be..23333f8 100644 (file)
@@ -49,13 +49,10 @@ cspi_check_ev (CORBA_Environment *ev, const char *error_string)
 
       err = bonobo_exception_get_text (ev);
 
-      fprintf (stderr, "AT-SPI error: %s: %s\n",
-              error_string, err);
+      g_warning ("AT-SPI error: %s: %s\n", error_string, err);
 
       g_free (err);
 
       CORBA_exception_free (ev);
-
-      exit (-1);
     }
 }
diff --git a/cspi/spi-util.h b/cspi/spi-util.h
deleted file mode 100644 (file)
index 1154017..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __SPI_UTIL_H
-#define __SPI_UTIL_H
-
-void
-SPI_freeString (char *s);
-
-#endif /* __SPI_UTIL_H */
index 8fb38fb..ebe6119 100644 (file)
@@ -131,20 +131,11 @@ typedef unsigned long AccessibleKeyMaskType;
  *
  */
 
-/**
- * SPI_init:
- *
- * Connects to the accessibility registry and initializes the SPI.
- *
- * Returns: 0 on success, otherwise an integer error code.
- **/
 int
-SPI_init (void);
+SPI_init (SPIBoolean isGNOMEApp);
 
 /**
  * SPI_event_main:
- * @isGNOMEApp: a #SPIBoolean indicating whether the client of the SPI
- *              will use the Gnome event loop or not.
  *
  * Starts/enters the main event loop for the SPI services.
  *
@@ -153,7 +144,7 @@ SPI_init (void);
  *
  **/
 void
-SPI_event_main (SPIBoolean isGNOMEApp);
+SPI_event_main (void);
 
 /**
  * SPI_event_is_ready:
@@ -186,7 +177,6 @@ SPI_nextEvent (SPIBoolean waitForEvent);
  * SPI_exit:
  *
  * Disconnects from the Accessibility Registry and releases resources.
- * Not Yet Implemented.
  *
  **/
 void
@@ -206,7 +196,8 @@ SPI_exit (void);
  *
  **/
 AccessibleEventListener *
-createAccessibleEventListener (AccessibleEventListenerCB callback);
+createAccessibleEventListener (AccessibleEventListenerCB callback,
+                              void                     *user_data);
 
 /**
  * AccessibleEventListener_addCallback:
@@ -219,8 +210,9 @@ createAccessibleEventListener (AccessibleEventListenerCB callback);
  *
  **/
 SPIBoolean
-AccessibleEventListener_addCallback (AccessibleEventListener *listener,
-                                    AccessibleEventListenerCB callback);
+AccessibleEventListener_addCallback (AccessibleEventListener  *listener,
+                                    AccessibleEventListenerCB callback,
+                                    void                     *user_data);
 
 /**
  * AccessibleEventListener_removeCallback:
@@ -233,7 +225,7 @@ AccessibleEventListener_addCallback (AccessibleEventListener *listener,
  *
  **/
 SPIBoolean
-AccessibleEventListener_removeCallback (AccessibleEventListener *listener,
+AccessibleEventListener_removeCallback (AccessibleEventListener  *listener,
                                        AccessibleEventListenerCB callback);
 
 /**
@@ -246,7 +238,8 @@ AccessibleEventListener_removeCallback (AccessibleEventListener *listener,
  *
  **/
 AccessibleKeystrokeListener *
-createAccessibleKeystrokeListener (AccessibleKeystrokeListenerCB callback);
+createAccessibleKeystrokeListener (AccessibleKeystrokeListenerCB callback,
+                                  void                         *user_data);
 
 /**
  * KeystrokeListener_addCallback:
@@ -259,8 +252,9 @@ createAccessibleKeystrokeListener (AccessibleKeystrokeListenerCB callback);
  *
  **/
 SPIBoolean
-AccessibleKeystrokeListener_addCallback (AccessibleKeystrokeListener *listener,
-                                        AccessibleKeystrokeListenerCB callback);
+AccessibleKeystrokeListener_addCallback (AccessibleKeystrokeListener  *listener,
+                                        AccessibleKeystrokeListenerCB callback,
+                                        void                         *user_data);
 
 /**
  * AccessibleKeystrokeListener_removeCallback:
@@ -276,6 +270,8 @@ SPIBoolean
 AccessibleKeystrokeListener_removeCallback (AccessibleKeystrokeListener *listener,
                                            AccessibleKeystrokeListenerCB callback);
 
+void AccessibleKeystrokeListener_unref (AccessibleKeystrokeListener *listener);
+
 /*
  *
  * Global functions serviced by the registry
@@ -538,7 +534,7 @@ Accessible_getRelationSet (Accessible *obj);
  * Returns: a UTF-8 string indicating the UI role of the #Accessible object.
  *
  **/
-char *
+const char *
 Accessible_getRole (Accessible *obj);
 
 /**
@@ -568,6 +564,18 @@ SPIBoolean
 Accessible_isAction (Accessible *obj);
 
 /**
+ * Accessible_isApplication:
+ * @obj: a pointer to the #Accessible instance to query.
+ *
+ * Query whether the specified #Accessible implements #AccessibleApplication.
+ *
+ * Returns: #TRUE if @obj implements the #AccessibleApplication interface,
+ *          #FALSE otherwise.
+ **/
+SPIBoolean
+Accessible_isApplication (Accessible *obj);
+
+/**
  * Accessible_isComponent:
  * @obj: a pointer to the #Accessible instance to query.
  *
@@ -654,10 +662,31 @@ Accessible_isText (Accessible *obj);
 SPIBoolean
 Accessible_isValue (Accessible *obj);
 
+/**
+ * Accessible_getAction:
+ * @obj: a pointer to the #Accessible instance to query.
+ *
+ * Get the #AccessibleAction interface for an #Accessible.
+ *
+ * Returns: a pointer to an #AccessibleAction interface instance, or
+ *          NULL if @obj does not implement #AccessibleAction.
+ **/
 AccessibleAction *
 Accessible_getAction (Accessible *obj);
 
 /**
+ * Accessible_getApplication:
+ * @obj: a pointer to the #Accessible instance to query.
+ *
+ * Get the #AccessibleApplication interface for an #Accessible.
+ *
+ * Returns: a pointer to an #AccessibleApplication interface instance, or
+ *          NULL if @obj does not implement #AccessibleApplication.
+ **/
+AccessibleApplication *
+Accessible_getApplication (Accessible *obj);
+
+/**
  * Accessible_getComponent:
  * @obj: a pointer to the #Accessible instance to query.
  *
@@ -1010,7 +1039,7 @@ AccessibleEditableText_setTextContents (AccessibleEditableText *obj,
 SPIBoolean
 AccessibleEditableText_insertText (AccessibleEditableText *obj,
                                    long int position,
-                                   char *text,
+                                   const char *text,
                                    long int length);
 
 SPIBoolean
@@ -1429,6 +1458,9 @@ SPIBoolean
 AccessibleValue_setCurrentValue (AccessibleValue *obj,
                                  float newValue);
 
+void
+SPI_freeString (char *s);
+
 G_END_DECLS
 
 #endif
index fbd399a..d753ca6 100644 (file)
@@ -1,37 +1,26 @@
 #include <stdlib.h> /* for malloc */
 #include <cspi/spi-private.h>
 
-#define MAX_ROLES 100
-
-static char *role_names [MAX_ROLES] =
+static const char *role_names [] =
 {
-  " ",
-  "accelerator label",
+  "<invalid>",
   "alert",
-  "animation",
-  "arrow",
-  "calendar",
   "canvas",
   "check box",
-  "menu item",
   "color chooser",
   "column header",
   "combo box",
-  "date editor",
   "desktop icon",
   "desktop frame",
-  "dial",
   "dialog",
   "directory pane",
-  "drawing area",
   "file chooser",
   "filler",
-  "font chooser",
+  "focus traversable",
   "frame",
   "glass pane",
   "HTML container",
   "icon",
-  "image",
   "internal frame",
   "label",
   "layered pane",
@@ -49,7 +38,6 @@ static char *role_names [MAX_ROLES] =
   "progress bar",
   "pushbutton",
   "radiobutton",
-  "radio menu item",
   "root pane",
   "row header",
   "scrollbar",
@@ -57,23 +45,38 @@ static char *role_names [MAX_ROLES] =
   "separator",
   "slider",
   "split pane",
-  "spin button",
-  "status bar",
   "table",
   "table cell",
   "table column header",
   "table row header",
-  "tearoff menu item",
   "text",
   "toggle button",
   "toolbar",
   "tooltip",
   "tree",
-  " ",
+  "<unknown>",
   "viewport",
   "window",
+
+  /* These have no equivalent AccessibleRole enum values */
+  "accelerator label",
+  "animation",
+  "arrow",
+  "calendar",
+  "menu item",
+  "date editor",
+  "dial",
+  "drawing area",
+  "font chooser",
+  "image",
+  "radio menu item",
+  "tearoff menu item",
+  "spin button",
+  "status bar",
 };
 
+#define MAX_ROLES (sizeof (role_names) / sizeof (char *))
+
 /**
  * AccessibleRole_getName:
  * @role: an #AccessibleRole object to query.
@@ -82,16 +85,21 @@ static char *role_names [MAX_ROLES] =
  *
  * Returns: a localizable string name for an #AccessibleRole enumerated type.
  **/
-char*
+const char *
 AccessibleRole_getName (AccessibleRole role)
 {
+  if (role < MAX_ROLES)
+    {
+      return role_names [(int) role];
+    }
+  else
+    {
+      return "";
+    }
   /*
    * TODO: replace with implementation linked to ATK, which
    *  now supports Role/Name mapping
    */
-       
-  if (role < MAX_ROLES) return role_names [(int) role];
-  else return "";
 }
 
 /**
@@ -215,8 +223,7 @@ Accessible *
 Accessible_getChildAtIndex (Accessible *obj,
                             long int childIndex)
 {
-  Accessible *retval = cspi_object_add (Accessibility_Accessible_getChildAtIndex (CSPI_OBJREF (obj), childIndex, cspi_ev ()));
-  cspi_check_ev (cspi_ev (), "getChildAtIndex");
+  Accessible *retval = cspi_object_add_check (Accessibility_Accessible_getChildAtIndex (CSPI_OBJREF (obj), childIndex, cspi_ev ()));
   return retval;
 }
 
@@ -264,10 +271,12 @@ Accessible_getRelationSet (Accessible *obj)
   
   for (i=0; i<n_relations; ++i)
     {
-      relations[i] = cspi_object_add (relation_set->_buffer[i]);
+      relations[i] = cspi_object_add (CORBA_Object_duplicate (relation_set->_buffer[i], cspi_ev ()));
     }
   relations[i] = CORBA_OBJECT_NIL;
 
+  CORBA_free (relation_set);
+
   return relations;
 }
 
@@ -280,10 +289,10 @@ Accessible_getRelationSet (Accessible *obj)
  * Returns: a UTF-8 string indicating the UI role of the #Accessible object.
  *
  **/
-char *
+const char *
 Accessible_getRole (Accessible *obj)
 {
-  char *retval = AccessibleRole_getName (
+  const char *retval = AccessibleRole_getName (
                  Accessibility_Accessible_getRole (CSPI_OBJREF (obj), cspi_ev ()));
   cspi_check_ev (cspi_ev (), "getRole");
   return retval;
@@ -305,36 +314,6 @@ Accessible_getStateSet (Accessible *obj)
 
 /* Interface query methods */
 
-static SPIBoolean
-cspi_accessible_is_a (Accessible *obj,
-                    const char *interface_name)
-{
-  SPIBoolean        retval;
-  Bonobo_Unknown unknown;
-
-  unknown = Bonobo_Unknown_queryInterface (CSPI_OBJREF (obj),
-                                          interface_name, cspi_ev ());
-
-  if (BONOBO_EX (cspi_ev ()))
-    {
-      g_error ("Exception '%s' checking if is '%s'",
-              bonobo_exception_get_text (cspi_ev ()),
-              interface_name);
-    }
-
-  if (unknown != CORBA_OBJECT_NIL)
-    {
-      retval = TRUE;
-      bonobo_object_release_unref (unknown, NULL);
-    }
-  else
-    {
-      retval= FALSE;
-    }
-
-  return retval;
-}
-
 /**
  * Accessible_isAction:
  * @obj: a pointer to the #Accessible instance to query.
@@ -352,6 +331,22 @@ Accessible_isAction (Accessible *obj)
 }
 
 /**
+ * Accessible_isApplication:
+ * @obj: a pointer to the #Accessible instance to query.
+ *
+ * Query whether the specified #Accessible implements #AccessibleApplication.
+ *
+ * Returns: #TRUE if @obj implements the #AccessibleApplication interface,
+ *          #FALSE otherwise.
+ **/
+SPIBoolean
+Accessible_isApplication (Accessible *obj)
+{
+  return cspi_accessible_is_a (obj,
+                             "IDL:Accessibility/Application:1.0");
+}
+
+/**
  * Accessible_isComponent:
  * @obj: a pointer to the #Accessible instance to query.
  *
@@ -480,6 +475,22 @@ Accessible_isValue (Accessible *obj)
 }
 
 /**
+ * Accessible_getApplication:
+ * @obj: a pointer to the #Accessible instance to query.
+ *
+ * Get the #AccessibleApplication interface for an #Accessible.
+ *
+ * Returns: a pointer to an #AccessibleApplication interface instance, or
+ *          NULL if @obj does not implement #AccessibleApplication.
+ **/
+AccessibleApplication *
+Accessible_getApplication (Accessible *obj)
+{
+  return (AccessibleApplication *) Accessible_queryInterface (
+         obj, "IDL:Accessibility/Application:1.0");
+}
+
+/**
  * Accessible_getAction:
  * @obj: a pointer to the #Accessible instance to query.
  *
@@ -650,6 +661,11 @@ GenericInterface *
 Accessible_queryInterface (Accessible *obj, char *interface_name)
 {
   Bonobo_Unknown iface;
+  
+  if (!obj)
+    {
+      return NULL;
+    }
 
   iface = Accessibility_Accessible_queryInterface (CSPI_OBJREF (obj),
                                                   interface_name,
index 97135c4..d8b3bce 100644 (file)
@@ -185,7 +185,7 @@ AccessibleComponent_getLayer (AccessibleComponent *obj)
   AccessibleComponentLayer retval;
   
   zlayer = Accessibility_Component_getLayer (CSPI_OBJREF (obj),
-                                             cspi_ev ());
+                                            cspi_ev ());
   switch (zlayer)
     {
     case Accessibility_LAYER_BACKGROUND:
@@ -208,6 +208,7 @@ AccessibleComponent_getLayer (AccessibleComponent *obj)
       break;
     default:
       retval = SPI_LAYER_INVALID;
+      break;
     }
   return retval;
 }
index 23b973e..dc61d1b 100644 (file)
@@ -86,7 +86,7 @@ AccessibleEditableText_setTextContents (AccessibleEditableText *obj,
 {
   Accessibility_EditableText_setTextContents (CSPI_OBJREF (obj),
                                              (CORBA_char *) newContents, cspi_ev ());
-  return TRUE; /* TODO: make bonobo method return a boolean */
+  return TRUE; /* TODO: make bonobo method return a SPIBoolean */
 }
 
 
@@ -110,11 +110,11 @@ AccessibleEditableText_setTextContents (AccessibleEditableText *obj,
 SPIBoolean
 AccessibleEditableText_insertText (AccessibleEditableText *obj,
                                    long int position,
-                                   char *text,
+                                   const char *text,
                                    long int length)
 {
   Accessibility_EditableText_insertText (CSPI_OBJREF (obj),
-                                        (CORBA_long) position, (CORBA_char *) text,
+                                        (CORBA_long) position, (const CORBA_char *) text,
                                         (CORBA_long) length, cspi_ev ());
   return TRUE;
 }
index bc8a355..d9c543b 100644 (file)
  *
  **/
 AccessibleEventListener *
-createAccessibleEventListener (AccessibleEventListenerCB callback)
+createAccessibleEventListener (AccessibleEventListenerCB callback,
+                              void                     *user_data)
 {
   AccessibleEventListener *listener = cspi_event_listener_new ();
   if (callback)
     {
-      AccessibleEventListener_addCallback (listener, callback);
+      AccessibleEventListener_addCallback (listener, callback, user_data);
     }
   return listener;
 }
@@ -60,9 +61,10 @@ createAccessibleEventListener (AccessibleEventListenerCB callback)
  **/
 SPIBoolean
 AccessibleEventListener_addCallback (AccessibleEventListener *listener,
-                                    AccessibleEventListenerCB callback)
+                                    AccessibleEventListenerCB callback,
+                                    void                     *user_data)
 {
-  cspi_event_listener_add_callback (listener, callback);
+  cspi_event_listener_add_callback (listener, callback, user_data);
   return TRUE;
 }
 
@@ -94,12 +96,13 @@ AccessibleEventListener_removeCallback (AccessibleEventListener  *listener,
  *
  **/
 AccessibleKeystrokeListener *
-createAccessibleKeystrokeListener (AccessibleKeystrokeListenerCB callback)
+createAccessibleKeystrokeListener (AccessibleKeystrokeListenerCB callback,
+                                  void                         *user_data)
 {
   CSpiKeystrokeListener *listener = cspi_keystroke_listener_new ();
   if (callback)
     {
-      AccessibleKeystrokeListener_addCallback (listener, callback);
+      AccessibleKeystrokeListener_addCallback (listener, callback, user_data);
     }
   return (AccessibleKeystrokeListener *)listener;
 }
@@ -116,9 +119,10 @@ createAccessibleKeystrokeListener (AccessibleKeystrokeListenerCB callback)
  **/
 SPIBoolean
 AccessibleKeystrokeListener_addCallback (AccessibleKeystrokeListener *listener,
-                                        AccessibleKeystrokeListenerCB callback)
+                                        AccessibleKeystrokeListenerCB callback,
+                                        void                         *user_data)
 {
-  cspi_keystroke_listener_add_callback (listener, callback);
+  cspi_keystroke_listener_add_callback (listener, callback, user_data);
   return TRUE;
 }
 
@@ -140,14 +144,14 @@ AccessibleKeystrokeListener_removeCallback (AccessibleKeystrokeListener *listene
   return TRUE;
 }
 
-
 /**
  * AccessibleKeystrokeListener_unref:
  * @listener: a pointer to the #AccessibleKeystrokeListener being operated on.
  *
  * Decrements an #AccessibleKeystrokeListener's reference count.
  **/
-void AccessibleKeystrokeListener_unref (AccessibleKeystrokeListener *listener)
+void
+AccessibleKeystrokeListener_unref (AccessibleKeystrokeListener *listener)
 {
   /* Would prefer this not to be bonobo api */
   bonobo_object_unref (BONOBO_OBJECT (listener));
index fba7fed..864dc14 100644 (file)
 #include <stdlib.h>
 #include <cspi/spi-private.h>
 
+#undef DEBUG_OBJECTS
+
 static CORBA_Environment ev = { 0 };
 static Accessibility_Registry registry = CORBA_OBJECT_NIL;
-static SPIBoolean is_gnome_app = FALSE;
-static GSList *live_refs = NULL;
+static SPIBoolean is_gnome_app = TRUE;
+static GHashTable *live_refs = NULL;
+
+static guint
+spi_object_hash (gconstpointer key)
+{
+  CORBA_Object object = (CORBA_Object) key;
+  guint        retval;
+  
+  retval = CORBA_Object_hash (object, 0, &ev);
+
+  return retval;
+}
+
+static gboolean
+spi_object_equal (gconstpointer a, gconstpointer b)
+{
+  CORBA_Object objecta = (CORBA_Object) a;
+  CORBA_Object objectb = (CORBA_Object) b;
+  gboolean     retval;
+
+  retval = CORBA_Object_is_equivalent (objecta, objectb, &ev);
+
+  return retval;
+}
+
+static void
+spi_object_release (gpointer  value)
+{
+  Accessible *a = (Accessible *) value;
+
+#ifdef DEBUG_OBJECTS
+  g_print ("releasing %p => %p\n", a, a->objref);
+#endif
+
+  bonobo_object_release_unref (a->objref, NULL);
+
+  memset (a, 0xaa, sizeof (Accessible));
+  a->ref_count = -1;
+
+#ifndef DEBUG_OBJECTS
+  g_free (a);
+#endif
+}
+
+
+SPIBoolean
+cspi_accessible_is_a (Accessible *obj,
+                     const char *interface_name)
+{
+  SPIBoolean        retval;
+  Bonobo_Unknown unknown;
+
+  if (obj == NULL)
+    {
+      return FALSE;
+    }
+
+  unknown = Bonobo_Unknown_queryInterface (CSPI_OBJREF (obj),
+                                          interface_name, cspi_ev ());
+
+  if (BONOBO_EX (cspi_ev ()))
+    {
+      g_error ("Exception '%s' checking if is '%s'",
+              bonobo_exception_get_text (cspi_ev ()),
+              interface_name);
+    }
+
+  if (unknown != CORBA_OBJECT_NIL)
+    {
+      retval = TRUE;
+      bonobo_object_release_unref (unknown, NULL);
+    }
+  else
+    {
+      retval = FALSE;
+    }
+
+  return retval;
+}
+
+static GHashTable *
+get_live_refs (void)
+{
+  if (!live_refs) 
+    {
+      live_refs = g_hash_table_new_full (spi_object_hash,
+                                        spi_object_equal,
+                                        NULL,
+                                        spi_object_release);
+    }
+  return live_refs;
+}
 
 CORBA_Environment *
 cspi_ev (void)
@@ -54,21 +147,62 @@ cspi_object_add (CORBA_Object corba_object)
 {
   Accessible *ref;
 
-  if (corba_object != CORBA_OBJECT_NIL)
+  if (corba_object == CORBA_OBJECT_NIL)
+    {
+      ref = NULL;
+    }
+  else
     {
-      ref = g_new (Accessible, 1);
+      if ((ref = g_hash_table_lookup (get_live_refs (), corba_object)))
+        {
+          g_assert (ref->ref_count > 0);
+         ref->ref_count++;
+          bonobo_object_release_unref (corba_object, NULL);
+#ifdef DEBUG_OBJECTS
+          g_print ("returning cached %p => %p\n", ref, ref->objref);
+#endif
+       }
+      else
+        {
+          ref = g_new (Accessible, 1);
+
+#ifdef DEBUG_OBJECTS
+          g_print ("allocating %p => %p\n", ref, corba_object);
+#endif
+
+          ref->objref = corba_object;
+          ref->ref_count = 1;
+
+          g_hash_table_insert (get_live_refs (), ref->objref, ref);
+       }
+    }
 
-      ref->objref = CORBA_Object_duplicate (corba_object, cspi_ev());
-      ref->ref_count = 1;
+  return ref;
+}
 
-      live_refs = g_slist_prepend (live_refs, ref);
+Accessible *
+cspi_object_add_check (CORBA_Object corba_object)
+{
+  Accessible *retval;
+
+  if (ev._major == CORBA_USER_EXCEPTION &&
+      !strcmp (ev._id, ex_Accessibility_ChildGone))
+    {
+      retval = NULL;
+    }
+  else if (ev._major != CORBA_NO_EXCEPTION)
+    {
+      cspi_check_ev (cspi_ev (), "pre method check");
+      retval = NULL;
     }
   else
-   {
-     ref = NULL;
-   }
+    {
+      retval = cspi_object_add (corba_object);
 
-  return ref;
+      cspi_check_ev (cspi_ev (), "post method check");
+    }
+
+  return retval;
 }
 
 void
@@ -82,42 +216,29 @@ cspi_object_ref (Accessible *accessible)
 void
 cspi_object_unref (Accessible *accessible)
 {
-  g_return_if_fail (accessible != NULL);
-       
-  if (--accessible->ref_count == 0)
+  if (accessible == NULL)
     {
-      live_refs = g_slist_remove (live_refs, accessible);
-
-      bonobo_object_release_unref (accessible->objref, cspi_ev ());
-
-      cspi_check_ev (cspi_ev (), "unref");
-
-      memset (accessible, 0xaa, sizeof (Accessible));
+      return;
+    }
 
-      g_free (accessible);
+  if (--accessible->ref_count == 0)
+    {
+      g_hash_table_remove (get_live_refs (), accessible->objref);
     }
 }
 
 static void
 cspi_cleanup (void)
 {
-  GSList *l, *refs;
+  GHashTable *refs;
 
   refs = live_refs;
   live_refs = NULL;
-
-  for (l = refs; l; l = l->next)
+  if (refs)
     {
-      Accessible *a = l->data;
-
-      g_print ("releasing %p\n", l->data);
-      bonobo_object_release_unref (a->objref, NULL);
-
-      g_free (a);
+      g_hash_table_destroy (refs);
     }
 
-  g_slist_free (refs);
-
   if (registry != CORBA_OBJECT_NIL)
     {
       bonobo_object_release_unref (registry, NULL);
@@ -125,26 +246,32 @@ cspi_cleanup (void)
     }
 }
 
+static gboolean SPI_inited = FALSE;
+
 /**
  * SPI_init:
+ * @isGNOMEApp: a #SPIBoolean indicating whether the client of the SPI
+ *              will use the Gnome event loop or not.  Clients that have
+ *              their own GUIS will usually specify #TRUE here, and must
+ *              do so if they use Gnome GUI components.
  *
  * Connects to the accessibility registry and initializes the SPI.
  *
  * Returns: 0 on success, otherwise an integer error code.
  **/
 int
-SPI_init (void)
+SPI_init (SPIBoolean isGNOMEApp)
 {
   int argc = 0;
   char *obj_id;
-  static gboolean inited = FALSE;
+  is_gnome_app = isGNOMEApp;
 
-  if (inited)
+  if (SPI_inited)
     {
       return 1;
     }
 
-  inited = TRUE;
+  SPI_inited = TRUE;
 
   CORBA_exception_init (&ev);
 
@@ -169,33 +296,30 @@ SPI_init (void)
       g_error ("Could not locate registry");
     }
 
-  Accessibility_Registry_ref (registry, &ev);
-  
   bonobo_activate ();
+
+  if (isGNOMEApp)
+    {
+      g_atexit (cspi_cleanup);
+    }
   
   return 0;
 }
 
 /**
  * SPI_event_main:
- * @isGNOMEApp: a #SPIBoolean indicating whether the client of the SPI
- *              will use the Gnome event loop or not.  Clients that have
- *              their own GUIS will usually specify #TRUE here, and must
- *              do so if they use Gnome GUI components.
  *
  * Starts/enters the main event loop for the SPI services.
  *
- * (NOTE: This method does not return control, it is exited via a call to SPI_exit()
- * from within an event handler).
+ * (NOTE: This method does not return control, it is exited via a call
+ * to SPI_exit() from within an event handler).
  *
  **/
 void
-SPI_event_main (SPIBoolean isGNOMEApp)
+SPI_event_main ()
 {
-  is_gnome_app = isGNOMEApp;
-  if (isGNOMEApp)
+  if (cspi_is_gnome_app ())
     {
-      g_atexit (cspi_cleanup);
       bonobo_main ();
     }
   else
@@ -250,7 +374,15 @@ SPI_nextEvent (SPIBoolean waitForEvent)
 void
 SPI_exit (void)
 {
-  cspi_cleanup();
+  if (!SPI_inited)
+    {
+      return;
+    }
+
+  SPI_inited = FALSE;
+
+  cspi_cleanup ();
+
   if (cspi_is_gnome_app ())
     {
       bonobo_main_quit ();
index cd7bdbc..3fa2929 100644 (file)
@@ -100,7 +100,7 @@ registerGlobalEventListener (AccessibleEventListener *listener,
   Accessibility_Registry_registerGlobalEventListener (
                          cspi_registry (),
                          (Accessibility_EventListener)
-                            bonobo_object_corba_objref (bonobo_object (listener)),
+                            BONOBO_OBJREF (bonobo_object (listener)),
                          eventType,
                          cspi_ev ());
 
@@ -126,15 +126,11 @@ deregisterGlobalEventListenerAll (AccessibleEventListener *listener)
 {
   Accessibility_Registry_deregisterGlobalEventListenerAll (
                          cspi_registry (),
-                         (Accessibility_EventListener)
-                            CORBA_Object_duplicate (
-                                   bonobo_object_corba_objref (
-                                           bonobo_object (listener)), cspi_ev ()),
-                         cspi_ev ());
+                        (Accessibility_EventListener) BONOBO_OBJREF (listener),
+                        cspi_ev ());
   if (!cspi_exception ())
     {
       bonobo_object_unref (BONOBO_OBJECT (listener));      
-      /* Would prefer that this were not a bonobo object: g_object_unref (listener);*/
     }
 
   return !cspi_exception ();
@@ -157,9 +153,7 @@ deregisterGlobalEventListener (AccessibleEventListener *listener,
 {
   Accessibility_Registry_deregisterGlobalEventListener (
          cspi_registry (),
-         (Accessibility_EventListener)
-         CORBA_Object_duplicate (
-                 bonobo_object_corba_objref (bonobo_object (listener)), cspi_ev ()),
+         (Accessibility_EventListener) BONOBO_OBJREF (listener),
          (CORBA_char *) eventType,
          cspi_ev ());
 
@@ -196,9 +190,9 @@ getDesktopCount ()
 Accessible*
 getDesktop (int i)
 {
-  return cspi_object_add (Accessibility_Registry_getDesktop (cspi_registry (),
-                                                            (CORBA_short) i,
-                                                            cspi_ev ()));
+  return cspi_object_add_check (Accessibility_Registry_getDesktop (cspi_registry (),
+                                                                  (CORBA_short) i,
+                                                                  cspi_ev ()));
 }
 
 /**
@@ -252,65 +246,74 @@ registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
                                     AccessibleKeyEventMask eventmask,
                                     AccessibleKeyListenerSyncType sync_type)
 {
-  Accessibility_ControllerEventMask *controller_event_mask =
-         Accessibility_ControllerEventMask__alloc();
-  Accessibility_DeviceEventController device_event_controller = 
-         Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
-  Accessibility_KeySet *key_set = Accessibility_KeySet__alloc();
-  Accessibility_KeyEventTypeSeq *key_events = Accessibility_KeyEventTypeSeq__alloc();
-  Accessibility_KeystrokeListener cspi_listener_corba_ref;
-  gint i, mask;
-  Accessibility_DeviceEventController_ref (device_event_controller, cspi_ev ());
+  gint                                i, mask;
+  Accessibility_KeySet                key_set;
+  Accessibility_KeyEventTypeSeq       key_events;
+  Accessibility_ControllerEventMask   controller_event_mask;
+  Accessibility_DeviceEventController device_event_controller;
+
+  device_event_controller = 
+    Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
+
+  g_return_if_fail (cspi_warn_ev (cspi_ev (), "getting event controller"));
 
   /* copy the keyval filter values from the C api into the CORBA KeySet */
   if (keys)
     {
-      key_set->_buffer = Accessibility_KeySet_allocbuf (
-                                                   (unsigned long) keys->len);
-      key_set->_length = (unsigned long) keys->len;
-      for (i=0; i < key_set->_length; ++i)
+      key_set._length = keys->len;
+      key_set._buffer = Accessibility_KeySet_allocbuf (keys->len);
+      for (i = 0; i < key_set._length; ++i)
         {
           /* we overload the keyset long w/keycodes, the - bit acts as a flag */
-          key_set->_buffer[i] = (keys->keysyms[i]) ? keys->keysyms[i] :
+          key_set._buffer[i] = (keys->keysyms[i]) ? keys->keysyms[i] :
                                                 -keys->keycodes[i];
          /* g_print ("key-set %d = %d\n", i, (int) key_set->_buffer[i]); */
         }
     }
+  else
+    {
+      key_set._length = 0;
+      key_set._buffer = NULL;
+    }
+       
   /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
-  mask=1;
-  i=0;
+  mask = 1;
+  i = 0;
   do
     {
-      if (mask & eventmask) ++i; 
+      if (mask & eventmask)
+        {
+          ++i; 
+       }
       mask <<= 1;
-    } while (mask & 0xFFFF);
+    }
+  while (mask & 0xFFFF);
   
-  key_events->_buffer = Accessibility_KeyEventTypeSeq_allocbuf (i);
-  i=0;
+  key_events._buffer = Accessibility_KeyEventTypeSeq_allocbuf (i);
+  i = 0;
   if (eventmask & SPI_KEY_PRESSED)
     {
-      key_events->_buffer[i++] = Accessibility_KEY_PRESSED;
+      key_events._buffer[i++] = Accessibility_KEY_PRESSED;
     }
   if (eventmask & SPI_KEY_RELEASED)
     {
-      key_events->_buffer[i++] = Accessibility_KEY_RELEASED;
+      key_events._buffer[i++] = Accessibility_KEY_RELEASED;
     }
-  key_events->_length = i;
+  key_events._length = i;
   
-  controller_event_mask->value = (CORBA_unsigned_long) modmask;
-  controller_event_mask->refcount = (CORBA_unsigned_short) 1;
+  controller_event_mask.value = (CORBA_unsigned_long) modmask;
+  controller_event_mask.refcount = (CORBA_unsigned_short) 1;
 
-  cspi_listener_corba_ref = (Accessibility_KeystrokeListener)
-         CORBA_Object_duplicate (bonobo_object_corba_objref (bonobo_object (listener)), cspi_ev ());
-  
-         Accessibility_DeviceEventController_registerKeystrokeListener (
+  Accessibility_DeviceEventController_registerKeystrokeListener (
          device_event_controller,
-         cspi_listener_corba_ref,
-         key_set,
-         controller_event_mask,
-         key_events,
+         BONOBO_OBJREF (listener),
+         &key_set,
+         &controller_event_mask,
+         &key_events,
          (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0),
          cspi_ev ());
+
+  bonobo_object_release_unref (device_event_controller, cspi_ev ());
 }
 
 /**
@@ -327,28 +330,35 @@ void
 deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
                                       AccessibleKeyMaskType modmask)
 {
-  Accessibility_ControllerEventMask *controller_event_mask =
-         Accessibility_ControllerEventMask__alloc();
-  Accessibility_DeviceEventController device_event_controller = 
-         Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
-  Accessibility_KeySet *all_keys = Accessibility_KeySet__alloc();
-  Accessibility_KeyEventTypeSeq *key_events = Accessibility_KeyEventTypeSeq__alloc();
-  Accessibility_KeystrokeListener cspi_listener_corba_ref;
-  Accessibility_DeviceEventController_unref (device_event_controller, cspi_ev ());
-  controller_event_mask->value = (CORBA_unsigned_long) modmask;
-  controller_event_mask->refcount = (CORBA_unsigned_short) 1;
-
-  cspi_listener_corba_ref = (Accessibility_KeystrokeListener)
-         CORBA_Object_duplicate (BONOBO_OBJREF(listener), cspi_ev ());
-  
+  Accessibility_ControllerEventMask   controller_event_mask;
+  Accessibility_KeySet                key_set;
+  Accessibility_KeyEventTypeSeq       key_events;
+  Accessibility_DeviceEventController device_event_controller;
+
+  device_event_controller = 
+    Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
+
+  g_return_if_fail (cspi_warn_ev (cspi_ev (), "getting event controller"));
+
+  controller_event_mask.value = (CORBA_unsigned_long) modmask;
+  controller_event_mask.refcount = (CORBA_unsigned_short) 1;
+
+  key_events._buffer = NULL;
+  key_events._length = 0;
+
+  key_set._buffer = NULL;
+  key_set._length = 0;
+
   Accessibility_DeviceEventController_deregisterKeystrokeListener (
          device_event_controller,
-         cspi_listener_corba_ref,
-         all_keys,
-         controller_event_mask,
-         key_events,
+         BONOBO_OBJREF (listener),
+         &key_set,
+         &controller_event_mask,
+         &key_events,
          (CORBA_boolean) TRUE,
          cspi_ev ());
+
+  bonobo_object_release_unref (device_event_controller, NULL);
 }
 
 /**
@@ -372,10 +382,15 @@ generateKeyEvent (long int keyval, AccessibleKeySynthType synth_type)
  */
   Accessibility_DeviceEventController device_event_controller = 
          Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
+
+  g_return_if_fail (cspi_warn_ev (cspi_ev (), "getting event controller"));
+
   Accessibility_DeviceEventController_generateKeyEvent (device_event_controller,
                                                        keyval,
                                                        (unsigned long) synth_type,
                                                        cspi_ev ());
+
+  bonobo_object_release_unref (device_event_controller, NULL);
 }
 
 /**
index dd663ee..7b0ea9e 100644 (file)
@@ -170,7 +170,7 @@ SPIBoolean
 AccessibleSelection_selectAll (AccessibleSelection *obj)
 {
   Accessibility_Selection_selectAll (CSPI_OBJREF (obj), cspi_ev ());
-  return TRUE; /* TODO: change the bonobo method to return boolean */
+  return TRUE; /* TODO: change the bonobo method to return SPIBoolean */
 }
 
 
index 7ea77ca..530b357 100644 (file)
@@ -26,6 +26,7 @@ Event Listener Support
 </para>
 
 @event: 
+@user_data: 
 
 
 <!-- ##### FUNCTION createAccessibleEventListener ##### -->
@@ -34,6 +35,7 @@ Event Listener Support
 </para>
 
 @callback: 
+@user_data: 
 @Returns: 
 
 
@@ -44,6 +46,7 @@ Event Listener Support
 
 @listener: 
 @callback: 
+@user_data: 
 @Returns: 
 
 
index 80b72a3..fd319ec 100644 (file)
@@ -62,3 +62,16 @@ AccessibleImage Interface
 @ctype: 
 
 
+<!-- ##### FUNCTION AccessibleImage_getImageExtents ##### -->
+<para>
+
+</para>
+
+@obj: 
+@x: 
+@y: 
+@width: 
+@height: 
+@ctype: 
+
+
index 98db998..81f28de 100644 (file)
@@ -19,6 +19,7 @@ SPI main loop and initialization
 
 </para>
 
+@isGNOMEApp: 
 @Returns: 
 
 
@@ -27,6 +28,7 @@ SPI main loop and initialization
 
 </para>
 
+<!-- # Unused Parameters # -->
 @isGNOMEApp: 
 
 
index cf984ce..7c74b06 100644 (file)
@@ -56,6 +56,7 @@ Registry queries
 </para>
 
 @stroke: 
+@user_data: 
 @Returns: 
 
 
@@ -95,6 +96,7 @@ Registry queries
 </para>
 
 @callback: 
+@user_data: 
 @Returns: 
 
 
@@ -165,6 +167,7 @@ Registry queries
 
 @listener: 
 @callback: 
+@user_data: 
 @Returns: 
 
 
index cfebaa9..7068a82 100644 (file)
@@ -32,6 +32,7 @@
 module Accessibility {
   
   typedef sequence<Relation> RelationSet;
+  exception ChildGone {} ;
 
   struct BoundingBox {
          long x;
@@ -81,7 +82,8 @@ module Accessibility {
      *
      * Returns: the 'nth' @Accessible child of this object.
      **/
-    Accessible         getChildAtIndex (in long index);
+    Accessible         getChildAtIndex (in long index)
+           raises (ChildGone);
 
     /**
      * getIndexInParent:
index 2574a80..6372c47 100644 (file)
@@ -37,7 +37,6 @@ module Accessibility
   };
 
   interface EventListener : Bonobo::Unknown {
-    attribute long hash_id;
     oneway void notifyEvent (in Event e);
   };
 
index cfebaa9..7068a82 100644 (file)
@@ -32,6 +32,7 @@
 module Accessibility {
   
   typedef sequence<Relation> RelationSet;
+  exception ChildGone {} ;
 
   struct BoundingBox {
          long x;
@@ -81,7 +82,8 @@ module Accessibility {
      *
      * Returns: the 'nth' @Accessible child of this object.
      **/
-    Accessible         getChildAtIndex (in long index);
+    Accessible         getChildAtIndex (in long index)
+           raises (ChildGone);
 
     /**
      * getIndexInParent:
index 2574a80..6372c47 100644 (file)
@@ -37,7 +37,6 @@ module Accessibility
   };
 
   interface EventListener : Bonobo::Unknown {
-    attribute long hash_id;
     oneway void notifyEvent (in Event e);
   };
 
index 977ace8..b71fb1c 100644 (file)
@@ -14,12 +14,11 @@ libspiincludedir = $(includedir)/at-spi-1.0/libspi
 
 libspiinclude_HEADERS = Accessibility.h \
                        accessible.h \
-                       accessibleeventlistener.h \
+                       eventlistener.h \
                        action.h \
                         application.h \
                        base.h \
                        component.h \
-                        desktop.h \
                        deviceeventcontroller.h \
                        editabletext.h\
                        hyperlink.h\
@@ -29,7 +28,6 @@ libspiinclude_HEADERS = Accessibility.h \
                        keymasks.h \
                        libspi.h \
                         listener.h \
-                        registry.h \
                        relation.h \
                        selection.h \
                        table.h \
@@ -58,6 +56,7 @@ libspi_la_SOURCES = accessible.c         \
                    action.h\
                    application.c        \
                     application.h        \
+                   base.c               \
                    component.c          \
                    component.h          \
                     desktop.c            \
@@ -86,8 +85,7 @@ libspi_la_SOURCES = accessible.c         \
                    value.h\
                     listener.c           \
                     listener.h           \
-                   accessibleeventlistener.c   \
-                   accessibleeventlistener.h   \
+                   eventlistener.c      \
                     registry.c           \
                     registry.h           \
                    keymasks.h          \
index 3b8e364..ff11bbd 100644 (file)
 
 #include <config.h>
 #include <stdio.h>
+#include <bonobo/bonobo-exception.h>
+#include <atk/atk.h>
 #include <libspi/libspi.h>
 
 /* Our parent Gtk object type  */
-#define PARENT_TYPE BONOBO_TYPE_OBJECT
+#define PARENT_TYPE SPI_TYPE_BASE
 
-/* A pointer to our parent object class */
-static GObjectClass *spi_accessible_parent_class;
-
-/*
- * Implemented GObject::finalize
- */
-static void
-spi_accessible_object_finalize (GObject *object)
+static AtkObject *
+get_accessible_from_servant (PortableServer_Servant servant)
 {
-        SpiAccessible *accessible = SPI_ACCESSIBLE (object);
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
 
-       ATK_OBJECT (accessible->atko); /* assertion */
-        g_object_unref (G_OBJECT(accessible->atko));
-        accessible->atko = NULL;
+  if (!object)
+    {
+      return NULL;
+    }
 
-        spi_accessible_parent_class->finalize (object);
+  return object->atko;
 }
 
 /*
@@ -54,13 +51,22 @@ static CORBA_char *
 impl_accessibility_accessible_get_name (PortableServer_Servant servant,
                                         CORBA_Environment     *ev)
 {
-  CORBA_char * retval;
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  retval = (CORBA_char *) atk_object_get_name (accessible->atko);
-  if (retval )
-    retval = CORBA_string_dup (retval);
+  const gchar *name;
+  CORBA_char  *retval;
+  AtkObject   *object = get_accessible_from_servant (servant);
+
+  g_return_val_if_fail (object != NULL, CORBA_string_dup (""));
+
+  name = atk_object_get_name (object);
+
+  if (name)
+    {
+      retval = CORBA_string_dup (name);
+    }
   else
-    retval = CORBA_string_dup ("");
+    {
+      retval = CORBA_string_dup ("");
+    }
 
   return retval;
 }
@@ -73,9 +79,11 @@ impl_accessibility_accessible_set_name (PortableServer_Servant servant,
                                         const CORBA_char      *name,
                                         CORBA_Environment     *ev)
 {
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  atk_object_set_name (accessible->atko, name);
-  printf ("SpiAccessible set_name called: %s\n", name);
+  AtkObject *object = get_accessible_from_servant (servant);
+
+  g_return_if_fail (object != NULL);
+
+  atk_object_set_name (object, name);
 }
 
 /*
@@ -85,13 +93,22 @@ static CORBA_char *
 impl_accessibility_accessible_get_description (PortableServer_Servant servant,
                                                CORBA_Environment     *ev)
 {
-  CORBA_char * retval;
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  retval = CORBA_string_dup (atk_object_get_description (accessible->atko));
-  if (retval )
-    retval = CORBA_string_dup (retval);
+  const gchar *descr;
+  CORBA_char  *retval;
+  AtkObject   *object = get_accessible_from_servant (servant);
+
+  g_return_val_if_fail (object != NULL, CORBA_string_dup (""));
+
+  descr = atk_object_get_description (object);
+
+  if (descr)
+    {
+      retval = CORBA_string_dup (descr);
+    }
   else
-    retval = CORBA_string_dup ("");
+    {
+      retval = CORBA_string_dup ("");
+    }
 
   return retval;
 }
@@ -101,12 +118,14 @@ impl_accessibility_accessible_get_description (PortableServer_Servant servant,
  */
 static void
 impl_accessibility_accessible_set_description (PortableServer_Servant servant,
-                                               const CORBA_char      *name,
+                                               const CORBA_char      *descr,
                                                CORBA_Environment     *ev)
 {
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  atk_object_set_description (accessible->atko, name);
-  printf ("SpiAccessible set_description called: %s\n", name);
+  AtkObject *object = get_accessible_from_servant (servant);
+
+  g_return_if_fail (object != NULL);
+
+  atk_object_set_description (object, descr);
 }
 
 /*
@@ -116,14 +135,14 @@ static Accessibility_Accessible
 impl_accessibility_accessible_get_parent (PortableServer_Servant servant,
                                           CORBA_Environment     *ev)
 {
-  Accessibility_Accessible retval;
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  AtkObject     *parent;
+  AtkObject *parent;
+  AtkObject *object = get_accessible_from_servant (servant);
 
-  parent = atk_object_get_parent (accessible->atko);
-  retval = BONOBO_OBJREF (spi_accessible_new (parent));
+  g_return_val_if_fail (object != NULL, CORBA_OBJECT_NIL);
 
-  return bonobo_object_dup_ref (retval, ev);
+  parent = atk_object_get_parent (object);
+
+  return spi_accessible_new_return (parent, FALSE, ev);
 }
 
 /*
@@ -133,11 +152,11 @@ static CORBA_long
 impl_accessibility_accessible_get_index_in_parent (PortableServer_Servant servant,
                                                    CORBA_Environment     *ev)
 {
-  CORBA_long retval;
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  retval = (CORBA_long) atk_object_get_index_in_parent (accessible->atko);
-  printf ("SpiAccessible get_index_in_parent called\n");
-  return retval;
+  AtkObject *object = get_accessible_from_servant (servant);
+
+  g_return_val_if_fail (object != NULL, -1);
+
+  return atk_object_get_index_in_parent (object);
 }
 
 /*
@@ -147,11 +166,11 @@ static CORBA_long
 impl_accessibility_accessible_get_child_count (PortableServer_Servant servant,
                                                CORBA_Environment     *ev)
 {
-  CORBA_long retval;
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  retval = (CORBA_long) atk_object_get_n_accessible_children (accessible->atko);
-  printf ("SpiAccessible get_childCount called: %d\n", (int) retval);
-  return retval;
+  AtkObject *object = get_accessible_from_servant (servant);
+
+  g_return_val_if_fail (object != NULL, 0);
+
+  return atk_object_get_n_accessible_children (object);
 }
 
 /*
@@ -162,11 +181,14 @@ impl_accessibility_accessible_get_child_at_index (PortableServer_Servant servant
                                                   const CORBA_long      index,
                                                   CORBA_Environment     *ev)
 {
-  Accessibility_Accessible retval;
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  AtkObject *child = atk_object_ref_accessible_child (accessible->atko, (gint) index);
-  retval = BONOBO_OBJREF (spi_accessible_new (child));
-  return bonobo_object_dup_ref (retval, ev);
+  AtkObject *child;
+  AtkObject *object = get_accessible_from_servant (servant);
+
+  g_return_val_if_fail (object != NULL, 0);
+
+  child = atk_object_ref_accessible_child (object, index);
+
+  return spi_accessible_new_return (child, TRUE, ev);
 }
 
 /*
@@ -176,13 +198,14 @@ static Accessibility_StateSet
 impl_accessibility_accessible_get_state (PortableServer_Servant servant,
                                         CORBA_Environment     *ev)
 {
-  Accessibility_StateSet retval;
-/*  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-    AtkStateSet *state = atk_object_ref_state_set (accessible->atko); */
-  retval = CORBA_OBJECT_NIL;
+  AtkObject *object = get_accessible_from_servant (servant);
+
+  bonobo_return_val_if_fail (object != NULL, NULL, ev);
+
   printf ("SpiAccessible get_state.\n");
+
   /* TODO: implement the bonobo stateset class */
-  return (Accessibility_StateSet) retval;
+  return (Accessibility_StateSet) NULL;
 }
 
 /*
@@ -195,18 +218,24 @@ impl_accessibility_accessible_get_relation_set (PortableServer_Servant servant,
   Accessibility_RelationSet *retval;
   gint n_relations;
   gint i;
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  AtkRelationSet *relation_set = atk_object_ref_relation_set (accessible->atko);
+  AtkRelationSet *relation_set;
+  AtkObject      *object = get_accessible_from_servant (servant);
+
+  bonobo_return_val_if_fail (object != NULL, NULL, ev);
+
+  relation_set = atk_object_ref_relation_set (object);
+
   n_relations = atk_relation_set_get_n_relations (relation_set);
   retval = CORBA_sequence_Accessibility_Relation__alloc ();
   CORBA_sequence_Accessibility_Relation_allocbuf (n_relations);
          
-  for (i=0; i<n_relations; ++i)
+  for (i = 0; i < n_relations; ++i)
     {
       retval->_buffer[i] =
-             bonobo_object_dup_ref (bonobo_object_corba_objref (
-                     BONOBO_OBJECT (spi_relation_new (atk_relation_set_get_relation (relation_set, i)))),
-                                     ev);
+        bonobo_object_dup_ref (
+          BONOBO_OBJREF (
+            spi_relation_new (atk_relation_set_get_relation (relation_set, i))),
+         ev);
     }
   
   printf ("SpiAccessible get_relation_set.\n");
@@ -220,22 +249,22 @@ static Accessibility_Role
 impl_accessibility_accessible_get_role (PortableServer_Servant servant,
                                        CORBA_Environment     *ev)
 {
+  AtkRole            role;
   Accessibility_Role retval;
-  SpiAccessible *accessible = SPI_ACCESSIBLE (bonobo_object_from_servant (servant));
-  AtkRole role = atk_object_get_role (accessible->atko);
-  retval = role; /* relies on ability to cast these back and forth */
-  printf ("SpiAccessible get_role.\n");
-  return (Accessibility_Role) retval;
+  AtkObject         *object = get_accessible_from_servant (servant);
+
+  g_return_val_if_fail (object != NULL, 0);
+
+  role = atk_object_get_role (object);
+  retval = role; /* FIXME: relies on ability to cast these back and forth */
+
+  return retval;
 }
 
 static void
 spi_accessible_class_init (SpiAccessibleClass *klass)
 {
-        GObjectClass * object_class = (GObjectClass *) klass;
         POA_Accessibility_Accessible__epv *epv = &klass->epv;
-        spi_accessible_parent_class = g_type_class_peek_parent (klass);
-
-        object_class->finalize = spi_accessible_object_finalize;
 
         epv->_get_name = impl_accessibility_accessible_get_name;
         epv->_set_name = impl_accessibility_accessible_set_name;
@@ -262,14 +291,46 @@ BONOBO_TYPE_FUNC_FULL (SpiAccessible,
                       PARENT_TYPE,
                       spi_accessible);
 
+static GHashTable *public_corba_refs = NULL;
+
+static GHashTable *
+get_public_refs (void)
+{
+  if (!public_corba_refs)
+    {
+      public_corba_refs = g_hash_table_new (NULL, NULL);
+    }
+  return public_corba_refs;
+}
+
+static void
+de_register_public_ref (SpiBase *object)
+{
+  g_hash_table_remove (get_public_refs (), object->atko);
+}
+
 SpiAccessible *
 spi_accessible_new (AtkObject *o)
 {
-    SpiAccessible *retval = g_object_new (SPI_ACCESSIBLE_TYPE, NULL);
+    SpiAccessible *retval;
     CORBA_Environment ev;
+
     CORBA_exception_init (&ev);
-    g_object_ref (o);
-    retval->atko = ATK_OBJECT (o);
+
+    if ((retval = g_hash_table_lookup (get_public_refs (), o)))
+      {
+        bonobo_object_ref (BONOBO_OBJECT (retval));
+       return retval;
+      }
+
+    retval = g_object_new (SPI_ACCESSIBLE_TYPE, NULL);
+
+    spi_base_construct (SPI_BASE (retval), o);
+
+    g_hash_table_insert (get_public_refs (), o, retval);
+    g_signal_connect (G_OBJECT (retval), "destroy",
+                     G_CALLBACK (de_register_public_ref),
+                     NULL);
 
     /* aggregate appropriate SPI interfaces based on ATK interfaces */
 
@@ -329,3 +390,36 @@ spi_accessible_new (AtkObject *o)
 
     return retval;
 }
+
+/**
+ * spi_accessible_new_return:
+ * @o: an AtkObject or NULL
+ * @release_ref: whether to unref this AtkObject before return
+ * @ev: a CORBA environment
+ * 
+ * A helper function to instantiate a CORBA accessiblility
+ * proxy from an AtkObject.
+ * 
+ * Return value: the proxy or CORBA_OBJECT_NIL
+ **/
+Accessibility_Accessible
+spi_accessible_new_return (AtkObject         *o,
+                          gboolean           release_ref,
+                          CORBA_Environment *ev)
+{
+  SpiAccessible *accessible;
+
+  if (!o)
+    {
+      return CORBA_OBJECT_NIL;
+    }
+
+  accessible = spi_accessible_new (o);
+
+  if (release_ref)
+    {
+      g_object_unref (G_OBJECT (o));
+    }
+
+  return CORBA_Object_duplicate (BONOBO_OBJREF (accessible), ev);
+}
index 9d85556..e263f6d 100644 (file)
 #ifndef SPI_ACCESSIBLE_H_
 #define SPI_ACCESSIBLE_H_
 
-#include <glib/gmacros.h>
-#include <bonobo/bonobo-object.h>
-#include <atk/atkobject.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
 
 G_BEGIN_DECLS
 
 #define SPI_ACCESSIBLE_TYPE        (spi_accessible_get_type ())
 #define SPI_ACCESSIBLE(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_ACCESSIBLE_TYPE, SpiAccessible))
 #define SPI_ACCESSIBLE_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_ACCESSIBLE_TYPE, SpiAccessibleClass))
-#define IS_SPI_ACCESSIBLE(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_ACCESSIBLE_TYPE))
-#define IS_SPI_ACCESSIBLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_ACCESSIBLE_TYPE))
+#define SPI_IS_ACCESSIBLE(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_ACCESSIBLE_TYPE))
+#define SPI_IS_ACCESSIBLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_ACCESSIBLE_TYPE))
 
 typedef struct {
-        BonoboObject parent;
-        AtkObject *atko;
+       SpiBase parent;
 } SpiAccessible;
 
 typedef struct {
-        BonoboObjectClass parent_class;
+        SpiBaseClass parent_class;
         POA_Accessibility_Accessible__epv epv;
 } SpiAccessibleClass;
 
-GType          spi_accessible_get_type (void);
-SpiAccessible *spi_accessible_new      (AtkObject *o);
-
+GType                    spi_accessible_get_type   (void);
+SpiAccessible           *spi_accessible_new        (AtkObject         *o);
+Accessibility_Accessible spi_accessible_new_return (AtkObject         *o,
+                                                   gboolean           release_ref,
+                                                   CORBA_Environment *ev);
 
 G_END_DECLS
 
index 1164afa..f0a1c69 100644 (file)
@@ -79,6 +79,11 @@ impl_accessible_event_notify_event (PortableServer_Servant     servant,
     }
 
   g_signal_emit (G_OBJECT (listener), signals [EVENT], 0, e); 
+
+  if (e->source != CORBA_OBJECT_NIL)
+    {
+      Accessibility_Accessible_unref (e->source, ev);
+    }
 }
 
 static void
index 0f4d2d4..725623f 100644 (file)
@@ -1,3 +1,4 @@
+#error This is a stale header ...
 /*
  * AT-SPI - Assistive Technology Service Provider Interface
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
index 1a23332..3154464 100644 (file)
@@ -25,6 +25,7 @@
 #include <config.h>
 #include <stdio.h>
 #include <libspi/action.h>
+#include <atk/atkaction.h>
 
 /*
  * Static function declarations
@@ -34,8 +35,6 @@ static void
 spi_action_class_init (SpiActionClass *klass);
 static void
 spi_action_init (SpiAction *action);
-static void
-spi_action_finalize (GObject *obj);
 static CORBA_long
 impl__get_nActions(PortableServer_Servant servant,
                 CORBA_Environment * ev);
@@ -55,22 +54,15 @@ impl_getKeyBinding (PortableServer_Servant servant,
                    const CORBA_long index,
                    CORBA_Environment * ev);
 
-static GObjectClass *parent_class;
-
 BONOBO_TYPE_FUNC_FULL (SpiAction,
                       Accessibility_Action,
-                      BONOBO_TYPE_OBJECT,
+                      SPI_TYPE_BASE,
                       spi_action);
 
 static void
 spi_action_class_init (SpiActionClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Action__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_action_finalize;
-
 
   /* Initialize epv table */
 
@@ -86,66 +78,63 @@ spi_action_init (SpiAction *action)
 {
 }
 
-static void
-spi_action_finalize (GObject *obj)
-{
-  SpiAction *action = SPI_ACTION (obj);
-  g_object_unref (action->atko);
-  action->atko = NULL;
-  parent_class->finalize (obj);
-}
-
 SpiAction *
 spi_action_interface_new (AtkObject *obj)
 {
   SpiAction *new_action = g_object_new (SPI_ACTION_TYPE, NULL);
-  new_action->atko = obj;
-  g_object_ref (obj);
+
+  spi_base_construct (SPI_BASE (new_action), obj);
+
   return new_action;
 }
 
+static AtkAction *
+get_action_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (servant);
+  return ATK_ACTION (object->atko);
+}
+
 static CORBA_long
-impl__get_nActions(PortableServer_Servant servant,
-           CORBA_Environment * ev)
+impl__get_nActions (PortableServer_Servant servant,
+                   CORBA_Environment     *ev)
 {
-  SpiAction *action = SPI_ACTION (bonobo_object_from_servant(servant));
-  return (CORBA_long) atk_action_get_n_actions (ATK_ACTION(action->atko));
+  AtkAction *action = get_action_from_servant (servant);
+  return (CORBA_long) atk_action_get_n_actions (action);
 }
 
 static CORBA_boolean
 impl_doAction (PortableServer_Servant servant,
               const CORBA_long index, CORBA_Environment * ev)
 {
-  SpiAction *action = SPI_ACTION (bonobo_object_from_servant (servant));
-  return (CORBA_boolean) atk_action_do_action (ATK_ACTION(action->atko), (gint) index);
+  AtkAction *action = get_action_from_servant (servant);
+  return (CORBA_boolean) atk_action_do_action (action, (gint) index);
 }
 
-
 static CORBA_string
 impl_getDescription (PortableServer_Servant servant,
                const CORBA_long index,
                CORBA_Environment * ev)
 {
-  SpiAction *action = SPI_ACTION (bonobo_object_from_servant(servant));
+  AtkAction *action = get_action_from_servant (servant);
   const gchar *rv;
   
-  rv = atk_action_get_description (ATK_ACTION(action->atko), (gint) index);
+  rv = atk_action_get_description (action, (gint) index);
   if (rv)
     return CORBA_string_dup (rv);
   else
     return CORBA_string_dup ("");
 }
 
-
 static CORBA_string
 impl_getName (PortableServer_Servant servant,
                const CORBA_long index,
                CORBA_Environment * ev)
 {
-  SpiAction *action = SPI_ACTION (bonobo_object_from_servant(servant));
+  AtkAction *action = get_action_from_servant (servant);
   const gchar *rv;
   
-  rv = atk_action_get_name (ATK_ACTION(action->atko), (gint) index);
+  rv = atk_action_get_name (action, (gint) index);
   if (rv)
     return CORBA_string_dup (rv);
   else
@@ -157,10 +146,10 @@ impl_getKeyBinding (PortableServer_Servant servant,
                    const CORBA_long index,
                    CORBA_Environment * ev)
 {
-  SpiAction *action = SPI_ACTION (bonobo_object_from_servant(servant));
+  AtkAction *action = get_action_from_servant (servant);
   const gchar *rv;
   
-  rv = atk_action_get_keybinding (ATK_ACTION(action->atko), (gint) index);
+  rv = atk_action_get_keybinding (action, (gint) index);
   if (rv)
     return CORBA_string_dup (rv);
   else
index cb63045..7396b4b 100644 (file)
@@ -20,9 +20,7 @@
 #ifndef SPI_ACTION_H_
 #define SPI_ACTION_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
 
 G_BEGIN_DECLS
 
@@ -36,20 +34,16 @@ typedef struct _Action SpiAction;
 typedef struct _ActionClass SpiActionClass;
 
 struct _Action {
-  BonoboObject parent;
-  AtkObject *atko;
+  SpiBase parent;
 };
 
 struct _ActionClass {
-  BonoboObjectClass parent_class;
+  SpiBaseClass parent_class;
   POA_Accessibility_Action__epv epv;
 };
 
-GType
-spi_action_get_type   (void);
-
-SpiAction *
-spi_action_interface_new       (AtkObject *obj);
+GType      spi_action_get_type      (void);
+SpiAction *spi_action_interface_new (AtkObject *obj);
 
 G_END_DECLS
 
index 1b5e14b..63f7f85 100644 (file)
 #include <atk/atkutil.h>
 #include <libspi/application.h>
 
-/*
- * Our parent Gtk object type
- */
+/* Our parent Gtk object type */
 #define PARENT_TYPE SPI_ACCESSIBLE_TYPE
 
-/*
- * A pointer to our parent object class
- */
+/* A pointer to our parent object class */
 static SpiAccessibleClass *spi_application_parent_class;
 
 static SpiApplication *the_app;
@@ -42,25 +38,25 @@ static SpiApplication *the_app;
 /* static methods */
 
 static void notify_listeners (GList *listeners,
-                             Accessibility_Event *e,
-                             CORBA_Environment *ev);
+                             SpiAccessible *source,
+                             Accessibility_Event *e);
 
-static char *reverse_lookup_name_for_toolkit_event (char *toolkit_name);
+static const char *reverse_lookup_name_for_toolkit_event (char *toolkit_name);
 
 static const char *
 lookup_toolkit_event_for_name (const char *generic_name)
 {
-    char *toolkit_specific_name;
-    SpiApplicationClass *klass = g_type_class_peek (SPI_APPLICATION_TYPE);
+  char *toolkit_specific_name;
+  SpiApplicationClass *klass = g_type_class_peek (SPI_APPLICATION_TYPE);
 #ifdef SPI_DEBUG
-    fprintf (stderr, "looking for %s in hash table.\n", generic_name);
+  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);
+  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);
+  fprintf (stderr, "generic event %s converted to %s\n", generic_name, toolkit_specific_name);
 #endif
-    return toolkit_specific_name;
+  return toolkit_specific_name;
 }
 
 /*
@@ -69,32 +65,48 @@ lookup_toolkit_event_for_name (const char *generic_name)
 static void
 spi_accessible_application_finalize (GObject *object)
 {
-  /* TODO: any necessary cleanup */
+  GList *l;
+  SpiApplication *application = (SpiApplication *) object;
+  CORBA_Environment ev;
+
+  CORBA_exception_init (&ev);
+
+  for (l = application->toolkit_listeners; l; l = l->next)
+    {
+      CORBA_Object_release ((CORBA_Object) l->data, &ev);
+    }
+
+  CORBA_exception_free (&ev);
+
+  g_list_free (application->toolkit_listeners);
+  application->toolkit_listeners = NULL;
+
   g_print ("application finalize called\n");
   (G_OBJECT_CLASS (spi_application_parent_class))->finalize (object);
 }
 
 static CORBA_string
 impl_accessibility_application_get_toolkit_name (PortableServer_Servant servant,
-                                                 CORBA_Environment *ev)
+                                                 CORBA_Environment     *ev)
 {
-       return CORBA_string_dup (atk_get_toolkit_name ());
+  return CORBA_string_dup (atk_get_toolkit_name ());
 }
 
 static CORBA_string
 impl_accessibility_application_get_version (PortableServer_Servant servant,
-                                            CORBA_Environment *ev)
+                                            CORBA_Environment     *ev)
 {
-       return CORBA_string_dup (atk_get_toolkit_version ());
+  return CORBA_string_dup (atk_get_toolkit_version ());
 }
 
 static CORBA_long
 impl_accessibility_application_get_id (PortableServer_Servant servant,
-                                       CORBA_Environment *ev)
+                                       CORBA_Environment     *ev)
 {
-       SpiApplication *application = SPI_APPLICATION (
-               bonobo_object_from_servant (servant));
-       return application->id;
+  SpiApplication *application = SPI_APPLICATION (
+    bonobo_object_from_servant (servant));
+
+  return application->id;
 }
 
 static void
@@ -102,116 +114,120 @@ impl_accessibility_application_set_id (PortableServer_Servant servant,
                                        const CORBA_long id,
                                        CORBA_Environment *ev)
 {
-       SpiApplication *application = SPI_APPLICATION (
-               bonobo_object_from_servant (servant));
-       application->id = id;
+  SpiApplication *application = SPI_APPLICATION (
+    bonobo_object_from_servant (servant));
+
+  application->id = id;
 }
 
-#define APP_STATIC_BUFF_SZ 64
+static AtkObject *
+get_atk_object_ref (GObject *gobject)
+{
+  AtkObject *aobject;
+
+  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
+    {
+      aobject = NULL;
+      g_error ("received event from non-AtkImplementor");
+    }
+
+  return aobject;
+}
 
 static gboolean
 spi_application_object_event_listener (GSignalInvocationHint *signal_hint,
-                                  guint n_param_values,
-                                  const GValue *param_values,
-                                  gpointer data)
+                                      guint                   n_param_values,
+                                      const GValue           *param_values,
+                                      gpointer                data)
 {
-  Accessibility_Event *e = Accessibility_Event__alloc();
-  AtkObject *aobject;
-  GObject *gobject;
+  Accessibility_Event e;
+  AtkObject     *aobject;
   SpiAccessible *source;
-  CORBA_Environment ev;
-  GSignalQuery signal_query;
-  const gchar *name;
-  char sbuf[APP_STATIC_BUFF_SZ];
-  char *generic_name;
+  GSignalQuery   signal_query;
+  gchar         *event_name;
+  const char    *generic_name;
+
+  g_return_val_if_fail (the_app != NULL, FALSE);
   
   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);
+  /* TODO: move GTK reference out of app.c into bridge */
+  event_name = g_strdup_printf ("Gtk:%s:%s",
+                               g_type_name (signal_query.itype),
+                               signal_query.signal_name);
 
-  generic_name = reverse_lookup_name_for_toolkit_event (sbuf);
-  gobject = g_value_get_object (param_values + 0);
+  generic_name = reverse_lookup_name_for_toolkit_event (event_name);
 
-  /* 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
-  {
-    aobject = NULL;
-    g_error("received event from non-AtkImplementor");
-  }
+  fprintf (stderr, "Received (object) signal %s maps to '%s'\n",
+          event_name, generic_name);
+
+  g_free (event_name);
 
   g_return_val_if_fail (generic_name, FALSE);
-  if (generic_name)
-    {
-        source = spi_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 spi_accessible_new() above should have added an extra ref */
+
+  aobject = get_atk_object_ref (g_value_get_object (param_values + 0));
+
+  source = spi_accessible_new (aobject);
+  e.type = CORBA_string_dup (generic_name);
+  e.source = CORBA_OBJECT_NIL;
+  e.detail1 = 0;
+  e.detail2 = 0;
+
+  notify_listeners (the_app->toolkit_listeners, source, &e);
+
+  bonobo_object_unref (BONOBO_OBJECT (source));
+
   g_object_unref (G_OBJECT (aobject));
 
   return TRUE;
 }
 
-
 static gboolean
 spi_application_toolkit_event_listener (GSignalInvocationHint *signal_hint,
-                                   guint n_param_values,
-                                   const GValue *param_values,
-                                   gpointer data)
+                                       guint                  n_param_values,
+                                       const GValue          *param_values,
+                                       gpointer               data)
 {
-  Accessibility_Event *e = Accessibility_Event__alloc();
-  AtkObject *aobject;
-  GObject *gobject;
+  Accessibility_Event e;
+  AtkObject      *aobject;
   SpiAccessible *source;
-  CORBA_Environment ev;
-  GSignalQuery signal_query;
-  const char *name;
-  char sbuf[APP_STATIC_BUFF_SZ];
+  GSignalQuery   signal_query;
+  char          *event_name;
+
+  g_return_val_if_fail (the_app != NULL, FALSE);
 
   g_signal_query (signal_hint->signal_id, &signal_query);
-  name = signal_query.signal_name;
-  fprintf (stderr, "Received 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);
+  /* TODO: move GTK reference out of app.c into bridge */
+  event_name = g_strdup_printf ("Gtk:%s:%s",
+                               g_type_name (signal_query.itype), 
+                               signal_query.signal_name);
+
+  fprintf (stderr, "Received signal %s\n", event_name);
+
+  aobject = get_atk_object_ref (g_value_get_object (param_values + 0));
+
+  source = spi_accessible_new (aobject);
+  e.type = CORBA_string_dup (event_name);
+  e.source = CORBA_OBJECT_NIL;
+  e.detail1 = 0;
+  e.detail2 = 0;
+  notify_listeners (the_app->toolkit_listeners, source, &e);
+
+  bonobo_object_unref (BONOBO_OBJECT (source));
+  g_object_unref (G_OBJECT (aobject));
+
+  g_free (event_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 = spi_accessible_new (aobject);
-      e->type = CORBA_string_dup (sbuf);
-      e->source = BONOBO_OBJREF (source);
-      e->detail1 = 0;
-      e->detail2 = 0;
-      if (the_app) notify_listeners (the_app->toolkit_listeners, e, &ev);
-      bonobo_object_unref (BONOBO_OBJECT (source));
-      g_object_unref (G_OBJECT (aobject));
-    }
   return TRUE;
 }
 
@@ -223,7 +239,7 @@ impl_accessibility_application_register_toolkit_event_listener (PortableServer_S
 {
   guint spi_listener_id;
   spi_listener_id =
-     atk_add_global_event_listener (spi_application_toolkit_event_listener, (char *) event_name);
+     atk_add_global_event_listener (spi_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
@@ -246,7 +262,7 @@ impl_accessibility_application_register_object_event_listener (PortableServer_Se
   {
     spi_listener_id =
        atk_add_global_event_listener (spi_application_object_event_listener,
-                                     CORBA_string_dup (toolkit_specific_event_name));
+                                     toolkit_specific_event_name);
     the_app->toolkit_listeners = g_list_append (the_app->toolkit_listeners,
                                              CORBA_Object_duplicate (listener, ev));
   }
@@ -258,34 +274,38 @@ impl_accessibility_application_register_object_event_listener (PortableServer_Se
 }
 
 static void
-notify_listeners (GList *listeners, Accessibility_Event *e, CORBA_Environment *ev)
+notify_listeners (GList *listeners, SpiAccessible *source, Accessibility_Event *e)
 {
-    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
-        */
+  GList *l;
+  CORBA_Environment ev;
+
+  CORBA_exception_init (&ev);
+
+  for (l = listeners; l; l = l->next)
+    {
+      Accessibility_EventListener listener = l->data;
+
+      e->source = bonobo_object_dup_ref (BONOBO_OBJREF (source), &ev);
+
+      Accessibility_EventListener_notifyEvent (listener, e, &ev);
+      /*
+       * when this (oneway) call completes, the CORBA refcount and
+       * Bonobo_Unknown refcount will be decremented by the recipient
+       */
+      CORBA_exception_free (&ev);
     }
 }
 
-static char *
+static const char *
 reverse_lookup_name_for_toolkit_event (char *toolkit_specific_name)
 {
-    char *generic_name;
+    const char *generic_name;
     SpiApplicationClass *klass = g_type_class_peek (SPI_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);
+           (const 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
@@ -327,9 +347,8 @@ spi_application_class_init (SpiApplicationClass *klass)
 }
 
 static void
-spi_application_init (SpiApplication  *application)
+spi_application_init (SpiApplication *application)
 {
-  application->parent.atko = g_object_new (ATK_TYPE_OBJECT, NULL);
   application->toolkit_listeners = NULL;
   the_app = application;
 }
@@ -341,9 +360,9 @@ BONOBO_TYPE_FUNC_FULL (SpiApplication,
 SpiApplication *
 spi_application_new (AtkObject *app_root)
 {
-    SpiApplication *retval = g_object_new (SPI_APPLICATION_TYPE, NULL);
-    g_object_unref (retval->parent.atko);
-    retval->parent.atko = app_root;
-    g_object_ref (G_OBJECT (app_root));
-    return retval;
+  SpiApplication *retval = g_object_new (SPI_APPLICATION_TYPE, NULL);
+
+  spi_base_construct (SPI_BASE (retval), app_root);
+
+  return retval;
 }
index b1c9140..dfdec56 100644 (file)
 #ifndef SPI_APPLICATION_H_
 #define SPI_APPLICATION_H_
 
-#include <glib/gmacros.h>
-#include <atk/atkobject.h>
 #include <libspi/accessible.h>
-#include <libspi/application.h>
-#include <libspi/Accessibility.h>
 
 G_BEGIN_DECLS
 
 #define SPI_APPLICATION_TYPE        (spi_application_get_type ())
 #define SPI_APPLICATION(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_APPLICATION_TYPE, SpiApplication))
 #define SPI_APPLICATION_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_APPLICATION_TYPE, SpiApplicationClass))
-#define IS_SPI_APPLICATION(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_APPLICATION_TYPE))
-#define IS_SPI_APPLICATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_APPLICATION_TYPE))
+#define SPI_IS_APPLICATION(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_APPLICATION_TYPE))
+#define SPI_IS_APPLICATION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_APPLICATION_TYPE))
 
 typedef struct {
         SpiAccessible parent;
@@ -51,7 +47,11 @@ typedef struct {
 } SpiApplicationClass;
 
 GType           spi_application_get_type (void);
-SpiApplication *spi_application_new      (AtkObject *app_root);
+SpiApplication *spi_application_new      (AtkObject    *app_root);
+void            spi_emit_eventv          (GObject      *gobject,
+                                         unsigned long detail1,
+                                         unsigned long detail2,
+                                         const char   *format, ...);
 
 G_END_DECLS
 
index a7f4097..b4d19f8 100644 (file)
@@ -1,50 +1,88 @@
-#include <libspi/base.h>
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2001 Ximian Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* object.c: the base object managing an AtkObject proxy */
+
+#include <config.h>
+#include <stdio.h>
+#include <libspi/libspi.h>
+
+/* Our parent Gtk object type  */
+#define PARENT_TYPE BONOBO_TYPE_OBJECT
 
 /* A pointer to our parent object class */
 static GObjectClass *spi_base_parent_class;
 
+/*
+ * Implemented GObject::dispose
+ */
 static void
-spi_base_dispose (GObject *object)
+spi_base_object_dispose (GObject *gobject)
 {
-       SpiBase *base = SPI_BASE (object);
+  SpiBase *object = SPI_BASE (gobject);
 
-       if (base->atko) {
-               g_object_unref (base->atko);
-               base->atko = NULL;
-       }
+  if (object->atko)
+    {
+      g_assert (ATK_IS_OBJECT (object->atko));
+      g_object_unref (G_OBJECT (object->atko));
+      object->atko = NULL;
+    }
 
-       spi_base_parent_class->dispose (object);
+  spi_base_parent_class->dispose (gobject);
 }
 
 static void
-spi_base_class_init (GObjectClass *klass)
+spi_base_class_init (SpiBaseClass *klass)
 {
-       spi_base_parent_class = g_type_klass_peek_parent (klass);
+        GObjectClass * object_class = (GObjectClass *) klass;
 
-       klass->dispose = spi_base_dispose;
+        spi_base_parent_class = g_type_class_peek_parent (klass);
+
+        object_class->dispose = spi_base_object_dispose;
 }
 
 static void
-spi_base_init (SpiBase *base)
+spi_base_init (SpiBase *object)
 {
 }
 
-BONOBO_TYPE_FUNC (SpiBase, BONOBO_TYPE_OBJECT, spi_base);
+BONOBO_TYPE_FUNC (SpiBase, PARENT_TYPE, spi_base);
 
-gpointer
-spi_base_construct (SpiBase   *base,
-                   AtkObject *o)
+void
+spi_base_construct (SpiBase *object, AtkObject *aobject)
 {
-       g_return_val_if_fail (ATK_IS_OBJECT (o), NULL);
-       g_return_val_if_fail (SPI_IS_BASE (base), NULL);
+  object->atko = g_object_ref (G_OBJECT (aobject));
+}
 
-       base->atko = g_object_ref (o);
+void
+spi_base_construct_default (SpiBase *object)
+{
+  object->atko = g_object_new (ATK_TYPE_OBJECT, NULL);
 }
 
 AtkObject *
-spi_base_get_atk_object (SpiBase *base)
+spi_base_get_atkobject (SpiBase *object)
 {
-       g_return_val_if_fail (SPI_IS_BASE (base), NULL);
+  g_return_val_if_fail (ATK_IS_OBJECT (object), NULL);
 
-       return base->atko;
+  return object->atko;
 }
index dae8961..2f1c206 100644 (file)
@@ -1,5 +1,5 @@
 /* AT-SPI : Assistive Technology Service Provider Interface
- * Copyright 2001 Ximian, Inc.
+ * Copyright 2001 Sun Microsystems Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
 #ifndef SPI_BASE_H_
 #define SPI_BASE_H_
 
 #include <glib/gmacros.h>
-#include <bonobo/bonobo-object.h>
 #include <atk/atkobject.h>
+#include <bonobo/bonobo-object.h>
+#include <libspi/Accessibility.h>
 
 G_BEGIN_DECLS
 
-#define SPI_ACCESSIBLE_TYPE        (spi_accessible_get_type ())
-#define SPI_ACCESSIBLE(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_ACCESSIBLE_TYPE, SpiAccessible))
-#define SPI_ACCESSIBLE_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_ACCESSIBLE_TYPE, SpiAccessibleClass))
-#define IS_SPI_ACCESSIBLE(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_ACCESSIBLE_TYPE))
-#define IS_SPI_ACCESSIBLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_ACCESSIBLE_TYPE))
+#define SPI_TYPE_BASE        (spi_base_get_type ())
+#define SPI_BASE(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_TYPE_BASE, SpiBase))
+#define SPI_BASE_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_TYPE_BASE, SpiBaseClass))
+#define SPI_IS_BASE(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_TYPE_BASE))
+#define SPI_IS_BASE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_TYPE_BASE))
 
 typedef struct {
         BonoboObject parent;
-
         AtkObject   *atko;
 } SpiBase;
 
@@ -41,10 +42,11 @@ typedef struct {
         BonoboObjectClass parent_class;
 } SpiBaseClass;
 
-GType      spi_base_get_type       (void);
-gpointer   spi_base_construct      (SpiBase   *base,
-                                   AtkObject *o);
-AtkObject *spi_base_get_atk_object (SpiBase   *base);
+GType      spi_base_get_type          (void);
+void       spi_base_construct         (SpiBase   *base,
+                                      AtkObject *aobject);
+void       spi_base_construct_default (SpiBase   *base);
+AtkObject *spi_base_get_atkbase       (SpiBase   *base);
 
 G_END_DECLS
 
index 86c5315..b519286 100644 (file)
 #include <libspi/component.h>
 
 /* Our parent Gtk object type */
-#define PARENT_TYPE BONOBO_TYPE_OBJECT
+#define PARENT_TYPE SPI_TYPE_BASE
 
 /* A pointer to our parent object class */
 static GObjectClass *spi_component_parent_class;
 
-/*
- * Implemented GObject::finalize
- */
-static void
-accessibility_component_object_finalize (GObject *object)
+static AtkComponent *
+get_component_from_servant (PortableServer_Servant servant)
 {
-        SpiComponent *component = SPI_COMPONENT (object);
-
-        printf("spi_accessible_component_object_finalize called\n");
-        g_object_unref (component->atko);
-       component->atko = NULL;
-
-        printf("component atko freed, calling parent finalize\n");
-        spi_component_parent_class->finalize (object);
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+  g_return_val_if_fail (object != NULL, NULL);
+  return ATK_COMPONENT (object->atko);
 }
 
 /*
@@ -60,14 +52,11 @@ impl_accessibility_component_contains (PortableServer_Servant servant,
                                        CORBA_Environment     *ev)
 {
   CORBA_boolean retval;
-  BonoboObject *obj;
-  SpiComponent *component;
-
-  obj = bonobo_object_from_servant (servant);
-  g_return_val_if_fail (IS_SPI_COMPONENT(obj), FALSE);
-  component = SPI_COMPONENT (obj);
-  g_return_val_if_fail (ATK_IS_COMPONENT(component->atko), FALSE);
-  retval = atk_component_contains (ATK_COMPONENT (component->atko), (gint) x, (gint) y,
+  AtkComponent *component = get_component_from_servant (servant);
+
+  g_return_val_if_fail (component != NULL, FALSE);
+
+  retval = atk_component_contains (component, (gint) x, (gint) y,
                                   (AtkCoordType) coord_type);
   return retval;
 }
@@ -82,50 +71,40 @@ impl_accessibility_component_get_accessible_at_point (PortableServer_Servant ser
                                                       CORBA_short coord_type,
                                                       CORBA_Environment     *ev)
 {
-  BonoboObject *obj;
-  SpiComponent *component;
-  Accessibility_Accessible retval;
-  AtkObject *child;
-
-  obj = bonobo_object_from_servant (servant);
-  g_return_val_if_fail (IS_SPI_COMPONENT(obj), CORBA_OBJECT_NIL);
-  component = SPI_COMPONENT (obj);
-  g_return_val_if_fail (ATK_IS_COMPONENT(component->atko), CORBA_OBJECT_NIL);
-
-  child = atk_component_ref_accessible_at_point (ATK_COMPONENT (component->atko),
-                                                  (gint) x, (gint) y,
-                                                  (AtkCoordType) coord_type);
-  retval = bonobo_object_corba_objref (bonobo_object (spi_accessible_new (child)));
-  return CORBA_Object_duplicate (retval, ev);
+  AtkObject    *child;
+  AtkComponent *component = get_component_from_servant (servant);
+
+  g_return_val_if_fail (component != NULL, FALSE);
+
+  child = atk_component_ref_accessible_at_point (component,
+                                                (gint) x, (gint) y,
+                                                (AtkCoordType) coord_type);
+  return spi_accessible_new_return (child, TRUE, ev);
 }
 
 /*
  * CORBA Accessibility::Component::getExtents method implementation
  */
-static void
+static Accessibility_BoundingBox
 impl_accessibility_component_get_extents (PortableServer_Servant servant,
-                                          CORBA_long * x,
-                                          CORBA_long * y,
-                                          CORBA_long * width,
-                                          CORBA_long * height,
-                                          const CORBA_short coord_type,
+                                          const CORBA_short      coord_type,
                                           CORBA_Environment     *ev)
 {
-  BonoboObject *obj;
-  SpiComponent *component;
   gint ix, iy, iw, ih;
+  Accessibility_BoundingBox retval;
+  AtkComponent *component = get_component_from_servant (servant);
 
-  obj = bonobo_object_from_servant (servant);
-  g_return_if_fail (IS_SPI_COMPONENT(obj));
-  component = SPI_COMPONENT (obj);
-  g_return_if_fail (ATK_IS_COMPONENT (component->atko));
+  g_return_if_fail (component != NULL);
 
-  atk_component_get_extents (ATK_COMPONENT (component->atko), &ix, &iy, &iw, &ih,
-                                  (AtkCoordType) coord_type);
-  *x = (CORBA_long) ix;
-  *y = (CORBA_long) iy;
-  *width = (CORBA_long) iw;
-  *height = (CORBA_long) ih;
+  atk_component_get_extents (component, &ix, &iy, &iw, &ih,
+                            (AtkCoordType) coord_type);
+
+  retval.x = ix;
+  retval.y = ix;
+  retval.width = iw;
+  retval.height = ih;
+
+  return retval;
 }
 
 /*
@@ -138,15 +117,12 @@ impl_accessibility_component_get_position (PortableServer_Servant servant,
                                            const CORBA_short coord_type,
                                            CORBA_Environment     *ev)
 {
-  BonoboObject *obj = bonobo_object_from_servant (servant);
-  SpiComponent *component;
   gint ix, iy;
+  AtkComponent *component = get_component_from_servant (servant);
 
-  g_return_if_fail (IS_SPI_COMPONENT(obj));
-  component = SPI_COMPONENT(obj);
-  g_return_if_fail (ATK_IS_COMPONENT(component->atko));
+  g_return_if_fail (component != NULL);
 
-  atk_component_get_position (ATK_COMPONENT (component->atko), &ix, &iy,
+  atk_component_get_position (component, &ix, &iy,
                               (AtkCoordType) coord_type);
   *x = (CORBA_long) ix;
   *y = (CORBA_long) iy;
@@ -161,14 +137,12 @@ impl_accessibility_component_get_size (PortableServer_Servant servant,
                                        CORBA_long * height,
                                        CORBA_Environment     *ev)
 {
-  SpiComponent *component;
-  BonoboObject *obj = bonobo_object_from_servant (servant);
   gint iw, ih;
+  AtkComponent *component = get_component_from_servant (servant);
+
+  g_return_if_fail (component != NULL);
 
-  g_return_if_fail (IS_SPI_COMPONENT(obj));
-  component = SPI_COMPONENT(obj);
-  g_return_if_fail (ATK_IS_COMPONENT(component->atko));
-  atk_component_get_size (ATK_COMPONENT (component->atko), &iw, &ih);
+  atk_component_get_size (component, &iw, &ih);
   *width = (CORBA_long) iw;
   *height = (CORBA_long) ih;
 }
@@ -177,14 +151,12 @@ static Accessibility_ComponentLayer
 impl_accessibility_component_get_layer (PortableServer_Servant servant,
                                        CORBA_Environment     *ev)
 {
-  SpiComponent *component;
-  AtkLayer atklayer;
-  BonoboObject *obj = bonobo_object_from_servant (servant);
-
-  g_return_if_fail (IS_SPI_COMPONENT(obj));
-  component = SPI_COMPONENT(obj);
-  g_return_if_fail (ATK_IS_COMPONENT(component->atko));
-  atklayer = atk_object_get_layer (ATK_OBJECT (component->atko));
+  AtkLayer      atklayer;
+  AtkComponent *component = get_component_from_servant (servant);
+
+  g_return_val_if_fail (component != NULL, Accessibility_LAYER_INVALID);
+
+  atklayer = atk_object_get_layer (ATK_OBJECT (component));
   switch (atklayer)
     {
       case ATK_LAYER_BACKGROUND:
@@ -209,24 +181,19 @@ static CORBA_short
 impl_accessibility_component_get_mdi_z_order (PortableServer_Servant servant,
                                              CORBA_Environment     *ev)
 {
-  SpiComponent *component;
-  BonoboObject *obj = bonobo_object_from_servant (servant);
+  AtkComponent *component = get_component_from_servant (servant);
+
+  g_return_val_if_fail (component != NULL, -1);
 
-  g_return_if_fail (IS_SPI_COMPONENT(obj));
-  component = SPI_COMPONENT(obj);
-  g_return_if_fail (ATK_IS_COMPONENT(component->atko));
-  return (CORBA_short) atk_object_get_mdi_zorder (ATK_OBJECT (component->atko));
+  return (CORBA_short) atk_object_get_mdi_zorder (ATK_OBJECT (component));
 }
 
 static void
 spi_component_class_init (SpiComponentClass *klass)
 {
-        GObjectClass * object_class = (GObjectClass *) klass;
         POA_Accessibility_Component__epv *epv = &klass->epv;
         spi_component_parent_class = g_type_class_peek_parent (klass);
 
-        object_class->finalize = accessibility_component_object_finalize;
-
         epv->contains = impl_accessibility_component_contains;
         epv->getAccessibleAtPoint = impl_accessibility_component_get_accessible_at_point;
         epv->getExtents = impl_accessibility_component_get_extents;
@@ -250,7 +217,8 @@ SpiComponent *
 spi_component_interface_new (AtkObject *o)
 {
     SpiComponent *retval = g_object_new (SPI_COMPONENT_TYPE, NULL);
-    retval->atko = o;
-    g_object_ref (o);
+
+    spi_base_construct (SPI_BASE (retval), o);
+
     return retval;
 }
index 667b1fe..769b7e5 100644 (file)
 #ifndef SPI_COMPONENT_H_
 #define SPI_COMPONENT_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
+#include <atk/atkcomponent.h>
 
 G_BEGIN_DECLS
 
 #define SPI_COMPONENT_TYPE        (spi_component_get_type ())
 #define SPI_COMPONENT(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_COMPONENT_TYPE, SpiComponent))
 #define SPI_COMPONENT_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_COMPONENT_TYPE, SpiComponentClass))
-#define IS_SPI_COMPONENT(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_COMPONENT_TYPE))
-#define IS_SPI_COMPONENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_COMPONENT_TYPE))
+#define SPI_IS_COMPONENT(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_COMPONENT_TYPE))
+#define SPI_IS_COMPONENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_COMPONENT_TYPE))
 
 typedef struct {
-        BonoboObject parent;
-        AtkObject   *atko;
+        SpiBase parent;
 } SpiComponent;
 
 typedef struct {
-        BonoboObjectClass parent_class;
+        SpiBaseClass parent_class;
         POA_Accessibility_Component__epv epv;
 } SpiComponentClass;
 
index 8907d42..9258398 100644 (file)
@@ -2,7 +2,7 @@
  * AT-SPI - Assistive Technology Service Provider Interface
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
- * Copyright 2001 Sun Microsystems Inc.
+ * Copyright 2001 Sun Microsystems Inc., Ximian Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 /* Our parent Gtk object type */
 #define PARENT_TYPE SPI_ACCESSIBLE_TYPE
 
+typedef struct {
+       SpiDesktop *desktop;
+       Accessibility_Application ref;
+} Application;
+
 /* A pointer to our parent object class */
 static SpiAccessibleClass *parent_class;
 
 static void
-spi_desktop_init (SpiDesktop  *desktop)
+spi_desktop_init (SpiDesktop *desktop)
 {
-  SPI_ACCESSIBLE (desktop)->atko = g_object_new (ATK_TYPE_OBJECT, NULL);
+  spi_base_construct_default (SPI_BASE (desktop));
+
   desktop->applications = NULL;
-  atk_object_set_name (ATK_OBJECT (SPI_ACCESSIBLE (desktop)->atko), "main");
+
+  atk_object_set_name (SPI_BASE (desktop)->atko, "main");
 }
 
 static void
-spi_desktop_finalize (GObject *object)
+spi_desktop_dispose (GObject *object)
 {
-  (G_OBJECT_CLASS (parent_class))->finalize (object); 
+  SpiDesktop *desktop = (SpiDesktop *) object;
+
+  while (desktop->applications)
+    {
+      Application *app = (Application *) desktop->applications;
+      spi_desktop_remove_application (desktop, app->ref);
+    }
+
+  G_OBJECT_CLASS (parent_class)->dispose (object); 
 }
 
 static CORBA_long
 impl_desktop_get_child_count (PortableServer_Servant servant,
-                              CORBA_Environment ev)
+                              CORBA_Environment     *ev)
 {
   SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
+
   if (desktop->applications)
     {
       return g_list_length (desktop->applications);
@@ -64,41 +80,47 @@ impl_desktop_get_child_count (PortableServer_Servant servant,
 
 static Accessibility_Accessible
 impl_desktop_get_child_at_index (PortableServer_Servant servant,
-                                 const CORBA_long index,
-                                 CORBA_Environment ev)
+                                 const CORBA_long       index,
+                                 CORBA_Environment     *ev)
 {
-  SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
+  SpiDesktop  *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
   CORBA_Object retval;
-  if ((desktop->applications) && (index < g_list_length (desktop->applications)))
+  Application *app;
+
+  app = g_list_nth_data (desktop->applications, index);
+
+  if (app)
     {
-      fprintf (stderr, "getting application %ld\n", (long) index);
-      /* */
-      fprintf (stderr, "object address %p\n",
-               g_list_nth_data (desktop->applications, index));
-      retval =  bonobo_object_dup_ref (
-              (CORBA_Object) g_list_nth_data (desktop->applications, index), ev);
+      retval = bonobo_object_dup_ref (app->ref, ev);
+      if (BONOBO_EX (ev))
+        {
+          CORBA_exception_free (ev);
+         CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+                              ex_Accessibility_ChildGone, NULL);
+         retval = CORBA_OBJECT_NIL;
+       }
     }
   else
     {
-      fprintf (stderr, "no %ldth child\n", (long) index);
       retval = CORBA_OBJECT_NIL;
     }
+
   return (Accessibility_Accessible) retval;
 }
 
 static void
-spi_desktop_class_init (SpiDesktopClass  *klass)
+spi_desktop_class_init (SpiDesktopClass *klass)
 {
-        GObjectClass * object_class = (GObjectClass *) klass;
-        SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass;
-        POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv;
+  GObjectClass * object_class = (GObjectClass *) klass;
+  SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass;
+  POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv;
 
-        object_class->finalize = spi_desktop_finalize;
+  object_class->dispose = spi_desktop_dispose;
+  
+  parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE);
 
-        parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE);
-
-        epv->_get_childCount = impl_desktop_get_child_count;
-        epv->getChildAtIndex = impl_desktop_get_child_at_index;
+  epv->_get_childCount = impl_desktop_get_child_count;
+  epv->getChildAtIndex = impl_desktop_get_child_at_index;
 }
 
 BONOBO_TYPE_FUNC_FULL (SpiDesktop,
@@ -109,7 +131,80 @@ BONOBO_TYPE_FUNC_FULL (SpiDesktop,
 SpiDesktop *
 spi_desktop_new (void)
 {
-    SpiDesktop *retval = g_object_new (SPI_DESKTOP_TYPE, NULL);
+  SpiDesktop *retval = g_object_new (SPI_DESKTOP_TYPE, NULL);
+
+  return retval;
+}
+
+static void
+abnormal_application_termination (gpointer object, Application *app)
+{
+  g_return_if_fail (SPI_IS_DESKTOP (app->desktop));
+
+  spi_desktop_remove_application (app->desktop, app->ref);
+}
+
+void
+spi_desktop_add_application (SpiDesktop *desktop,
+                            const Accessibility_Application application)
+{
+  CORBA_Environment ev;
+  Application       *app;
+  Accessibility_Application ref;
+
+  g_return_if_fail (SPI_IS_DESKTOP (desktop));
+
+  spi_desktop_remove_application (desktop, application);
+
+  CORBA_exception_init (&ev);
+
+  ref = bonobo_object_dup_ref (application, &ev);
+
+  if (!BONOBO_EX (&ev))
+    {
+      app = g_new (Application, 1);
+      app->desktop = desktop;
+      app->ref = ref;
+
+      desktop->applications = g_list_append (desktop->applications, app);
+
+      ORBit_small_listen_for_broken (app->ref, G_CALLBACK (abnormal_application_termination), app);
+    }
+
+  CORBA_exception_free (&ev);
+}
+
+void
+spi_desktop_remove_application (SpiDesktop *desktop,
+                               const Accessibility_Application app_ref)
+{
+  GList *l;
+  CORBA_Environment ev;
 
-    return retval;
+  g_return_if_fail (SPI_IS_DESKTOP (desktop));
+
+  CORBA_exception_init (&ev);
+
+  for (l = desktop->applications; l; l = l->next)
+    {
+      Application *app = (Application *) l->data;
+
+      if (CORBA_Object_is_equivalent (app->ref, app_ref, &ev))
+        {
+         break;
+       }
+    }
+
+  CORBA_exception_free (&ev);
+
+  if (l)
+    {
+      Application *app = (Application *) l->data;
+
+      desktop->applications = g_list_delete_link (desktop->applications, l);
+
+      ORBit_small_unlisten_for_broken (app->ref, G_CALLBACK (abnormal_application_termination));
+      bonobo_object_release_unref (app->ref, NULL);
+      g_free (app);
+    }
 }
index 7a4e290..8c60834 100644 (file)
 #ifndef SPI_DESKTOP_H_
 #define SPI_DESKTOP_H_
 
-#include <bonobo/bonobo-xobject.h>
-#include <atk/atkobject.h>
 #include <libspi/accessible.h>
-#include <libspi/application.h>
-#include <libspi/Accessibility.h>
 
 G_BEGIN_DECLS
 
 #define SPI_DESKTOP_TYPE        (spi_desktop_get_type ())
 #define SPI_DESKTOP(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_DESKTOP_TYPE, SpiDesktop))
 #define SPI_DESKTOP_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_DESKTOP_TYPE, SpiDesktopClass))
-#define IS_SPI_DESKTOP(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_DESKTOP_TYPE))
-#define IS_SPI_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DESKTOP_TYPE))
+#define SPI_IS_DESKTOP(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DESKTOP_TYPE))
+#define SPI_IS_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DESKTOP_TYPE))
 
 typedef struct {
         SpiAccessible parent;
-        GList *applications; /* TODO: maybe change this so it's generated on-demand ? */
+        GList        *applications;
 } SpiDesktop;
 
 typedef struct {
@@ -47,10 +43,12 @@ typedef struct {
         POA_Accessibility_Desktop__epv epv;
 } SpiDesktopClass;
 
-GType               spi_desktop_get_type           (void);
-void                spi_desktop_add_application    (SpiApplication *app);
-void                spi_desktop_remove_application (SpiApplication *app);
-SpiDesktop             *spi_desktop_new               (void);
+GType       spi_desktop_get_type           (void);
+SpiDesktop *spi_desktop_new                (void);
+void        spi_desktop_add_application    (SpiDesktop *desktop,
+                                           const Accessibility_Application application);
+void        spi_desktop_remove_application (SpiDesktop *desktop,
+                                           const Accessibility_Application application);
 
 G_END_DECLS
 
index e3e8c97..8b9ba60 100644 (file)
@@ -33,8 +33,8 @@ G_BEGIN_DECLS
 #define SPI_DEVICE_EVENT_CONTROLLER_TYPE        (spi_device_event_controller_get_type ())
 #define SPI_DEVICE_EVENT_CONTROLLER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_DEVICE_EVENT_CONTROLLER_TYPE, SpiDeviceEventController))
 #define SPI_DEVICE_EVENT_CONTROLLER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_DEVICE_EVENT_CONTROLLER_TYPE, SpiDeviceEventControllerClass))
-#define IS_SPI_DEVICE_EVENT_CONTROLLER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
-#define IS_SPI_DEVICE_EVENT_CONTROLLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
+#define SPI_IS_DEVICE_EVENT_CONTROLLER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
+#define SPI_IS_DEVICE_EVENT_CONTROLLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
 #define SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPI_DEVICE_EVENT_CONTROLLER_TYPE, SpiDeviceEventControllerClass))
 
 typedef struct {
@@ -51,8 +51,9 @@ typedef struct {
        gboolean (*check_key_event) (SpiDeviceEventController *controller);
 } SpiDeviceEventControllerClass;
 
-GType                     spi_device_event_controller_get_type   (void);
-SpiDeviceEventController *spi_device_event_controller_new        (void *registry);
+GType                     spi_device_event_controller_get_type        (void);
+SpiDeviceEventController *spi_device_event_controller_new             (void *registry);
+gboolean                  spi_device_event_controller_check_key_event (SpiDeviceEventController *controller);
 
 G_END_DECLS
 
index 551e2b6..7a14352 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <config.h>
 #include <stdio.h>
+#include <atk/atkeditabletext.h>
 #include <libspi/editabletext.h>
 
 /* Static function declarations */
@@ -32,42 +33,37 @@ static void
 spi_editable_text_class_init (SpiEditableTextClass *klass);
 static void
 spi_editable_text_init (SpiEditableText *editable);
-static void
-spi_editable_text_finalize (GObject *obj);
 static CORBA_boolean
-impl_setAttributes (PortableServer_Servant _servant,
+impl_setAttributes (PortableServer_Servant servant,
                       const CORBA_char * attributes,
                       const CORBA_long startPos,
                       const CORBA_long endPos,
-                      CORBA_Environment * ev);
+                      CORBA_Environment *ev);
 static void
-impl_setTextContents (PortableServer_Servant _servant,
+impl_setTextContents (PortableServer_Servant servant,
                      const CORBA_char * newContents,
-                     CORBA_Environment * ev);
+                     CORBA_Environment *ev);
 static void 
-impl_insertText (PortableServer_Servant _servant,
+impl_insertText (PortableServer_Servant servant,
                 const CORBA_long position,
                 const CORBA_char * text,
                 const CORBA_long length,
-                CORBA_Environment * ev);
+                CORBA_Environment *ev);
 static void 
-impl_copyText (PortableServer_Servant _servant,
+impl_copyText (PortableServer_Servant servant,
               const CORBA_long startPos, const CORBA_long endPos,
-              CORBA_Environment * ev);
+              CORBA_Environment *ev);
 static void 
-impl_cutText (PortableServer_Servant _servant,
+impl_cutText (PortableServer_Servant servant,
              const CORBA_long startPos, const CORBA_long endPos,
-             CORBA_Environment * ev);
+             CORBA_Environment *ev);
 static void 
-impl_deleteText (PortableServer_Servant _servant,
+impl_deleteText (PortableServer_Servant servant,
                 const CORBA_long startPos, const CORBA_long endPos,
-                CORBA_Environment * ev);
+                CORBA_Environment *ev);
 static void
-impl_pasteText (PortableServer_Servant _servant,
-               const CORBA_long position, CORBA_Environment * ev);
-
-static GObjectClass *parent_class;
-
+impl_pasteText (PortableServer_Servant servant,
+               const CORBA_long position, CORBA_Environment *ev);
 
 BONOBO_TYPE_FUNC_FULL (SpiEditableText,
                       Accessibility_EditableText,
@@ -77,12 +73,8 @@ BONOBO_TYPE_FUNC_FULL (SpiEditableText,
 static void
 spi_editable_text_class_init (SpiEditableTextClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_EditableText__epv *epv = &klass->epv;
-  parent_class = g_type_interface_peek_parent (klass);
 
-  object_class->finalize = spi_editable_text_finalize;
-  
   /* Initialize epv table */
 
   epv->setAttributes = impl_setAttributes;
@@ -94,79 +86,81 @@ spi_editable_text_class_init (SpiEditableTextClass *klass)
   epv->pasteText = impl_pasteText;
 }
 
+
 static void
 spi_editable_text_init (SpiEditableText *editable)
 {
 }
 
-static void
-spi_editable_text_finalize (GObject *obj)
-{
-  parent_class->finalize (obj);
-}
 
 SpiEditableText *
 spi_editable_text_interface_new (AtkObject *obj)
 {
   SpiEditableText *new_editable = g_object_new (
          SPI_EDITABLE_TEXT_TYPE, NULL);
-  (SPI_TEXT (new_editable))->atko = obj;
-  g_object_ref (obj);
+
+  spi_text_construct (SPI_TEXT (new_editable), obj);
+
   return new_editable;
 }
 
+
+static AtkEditableText *
+get_editable_text_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+
+  if (!object)
+    {
+      return NULL;
+    }
+
+  return ATK_EDITABLE_TEXT (object->atko);
+}
+
+
 static CORBA_boolean
-impl_setAttributes (PortableServer_Servant _servant,
-                      const CORBA_char * attributes,
-                      const CORBA_long startPos,
-                      const CORBA_long endPos,
-                                        CORBA_Environment * ev)
+impl_setAttributes (PortableServer_Servant servant,
+                   const CORBA_char * attributes,
+                   const CORBA_long startPos,
+                   const CORBA_long endPos,
+                   CORBA_Environment *ev)
 {
-  SpiEditableText *editable;
-  BonoboObject *obj;
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_SPI_EDITABLE_TEXT (obj), FALSE);
-  editable = SPI_EDITABLE_TEXT(bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (ATK_IS_EDITABLE_TEXT ( (SPI_TEXT (obj))->atko), FALSE);
+  AtkEditableText *editable = get_editable_text_from_servant (servant);
+
+  g_return_val_if_fail (editable != NULL, FALSE);
 
   g_print ("setRunAttributes not implemented.\n");
 
   return FALSE;
 }
 
+
 static void
-impl_setTextContents (PortableServer_Servant _servant,
-                     const CORBA_char newContents,
-                     CORBA_Environment ev)
+impl_setTextContents (PortableServer_Servant servant,
+                     const CORBA_char     *newContents,
+                     CORBA_Environment    *ev)
 {
-  SpiEditableText *editable;
-  BonoboObject *obj;
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_SPI_EDITABLE_TEXT (obj));
-  editable = SPI_EDITABLE_TEXT(bonobo_object_from_servant (_servant));
-  g_return_if_fail (ATK_IS_EDITABLE_TEXT ( (SPI_TEXT (obj))->atko));
+  AtkEditableText *editable = get_editable_text_from_servant (servant);
+
+  g_return_if_fail (editable != NULL);
   
-  atk_editable_text_set_text_contents (ATK_EDITABLE_TEXT( SPI_TEXT (editable)->atko),
-                                      (gchar *) newContents);
+  atk_editable_text_set_text_contents (editable, (gchar *) newContents);
 }
 
 
-
 static void 
-impl_insertText (PortableServer_Servant _servant,
-                const CORBA_long position,
-                const CORBA_char text,
-                const CORBA_long length,
-                CORBA_Environment ev)
+impl_insertText (PortableServer_Servant servant,
+                const CORBA_long      position,
+                const CORBA_char     *text,
+                const CORBA_long      length,
+                CORBA_Environment    *ev)
 {
-  SpiEditableText *editable;
-  BonoboObject *obj;
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_SPI_EDITABLE_TEXT (obj));
-  editable = SPI_EDITABLE_TEXT(bonobo_object_from_servant (_servant));
-  g_return_if_fail (ATK_IS_EDITABLE_TEXT ( (SPI_TEXT (obj))->atko));
-
-  atk_editable_text_insert_text (ATK_EDITABLE_TEXT( SPI_TEXT (editable)->atko),
+  AtkEditableText *editable = get_editable_text_from_servant (servant);
+
+  g_return_if_fail (editable != NULL);
+
+  atk_editable_text_insert_text (editable,
                                 (gchar *) text,
                                 (gint) length,
                                 (gint *) &position);
@@ -174,70 +168,51 @@ impl_insertText (PortableServer_Servant _servant,
 
 
 static void 
-impl_copyText (PortableServer_Servant _servant,
+impl_copyText (PortableServer_Servant servant,
               const CORBA_long startPos, const CORBA_long endPos,
-              CORBA_Environment * ev)
+              CORBA_Environment *ev)
 {
-  SpiEditableText *editable;
-  BonoboObject *obj;
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_SPI_EDITABLE_TEXT (obj));
-  editable = SPI_EDITABLE_TEXT(bonobo_object_from_servant (_servant));
-  g_return_if_fail (ATK_IS_EDITABLE_TEXT ( (SPI_TEXT (obj))->atko));
-
-  atk_editable_text_copy_text (ATK_EDITABLE_TEXT( SPI_TEXT(editable)->atko),
-                              (gint) startPos, (gint) endPos);
-}
+  AtkEditableText *editable = get_editable_text_from_servant (servant);
+
+  g_return_if_fail (editable != NULL);
 
+  atk_editable_text_copy_text (editable, (gint) startPos, (gint) endPos);
+}
 
 
 static void 
-impl_cutText (PortableServer_Servant _servant,
+impl_cutText (PortableServer_Servant servant,
              const CORBA_long startPos, const CORBA_long endPos,
-             CORBA_Environment * ev)
+             CORBA_Environment *ev)
 {
-  SpiEditableText *editable;
-  BonoboObject *obj;
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_SPI_EDITABLE_TEXT (obj));
-  editable = SPI_EDITABLE_TEXT(bonobo_object_from_servant (_servant));
-  g_return_if_fail (ATK_IS_EDITABLE_TEXT ( (SPI_TEXT (obj))->atko));
-
-  atk_editable_text_cut_text (ATK_EDITABLE_TEXT(SPI_TEXT (editable)->atko),
-                                (gint) startPos, (gint) endPos);
-}
+  AtkEditableText *editable = get_editable_text_from_servant (servant);
 
+  g_return_if_fail (editable != NULL);
 
+  atk_editable_text_cut_text (editable, (gint) startPos, (gint) endPos);
+}
 
 
 static void 
-impl_deleteText (PortableServer_Servant _servant,
+impl_deleteText (PortableServer_Servant servant,
                 const CORBA_long startPos, const CORBA_long endPos,
-                CORBA_Environment * ev)
+                CORBA_Environment *ev)
 {
-  SpiEditableText *editable;
-  BonoboObject *obj;
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_SPI_EDITABLE_TEXT (obj));
-  editable = SPI_EDITABLE_TEXT(bonobo_object_from_servant (_servant));
-  g_return_if_fail (ATK_IS_EDITABLE_TEXT ( (SPI_TEXT (obj))->atko));
-
-  atk_editable_text_delete_text (ATK_EDITABLE_TEXT( SPI_TEXT(editable)->atko),
-                                (gint) startPos, (gint) endPos);
+  AtkEditableText *editable = get_editable_text_from_servant (servant);
+
+  g_return_if_fail (editable != NULL);
+
+  atk_editable_text_delete_text (editable, (gint) startPos, (gint) endPos);
 }
 
 
 static void
-impl_pasteText (PortableServer_Servant _servant,
-               const CORBA_long position, CORBA_Environment * ev)
+impl_pasteText (PortableServer_Servant servant,
+               const CORBA_long position, CORBA_Environment *ev)
 {
-  SpiEditableText *editable;
-  BonoboObject *obj;
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_SPI_EDITABLE_TEXT (obj));
-  editable = SPI_EDITABLE_TEXT(bonobo_object_from_servant (_servant));
-  g_return_if_fail (ATK_IS_EDITABLE_TEXT ( (SPI_TEXT (obj))->atko));
-
-  atk_editable_text_paste_text (ATK_EDITABLE_TEXT( SPI_TEXT(editable)->atko), position);
-}
+  AtkEditableText *editable = get_editable_text_from_servant (servant);
 
+  g_return_if_fail (editable != NULL);
+
+  atk_editable_text_paste_text (editable, position);
+}
index f61866f..9e0f0d1 100644 (file)
 #ifndef SPI_EDITABLE_TEXT_H_
 #define SPI_EDITABLE_TEXT_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
 #include <libspi/text.h>
 
 G_BEGIN_DECLS
 
-#define SPI_EDITABLE_TEXT_TYPE        (spi_editable_text_get_type ())
-#define SPI_EDITABLE_TEXT(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_EDITABLE_TEXT_TYPE, SpiEditableText))
+#define SPI_EDITABLE_TEXT_TYPE            (spi_editable_text_get_type ())
+#define SPI_EDITABLE_TEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_EDITABLE_TEXT_TYPE, SpiEditableText))
 #define SPI_EDITABLE_TEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_EDITABLE_TEXT_TYPE, SpiEditableText))
-#define IS_SPI_EDITABLE_TEXT(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_EDITABLE_TEXT_TYPE))
-#define IS_SPI_EDITABLE_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_EDITABLE_TEXT_TYPE))
+#define SPI_IS_EDITABLE_TEXT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_EDITABLE_TEXT_TYPE))
+#define SPI_IS_EDITABLE_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_EDITABLE_TEXT_TYPE))
 
-typedef struct _EditableText SpiEditableText;
-typedef struct _EditableTextClass SpiEditableTextClass;
+typedef struct _SpiEditableText      SpiEditableText;
+typedef struct _SpiEditableTextClass SpiEditableTextClass;
 
-struct _EditableText {
+struct _SpiEditableText {
   SpiText parent;
 };
 
-struct _EditableTextClass {
+struct _SpiEditableTextClass {
   SpiTextClass parent_class;
   POA_Accessibility_EditableText__epv epv;
 };
 
-GType
-spi_editable_text_get_type   (void);
-
-SpiEditableText *
-spi_editable_text_interface_new       ( AtkObject *obj);
+GType            spi_editable_text_get_type      (void);
+SpiEditableText *spi_editable_text_interface_new (AtkObject *obj);
 
 G_END_DECLS
 
index 1164afa..8dde552 100644 (file)
 #ifdef SPI_DEBUG
 #include <stdio.h>
 #endif
-#include <libspi/accessibleeventlistener.h>
+#include <libspi/eventlistener.h>
 
 /* Our parent Gtk object type */
 #define PARENT_TYPE SPI_LISTENER_TYPE
 
-/* A pointer to our parent object class */
-static SpiListenerClass *spi_event_listener_parent_class;
-
 enum {
        EVENT,
        LAST_SIGNAL
@@ -41,53 +38,29 @@ enum {
 static guint signals [LAST_SIGNAL];
 
 /*
- * Implemented GObject::finalize
- */
-static void
-spi_event_listener_object_finalize (GObject *object)
-{
-       SpiEventListener *listener = SPI_ACCESSIBLE_EVENT_SPI_LISTENER (object);
-#ifdef SPI_DEBUG
-        fprintf(stderr, "spi_listener_object_finalize called\n");
-#endif
-       g_list_free (listener->callbacks);
-
-        ((GObjectClass *) spi_event_listener_parent_class)->finalize (object);
-}
-
-/*
  * CORBA Accessibility::Listener::notifyEvent method implementation
  */
-
 static void
 impl_accessible_event_notify_event (PortableServer_Servant     servant,
                                     const Accessibility_Event *e,
                                     CORBA_Environment         *ev)
 {
-  GList *l;
-  VoidSpiEventListenerCB cb;
-  SpiEventListener *listener = SPI_ACCESSIBLE_EVENT_SPI_LISTENER (
-                                       bonobo_object_from_servant (servant));
+  SpiEventListener *listener = SPI_EVENT_LISTENER (
+         bonobo_object_from_servant (servant));
+
+  g_signal_emit (G_OBJECT (listener), signals [EVENT], 0, e);
 
-  for (l = listener->callbacks; l; l = l->next)
+  if (e->source != CORBA_OBJECT_NIL)
     {
-      cb = (VoidSpiEventListenerCB) l->data;
-      if (cb)
-        {
-          (*cb) (e);
-        }
+      Accessibility_Accessible_unref (e->source, ev);
     }
-
-  g_signal_emit (G_OBJECT (listener), signals [EVENT], 0, e); 
 }
 
 static void
 spi_event_listener_class_init (SpiEventListenerClass *klass)
 {
-        GObjectClass * object_class = (GObjectClass *) klass;
-        SpiListenerClass * spi_listener_class = (SpiListenerClass *) klass;
+        SpiListenerClass *spi_listener_class = (SpiListenerClass *) klass;
         POA_Accessibility_EventListener__epv *epv = &spi_listener_class->epv;
-        spi_event_listener_parent_class = g_type_class_ref (SPI_LISTENER_TYPE);
 
        signals [EVENT] = g_signal_new (
                "event",
@@ -98,15 +71,12 @@ spi_event_listener_class_init (SpiEventListenerClass *klass)
                g_cclosure_marshal_VOID__POINTER,
                G_TYPE_NONE, 1, G_TYPE_POINTER);
 
-        object_class->finalize = spi_event_listener_object_finalize;
-
         epv->notifyEvent = impl_accessible_event_notify_event;
 }
 
 static void
 spi_event_listener_init (SpiEventListener *listener)
 {
-        listener->callbacks = NULL;
 }
 
 BONOBO_TYPE_FUNC (SpiEventListener,
@@ -117,20 +87,6 @@ SpiEventListener *
 spi_event_listener_new ()
 {
     SpiEventListener *retval = g_object_new (
-           SPI_ACCESSIBLE_EVENT_SPI_LISTENER_TYPE, NULL);
+           SPI_EVENT_LISTENER_TYPE, NULL);
     return retval;
 }
-
-void
-spi_event_listener_add_callback (SpiEventListener *listener,
-                                VoidSpiEventListenerCB callback)
-{
-  listener->callbacks = g_list_prepend (listener->callbacks, callback);
-}
-
-void
-spi_event_listener_remove_callback (SpiEventListener *listener,
-                                   VoidSpiEventListenerCB callback)
-{
-  listener->callbacks = g_list_remove (listener->callbacks, callback);
-}
index 0f4d2d4..1c79b22 100644 (file)
 
 G_BEGIN_DECLS
 
-/* FIXME: these macro names are all messed up, probably from the namespacing */
-
-#define SPI_ACCESSIBLE_EVENT_SPI_LISTENER_TYPE        (spi_event_listener_get_type ())
-#define SPI_ACCESSIBLE_EVENT_SPI_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_ACCESSIBLE_EVENT_SPI_LISTENER_TYPE, SpiEventListener))
-#define SPI_ACCESSIBLE_EVENT_SPI_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_ACCESSIBLE_EVENT_SPI_LISTENER_TYPE, SpiEventListenerClass))
-#define IS_SPI_ACCESSIBLE_EVENT_SPI_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_ACCESSIBLE_EVENT_SPI_LISTENER_TYPE))
-#define IS_SPI_ACCESSIBLE_EVENT_SPI_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_ACCESSIBLE_EVENT_SPI_LISTENER_TYPE))
-
-typedef void (*VoidSpiEventListenerCB) (const Accessibility_Event *e);
+#define SPI_EVENT_LISTENER_TYPE        (spi_event_listener_get_type ())
+#define SPI_EVENT_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_EVENT_LISTENER_TYPE, SpiEventListener))
+#define SPI_EVENT_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_EVENT_LISTENER_TYPE, SpiEventListenerClass))
+#define SPI_IS_EVENT_LISTENER(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_EVENT_LISTENER_TYPE))
+#define SPI_IS_EVENT_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_EVENT_LISTENER_TYPE))
 
 typedef struct _SpiEventListener SpiEventListener;
 
 struct _SpiEventListener {
   SpiListener parent;
-  GList      *callbacks;
 };
 
 typedef struct {
@@ -55,10 +50,6 @@ typedef struct {
 
 GType              spi_event_listener_get_type        (void);
 SpiEventListener  *spi_event_listener_new             (void);
-void               spi_event_listener_add_callback    (SpiEventListener      *listener,
-                                                      VoidSpiEventListenerCB callback);
-void               spi_event_listener_remove_callback (SpiEventListener      *listener,
-                                                      VoidSpiEventListenerCB callback);
 
 G_END_DECLS
 
index eb31975..36b538d 100644 (file)
@@ -33,8 +33,6 @@ static void
 spi_hyperlink_class_init (SpiHyperlinkClass *klass);
 static void
 spi_hyperlink_init (SpiHyperlink *hyperlink);
-static void
-spi_hyperlink_finalize (GObject *obj);
 static CORBA_string
 impl_getURI (PortableServer_Servant _servant,
             const CORBA_long i, CORBA_Environment * ev);
@@ -55,22 +53,17 @@ static CORBA_boolean
 impl_isValid (PortableServer_Servant _servant,
              CORBA_Environment * ev);
 
-static GObjectClass *parent_class;
-
 
 BONOBO_TYPE_FUNC_FULL (SpiHyperlink,
                       Accessibility_Hyperlink,
-                      BONOBO_TYPE_OBJECT,
+                      SPI_TYPE_BASE,
                       spi_hyperlink);
 
+
 static void
 spi_hyperlink_class_init (SpiHyperlinkClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Hyperlink__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_hyperlink_finalize;
 
   /* Initialize epv table */
 
@@ -82,101 +75,122 @@ spi_hyperlink_class_init (SpiHyperlinkClass *klass)
   epv->isValid = impl_isValid;
 }
 
+
 static void
 spi_hyperlink_init (SpiHyperlink *hyperlink)
 {
 }
 
-static void
-spi_hyperlink_finalize (GObject *obj)
-{
-  SpiHyperlink *hyperlink = SPI_HYPERLINK(obj);
-  g_object_unref (hyperlink->hyperlink);
-  hyperlink->hyperlink = NULL;
-  parent_class->finalize (obj);
-}
 
 SpiHyperlink *
-spi_hyperlink_new (AtkHyperlink *hyperlink)
+spi_hyperlink_new (AtkObject *object)
 {
   SpiHyperlink *new_hyperlink = g_object_new (
          SPI_HYPERLINK_TYPE, NULL);
-  g_object_ref (hyperlink);
-  new_hyperlink->hyperlink = hyperlink;
+
+  spi_base_construct (SPI_BASE (new_hyperlink), object);
+
   return new_hyperlink;
 }
 
 
+static AtkHyperlink *
+get_hyperlink_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+
+  if (!object)
+    {
+      return NULL;
+    }
+
+  return ATK_HYPERLINK (object->atko);
+}
+
 
 static CORBA_short
-impl__get_n_anchors (PortableServer_Servant _servant,
-                    CORBA_Environment ev)
+impl__get_n_anchors (PortableServer_Servant servant,
+                    CORBA_Environment     *ev)
 {
-  SpiHyperlink *link = SPI_HYPERLINK(bonobo_object_from_servant(_servant));
-  return (CORBA_short) atk_hyperlink_get_n_anchors (ATK_HYPERLINK(link->hyperlink));
-}
+  AtkHyperlink *link = get_hyperlink_from_servant (servant);
+
+  g_return_val_if_fail (link != NULL, 0);
 
+  return (CORBA_short) atk_hyperlink_get_n_anchors (link);
+}
 
 
 static CORBA_long
-impl__get_startIndex (PortableServer_Servant _servant,
-                     CORBA_Environment ev)
+impl__get_startIndex (PortableServer_Servant servant,
+                     CORBA_Environment     *ev)
 {
-  SpiHyperlink *link = SPI_HYPERLINK(bonobo_object_from_servant(_servant));
-  return (CORBA_long) atk_hyperlink_get_start_index (ATK_HYPERLINK(link->hyperlink));
-}
+  AtkHyperlink *link = get_hyperlink_from_servant (servant);
 
+  g_return_val_if_fail (link != NULL, -1);
+
+  return (CORBA_long) atk_hyperlink_get_start_index (link);
+}
 
 
 static CORBA_long
-impl__get_endIndex (PortableServer_Servant _servant,
-                   CORBA_Environment ev)
+impl__get_endIndex (PortableServer_Servant servant,
+                   CORBA_Environment     *ev)
 {
-  SpiHyperlink *link = SPI_HYPERLINK(bonobo_object_from_servant(_servant));
-  return (CORBA_long) atk_hyperlink_get_end_index (ATK_HYPERLINK(link->hyperlink));
-}
+  AtkHyperlink *link = get_hyperlink_from_servant (servant);
+
+  g_return_val_if_fail (link != NULL, -1);
 
+  return (CORBA_long) atk_hyperlink_get_end_index (link);
+}
 
 
 static CORBA_string
-impl_getURI (PortableServer_Servant _servant,
-  const CORBA_long i, CORBA_Environment * ev)
+impl_getURI (PortableServer_Servant servant,
+            const CORBA_long i, CORBA_Environment *ev)
 {
-  SpiHyperlink *link = SPI_HYPERLINK(bonobo_object_from_servant(_servant));
   gchar *uri;
   CORBA_char *rv;
-  uri = atk_hyperlink_get_uri (ATK_HYPERLINK(link->hyperlink), (gint) i);
+  AtkHyperlink *link = get_hyperlink_from_servant (servant);
+
+  g_return_val_if_fail (link != NULL, CORBA_string_dup (""));
+
+  uri = atk_hyperlink_get_uri (link, (gint) i);
   if (uri)
     {
       rv = CORBA_string_dup (uri);
       g_free (uri);
-      }
+    }
   else
     rv = CORBA_string_dup ("");
+
   return rv;
 } 
 
 
-
 static Accessibility_Accessible
-impl_getObject (PortableServer_Servant _servant,
-               const CORBA_long i,
-               CORBA_Environment ev)
+impl_getObject (PortableServer_Servant servant,
+               const CORBA_long       i,
+               CORBA_Environment     *ev)
 {
-  SpiHyperlink *link = SPI_HYPERLINK(bonobo_object_from_servant(_servant));
-  AtkObject *atk_object;
-  Accessibility_Accessible rv;
-  atk_object = atk_hyperlink_get_object (ATK_HYPERLINK(link->hyperlink), (gint) i);
-  rv = bonobo_object_corba_objref (BONOBO_OBJECT(spi_accessible_new(atk_object)));
-  return rv;
-}
+  AtkObject    *atk_object;
+  AtkHyperlink *link = get_hyperlink_from_servant (servant);
+
+  g_return_val_if_fail (link != NULL, CORBA_OBJECT_NIL);
 
+  atk_object = atk_hyperlink_get_object (link, (gint) i);
+
+  return spi_accessible_new_return (atk_object, FALSE, ev);
+}
 
 
 static CORBA_boolean
-impl_isValid (PortableServer_Servant _servant,
-             CORBA_Environment ev)
+impl_isValid (PortableServer_Servant servant,
+             CORBA_Environment     *ev)
 {
-  SpiHyperlink *link = SPI_HYPERLINK(bonobo_object_from_servant(_servant));
-  return (CORBA_boolean) atk_hyperlink_is_valid (ATK_HYPERLINK(link->hyperlink));
+  AtkHyperlink *link = get_hyperlink_from_servant (servant);
+
+  g_return_val_if_fail (link != NULL, TRUE);
+
+  return (CORBA_boolean) atk_hyperlink_is_valid (link);
 }
+
index d79c5e5..262bc54 100644 (file)
 #ifndef SPI_HYPERLINK_H_
 #define SPI_HYPERLINK_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
+#include <atk/atkhyperlink.h>
 
 G_BEGIN_DECLS
 
 #define SPI_HYPERLINK_TYPE        (spi_hyperlink_get_type ())
 #define SPI_HYPERLINK(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_HYPERLINK_TYPE, SpiHyperlink))
 #define SPI_HYPERLINK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_HYPERLINK_TYPE, SpiHyperlinkClass))
-#define IS_SPI_HYPERLINK(obj)       (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_HYPERLINK_TYPE))
-#define IS_SPI_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_HYPERLINK_TYPE))
+#define SPI_IS_HYPERLINK(obj)       (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_HYPERLINK_TYPE))
+#define SPI_IS_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_HYPERLINK_TYPE))
 
-typedef struct _Hyperlink SpiHyperlink;
+typedef struct _Hyperlink      SpiHyperlink;
 typedef struct _HyperlinkClass SpiHyperlinkClass;
 
 struct _Hyperlink {
-  BonoboObject parent;
-  AtkHyperlink *hyperlink;
+  SpiBase parent;
 };
 
 struct _HyperlinkClass {
-  BonoboObjectClass parent_class;
+  SpiBaseClass parent_class;
   POA_Accessibility_Hyperlink__epv epv;
 };
 
-GType
-spi_hyperlink_get_type   (void);
-
-SpiHyperlink *
-spi_hyperlink_new       ();
+GType         spi_hyperlink_get_type (void);
+SpiHyperlink *spi_hyperlink_new      (AtkObject *object);
 
 G_END_DECLS
 
index 17d3b4d..3aac466 100644 (file)
@@ -2,7 +2,7 @@
  * AT-SPI - Assistive Technology Service Provider Interface
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
- * Copyright 2001 Sun Microsystems Inc.
+ * Copyright 2001 Sun Microsystems Inc, Ximian Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 
 #include <config.h>
 #include <stdio.h>
+#include <atk/atkhypertext.h>
 #include <libspi/hyperlink.h>
 #include <libspi/hypertext.h>
 
-/* Static function declarations */
-
-static GObjectClass *parent_class;
-
-static void
-spi_hypertext_finalize (GObject *obj)
-{
-  parent_class->finalize (obj);
-}
-
 SpiHypertext *
 spi_hypertext_interface_new (AtkObject *obj)
 {
   SpiHypertext *new_hypertext = g_object_new (SPI_HYPERTEXT_TYPE, NULL);
-  (SPI_TEXT (new_hypertext))->atko = obj;
-  g_object_ref (obj);
+
+  spi_text_construct (SPI_TEXT (new_hypertext), obj);
+
   return new_hypertext;
 }
 
 
+static AtkHypertext *
+get_hypertext_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+
+  if (!object)
+    {
+      return NULL;
+    }
+
+  return ATK_HYPERTEXT (object->atko);
+}
+
 
 static CORBA_long
-impl_getNLinks (PortableServer_Servant _servant,
-               CORBA_Environment ev)
+impl_getNLinks (PortableServer_Servant servant,
+               CORBA_Environment     *ev)
 {
-  SpiHypertext *hypertext = SPI_HYPERTEXT (bonobo_object_from_servant(_servant));
-  return (CORBA_long)
-    atk_hypertext_get_n_links (ATK_HYPERTEXT ((SPI_TEXT (hypertext))->atko));
-}
+  AtkHypertext *hypertext = get_hypertext_from_servant (servant);
 
+  g_return_val_if_fail (hypertext != NULL, 0);
+
+  return (CORBA_long) atk_hypertext_get_n_links (hypertext);
+}
 
 
 static Accessibility_Hyperlink
@@ -65,41 +71,39 @@ impl_getLink (PortableServer_Servant servant,
              CORBA_Environment     *ev)
 {
   AtkHyperlink *link;
-  SpiHypertext *hypertext;
   Accessibility_Hyperlink rv;
-  
-  hypertext = SPI_HYPERTEXT (bonobo_object_from_servant (servant));
+  AtkHypertext *hypertext = get_hypertext_from_servant (servant);
 
-  link = atk_hypertext_get_link (
-         ATK_HYPERTEXT ((SPI_TEXT (hypertext))->atko), linkIndex);
+  g_return_val_if_fail (hypertext != NULL, CORBA_OBJECT_NIL);
+  
+  link = atk_hypertext_get_link (hypertext, linkIndex);
+  g_return_val_if_fail (link != NULL, CORBA_OBJECT_NIL);
 
-  rv = bonobo_object_corba_objref (BONOBO_OBJECT (
-         spi_hyperlink_new (ATK_OBJECT (link))));
+  rv = BONOBO_OBJREF (spi_hyperlink_new (ATK_OBJECT (link)));
 
-  return rv;
+  return CORBA_Object_duplicate (rv, ev);
 }
 
 
-
 static CORBA_long
-impl_getLinkIndex (PortableServer_Servant _servant,
-                  const CORBA_long characterIndex,
-                                 CORBA_Environment * ev)
+impl_getLinkIndex (PortableServer_Servant servant,
+                  const CORBA_long       characterIndex,
+                  CORBA_Environment     *ev)
 {
-  SpiHypertext *hypertext = SPI_HYPERTEXT(bonobo_object_from_servant(_servant));
+  AtkHypertext *hypertext = get_hypertext_from_servant (servant);
+
+  g_return_val_if_fail (hypertext != NULL, 0);
+
   return (CORBA_long)
-    atk_hypertext_get_link_index (ATK_HYPERTEXT ((SPI_TEXT (hypertext))->atko),
+    atk_hypertext_get_link_index (hypertext,
                                  (gint) characterIndex);
 }
 
+
 static void
 spi_hypertext_class_init (SpiHypertextClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Hypertext__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_hypertext_finalize;
 
   /* Initialize epv table */
 
@@ -108,11 +112,13 @@ spi_hypertext_class_init (SpiHypertextClass *klass)
   epv->getLinkIndex = impl_getLinkIndex;
 }
 
+
 static void
 spi_hypertext_init (SpiHypertext *hypertext)
 {
 }
 
+
 BONOBO_TYPE_FUNC_FULL (SpiHypertext,
                       Accessibility_Hypertext,
                       BONOBO_TYPE_OBJECT,
index e5db02f..b197ff7 100644 (file)
 #ifndef SPI_HYPERTEXT_H_
 #define SPI_HYPERTEXT_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
 #include <libspi/text.h>
 
 G_BEGIN_DECLS
 
-#define SPI_HYPERTEXT_TYPE        (spi_hypertext_get_type ())
-#define SPI_HYPERTEXT(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_HYPERTEXT_TYPE, SpiHypertext))
+#define SPI_HYPERTEXT_TYPE            (spi_hypertext_get_type ())
+#define SPI_HYPERTEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_HYPERTEXT_TYPE, SpiHypertext))
 #define SPI_HYPERTEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_HYPERTEXT_TYPE, SpiHypertextClass))
-#define IS_SPI_HYPERTEXT(obj)       (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_HYPERTEXT_TYPE))
-#define IS_HYPESPI_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_HYPERTEXT_TYPE))
+#define SPI_IS_HYPERTEXT(obj)         (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_HYPERTEXT_TYPE))
+#define SPI_IS_HYPERTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_HYPERTEXT_TYPE))
 
-typedef struct _Hypertext SpiHypertext;
-typedef struct _HypertextClass SpiHypertextClass;
+typedef struct _SpiHypertext      SpiHypertext;
+typedef struct _SpiHypertextClass SpiHypertextClass;
 
-struct _Hypertext {
+struct _SpiHypertext {
   SpiText parent;
 };
 
-struct _HypertextClass {
-  BonoboObjectClass parent_class;
+struct _SpiHypertextClass {
+  SpiTextClass parent_class;
   POA_Accessibility_Hypertext__epv epv;
 };
 
index 645490c..5598ae6 100644 (file)
 #include <stdio.h>
 #include <libspi/image.h>
 
-/* A pointer to our parent object class */
-static GObjectClass *parent_class;
-
-static void
-spi_image_finalize (GObject *obj)
-{
-  SpiImage *image = SPI_IMAGE (obj);
-  g_object_unref (image->atko);
-  image->atko = NULL;
-  parent_class->finalize (obj);
-}
 
 SpiImage *
 spi_image_interface_new (AtkObject *obj)
 {
   SpiImage *new_image = g_object_new (SPI_IMAGE_TYPE, NULL);
-  new_image->atko = obj;
-  g_object_ref (obj);
+
+  spi_base_construct (SPI_BASE (new_image), obj);
+
   return new_image;
 }
 
 
+static AtkImage *
+get_image_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+
+  if (!object)
+    {
+      return NULL;
+    }
+
+  return ATK_IMAGE (object->atko);
+}
+
 
 static void 
-impl_getImagePosition (PortableServer_Servant _servant,
+impl_getImagePosition (PortableServer_Servant servant,
                       CORBA_long * x, CORBA_long * y,
                       const CORBA_short coordType,
-                      CORBA_Environment * ev)
+                      CORBA_Environment *ev)
 {
-  SpiImage *image = SPI_IMAGE (bonobo_object_from_servant(_servant));
-  atk_image_get_image_position (ATK_IMAGE(image->atko),
+  AtkImage *image = get_image_from_servant (servant);
+
+  g_return_if_fail (image != NULL);
+
+  atk_image_get_image_position (image,
                                (gint *) x, (gint *) y,
                                (AtkCoordType) coordType);
 }
 
 
-
 static void 
-impl_getImageSize (PortableServer_Servant _servant,
+impl_getImageSize (PortableServer_Servant servant,
                   CORBA_long * width, CORBA_long * height,
-                           CORBA_Environment * ev)
+                  CORBA_Environment *ev)
 {
-  SpiImage *image = SPI_IMAGE (bonobo_object_from_servant(_servant));
-  atk_image_get_image_size (ATK_IMAGE(image->atko),
+  AtkImage *image = get_image_from_servant (servant);
+
+  g_return_if_fail (image != NULL);
+
+  atk_image_get_image_size (image,
                            (gint *) width, (gint *) height);
 }
 
 
-
 static CORBA_string 
 impl__get_imageDescription (PortableServer_Servant servant,
                            CORBA_Environment     *ev)
 {
-  SpiImage *image;
   const char *rv;
+  AtkImage   *image = get_image_from_servant (servant);
+
+  g_return_val_if_fail (image != NULL, CORBA_string_dup (""));
 
-  image = SPI_IMAGE (bonobo_object_from_servant (servant));
+  rv = atk_image_get_image_description (image);
 
-  rv = atk_image_get_image_description (ATK_IMAGE (image->atko));
   if (rv)
-    return CORBA_string_dup (rv);
+    {
+      return CORBA_string_dup (rv);
+    }
   else
-    return CORBA_string_dup ("");
+    {
+      return CORBA_string_dup ("");
+    }
 }
 
 
 static void
 spi_image_class_init (SpiImageClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Image__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_image_finalize;
-
 
   /* Initialize epv table */
 
@@ -116,5 +123,5 @@ spi_image_init (SpiImage *image)
 
 BONOBO_TYPE_FUNC_FULL (SpiImage,
                       Accessibility_Image,
-                      BONOBO_TYPE_OBJECT,
+                      SPI_TYPE_BASE,
                       spi_image);
index 71085e3..bd45bf5 100644 (file)
 #ifndef SPI_IMAGE_H_
 #define SPI_IMAGE_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
+#include <atk/atkimage.h>
 
 G_BEGIN_DECLS
 
-#define SPI_IMAGE_TYPE        (spi_image_get_type ())
-#define SPI_IMAGE(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_IMAGE_TYPE, SpiImage))
+#define SPI_IMAGE_TYPE            (spi_image_get_type ())
+#define SPI_IMAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_IMAGE_TYPE, SpiImage))
 #define SPI_IMAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_IMAGE_TYPE, SpiImageClass))
-#define IS_SPI_IMAGE(obj)       (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_IMAGE_TYPE))
-#define IS_SPI_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_IMAGE_TYPE))
+#define SPI_IS_IMAGE(obj)         (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_IMAGE_TYPE))
+#define SPI_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_IMAGE_TYPE))
 
 typedef struct _Image SpiImage;
 typedef struct _ImageClass SpiImageClass;
 
 struct _Image {
-  BonoboObject parent;
-  AtkObject *atko;
+  SpiBase parent;
 };
 
 struct _ImageClass {
-  BonoboObjectClass parent_class;
+  SpiBaseClass parent;
   POA_Accessibility_Image__epv epv;
 };
 
-GType
-spi_image_get_type   (void);
-
-SpiImage *
-spi_image_interface_new       (AtkObject *obj);
+GType     spi_image_get_type      (void);
+SpiImage *spi_image_interface_new (AtkObject *obj);
 
 G_END_DECLS
 
index 6809027..43f2cf0 100644 (file)
 /* Our parent Gtk object type  */
 #define PARENT_TYPE BONOBO_TYPE_OBJECT
 
-/* A pointer to our parent object class */
-static BonoboObjectClass *keystroke_listener_parent_class;
-
 enum {
        KEY_EVENT,
        LAST_SIGNAL
 };
 static guint signals [LAST_SIGNAL];
 
-/* GObject::finalize */
-static void
-spi_keystroke_listener_object_finalize (GObject *object)
-{
-  SpiKeystrokeListener *listener = SPI_KEYSTROKE_LISTENER (object);
-
-  g_list_free (listener->callbacks);
-#ifdef SPI_DEBUG
-  fprintf(stderr, "keystroke_listener_object_finalize called\n");
-#endif
-  ((GObjectClass *) keystroke_listener_parent_class)->finalize (object);
-}
-
-void   spi_keystroke_listener_add_callback (SpiKeystrokeListener *listener,
-                                           BooleanKeystrokeListenerCB callback)
-{
-  listener->callbacks = g_list_append (listener->callbacks, callback);
-#ifdef SPI_DEBUG
-        fprintf(stderr, "keystroke_listener_add_callback (%p) called\n",
-               (gpointer) callback);
-#endif
-}
-
-void
-spi_keystroke_listener_remove_callback (SpiKeystrokeListener *listener,
-                                       BooleanKeystrokeListenerCB callback)
-{
-  listener->callbacks = g_list_remove (listener->callbacks, callback);
-}
-
 /*
  * CORBA Accessibility::KeystrokeListener::keyEvent method implementation
  */
 static CORBA_boolean
-impl_key_event (PortableServer_Servant     servant,
+impl_key_event (PortableServer_Servant         servant,
                const Accessibility_KeyStroke *key,
-               CORBA_Environment         *ev)
+               CORBA_Environment             *ev)
 {
-  SpiKeystrokeListener *listener = SPI_KEYSTROKE_LISTENER (bonobo_object_from_servant (servant));
-  GList *callbacks = listener->callbacks;
   gboolean was_consumed = FALSE;
+  SpiKeystrokeListener *listener = SPI_KEYSTROKE_LISTENER (
+         bonobo_object_from_servant (servant));
 
   g_signal_emit (G_OBJECT (listener), signals [KEY_EVENT], 0, key, &was_consumed);
-  if (was_consumed)
-    {
-      return TRUE;
-    }
 
-#ifdef SPI_KEYEVENT_DEBUG
-  if (ev->_major != CORBA_NO_EXCEPTION) {
-    fprintf(stderr,
-            ("Accessibility app error: exception during keystroke notification: %s\n"),
-            CORBA_exception_id(ev));
-    exit(-1);
-  }
-  else {
-    fprintf(stderr, "%s%c",
-           (key->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
-           ((key->modifiers & SPI_KEYMASK_SHIFT)^(key->modifiers & SPI_KEYMASK_SHIFTLOCK))?
-           (char) toupper((int) key->keyID) : (char) tolower((int) key->keyID));
-  }
-#endif
-  /* TODO: convert from the CORBA-based struct to a c-type-based one ? */
-#ifdef SPI_KEYSTROKE_DEBUG  
-    fprintf (stderr, "Key:\tsym %ld\n\tmods %x\n\tcode %d\n\ttime %ld\n",
-          (long) key->keyID,
-          (unsigned int) key->modifiers,
-          (int) key->keycode,
-          (long int) key->timestamp);
-#endif
-  while (callbacks)
-  {
-         BooleanKeystrokeListenerCB cb = (BooleanKeystrokeListenerCB) callbacks->data;
-         was_consumed = (*cb) (key) || was_consumed;
-         callbacks = g_list_next (callbacks);
-  }
   return was_consumed;
 }
 
-
 static gboolean
 boolean_handled_accumulator (GSignalInvocationHint *ihint,
                             GValue                *return_accu,
@@ -178,9 +112,7 @@ marshal_BOOLEAN__POINTER (GClosure     *closure,
 static void
 spi_keystroke_listener_class_init (SpiKeystrokeListenerClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_KeystrokeListener__epv *epv = &klass->epv;
-  keystroke_listener_parent_class = g_type_class_peek_parent (klass);
   
   signals [KEY_EVENT] = g_signal_new (
     "key_event",
@@ -191,15 +123,12 @@ spi_keystroke_listener_class_init (SpiKeystrokeListenerClass *klass)
     marshal_BOOLEAN__POINTER,
     G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
   
-  object_class->finalize = spi_keystroke_listener_object_finalize;
-  
   epv->keyEvent = impl_key_event;
 }
 
 static void
 spi_keystroke_listener_init (SpiKeystrokeListener *keystroke_listener)
 {
-  keystroke_listener->callbacks = NULL;
 }
 
 BONOBO_TYPE_FUNC_FULL (SpiKeystrokeListener,
index 60a45dd..5bd61eb 100644 (file)
@@ -33,15 +33,14 @@ G_BEGIN_DECLS
 #define SPI_KEYSTROKE_LISTENER_TYPE        (spi_keystroke_listener_get_type ())
 #define SPI_KEYSTROKE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_KEYSTROKE_LISTENER_TYPE, SpiKeystrokeListener))
 #define SPI_KEYSTROKE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_KEYSTROKE_LISTENER_TYPE, SpiKeystrokeListenerClass))
-#define IS_SPI_KEYSTROKE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_KEYSTROKE_LISTENER_TYPE))
-#define IS_SPI_KEYSTROKE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_KEYSTROKE_LISTENER_TYPE))
+#define SPI_IS_KEYSTROKE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_KEYSTROKE_LISTENER_TYPE))
+#define SPI_IS_KEYSTROKE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_KEYSTROKE_LISTENER_TYPE))
 
-typedef gboolean (*BooleanKeystrokeListenerCB) (const void *keystroke_ptr);
+typedef struct _SpiKeystrokeListener SpiKeystrokeListener;
 
-typedef struct {
+struct _SpiKeystrokeListener {
         BonoboObject parent;
-       GList *callbacks;
-} SpiKeystrokeListener;
+};
 
 typedef struct {
         BonoboObjectClass parent_class;
@@ -53,11 +52,6 @@ typedef struct {
 
 GType                  spi_keystroke_listener_get_type        (void);
 SpiKeystrokeListener  *spi_keystroke_listener_new             (void);
-void                   spi_keystroke_listener_add_callback    (SpiKeystrokeListener *listener,
-                                                              BooleanKeystrokeListenerCB callback);
-void                   spi_keystroke_listener_remove_callback (SpiKeystrokeListener *listener,
-                                                              BooleanKeystrokeListenerCB callback);
-
 
 G_END_DECLS
 
index 5b5ea71..d3f18dd 100644 (file)
@@ -37,8 +37,8 @@
 #include <libspi/text.h>
 #include <libspi/value.h>
 #include <libspi/listener.h>
+#include <libspi/eventlistener.h>
 #include <libspi/keystrokelistener.h>
-#include <libspi/accessibleeventlistener.h>
 #include <libspi/deviceeventcontroller.h>
 #include <libspi/registry.h>
 #include <libspi/keymasks.h>
index f751904..9c2547c 100644 (file)
@@ -76,7 +76,10 @@ impl_notify_event (PortableServer_Servant     servant,
            ? "yes" : "no");
   */
 #endif
-  Accessibility_Accessible_unref (e->source, ev);
+  if (e->source != CORBA_OBJECT_NIL)
+    {
+      Accessibility_Accessible_unref (e->source, ev);
+    }
 }
 
 static void
index 2c2533b..9016d6a 100644 (file)
@@ -32,8 +32,8 @@ G_BEGIN_DECLS
 #define SPI_LISTENER_TYPE        (spi_listener_get_type ())
 #define SPI_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_LISTENER_TYPE, SpiListener))
 #define SPI_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_LISTENER_TYPE, SpiListenerClass))
-#define IS_SPI_LISTENER(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_LISTENER_TYPE))
-#define IS_SPI_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_LISTENER_TYPE))
+#define SPI_IS_LISTENER(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_LISTENER_TYPE))
+#define SPI_IS_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_LISTENER_TYPE))
 
 typedef struct {
         BonoboObject parent;
@@ -44,8 +44,8 @@ typedef struct {
         POA_Accessibility_EventListener__epv epv;
 } SpiListenerClass;
 
-GType               spi_listener_get_type   (void);
-SpiListener            *spi_listener_new       (void);
+GType        spi_listener_get_type (void);
+SpiListener *spi_listener_new      (void);
 
 G_END_DECLS
 
index 956e088..f2fabf5 100644 (file)
 #  include <stdio.h>
 #endif
 
-/*
- * We'd like to replace the dependance on X-isms with a wrapper layer,
- * to the extent that it can't be done with pure GDK.
- * Anyone want to help?
- */
-#include <X11/Xlib.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-
 #include <libspi/registry.h>
 
 /* Our parent GObject type  */
@@ -90,8 +81,7 @@ spi_listener_struct_new (Accessibility_EventListener listener, CORBA_Environment
 void
 spi_listener_struct_free (SpiListenerStruct *ls, CORBA_Environment *ev)
 {
-  /* TODO: sanity check for ls */
-  Accessibility_EventListener_unref (ls->listener, ev);
+  bonobo_object_release_unref (ls->listener, ev);
   g_free (ls);
 }
 
@@ -124,10 +114,8 @@ impl_accessibility_registry_register_application (PortableServer_Servant servant
 #ifdef SPI_DEBUG
   fprintf (stderr, "registering app %p\n", application);
 #endif
-  registry->desktop->applications = g_list_append (registry->desktop->applications,
-                                                   bonobo_object_dup_ref (application, ev));
+  spi_desktop_add_application (registry->desktop, application);
 
-  /* TODO: create unique string here (with libuuid call ?) and hash ? */
   Accessibility_Application__set_id (application, _get_unique_id(), ev);
 
   /*
@@ -276,32 +264,12 @@ impl_accessibility_registry_deregister_application (PortableServer_Servant serva
                                                     CORBA_Environment * ev)
 {
   SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
-  GList *list = g_list_find_custom (registry->desktop->applications, application, compare_corba_objects);
 
-#ifdef SPI_DEBUG
-  gint i;
-#endif
+  spi_desktop_remove_application (registry->desktop, application);
 
-  if (list)
-    {
 #ifdef SPI_DEBUG
-      fprintf (stderr, "deregistering application %p\n", application);
+  fprintf (stderr, "de-registered app %p\n", application);
 #endif
-      registry->desktop->applications = g_list_delete_link (registry->desktop->applications, list);
-#ifdef SPI_DEBUG
-      fprintf (stderr, "there are now %d apps registered.\n", g_list_length (registry->desktop->applications));
-      for (i = 0; i < g_list_length (registry->desktop->applications); ++i)
-        {
-          fprintf (stderr, "getting application %d\n", i);
-          fprintf (stderr, "object address %p\n",
-                      g_list_nth_data (registry->desktop->applications, i));
-        }
-#endif      
-    }
-  else
-    {
-      fprintf (stderr, "could not deregister application %p\n", application);
-    }
 }
 
 /*
@@ -358,7 +326,7 @@ impl_accessibility_registry_deregister_global_event_listener_all (
                                                     CORBA_Environment      *ev)
 {
   SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
-  SpiListenerStruct *spi_listener_struct, *ls = spi_listener_struct_new (listener, ev);
+  SpiListenerStruct *ls = spi_listener_struct_new (listener, ev);
   GList *list;
   list = g_list_find_custom (registry->object_listeners, ls,
                             compare_listener_corbaref);
@@ -395,7 +363,7 @@ impl_accessibility_registry_deregister_global_event_listener (
                                                     CORBA_Environment      *ev)
 {
   SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
-  SpiListenerStruct ls, *spi_listener_struct;
+  SpiListenerStruct ls;
   EventTypeStruct etype;
   GList *list;
   GList **listeners;
@@ -410,6 +378,7 @@ impl_accessibility_registry_deregister_global_event_listener (
       break;
     case (ETYPE_WINDOW) :
       /* Support for Window Manager Events is not yet implemented */
+      listeners = NULL;
       break;
     case (ETYPE_TOOLKIT) :
       listeners = &registry->toolkit_listeners;
@@ -533,7 +502,10 @@ impl_registry_notify_event (PortableServer_Servant servant,
     default:
       break;
     }
-  /* Accessibility_Accessible_unref (e->source, ev);*/ /* This should be here! */
+  if (e->source != CORBA_OBJECT_NIL)
+    {
+      Accessibility_Accessible_unref (e->source, ev);
+    }
 }
 
 static long
@@ -550,46 +522,46 @@ _registry_notify_listeners (GList *listeners,
                             const Accessibility_Event *e_in,
                             CORBA_Environment *ev)
 {
-  gint n = 0;
-  SpiListenerStruct *ls;
-  GList *list;
-  EventTypeStruct etype;
-  Accessibility_Event *e_out;
-  gchar *s;
-  guint minor_hash;
+  GList              *l;
+  Accessibility_Event e_out;
+  SpiListenerStruct  *ls;
+  EventTypeStruct     etype;
+  guint               minor_hash;
+  CORBA_string        s;
+
+  e_out = *e_in;
   parse_event_type (&etype, e_in->type);
+
   s = g_strconcat (etype.major, etype.minor, NULL);
   minor_hash = g_str_hash (s);
   g_free (s);
 
-  for (list = listeners; list; list = list->next)
+  for (l = listeners; l; l = l->next)
     {
-      ls =  (SpiListenerStruct *) list->data;
+      ls = (SpiListenerStruct *) l->data;
+
 #ifdef SPI_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);
+      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
+
       if ((ls->event_type_hash == etype.hash) || (ls->event_type_hash == minor_hash))
         {
 #ifdef SPI_DEBUG
-          fprintf(stderr, "notifying listener #%d\n", n++);
-         s = Accessibility_Accessible__get_name(e_in->source, ev);
-          fprintf(stderr, "event source name %s\n", s);
-         g_free (s);
+          fprintf (stderr, "notifying listener %d\n", g_list_index (listeners, l->data));
+          s = Accessibility_Accessible__get_name (e_in->source, ev);
+         fprintf (stderr, "event source name %s\n", s);
+         CORBA_free (s);
 #endif
-         e_out = ORBit_copy_value (e_in, TC_Accessibility_Event);
-         e_out->source = bonobo_object_dup_ref (e_in->source, ev);
+         e_out.source = bonobo_object_dup_ref (e_in->source, ev);
           Accessibility_EventListener_notifyEvent ((Accessibility_EventListener) ls->listener,
-                                                   e_out,
+                                                   &e_out,
                                                    ev);
-         /* is it safe to free e_out now ? notifyEvent is a oneway... */
-         CORBA_free (e_out);
-          if (ev->_major != CORBA_NO_EXCEPTION) {
-                fprintf(stderr,
-                ("Accessibility app error: exception during event notification: %s\n"),
-                        CORBA_exception_id(ev));
-                exit(-1);
-          }
+          if (ev->_major != CORBA_NO_EXCEPTION)
+            {
+              g_error ("Accessibility app error: exception during event notification: %s\n",
+                      CORBA_exception_id (ev));
+           }
         }
     }
 }
@@ -633,7 +605,6 @@ spi_registry_init (SpiRegistry *registry)
   registry->object_listeners = NULL;
   registry->window_listeners = NULL;
   registry->toolkit_listeners = NULL;
-  registry->applications = NULL;
   registry->desktop = spi_desktop_new();
   registry->device_event_controller = NULL;
   registry->kbd_event_hook = _device_event_controller_hook;
@@ -648,5 +619,6 @@ SpiRegistry *
 spi_registry_new (void)
 {
     SpiRegistry *retval = g_object_new (SPI_REGISTRY_TYPE, NULL);
+    bonobo_object_set_immortal (BONOBO_OBJECT (retval), TRUE);
     return retval;
 }
index 61b0ed9..dbb7a81 100644 (file)
@@ -33,15 +33,14 @@ G_BEGIN_DECLS
 #define SPI_REGISTRY_TYPE        (spi_registry_get_type ())
 #define SPI_REGISTRY(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_REGISTRY_TYPE, SpiRegistry))
 #define SPI_REGISTRY_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_REGISTRY_TYPE, SpiRegistryClass))
-#define IS_SPI_REGISTRY(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_REGISTRY_TYPE))
-#define IS_SPI_REGISTRY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_REGISTRY_TYPE))
+#define SPI_IS_REGISTRY(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_REGISTRY_TYPE))
+#define SPI_IS_REGISTRY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_REGISTRY_TYPE))
 
 typedef struct {
   SpiListener parent;
   GList *object_listeners;
   GList *window_listeners;
   GList *toolkit_listeners;
-  GList *applications;
   struct SpiDeviceEventController *device_event_controller;
   SpiDesktop *desktop;
   gboolean (*kbd_event_hook) (gpointer source);
index 73bc192..9fb3de5 100644 (file)
 #include <stdio.h>
 #include <libspi/relation.h>
 
-/* A pointer to our parent object class */
-static GObjectClass *parent_class;
-
-static void
-spi_relation_finalize (GObject *obj)
-{
-  SpiRelation *relation = SPI_RELATION(obj);
-  g_object_unref (relation->relation);
-  relation->relation = NULL;
-  parent_class->finalize (obj);
-}
 
 SpiRelation *
 spi_relation_new (AtkRelation *obj)
 {
   SpiRelation *new_relation = g_object_new (SPI_RELATION_TYPE, NULL);
-  new_relation->relation = obj;
-  g_object_ref (obj);
+
+  spi_base_construct (SPI_BASE (new_relation), ATK_OBJECT (obj));
+
   return new_relation;
 }
 
+
 static void
 spi_relation_class_init (SpiRelationClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Relation__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_relation_finalize;
 
   epv->getRelationType  = NULL; /* TODO: finish me! */
   epv->getNTargets      = NULL;
   epv->getTarget        = NULL;
 }
 
+
 static void
 spi_relation_init (SpiRelation *relation)
 {
 }
 
+
 BONOBO_TYPE_FUNC_FULL (SpiRelation,
                       Accessibility_Relation,
-                      BONOBO_TYPE_OBJECT,
+                      SPI_TYPE_BASE,
                       spi_relation);
index b923557..eb1c05e 100644 (file)
 #ifndef SPI_RELATION_H_
 #define SPI_RELATION_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
+#include <atk/atkrelation.h>
 
 G_BEGIN_DECLS
 
-#define SPI_RELATION_TYPE        (spi_relation_get_type ())
-#define SPI_RELATION(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_RELATION_TYPE, SpiRelation))
+#define SPI_RELATION_TYPE            (spi_relation_get_type ())
+#define SPI_RELATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_RELATION_TYPE, SpiRelation))
 #define SPI_RELATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_RELATION_TYPE, SpiRelationClass))
-#define IS_SPI_RELATION(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_RELATION_TYPE))
-#define IS_SPI_RELATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_RELATION_TYPE))
+#define SPI_IS_RELATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_RELATION_TYPE))
+#define SPI_IS_RELATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_RELATION_TYPE))
 
 typedef struct _SpiRelation SpiRelation;
 typedef struct _SpiRelationClass SpiRelationClass;
 
 struct _SpiRelation {
-  BonoboObject parent;
-  AtkRelation *relation;
+  SpiBase parent;
 };
 
 struct _SpiRelationClass {
-  BonoboObjectClass parent_class;
+  SpiBaseClass parent_class;
   POA_Accessibility_Relation__epv epv;
 };
 
-GType
-spi_relation_get_type   (void);
-
-SpiRelation *
-spi_relation_new       (AtkRelation *relation);
+GType        spi_relation_get_type (void);
+SpiRelation *spi_relation_new      (AtkRelation *relation);
 
 G_END_DECLS
 
index f51c360..538a8c2 100644 (file)
 #include <libspi/accessible.h>
 #include <libspi/selection.h>
 
-/* A pointer to our parent object class */
-static GObjectClass *parent_class;
-
-static void
-spi_selection_finalize (GObject *obj)
-{
-  SpiSelection *selection = SPI_SELECTION (obj);
-  g_object_unref (selection->atko);
-  selection->atko = NULL;
-  parent_class->finalize (obj);
-}
 
 SpiSelection *
 spi_selection_interface_new (AtkObject *obj)
 {
   SpiSelection *new_selection = g_object_new (SPI_SELECTION_TYPE, NULL);
-  new_selection->atko = obj;
-  g_object_ref (obj);
+
+  spi_base_construct (SPI_BASE (new_selection), obj);
+
   return new_selection;
 }
 
 
+static AtkSelection *
+get_selection_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+
+  if (!object)
+    {
+      return NULL;
+    }
+
+  return ATK_SELECTION (object->atko);
+}
+
 
 static CORBA_long
-impl__get_nSelectedChildren (PortableServer_Servant _servant,
-                            CORBA_Environment ev)
+impl__get_nSelectedChildren (PortableServer_Servant servant,
+                            CORBA_Environment     *ev)
 {
-  BonoboObject *obj = bonobo_object_from_servant (_servant);
-  SpiSelection *selection;
-#ifdef SPI_DEBUG
-  fprintf (stderr, "calling impl__get_nSelectedChildren\n");
-#endif
-  g_return_val_if_fail (IS_SPI_SELECTION (obj), 0);
-  selection = SPI_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));
+  AtkSelection *selection = get_selection_from_servant (servant);
+
+  g_return_val_if_fail (selection != NULL, 0);
+
+  return (CORBA_long) atk_selection_get_selection_count (selection);
 }
 
 
 static Accessibility_Accessible
-impl_getSelectedChild (PortableServer_Servant _servant,
-                      const CORBA_long selectedChildIndex,
-                      CORBA_Environment ev)
+impl_getSelectedChild (PortableServer_Servant servant,
+                      const CORBA_long       selectedChildIndex,
+                      CORBA_Environment     *ev)
 {
-  BonoboObject *obj = bonobo_object_from_servant (_servant);
-  SpiSelection
-         *selection;
-  AtkObject *atk_object;
-  Accessibility_Accessible rv;
+  AtkObject    *atk_object;
+  AtkSelection *selection = get_selection_from_servant (servant);
+
+  g_return_val_if_fail (selection != NULL, CORBA_OBJECT_NIL);
+
 #ifdef SPI_DEBUG
   fprintf (stderr, "calling impl_getSelectedChild\n");
 #endif
-  g_return_val_if_fail (IS_SPI_SELECTION (obj), 0);
-  selection = SPI_SELECTION (obj);
-  g_return_val_if_fail (ATK_IS_SELECTION (selection->atko), 0);
 
-  atk_object = atk_selection_ref_selection (ATK_SELECTION (selection->atko),
+  atk_object = atk_selection_ref_selection (selection,
                                            (gint) selectedChildIndex);
-  g_return_val_if_fail (ATK_IS_OBJECT (atk_object), NULL);
+
+  g_return_val_if_fail (ATK_IS_OBJECT (atk_object), CORBA_OBJECT_NIL);
+
 #ifdef SPI_DEBUG
-  fprintf (stderr, "child type is %s\n", g_type_name (G_OBJECT_TYPE (atk_object)));
+  fprintf (stderr, "child type is %s\n",
+          g_type_name (G_OBJECT_TYPE (atk_object)));
 #endif
-  rv = bonobo_object_corba_objref (bonobo_object (spi_accessible_new (atk_object)));
-  g_object_unref (atk_object);
-  return CORBA_Object_duplicate (rv, ev);
-}
 
+  return spi_accessible_new_return (atk_object, TRUE, ev);
+}
 
 
 static CORBA_boolean
-impl_selectChild (PortableServer_Servant _servant,
-                 const CORBA_long childIndex,
-                 CORBA_Environment ev)
+impl_selectChild (PortableServer_Servant servant,
+                 const CORBA_long       childIndex,
+                 CORBA_Environment     *ev)
 {
-  SpiSelection *selection = SPI_SELECTION (bonobo_object_from_servant (_servant));
-  return (CORBA_boolean)
-    atk_selection_add_selection (ATK_SELECTION(selection->atko), (gint) childIndex);
-}
+  AtkSelection *selection = get_selection_from_servant (servant);
 
+  g_return_val_if_fail (selection != NULL, FALSE);
 
+  return (CORBA_boolean)
+    atk_selection_add_selection (selection, (gint) childIndex);
+}
 
 
 static CORBA_boolean
-impl_deselectSelectedChild (PortableServer_Servant _servant,
-                           const CORBA_long selectedChildIndex,
-                           CORBA_Environment ev)
+impl_deselectSelectedChild (PortableServer_Servant servant,
+                           const CORBA_long       selectedChildIndex,
+                           CORBA_Environment     *ev)
 {
-  SpiSelection *selection = SPI_SELECTION (bonobo_object_from_servant (_servant));
+  AtkSelection *selection = get_selection_from_servant (servant);
+
+  g_return_val_if_fail (selection != NULL, FALSE);
+
   return (CORBA_boolean)
-    atk_selection_remove_selection (ATK_SELECTION(selection->atko), (gint) selectedChildIndex);
+    atk_selection_remove_selection (selection, (gint) selectedChildIndex);
 }
 
 
-
 static CORBA_boolean
-impl_isChildSelected (PortableServer_Servant _servant,
-                     const CORBA_long childIndex,
-                     CORBA_Environment ev)
+impl_isChildSelected (PortableServer_Servant servant,
+                     const CORBA_long       childIndex,
+                     CORBA_Environment     *ev)
 {
-  SpiSelection *selection = SPI_SELECTION (bonobo_object_from_servant (_servant));
+  AtkSelection *selection = get_selection_from_servant (servant);
+
+  g_return_val_if_fail (selection != NULL, FALSE);
+
   return (CORBA_boolean)
-    atk_selection_is_child_selected (ATK_SELECTION(selection->atko), (gint) childIndex);
+    atk_selection_is_child_selected (selection, (gint) childIndex);
 }
 
 
-
 static void 
-impl_selectAll (PortableServer_Servant _servant,
-               CORBA_Environment ev)
+impl_selectAll (PortableServer_Servant servant,
+               CORBA_Environment     *ev)
 {
-  SpiSelection *selection = SPI_SELECTION (bonobo_object_from_servant (_servant));
-  atk_selection_select_all_selection (ATK_SELECTION(selection->atko));
-}
+  AtkSelection *selection = get_selection_from_servant (servant);
+
+  g_return_if_fail (selection != NULL);
 
+  atk_selection_select_all_selection (selection);
+}
 
 
 static void 
-impl_clearSelection (PortableServer_Servant _servant,
-                    CORBA_Environment ev)
+impl_clearSelection (PortableServer_Servant servant,
+                    CORBA_Environment     *ev)
 {
-  SpiSelection *selection = SPI_SELECTION (bonobo_object_from_servant (_servant));
-  atk_selection_clear_selection (ATK_SELECTION(selection->atko));
+  AtkSelection *selection = get_selection_from_servant (servant);
+
+  g_return_if_fail (selection != NULL);
+
+  atk_selection_clear_selection (selection);
 }
 
+
 static void
 spi_selection_class_init (SpiSelectionClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Selection__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_selection_finalize;
-
 
   /* Initialize epv table */
 
   epv->_get_nSelectedChildren = impl__get_nSelectedChildren;
-  epv->getSelectedChild = impl_getSelectedChild;
-  epv->selectChild = impl_selectChild;
-  epv->deselectSelectedChild = impl_deselectSelectedChild;
-  epv->isChildSelected = impl_isChildSelected;
-  epv->selectAll = impl_selectAll;
-  epv->clearSelection = impl_clearSelection;
+  epv->getSelectedChild       = impl_getSelectedChild;
+  epv->selectChild            = impl_selectChild;
+  epv->deselectSelectedChild  = impl_deselectSelectedChild;
+  epv->isChildSelected        = impl_isChildSelected;
+  epv->selectAll              = impl_selectAll;
+  epv->clearSelection         = impl_clearSelection;
 }
 
+
 static void
 spi_selection_init (SpiSelection *selection)
 {
 }
 
+
 BONOBO_TYPE_FUNC_FULL (SpiSelection,
                       Accessibility_Selection,
-                      BONOBO_TYPE_OBJECT,
+                      SPI_TYPE_BASE,
                       spi_selection);
index 7bf6736..7c5bd25 100644 (file)
 #ifndef SPI_SELECTION_H_
 #define SPI_SELECTION_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
+#include <atk/atkselection.h>
 
 G_BEGIN_DECLS
 
-#define SPI_SELECTION_TYPE        (spi_selection_get_type ())
-#define SPI_SELECTION(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_SELECTION_TYPE, SpiSelection))
+#define SPI_SELECTION_TYPE            (spi_selection_get_type ())
+#define SPI_SELECTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_SELECTION_TYPE, SpiSelection))
 #define SPI_SELECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_SELECTION_TYPE, SpiSelectionClass))
-#define IS_SPI_SELECTION(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_SELECTION_TYPE))
-#define IS_SPI_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_SELECTION_TYPE))
+#define SPI_IS_SELECTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_SELECTION_TYPE))
+#define SPI_IS_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_SELECTION_TYPE))
 
-typedef struct _Selection SpiSelection;
-typedef struct _SelectionClass SpiSelectionClass;
+typedef struct _SpiSelection      SpiSelection;
+typedef struct _SpiSelectionClass SpiSelectionClass;
 
-struct _Selection {
-  BonoboObject parent;
-  AtkObject *atko;
+struct _SpiSelection {
+  SpiBase parent;
 };
 
-struct _SelectionClass {
-  BonoboObjectClass parent_class;
+struct _SpiSelectionClass {
+  SpiBaseClass parent_class;
   POA_Accessibility_Selection__epv epv;
 };
 
-GType
-spi_selection_get_type   (void);
-
-SpiSelection *
-spi_selection_interface_new       (AtkObject *obj);
+GType         spi_selection_get_type      (void);
+SpiSelection *spi_selection_interface_new (AtkObject *obj);
 
 G_END_DECLS
 
index 63011d2..111c872 100644 (file)
 
 #include <config.h>
 #include <stdio.h>
+#include <bonobo/bonobo-exception.h>
+#include <atk/atktable.h>
 #include <libspi/accessible.h>
 #include <libspi/table.h>
 
-/* A pointer to our parent object class */
-static GObjectClass *parent_class;
-
-static void
-spi_table_finalize (GObject *obj)
-{
-  SpiTable *table = SPI_TABLE (obj);
-  g_object_unref (table->atko);
-  table->atko = NULL;  
-  parent_class->finalize (obj);
-}
 
 SpiTable *
 spi_table_interface_new (AtkObject *obj)
 {
   SpiTable *new_table = g_object_new (SPI_TABLE_TYPE, NULL);
-  new_table->atko = obj;
-  g_object_ref (obj);
+
+  spi_base_construct (SPI_BASE (new_table), obj);
+
   return new_table;
 }
 
 
+static AtkTable *
+get_table_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+
+  if (!object)
+    {
+      return NULL;
+    }
+
+  return ATK_TABLE (object->atko);
+}
+
 
 static Accessibility_Accessible
-impl__get_caption (PortableServer_Servant _servant,
-                  CORBA_Environment ev)
+impl__get_caption (PortableServer_Servant servant,
+                  CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
   AtkObject *atk_object;
-  Accessibility_Accessible rv;
+  AtkTable  *table = get_table_from_servant (servant);
 
-  atk_object = atk_table_get_caption (ATK_TABLE(table-> atko));
-  rv = bonobo_object_corba_objref (BONOBO_OBJECT(spi_accessible_new(atk_object)));
-  return CORBA_Object_duplicate (rv, ev);
-}
+  g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
 
+  atk_object = atk_table_get_caption (table);
+
+  return spi_accessible_new_return (atk_object, FALSE, ev);
+}
 
 
 static Accessibility_Accessible
-impl__get_summary (PortableServer_Servant _servant,
-                  CORBA_Environment ev)
+impl__get_summary (PortableServer_Servant servant,
+                  CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
   AtkObject *atk_object;
-  Accessibility_Accessible rv;
+  AtkTable  *table = get_table_from_servant (servant);
 
-  atk_object = atk_table_get_summary (ATK_TABLE(table->atko));
-  rv = bonobo_object_corba_objref (BONOBO_OBJECT(spi_accessible_new(atk_object)));
-  return CORBA_Object_duplicate (rv, ev);
-}
+  g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
 
+  atk_object = atk_table_get_summary (table);
+
+  return spi_accessible_new_return (atk_object, FALSE, ev);
+}
 
 
 static CORBA_long
-impl__get_nRows (PortableServer_Servant _servant,
-                CORBA_Environment ev)
+impl__get_nRows (PortableServer_Servant servant,
+                CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
-  return (CORBA_long)
-    atk_table_get_n_rows (ATK_TABLE(table->atko) );
-}
+  AtkTable *table = get_table_from_servant (servant);
 
+  g_return_val_if_fail (table != NULL, 0);
+
+  return (CORBA_long) atk_table_get_n_rows (table);
+}
 
 
 static CORBA_long
-impl__get_nColumns (PortableServer_Servant _servant,
-                   CORBA_Environment ev)
+impl__get_nColumns (PortableServer_Servant servant,
+                   CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
-  return (CORBA_long)
-    atk_table_get_n_columns (ATK_TABLE(table->atko));
-}
+  AtkTable *table = get_table_from_servant (servant);
+
+  g_return_val_if_fail (table != NULL, 0);
 
+  return (CORBA_long) atk_table_get_n_columns (table);
+}
 
 
 static Accessibility_Accessible
-impl_getAccessibleAt (PortableServer_Servant _servant,
-                     const CORBA_long row,
-                     const CORBA_long column,
-                     CORBA_Environment ev)
+impl_getAccessibleAt (PortableServer_Servant servant,
+                     const CORBA_long       row,
+                     const CORBA_long       column,
+                     CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
   AtkObject *atk_object;
-  Accessibility_Accessible rv;
+  AtkTable  *table = get_table_from_servant (servant);
 
-  atk_object = atk_table_ref_at (ATK_TABLE(table->atko),
-                                            (gint) row, (gint) column);
-  rv = bonobo_object_corba_objref (BONOBO_OBJECT(spi_accessible_new(atk_object)));
-  return CORBA_Object_duplicate (rv, ev);
-}
+  g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
 
+  atk_object = atk_table_ref_at (table,
+                                (gint) row, (gint) column);
+
+  return spi_accessible_new_return (atk_object, TRUE, ev);
+}
 
 
 static CORBA_long
-impl_getIndexAt (PortableServer_Servant _servant,
-                const CORBA_long row, const CORBA_long column,
-                CORBA_Environment * ev)
+impl_getIndexAt (PortableServer_Servant servant,
+                const CORBA_long       row,
+                const CORBA_long       column,
+                CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
+  AtkTable *table = get_table_from_servant (servant);
+
+  g_return_val_if_fail (table != NULL, 0);
+
   return (CORBA_long)
-    atk_table_get_index_at (ATK_TABLE(table->atko),
-                           (gint) row, (gint) column);
+    atk_table_get_index_at (table, (gint) row, (gint) column);
 }
 
 
-
 static CORBA_long
-impl_getRowAtIndex (PortableServer_Servant _servant,
-                   const CORBA_long index,
-                   CORBA_Environment ev)
+impl_getRowAtIndex (PortableServer_Servant servant,
+                   const CORBA_long       index,
+                   CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
+  AtkTable *table = get_table_from_servant (servant);
+
+  g_return_val_if_fail (table != NULL, 0);
+
   return (CORBA_long)
-    atk_table_get_row_at_index (ATK_TABLE(table->atko), (gint) index);
+    atk_table_get_row_at_index (table, (gint) index);
 }
 
 
-
 static CORBA_long
-impl_getColumnAtIndex (PortableServer_Servant _servant,
-                      const CORBA_long index,
-                      CORBA_Environment ev)
+impl_getColumnAtIndex (PortableServer_Servant servant,
+                      const CORBA_long       index,
+                      CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
+  AtkTable *table = get_table_from_servant (servant);
+
+  g_return_val_if_fail (table != NULL, 0);
+
   return (CORBA_long)
-    atk_table_get_column_at_index (ATK_TABLE(table->atko), (gint) index);
+    atk_table_get_column_at_index (table, (gint) index);
 }
 
 
-
 static CORBA_string
 impl_getRowDescription (PortableServer_Servant servant,
                        const CORBA_long       row,
                        CORBA_Environment     *ev)
 {
   const char *rv;
-  SpiTable   *table;
+  AtkTable   *table = get_table_from_servant (servant);
 
-  table = SPI_TABLE (bonobo_object_from_servant (servant));
+  g_return_val_if_fail (table != NULL, 0);
   
-  rv = atk_table_get_row_description (ATK_TABLE (table->atko), row);
+  rv = atk_table_get_row_description (table, row);
 
   if (rv)
-    return CORBA_string_dup (rv);
+    {
+      return CORBA_string_dup (rv);
+    }
   else
-    return CORBA_string_dup ("");
+    {
+      return CORBA_string_dup ("");
+    }
 }
 
 
-
 static CORBA_string
 impl_getColumnDescription (PortableServer_Servant servant,
                           const CORBA_long       column,
                           CORBA_Environment     *ev)
 {
   const char *rv;
-  SpiTable   *table;
+  AtkTable   *table = get_table_from_servant (servant);
 
-  table = SPI_TABLE (bonobo_object_from_servant (servant));
+  g_return_val_if_fail (table != NULL, CORBA_string_dup (""));
   
-  rv = atk_table_get_row_description (ATK_TABLE (table->atko), column);
+  rv = atk_table_get_row_description (table, column);
 
   if (rv)
-    return CORBA_string_dup (rv);
+    {
+      return CORBA_string_dup (rv);
+    }
   else
-    return CORBA_string_dup ("");
+    {
+      return CORBA_string_dup ("");
+    }
 }
 
 
-
 static CORBA_long
-impl_getRowExtentAt (PortableServer_Servant _servant,
-                    const CORBA_long row,
-                    const CORBA_long column,
-                    CORBA_Environment ev)
+impl_getRowExtentAt (PortableServer_Servant servant,
+                    const CORBA_long       row,
+                    const CORBA_long       column,
+                    CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
+  AtkTable *table = get_table_from_servant (servant);
+
+  g_return_val_if_fail (table != NULL, -1);
+
   return (CORBA_long)
-    atk_table_get_row_extent_at (ATK_TABLE(table->atko),
+    atk_table_get_row_extent_at (table,
                                 (gint) row, (gint) column);
 }
 
 
-
 static CORBA_long
-impl_getColumnExtentAt (PortableServer_Servant _servant,
-                       const CORBA_long row,
-                       const CORBA_long column,
-                       CORBA_Environment ev)
+impl_getColumnExtentAt (PortableServer_Servant servant,
+                       const CORBA_long       row,
+                       const CORBA_long       column,
+                       CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
+  AtkTable *table = get_table_from_servant (servant);
+
+  g_return_val_if_fail (table != NULL, -1);
+
   return (CORBA_long)
-    atk_table_get_column_extent_at (ATK_TABLE(table->atko),
-                                (gint) row, (gint) column);
+    atk_table_get_column_extent_at (table,
+                                   (gint) row, (gint) column);
 }
 
 
-
 static Accessibility_Table
-impl_getRowHeader (PortableServer_Servant _servant,
-                  const CORBA_long row,
-                  CORBA_Environment ev)
+impl_getRowHeader (PortableServer_Servant servant,
+                  const CORBA_long       row,
+                  CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
   AtkObject *header;
-  Accessibility_Table rv;
+  AtkTable  *table = get_table_from_servant (servant);
 
-  header = atk_table_get_row_header (ATK_TABLE(table->atko), (gint) row);
-  rv = bonobo_object_corba_objref (BONOBO_OBJECT(spi_accessible_new(header)));
-  return CORBA_Object_duplicate (rv, ev);
-}
+  g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
 
+  header = atk_table_get_row_header (table, (gint) row);
 
+  return spi_accessible_new_return (header, FALSE, ev);
+}
 
-static        Accessibility_Table
-impl_getColumnHeader (PortableServer_Servant _servant,
-                     const CORBA_long column,
-                     CORBA_Environment * ev)
+
+static Accessibility_Table
+impl_getColumnHeader (PortableServer_Servant servant,
+                     const CORBA_long       column,
+                     CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
   AtkObject *header;
-  Accessibility_Table rv;
+  AtkTable  *table = get_table_from_servant (servant);
 
-  header = atk_table_get_column_header (ATK_TABLE(table->atko), (gint) column);
-  rv = bonobo_object_corba_objref (BONOBO_OBJECT(spi_accessible_new(header)));
-  return CORBA_Object_duplicate (rv, ev);
-}
+  g_return_val_if_fail (table != NULL, CORBA_OBJECT_NIL);
+
+  header = atk_table_get_column_header (table, (gint) column);
 
+  return spi_accessible_new_return (header, FALSE, ev);
+}
 
 
 static Accessibility_LongSeq *
-impl_getSelectedRows (PortableServer_Servant _servant,
-                     CORBA_Environment ev)
+impl_getSelectedRows (PortableServer_Servant servant,
+                     CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
   gint *selectedRows;
   gint length;
   Accessibility_LongSeq *retval;
+  AtkTable *table = get_table_from_servant (servant);
+
+  bonobo_return_val_if_fail (table != NULL, NULL, ev);
 
-  length = atk_table_get_selected_rows (ATK_TABLE(table->atko), &selectedRows);
+  length = atk_table_get_selected_rows (table, &selectedRows);
+
+  bonobo_return_val_if_fail (length > 0, NULL, ev);
 
-  g_return_val_if_fail (length, NULL);
   retval = Accessibility_LongSeq__alloc ();
   retval->_maximum = retval->_length = (CORBA_long) length;
   retval->_buffer = Accessibility_LongSeq_allocbuf (length);
 
   while (--length)
-    retval->_buffer[length] = (CORBA_long) selectedRows[length];
+    {
+      retval->_buffer[length] = (CORBA_long) selectedRows[length];
+    }
+
   g_free ((gpointer) selectedRows);
+
   return retval;
 }
 
 
-
 static Accessibility_LongSeq *
-impl_getSelectedColumns (PortableServer_Servant _servant,
-                        CORBA_Environment ev)
+impl_getSelectedColumns (PortableServer_Servant servant,
+                        CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
   gint *selectedColumns;
   gint length;
   Accessibility_LongSeq *retval;
+  AtkTable *table = get_table_from_servant (servant);
+
+  bonobo_return_val_if_fail (table != NULL, NULL, ev);
 
-  length = atk_table_get_selected_columns (ATK_TABLE(table->atko), &selectedColumns);
+  length = atk_table_get_selected_columns (table, &selectedColumns);
 
-  g_return_val_if_fail (length, NULL);
+  bonobo_return_val_if_fail (length >= 0, NULL, ev);
 
   retval = Accessibility_LongSeq__alloc ();
   retval->_maximum = retval->_length = (CORBA_long) length;
   retval->_buffer = Accessibility_LongSeq_allocbuf (length);
 
   while (--length)
-    retval->_buffer[length] = (CORBA_long) selectedColumns[length];
+    {
+      retval->_buffer[length] = (CORBA_long) selectedColumns[length];
+    }
+
   g_free ((gpointer) selectedColumns);
+
   return retval;
 }
 
 
-
 static CORBA_boolean
-impl_isRowSelected (PortableServer_Servant _servant,
-                   const CORBA_long row,
-                   CORBA_Environment ev)
+impl_isRowSelected (PortableServer_Servant servant,
+                   const CORBA_long       row,
+                   CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
-  return (CORBA_boolean)
-    atk_table_is_row_selected (ATK_TABLE(table->atko), (gint) row);
-}
+  AtkTable *table = get_table_from_servant (servant);
 
+  g_return_val_if_fail (table != NULL, FALSE);
+
+  return (CORBA_boolean) atk_table_is_row_selected (table, (gint) row);
+}
 
 
 static CORBA_boolean
-impl_isColumnSelected (PortableServer_Servant _servant,
-                      const CORBA_long column,
-                      CORBA_Environment ev)
+impl_isColumnSelected (PortableServer_Servant servant,
+                      const CORBA_long       column,
+                      CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
-  return (CORBA_boolean)
-    atk_table_is_column_selected (ATK_TABLE(table->atko), (gint) column);
-}
+  AtkTable *table = get_table_from_servant (servant);
 
+  g_return_val_if_fail (table != NULL, FALSE);
+
+  return (CORBA_boolean) atk_table_is_column_selected (table, (gint) column);
+}
 
 
 static CORBA_boolean
-impl_isSelected (PortableServer_Servant _servant,
-                const CORBA_long row,
-                const CORBA_long column,
-                CORBA_Environment ev)
+impl_isSelected (PortableServer_Servant servant,
+                const CORBA_long       row,
+                const CORBA_long       column,
+                CORBA_Environment     *ev)
 {
-  SpiTable *table = SPI_TABLE (bonobo_object_from_servant (_servant));
-  return (CORBA_boolean)
-    atk_table_is_selected (ATK_TABLE(table->atko),
-                          (gint) row, (gint) column);
+  AtkTable *table = get_table_from_servant (servant);
+
+  g_return_val_if_fail (table != NULL, FALSE);
+
+  return (CORBA_boolean) atk_table_is_selected (table,
+                                               (gint) row, (gint) column);
 }
 
+
 static void
 spi_table_class_init (SpiTableClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Table__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_table_finalize;
-
 
   /* Initialize epv table */
 
@@ -382,5 +416,5 @@ spi_table_init (SpiTable *table)
 
 BONOBO_TYPE_FUNC_FULL (SpiTable,
                       Accessibility_Table,
-                      BONOBO_TYPE_OBJECT,
+                      SPI_TYPE_BASE,
                       spi_table);
index 29f4fcd..3a41b6e 100644 (file)
 #ifndef SPI_TABLE_H_
 #define SPI_TABLE_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
 
 G_BEGIN_DECLS
 
-#define SPI_TABLE_TYPE        (spi_table_get_type ())
-#define SPI_TABLE(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_TABLE_TYPE, SpiTable))
-#define SPI_TABLE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_TABLE_TYPE, SpiTableClass))
-#define IS_TABLE(obj)       (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_TABLE_TYPE))
-#define IS_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_TABLE_TYPE))
+#define SPI_TABLE_TYPE         (spi_table_get_type ())
+#define SPI_TABLE(obj)         (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_TABLE_TYPE, SpiTable))
+#define SPI_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPI_TABLE_TYPE, SpiTableClass))
+#define IS_TABLE(obj)          (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_TABLE_TYPE))
+#define IS_TABLE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_TABLE_TYPE))
 
-typedef struct _Table SpiTable;
-typedef struct _TableClass SpiTableClass;
+typedef struct _SpiTable      SpiTable;
+typedef struct _SpiTableClass SpiTableClass;
 
-struct _Table {
-  BonoboObject parent;
-  AtkObject *atko;
+struct _SpiTable {
+  SpiBase parent;
 };
 
-struct _TableClass {
-  BonoboObjectClass parent_class;
+struct _SpiTableClass {
+  SpiBaseClass parent_class;
   POA_Accessibility_Table__epv epv;
 };
 
-GType
-spi_table_get_type   (void);
-
-SpiTable *
-spi_table_interface_new       (AtkObject *obj);
+GType     spi_table_get_type      (void);
+SpiTable *spi_table_interface_new (AtkObject *obj);
 
 G_END_DECLS
 
index 0ce1bd1..bc74e26 100644 (file)
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <atk/atktext.h>
 #include <libspi/text.h>
 
 /* Our parent Gtk object type */
-#define PARENT_TYPE BONOBO_TYPE_OBJECT
+#define PARENT_TYPE SPI_TYPE_BASE
 
-/* A pointer to our parent object class */
-static GObjectClass *spi_text_parent_class;
+static AtkText *
+get_text_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+
+  if (!object)
+    {
+      return NULL;
+    }
+
+  return ATK_TEXT (object->atko);
+}
 
 static CORBA_string
-impl_getText (PortableServer_Servant _servant,
-             const CORBA_long startOffset,
-             const CORBA_long endOffset,
-             CORBA_Environment ev)
+impl_getText (PortableServer_Servant servant,
+             const CORBA_long       startOffset,
+             const CORBA_long       endOffset,
+             CORBA_Environment     *ev)
 {
-  SpiText *text;
   gchar *txt;
   CORBA_string rv;
-  BonoboObject *obj;
-  
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
-  text = SPI_TEXT (obj);
-  g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
+  AtkText *text = get_text_from_servant (servant);
+
+  g_return_val_if_fail (text != NULL, CORBA_string_dup (""));
   
-  txt = atk_text_get_text (ATK_TEXT(text->atko),
-                      (gint) startOffset, (gint) endOffset);
+  txt = atk_text_get_text (text, (gint) startOffset, (gint) endOffset);
   if (txt)
     {
       rv = CORBA_string_dup (txt);
@@ -58,34 +64,30 @@ impl_getText (PortableServer_Servant _servant,
     }
   else
     rv = CORBA_string_dup ("");
+
   return rv;
 }
 
 
-
 CORBA_string
-impl_getTextAfterOffset (PortableServer_Servant _servant,
+impl_getTextAfterOffset (PortableServer_Servant servant,
                         const CORBA_long offset,
                         const
                         Accessibility_TEXT_BOUNDARY_TYPE
                         type, CORBA_long * startOffset,
                         CORBA_long * endOffset,
-                        CORBA_Environment * ev)
+                        CORBA_Environment *ev)
 {
-  SpiText *text;
   gchar *txt;
   CORBA_char *rv;
   gint intStartOffset, intEndOffset;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
-  text = SPI_TEXT (obj);
-  g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
-  
-  txt = atk_text_get_text_after_offset (ATK_TEXT(text->atko),
-                                   (gint) offset, (AtkTextBoundary) type,
-                                   &intStartOffset, &intEndOffset);
+  g_return_val_if_fail (text != NULL, CORBA_string_dup (""));
+
+  txt = atk_text_get_text_after_offset (text,
+                                       (gint) offset, (AtkTextBoundary) type,
+                                       &intStartOffset, &intEndOffset);
   *startOffset = (CORBA_long) intStartOffset;
   *endOffset = (CORBA_long) intEndOffset;
 
@@ -93,36 +95,34 @@ impl_getTextAfterOffset (PortableServer_Servant _servant,
     {
       rv = CORBA_string_dup (txt);
       g_free (txt);
-      }
+    }
   else
     rv = CORBA_string_dup ("");
+
   return rv;
 }
 
 
-
 static CORBA_string
-impl_getTextAtOffset (PortableServer_Servant _servant,
+impl_getTextAtOffset (PortableServer_Servant servant,
                      const CORBA_long offset,
                      const Accessibility_TEXT_BOUNDARY_TYPE type,
                      CORBA_long * startOffset,
                      CORBA_long * endOffset,
-                     CORBA_Environment * ev)
+                     CORBA_Environment *ev)
 {
-  SpiText *text;
   CORBA_char *txt;
   CORBA_char *rv;
   gint intStartOffset, intEndOffset;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
+
+  g_return_val_if_fail (text != NULL, CORBA_string_dup (""));
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
-  text = SPI_TEXT (obj);
-  g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
+  txt = (CORBA_char *) atk_text_get_text_at_offset (
+         text,
+         (gint) offset, (AtkTextBoundary) type,
+         &intStartOffset, &intEndOffset);
 
-  txt = (CORBA_char *) atk_text_get_text_at_offset (ATK_TEXT (text->atko),
-                                   (gint) offset, (AtkTextBoundary) type,
-                                   &intStartOffset, &intEndOffset);
   *startOffset = (CORBA_long) intStartOffset;
   *endOffset = (CORBA_long) intEndOffset;
 
@@ -139,46 +139,39 @@ impl_getTextAtOffset (PortableServer_Servant _servant,
 
 
 static CORBA_unsigned_long
-impl_getCharacterAtOffset (PortableServer_Servant _servant,
+impl_getCharacterAtOffset (PortableServer_Servant servant,
                           const CORBA_long offset,
-                          CORBA_Environment * ev)
+                          CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
-  obj = (bonobo_object_from_servant (_servant));
-  
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_unsigned_long)0);
-  text = SPI_TEXT (obj);
-  g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_unsigned_long)0);
+  AtkText *text = get_text_from_servant (servant);
+
+  g_return_val_if_fail (text != NULL, 0);
 
   return (CORBA_unsigned_long)
-    atk_text_get_character_at_offset (ATK_TEXT(text->atko), (gint) offset);
+    atk_text_get_character_at_offset (text, (gint) offset);
 }
 
 
 static CORBA_string
-impl_getTextBeforeOffset (PortableServer_Servant _servant,
+impl_getTextBeforeOffset (PortableServer_Servant servant,
                          const CORBA_long offset,
                          const
                          Accessibility_TEXT_BOUNDARY_TYPE
                          type, CORBA_long * startOffset,
                          CORBA_long * endOffset,
-                         CORBA_Environment * ev)
+                         CORBA_Environment *ev)
 {
-  SpiText *text;
   gchar *txt;
   CORBA_char *rv;
   gint intStartOffset, intEndOffset;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
+
+  g_return_val_if_fail (text != NULL, CORBA_string_dup (""));
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
-  text = SPI_TEXT (obj);
-  g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
+  txt = atk_text_get_text_before_offset (text,
+                                        (gint) offset, (AtkTextBoundary) type,
+                                        &intStartOffset, &intEndOffset);
 
-  txt = atk_text_get_text_before_offset (ATK_TEXT(text->atko),
-                                   (gint) offset, (AtkTextBoundary) type,
-                                   &intStartOffset, &intEndOffset);
   *startOffset = (CORBA_long) intStartOffset;
   *endOffset = (CORBA_long) intEndOffset;
 
@@ -189,256 +182,196 @@ impl_getTextBeforeOffset (PortableServer_Servant _servant,
     }
   else
     rv = CORBA_string_dup ("");
+
   return rv;
 }
 
 
 static CORBA_long
-impl__get_caretOffset (PortableServer_Servant _servant,
-                    CORBA_Environment * ev)
+impl__get_caretOffset (PortableServer_Servant servant,
+                    CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)-1);
-  text = SPI_TEXT (obj);
-  g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_long)-1);
-  
-  return (CORBA_long)
-    atk_text_get_caret_offset (ATK_TEXT(text->atko));
-}
+  g_return_val_if_fail (text != NULL, -1);
 
+  return (CORBA_long) atk_text_get_caret_offset (text);
+}
 
 
 static CORBA_string
-impl_getAttributes (PortableServer_Servant _servant,
-                      const CORBA_long offset,
-                      CORBA_long * startOffset,
-                      CORBA_long * endOffset,
-                      CORBA_Environment * ev)
+impl_getAttributes (PortableServer_Servant servant,
+                   const CORBA_long offset,
+                   CORBA_long * startOffset,
+                   CORBA_long * endOffset,
+                   CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
-  text = SPI_TEXT (obj);
-  g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
+  g_return_val_if_fail (text != NULL, CORBA_string_dup (""));
 
   g_print ("getAttributes not yet implemented.\n");
 
   return CORBA_string_dup ("");
 }
 
+
 static void 
-impl_getCharacterExtents (PortableServer_Servant _servant,
+impl_getCharacterExtents (PortableServer_Servant servant,
                          const CORBA_long offset, CORBA_long * x,
                          CORBA_long * y, CORBA_long * width,
                          CORBA_long * height,
                          const CORBA_short coordType,
-                         CORBA_Environment * ev)
+                         CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_TEXT (obj));
-  text = SPI_TEXT (obj);
-  g_return_if_fail (ATK_IS_TEXT (text->atko));
+  g_return_if_fail (text != NULL);
 
-  atk_text_get_character_extents (ATK_TEXT(text->atko), (gint) offset,
-                                 (gint *) x, (gint *) y, (gint *) width, (gint *) height,
-                                 (AtkCoordType) coordType);
+  /* FIXME: Casting a CORBA_long to a gint * is inherantly risky */
+  atk_text_get_character_extents (
+         text, (gint) offset,
+         (gint *) x, (gint *) y, (gint *) width, (gint *) height,
+         (AtkCoordType) coordType);
 }
 
 
-
 static CORBA_long
-impl__get_characterCount (PortableServer_Servant _servant,
-                       CORBA_Environment * ev)
+impl__get_characterCount (PortableServer_Servant servant,
+                         CORBA_Environment    *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
   CORBA_long retval;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)0);
-  text = SPI_TEXT (obj);
+  g_return_val_if_fail (text != NULL, 0);
 
-  retval = (CORBA_long)
-    atk_text_get_character_count (ATK_TEXT(text->atko));
+  retval = (CORBA_long) atk_text_get_character_count (text);
 
   return retval;
 }
 
 
-
 static CORBA_long
-impl_getOffsetAtPoint (PortableServer_Servant _servant,
+impl_getOffsetAtPoint (PortableServer_Servant servant,
                       const CORBA_long x, const CORBA_long y,
                       const CORBA_short coordType,
-                      CORBA_Environment * ev)
+                      CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)-1);
-  text = SPI_TEXT (obj);
+  g_return_val_if_fail (text != NULL, -1);
 
   return (CORBA_long)
-    atk_text_get_offset_at_point (ATK_TEXT(text->atko),
-                                 (gint) x, (gint) y, (AtkCoordType) coordType);
+    atk_text_get_offset_at_point (text,
+                                 (gint) x, (gint) y,
+                                 (AtkCoordType) coordType);
 }
 
 
-
 static CORBA_long
-impl_getNSelections (PortableServer_Servant _servant,
-                    CORBA_Environment * ev)
+impl_getNSelections (PortableServer_Servant servant,
+                    CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)0);
-  text = SPI_TEXT (obj);
+  g_return_val_if_fail (text != NULL, 0);
 
-  return (CORBA_long)
-    atk_text_get_n_selections (ATK_TEXT(text->atko));
+  return (CORBA_long) atk_text_get_n_selections (text);
 }
 
 
-
 static void 
-impl_getSelection (PortableServer_Servant _servant,
+impl_getSelection (PortableServer_Servant servant,
                   const CORBA_long selectionNum,
                   CORBA_long * startOffset, CORBA_long * endOffset,
-                  CORBA_Environment * ev)
+                  CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_TEXT (obj));
-  text = SPI_TEXT (obj);
+  g_return_if_fail (text != NULL);
 
-  atk_text_get_selection (ATK_TEXT(text->atko), (gint) selectionNum,
+  atk_text_get_selection (text, (gint) selectionNum,
                          (gint *) startOffset, (gint *) endOffset);
 }
 
 
-
 static CORBA_boolean
-impl_addSelection (PortableServer_Servant _servant,
+impl_addSelection (PortableServer_Servant servant,
                   const CORBA_long startOffset,
                   const CORBA_long endOffset,
-                  CORBA_Environment * ev)
+                  CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_boolean)FALSE);
-  text = SPI_TEXT (obj);
+  g_return_val_if_fail (text != NULL, FALSE);
 
   return (CORBA_boolean)
-    atk_text_add_selection (ATK_TEXT(text->atko),
+    atk_text_add_selection (text,
                            (gint) startOffset, (gint) endOffset);
 }
 
 
-
 static CORBA_boolean
-impl_removeSelection (PortableServer_Servant _servant,
+impl_removeSelection (PortableServer_Servant servant,
                      const CORBA_long selectionNum,
-                     CORBA_Environment * ev)
+                     CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_boolean)FALSE);
-  text = SPI_TEXT (obj);
+  g_return_val_if_fail (text != NULL, FALSE);
 
   return (CORBA_boolean)
-    atk_text_remove_selection (ATK_TEXT(text->atko), (gint) selectionNum);
+    atk_text_remove_selection (text, (gint) selectionNum);
 }
 
 
-
 static CORBA_boolean
-impl_setSelection (PortableServer_Servant _servant,
+impl_setSelection (PortableServer_Servant servant,
                   const CORBA_long selectionNum,
                   const CORBA_long startOffset,
                   const CORBA_long endOffset,
-                  CORBA_Environment * ev)
+                  CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_boolean)FALSE);
-  text = SPI_TEXT (obj);
+  g_return_val_if_fail (text != NULL, FALSE);
 
   return (CORBA_boolean)
-    atk_text_set_selection (ATK_TEXT(text->atko),
+    atk_text_set_selection (text,
                            (gint) selectionNum, (gint) startOffset, (gint) endOffset);
 }
 
 
-
 static CORBA_boolean
-impl_setCaretOffset (PortableServer_Servant _servant,
+impl_setCaretOffset (PortableServer_Servant servant,
                     const CORBA_long value,
-                    CORBA_Environment * ev)
+                    CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_val_if_fail (IS_TEXT (obj), (CORBA_boolean)FALSE);
-  text = SPI_TEXT (obj);
+  g_return_val_if_fail (text != NULL, FALSE);
 
   return (CORBA_boolean)
-    atk_text_set_caret_offset (ATK_TEXT(text->atko), (gint) value);
+    atk_text_set_caret_offset (text, (gint) value);
 }
 
 
-
 static void 
-impl_getRowColAtOffset (PortableServer_Servant _servant,
+impl_getRowColAtOffset (PortableServer_Servant servant,
                        const CORBA_long offset, CORBA_long * row,
-                       CORBA_long * column, CORBA_Environment * ev)
+                       CORBA_long * column, CORBA_Environment *ev)
 {
-  SpiText *text;
-  BonoboObject *obj;
+  AtkText *text = get_text_from_servant (servant);
 
-  obj = (bonobo_object_from_servant (_servant));
-  g_return_if_fail (IS_TEXT (obj));
-  text = SPI_TEXT (obj);
+  g_return_if_fail (text != NULL);
 
   g_print ("getRowColAtOffset not yet implemented\n");
 }
 
 static void
-spi_text_object_finalize (GObject *obj)
-{
-  SpiText *text = SPI_TEXT (obj);
-  g_object_unref (text->atko);
-  text->atko = NULL;
-  spi_text_parent_class->finalize (obj);
-}
-
-static void
 spi_text_class_init (SpiTextClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Text__epv *epv = &klass->epv;
-  spi_text_parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_text_object_finalize;
 
   /* Initialize epv table */
 
@@ -470,11 +403,22 @@ BONOBO_TYPE_FUNC_FULL (SpiText,
                       PARENT_TYPE,
                       spi_text);
 
+void
+spi_text_construct (SpiText *text, AtkObject *obj)
+{
+  spi_base_construct (SPI_BASE (text), obj);
+}
+
 SpiText *
 spi_text_interface_new (AtkObject *obj)
 {
-  SpiText *new_text = g_object_new (SPI_TEXT_TYPE, NULL);
-  new_text->atko = obj;
-  g_object_ref (obj);
-  return new_text;
+  SpiText *retval;
+
+  g_return_val_if_fail (ATK_IS_TEXT (obj), NULL);
+
+  retval = g_object_new (SPI_TEXT_TYPE, NULL);
+
+  spi_text_construct (retval, obj);
+
+  return retval;
 }
index f8fe59f..6c12c73 100644 (file)
 #ifndef SPI_TEXT_H_
 #define SPI_TEXT_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
-#include <libspi/accessible.h>
+#include <libspi/base.h>
 
 G_BEGIN_DECLS
 
@@ -37,16 +34,17 @@ typedef struct _SpiText      SpiText;
 typedef struct _SpiTextClass SpiTextClass;
 
 struct _SpiText {
-  BonoboObject parent;
-  AtkObject *atko;
+  SpiBase parent;
 };
 
 struct _SpiTextClass {
-  BonoboObjectClass parent_class;
+  SpiBaseClass parent_class;
   POA_Accessibility_Text__epv epv;
 };
 
 GType    spi_text_get_type      (void);
+void     spi_text_construct     (SpiText   *text,
+                                AtkObject *obj);
 SpiText *spi_text_interface_new (AtkObject *obj);
 
 G_END_DECLS
index e9cdb09..c099b2c 100644 (file)
@@ -31,8 +31,6 @@ static void
 spi_value_class_init (SpiValueClass *klass);
 static void
 spi_value_init (SpiValue *value);
-static void
-spi_value_finalize (GObject *obj);
 static CORBA_float
 impl__get_minimumValue (PortableServer_Servant _servant,
                        CORBA_Environment * ev);
@@ -48,24 +46,16 @@ impl__set_currentValue (PortableServer_Servant _servant,
                        CORBA_Environment * ev);
 
 
-
-static GObjectClass *parent_class;
-
-
 BONOBO_TYPE_FUNC_FULL (SpiValue,
                       Accessibility_Value,
                       BONOBO_TYPE_OBJECT,
                       spi_value);
 
+
 static void
 spi_value_class_init (SpiValueClass *klass)
 {
-  GObjectClass * object_class = (GObjectClass *) klass;
   POA_Accessibility_Value__epv *epv = &klass->epv;
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = spi_value_finalize;
-
 
   /* Initialize epv table */
 
@@ -75,83 +65,100 @@ spi_value_class_init (SpiValueClass *klass)
   epv->_set_currentValue = impl__set_currentValue;
 }
 
+
 static void
 spi_value_init (SpiValue *value)
 {
 }
 
-static void
-spi_value_finalize (GObject *obj)
-{
-  SpiValue *value = SPI_VALUE (obj);
-  g_object_unref (value->atko);
-  value->atko = NULL;
-  parent_class->finalize (obj);
-}
 
 SpiValue *
 spi_value_interface_new (AtkObject *obj)
 {
   SpiValue *new_value = g_object_new (SPI_VALUE_TYPE, NULL);
-  new_value->atko = obj;
-  g_object_ref (obj);
+
+  spi_base_construct (SPI_BASE (new_value), obj);
+
   return new_value;
 }
 
 
+static AtkValue *
+get_value_from_servant (PortableServer_Servant servant)
+{
+  SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
+
+  if (!object)
+    {
+      return NULL;
+    }
+
+  return ATK_VALUE (object->atko);
+}
+
 
 static CORBA_float
-impl__get_minimumValue (PortableServer_Servant _servant,
-                      CORBA_Environment * ev)
+impl__get_minimumValue (PortableServer_Servant servant,
+                       CORBA_Environment     *ev)
 {
-  SpiValue *value = SPI_VALUE (bonobo_object_from_servant (_servant));
-  GValue gvalue = {0, };
+  GValue    gvalue = {0, };
+  AtkValue *value = get_value_from_servant (servant);
+
+  g_return_val_if_fail (value != NULL, 0.0);
 
   g_value_init (&gvalue, G_TYPE_FLOAT);
-  atk_value_get_minimum_value (ATK_VALUE(value->atko), &gvalue);
+  atk_value_get_minimum_value (value, &gvalue);
+
   return (CORBA_float) g_value_get_float (&gvalue);
 }
 
 
-
-static        CORBA_float
-impl__get_maximumValue (PortableServer_Servant _servant,
-                       CORBA_Environment * ev)
+static CORBA_float
+impl__get_maximumValue (PortableServer_Servant servant,
+                       CORBA_Environment     *ev)
 {
-  SpiValue *value = SPI_VALUE (bonobo_object_from_servant (_servant));
-  GValue gvalue = {0, };
+  GValue   gvalue = {0, };
+  AtkValue *value = get_value_from_servant (servant);
+
+  g_return_val_if_fail (value != NULL, 0.0);
 
   g_value_init (&gvalue, G_TYPE_FLOAT);
-  atk_value_get_maximum_value (ATK_VALUE(value->atko), &gvalue);
+  atk_value_get_maximum_value (value, &gvalue);
+
   return (CORBA_float) g_value_get_float (&gvalue);
 }
 
 
-
 static CORBA_float
-impl__get_currentValue (PortableServer_Servant _servant,
-                       CORBA_Environment ev)
+impl__get_currentValue (PortableServer_Servant servant,
+                       CORBA_Environment     *ev)
 {
-  SpiValue *value = SPI_VALUE (bonobo_object_from_servant (_servant));
-  GValue gvalue = {0, };
+  GValue   gvalue = {0, };
+  AtkValue *value = get_value_from_servant (servant);
+
+  g_return_val_if_fail (value != NULL, 0.0);
 
   g_value_init (&gvalue, G_TYPE_FLOAT);
-  atk_value_get_current_value (ATK_VALUE(value->atko), &gvalue);
+  atk_value_get_current_value (value, &gvalue);
+
   return (CORBA_float) g_value_get_float (&gvalue);
 }
 
 
 static void 
-impl__set_currentValue (PortableServer_Servant _servant,
-                       const CORBA_float value,
-                       CORBA_Environment ev)
+impl__set_currentValue (PortableServer_Servant servant,
+                       const CORBA_float      value,
+                       CORBA_Environment     *ev)
 {
-  SpiValue *val = SPI_VALUE (bonobo_object_from_servant (_servant));
-  GValue gvalue = {0, };
+  GValue    gvalue = {0, };
+  AtkValue *avalue = get_value_from_servant (servant);
+
+  g_return_if_fail (avalue != NULL);
 
   g_value_init (&gvalue, G_TYPE_FLOAT);
   g_value_set_float (&gvalue, (gfloat) value);
-  atk_value_set_current_value (ATK_VALUE(val->atko), &gvalue);
+
+  atk_value_set_current_value (avalue, &gvalue);
 }
 
 
index 2c841e5..5c561ae 100644 (file)
 #ifndef SPI_VALUE_H_
 #define SPI_VALUE_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atk.h>
-#include <libspi/Accessibility.h>
+#include <libspi/base.h>
+#include <atk/atkvalue.h>
 
 G_BEGIN_DECLS
 
-#define SPI_VALUE_TYPE        (spi_value_get_type ())
-#define SPI_VALUE(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_VALUE_TYPE, SpiValue))
-#define SPI_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_VALUE_TYPE, SpiValueClass))
-#define IS_SPI_VALUE(obj)       (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_VALUE_TYPE))
-#define IS_SPI_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_VALUE_TYPE))
+#define SPI_VALUE_TYPE            (spi_value_get_type ())
+#define SPI_VALUE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_VALUE_TYPE, SpiValue))
+#define SPI_ACTION_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST((klass), SPI_VALUE_TYPE, SpiValueClass))
+#define SPI_IS_VALUE(obj)         (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_VALUE_TYPE))
+#define SPI_IS_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_VALUE_TYPE))
 
 typedef struct _Value SpiValue;
 typedef struct _ValueClass SpiValueClass;
 
 struct _Value {
-  BonoboObject parent;
-  AtkObject *atko;
+  SpiBase parent;
 };
 
 struct _ValueClass {
-  BonoboObjectClass parent_class;
+  SpiBaseClass parent_class;
   POA_Accessibility_Value__epv epv;
 };
 
index 8907d42..9258398 100644 (file)
@@ -2,7 +2,7 @@
  * AT-SPI - Assistive Technology Service Provider Interface
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
- * Copyright 2001 Sun Microsystems Inc.
+ * Copyright 2001 Sun Microsystems Inc., Ximian Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 /* Our parent Gtk object type */
 #define PARENT_TYPE SPI_ACCESSIBLE_TYPE
 
+typedef struct {
+       SpiDesktop *desktop;
+       Accessibility_Application ref;
+} Application;
+
 /* A pointer to our parent object class */
 static SpiAccessibleClass *parent_class;
 
 static void
-spi_desktop_init (SpiDesktop  *desktop)
+spi_desktop_init (SpiDesktop *desktop)
 {
-  SPI_ACCESSIBLE (desktop)->atko = g_object_new (ATK_TYPE_OBJECT, NULL);
+  spi_base_construct_default (SPI_BASE (desktop));
+
   desktop->applications = NULL;
-  atk_object_set_name (ATK_OBJECT (SPI_ACCESSIBLE (desktop)->atko), "main");
+
+  atk_object_set_name (SPI_BASE (desktop)->atko, "main");
 }
 
 static void
-spi_desktop_finalize (GObject *object)
+spi_desktop_dispose (GObject *object)
 {
-  (G_OBJECT_CLASS (parent_class))->finalize (object); 
+  SpiDesktop *desktop = (SpiDesktop *) object;
+
+  while (desktop->applications)
+    {
+      Application *app = (Application *) desktop->applications;
+      spi_desktop_remove_application (desktop, app->ref);
+    }
+
+  G_OBJECT_CLASS (parent_class)->dispose (object); 
 }
 
 static CORBA_long
 impl_desktop_get_child_count (PortableServer_Servant servant,
-                              CORBA_Environment ev)
+                              CORBA_Environment     *ev)
 {
   SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
+
   if (desktop->applications)
     {
       return g_list_length (desktop->applications);
@@ -64,41 +80,47 @@ impl_desktop_get_child_count (PortableServer_Servant servant,
 
 static Accessibility_Accessible
 impl_desktop_get_child_at_index (PortableServer_Servant servant,
-                                 const CORBA_long index,
-                                 CORBA_Environment ev)
+                                 const CORBA_long       index,
+                                 CORBA_Environment     *ev)
 {
-  SpiDesktop *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
+  SpiDesktop  *desktop = SPI_DESKTOP (bonobo_object_from_servant (servant));
   CORBA_Object retval;
-  if ((desktop->applications) && (index < g_list_length (desktop->applications)))
+  Application *app;
+
+  app = g_list_nth_data (desktop->applications, index);
+
+  if (app)
     {
-      fprintf (stderr, "getting application %ld\n", (long) index);
-      /* */
-      fprintf (stderr, "object address %p\n",
-               g_list_nth_data (desktop->applications, index));
-      retval =  bonobo_object_dup_ref (
-              (CORBA_Object) g_list_nth_data (desktop->applications, index), ev);
+      retval = bonobo_object_dup_ref (app->ref, ev);
+      if (BONOBO_EX (ev))
+        {
+          CORBA_exception_free (ev);
+         CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+                              ex_Accessibility_ChildGone, NULL);
+         retval = CORBA_OBJECT_NIL;
+       }
     }
   else
     {
-      fprintf (stderr, "no %ldth child\n", (long) index);
       retval = CORBA_OBJECT_NIL;
     }
+
   return (Accessibility_Accessible) retval;
 }
 
 static void
-spi_desktop_class_init (SpiDesktopClass  *klass)
+spi_desktop_class_init (SpiDesktopClass *klass)
 {
-        GObjectClass * object_class = (GObjectClass *) klass;
-        SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass;
-        POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv;
+  GObjectClass * object_class = (GObjectClass *) klass;
+  SpiAccessibleClass * spi_accessible_class = (SpiAccessibleClass *) klass;
+  POA_Accessibility_Accessible__epv *epv = &spi_accessible_class->epv;
 
-        object_class->finalize = spi_desktop_finalize;
+  object_class->dispose = spi_desktop_dispose;
+  
+  parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE);
 
-        parent_class = g_type_class_ref (SPI_ACCESSIBLE_TYPE);
-
-        epv->_get_childCount = impl_desktop_get_child_count;
-        epv->getChildAtIndex = impl_desktop_get_child_at_index;
+  epv->_get_childCount = impl_desktop_get_child_count;
+  epv->getChildAtIndex = impl_desktop_get_child_at_index;
 }
 
 BONOBO_TYPE_FUNC_FULL (SpiDesktop,
@@ -109,7 +131,80 @@ BONOBO_TYPE_FUNC_FULL (SpiDesktop,
 SpiDesktop *
 spi_desktop_new (void)
 {
-    SpiDesktop *retval = g_object_new (SPI_DESKTOP_TYPE, NULL);
+  SpiDesktop *retval = g_object_new (SPI_DESKTOP_TYPE, NULL);
+
+  return retval;
+}
+
+static void
+abnormal_application_termination (gpointer object, Application *app)
+{
+  g_return_if_fail (SPI_IS_DESKTOP (app->desktop));
+
+  spi_desktop_remove_application (app->desktop, app->ref);
+}
+
+void
+spi_desktop_add_application (SpiDesktop *desktop,
+                            const Accessibility_Application application)
+{
+  CORBA_Environment ev;
+  Application       *app;
+  Accessibility_Application ref;
+
+  g_return_if_fail (SPI_IS_DESKTOP (desktop));
+
+  spi_desktop_remove_application (desktop, application);
+
+  CORBA_exception_init (&ev);
+
+  ref = bonobo_object_dup_ref (application, &ev);
+
+  if (!BONOBO_EX (&ev))
+    {
+      app = g_new (Application, 1);
+      app->desktop = desktop;
+      app->ref = ref;
+
+      desktop->applications = g_list_append (desktop->applications, app);
+
+      ORBit_small_listen_for_broken (app->ref, G_CALLBACK (abnormal_application_termination), app);
+    }
+
+  CORBA_exception_free (&ev);
+}
+
+void
+spi_desktop_remove_application (SpiDesktop *desktop,
+                               const Accessibility_Application app_ref)
+{
+  GList *l;
+  CORBA_Environment ev;
 
-    return retval;
+  g_return_if_fail (SPI_IS_DESKTOP (desktop));
+
+  CORBA_exception_init (&ev);
+
+  for (l = desktop->applications; l; l = l->next)
+    {
+      Application *app = (Application *) l->data;
+
+      if (CORBA_Object_is_equivalent (app->ref, app_ref, &ev))
+        {
+         break;
+       }
+    }
+
+  CORBA_exception_free (&ev);
+
+  if (l)
+    {
+      Application *app = (Application *) l->data;
+
+      desktop->applications = g_list_delete_link (desktop->applications, l);
+
+      ORBit_small_unlisten_for_broken (app->ref, G_CALLBACK (abnormal_application_termination));
+      bonobo_object_release_unref (app->ref, NULL);
+      g_free (app);
+    }
 }
index 7a4e290..8c60834 100644 (file)
 #ifndef SPI_DESKTOP_H_
 #define SPI_DESKTOP_H_
 
-#include <bonobo/bonobo-xobject.h>
-#include <atk/atkobject.h>
 #include <libspi/accessible.h>
-#include <libspi/application.h>
-#include <libspi/Accessibility.h>
 
 G_BEGIN_DECLS
 
 #define SPI_DESKTOP_TYPE        (spi_desktop_get_type ())
 #define SPI_DESKTOP(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_DESKTOP_TYPE, SpiDesktop))
 #define SPI_DESKTOP_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_DESKTOP_TYPE, SpiDesktopClass))
-#define IS_SPI_DESKTOP(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_DESKTOP_TYPE))
-#define IS_SPI_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DESKTOP_TYPE))
+#define SPI_IS_DESKTOP(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DESKTOP_TYPE))
+#define SPI_IS_DESKTOP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DESKTOP_TYPE))
 
 typedef struct {
         SpiAccessible parent;
-        GList *applications; /* TODO: maybe change this so it's generated on-demand ? */
+        GList        *applications;
 } SpiDesktop;
 
 typedef struct {
@@ -47,10 +43,12 @@ typedef struct {
         POA_Accessibility_Desktop__epv epv;
 } SpiDesktopClass;
 
-GType               spi_desktop_get_type           (void);
-void                spi_desktop_add_application    (SpiApplication *app);
-void                spi_desktop_remove_application (SpiApplication *app);
-SpiDesktop             *spi_desktop_new               (void);
+GType       spi_desktop_get_type           (void);
+SpiDesktop *spi_desktop_new                (void);
+void        spi_desktop_add_application    (SpiDesktop *desktop,
+                                           const Accessibility_Application application);
+void        spi_desktop_remove_application (SpiDesktop *desktop,
+                                           const Accessibility_Application application);
 
 G_END_DECLS
 
index e3e8c97..8b9ba60 100644 (file)
@@ -33,8 +33,8 @@ G_BEGIN_DECLS
 #define SPI_DEVICE_EVENT_CONTROLLER_TYPE        (spi_device_event_controller_get_type ())
 #define SPI_DEVICE_EVENT_CONTROLLER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_DEVICE_EVENT_CONTROLLER_TYPE, SpiDeviceEventController))
 #define SPI_DEVICE_EVENT_CONTROLLER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_DEVICE_EVENT_CONTROLLER_TYPE, SpiDeviceEventControllerClass))
-#define IS_SPI_DEVICE_EVENT_CONTROLLER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
-#define IS_SPI_DEVICE_EVENT_CONTROLLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
+#define SPI_IS_DEVICE_EVENT_CONTROLLER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
+#define SPI_IS_DEVICE_EVENT_CONTROLLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
 #define SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPI_DEVICE_EVENT_CONTROLLER_TYPE, SpiDeviceEventControllerClass))
 
 typedef struct {
@@ -51,8 +51,9 @@ typedef struct {
        gboolean (*check_key_event) (SpiDeviceEventController *controller);
 } SpiDeviceEventControllerClass;
 
-GType                     spi_device_event_controller_get_type   (void);
-SpiDeviceEventController *spi_device_event_controller_new        (void *registry);
+GType                     spi_device_event_controller_get_type        (void);
+SpiDeviceEventController *spi_device_event_controller_new             (void *registry);
+gboolean                  spi_device_event_controller_check_key_event (SpiDeviceEventController *controller);
 
 G_END_DECLS
 
index 1089017..c3f5509 100644 (file)
 #include "registry.h"
 
 int
-main (int argc,
-      char **argv)
+main (int argc, char **argv)
 {
-        SpiRegistry *registry;
-       GSource *keyevent_source;
-        char *obj_id;
+  int          ret;
+  char        *obj_id;
+  SpiRegistry *registry;
 
-        if (!bonobo_init (&argc, argv))
-          {
-            g_error ("Could not initialize oaf / Bonobo");
-          }
+  if (!bonobo_init (&argc, argv))
+    {
+      g_error ("Could not initialize oaf / Bonobo");
+    }
 
-        obj_id = "OAFIID:Accessibility_Registry:proto0.1";
+  obj_id = "OAFIID:Accessibility_Registry:proto0.1";
 
-        registry = spi_registry_new ();
+  registry = spi_registry_new ();
 
-        bonobo_activation_active_server_register (
-                obj_id,
-                bonobo_object_corba_objref (bonobo_object (registry)));
+  ret = bonobo_activation_active_server_register (
+         obj_id,
+         bonobo_object_corba_objref (bonobo_object (registry)));
 
+  if (ret != Bonobo_ACTIVATION_REG_SUCCESS)
+    {
 #ifdef AT_SPI_DEBUG
-        fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon is running.\n");
+      fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon was already running.\n");
 #endif
-  
-        g_timeout_add_full (G_PRIORITY_HIGH_IDLE, 200, registry->kbd_event_hook, registry, NULL);
-        bonobo_main ();
+    }
+  else
+    {
+#ifdef AT_SPI_DEBUG
+      fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon is running.\n");
+#endif
+      g_timeout_add_full (G_PRIORITY_HIGH_IDLE, 200, registry->kbd_event_hook, registry, NULL);
+      bonobo_main ();
+    }
 
-        return 0;
+  return 0;
 }
 
-
-
index 956e088..f2fabf5 100644 (file)
 #  include <stdio.h>
 #endif
 
-/*
- * We'd like to replace the dependance on X-isms with a wrapper layer,
- * to the extent that it can't be done with pure GDK.
- * Anyone want to help?
- */
-#include <X11/Xlib.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-
 #include <libspi/registry.h>
 
 /* Our parent GObject type  */
@@ -90,8 +81,7 @@ spi_listener_struct_new (Accessibility_EventListener listener, CORBA_Environment
 void
 spi_listener_struct_free (SpiListenerStruct *ls, CORBA_Environment *ev)
 {
-  /* TODO: sanity check for ls */
-  Accessibility_EventListener_unref (ls->listener, ev);
+  bonobo_object_release_unref (ls->listener, ev);
   g_free (ls);
 }
 
@@ -124,10 +114,8 @@ impl_accessibility_registry_register_application (PortableServer_Servant servant
 #ifdef SPI_DEBUG
   fprintf (stderr, "registering app %p\n", application);
 #endif
-  registry->desktop->applications = g_list_append (registry->desktop->applications,
-                                                   bonobo_object_dup_ref (application, ev));
+  spi_desktop_add_application (registry->desktop, application);
 
-  /* TODO: create unique string here (with libuuid call ?) and hash ? */
   Accessibility_Application__set_id (application, _get_unique_id(), ev);
 
   /*
@@ -276,32 +264,12 @@ impl_accessibility_registry_deregister_application (PortableServer_Servant serva
                                                     CORBA_Environment * ev)
 {
   SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
-  GList *list = g_list_find_custom (registry->desktop->applications, application, compare_corba_objects);
 
-#ifdef SPI_DEBUG
-  gint i;
-#endif
+  spi_desktop_remove_application (registry->desktop, application);
 
-  if (list)
-    {
 #ifdef SPI_DEBUG
-      fprintf (stderr, "deregistering application %p\n", application);
+  fprintf (stderr, "de-registered app %p\n", application);
 #endif
-      registry->desktop->applications = g_list_delete_link (registry->desktop->applications, list);
-#ifdef SPI_DEBUG
-      fprintf (stderr, "there are now %d apps registered.\n", g_list_length (registry->desktop->applications));
-      for (i = 0; i < g_list_length (registry->desktop->applications); ++i)
-        {
-          fprintf (stderr, "getting application %d\n", i);
-          fprintf (stderr, "object address %p\n",
-                      g_list_nth_data (registry->desktop->applications, i));
-        }
-#endif      
-    }
-  else
-    {
-      fprintf (stderr, "could not deregister application %p\n", application);
-    }
 }
 
 /*
@@ -358,7 +326,7 @@ impl_accessibility_registry_deregister_global_event_listener_all (
                                                     CORBA_Environment      *ev)
 {
   SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
-  SpiListenerStruct *spi_listener_struct, *ls = spi_listener_struct_new (listener, ev);
+  SpiListenerStruct *ls = spi_listener_struct_new (listener, ev);
   GList *list;
   list = g_list_find_custom (registry->object_listeners, ls,
                             compare_listener_corbaref);
@@ -395,7 +363,7 @@ impl_accessibility_registry_deregister_global_event_listener (
                                                     CORBA_Environment      *ev)
 {
   SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant));
-  SpiListenerStruct ls, *spi_listener_struct;
+  SpiListenerStruct ls;
   EventTypeStruct etype;
   GList *list;
   GList **listeners;
@@ -410,6 +378,7 @@ impl_accessibility_registry_deregister_global_event_listener (
       break;
     case (ETYPE_WINDOW) :
       /* Support for Window Manager Events is not yet implemented */
+      listeners = NULL;
       break;
     case (ETYPE_TOOLKIT) :
       listeners = &registry->toolkit_listeners;
@@ -533,7 +502,10 @@ impl_registry_notify_event (PortableServer_Servant servant,
     default:
       break;
     }
-  /* Accessibility_Accessible_unref (e->source, ev);*/ /* This should be here! */
+  if (e->source != CORBA_OBJECT_NIL)
+    {
+      Accessibility_Accessible_unref (e->source, ev);
+    }
 }
 
 static long
@@ -550,46 +522,46 @@ _registry_notify_listeners (GList *listeners,
                             const Accessibility_Event *e_in,
                             CORBA_Environment *ev)
 {
-  gint n = 0;
-  SpiListenerStruct *ls;
-  GList *list;
-  EventTypeStruct etype;
-  Accessibility_Event *e_out;
-  gchar *s;
-  guint minor_hash;
+  GList              *l;
+  Accessibility_Event e_out;
+  SpiListenerStruct  *ls;
+  EventTypeStruct     etype;
+  guint               minor_hash;
+  CORBA_string        s;
+
+  e_out = *e_in;
   parse_event_type (&etype, e_in->type);
+
   s = g_strconcat (etype.major, etype.minor, NULL);
   minor_hash = g_str_hash (s);
   g_free (s);
 
-  for (list = listeners; list; list = list->next)
+  for (l = listeners; l; l = l->next)
     {
-      ls =  (SpiListenerStruct *) list->data;
+      ls = (SpiListenerStruct *) l->data;
+
 #ifdef SPI_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);
+      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
+
       if ((ls->event_type_hash == etype.hash) || (ls->event_type_hash == minor_hash))
         {
 #ifdef SPI_DEBUG
-          fprintf(stderr, "notifying listener #%d\n", n++);
-         s = Accessibility_Accessible__get_name(e_in->source, ev);
-          fprintf(stderr, "event source name %s\n", s);
-         g_free (s);
+          fprintf (stderr, "notifying listener %d\n", g_list_index (listeners, l->data));
+          s = Accessibility_Accessible__get_name (e_in->source, ev);
+         fprintf (stderr, "event source name %s\n", s);
+         CORBA_free (s);
 #endif
-         e_out = ORBit_copy_value (e_in, TC_Accessibility_Event);
-         e_out->source = bonobo_object_dup_ref (e_in->source, ev);
+         e_out.source = bonobo_object_dup_ref (e_in->source, ev);
           Accessibility_EventListener_notifyEvent ((Accessibility_EventListener) ls->listener,
-                                                   e_out,
+                                                   &e_out,
                                                    ev);
-         /* is it safe to free e_out now ? notifyEvent is a oneway... */
-         CORBA_free (e_out);
-          if (ev->_major != CORBA_NO_EXCEPTION) {
-                fprintf(stderr,
-                ("Accessibility app error: exception during event notification: %s\n"),
-                        CORBA_exception_id(ev));
-                exit(-1);
-          }
+          if (ev->_major != CORBA_NO_EXCEPTION)
+            {
+              g_error ("Accessibility app error: exception during event notification: %s\n",
+                      CORBA_exception_id (ev));
+           }
         }
     }
 }
@@ -633,7 +605,6 @@ spi_registry_init (SpiRegistry *registry)
   registry->object_listeners = NULL;
   registry->window_listeners = NULL;
   registry->toolkit_listeners = NULL;
-  registry->applications = NULL;
   registry->desktop = spi_desktop_new();
   registry->device_event_controller = NULL;
   registry->kbd_event_hook = _device_event_controller_hook;
@@ -648,5 +619,6 @@ SpiRegistry *
 spi_registry_new (void)
 {
     SpiRegistry *retval = g_object_new (SPI_REGISTRY_TYPE, NULL);
+    bonobo_object_set_immortal (BONOBO_OBJECT (retval), TRUE);
     return retval;
 }
index 61b0ed9..dbb7a81 100644 (file)
@@ -33,15 +33,14 @@ G_BEGIN_DECLS
 #define SPI_REGISTRY_TYPE        (spi_registry_get_type ())
 #define SPI_REGISTRY(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_REGISTRY_TYPE, SpiRegistry))
 #define SPI_REGISTRY_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_REGISTRY_TYPE, SpiRegistryClass))
-#define IS_SPI_REGISTRY(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_REGISTRY_TYPE))
-#define IS_SPI_REGISTRY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_REGISTRY_TYPE))
+#define SPI_IS_REGISTRY(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_REGISTRY_TYPE))
+#define SPI_IS_REGISTRY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_REGISTRY_TYPE))
 
 typedef struct {
   SpiListener parent;
   GList *object_listeners;
   GList *window_listeners;
   GList *toolkit_listeners;
-  GList *applications;
   struct SpiDeviceEventController *device_event_controller;
   SpiDesktop *desktop;
   gboolean (*kbd_event_hook) (gpointer source);
index 1089017..c3f5509 100644 (file)
 #include "registry.h"
 
 int
-main (int argc,
-      char **argv)
+main (int argc, char **argv)
 {
-        SpiRegistry *registry;
-       GSource *keyevent_source;
-        char *obj_id;
+  int          ret;
+  char        *obj_id;
+  SpiRegistry *registry;
 
-        if (!bonobo_init (&argc, argv))
-          {
-            g_error ("Could not initialize oaf / Bonobo");
-          }
+  if (!bonobo_init (&argc, argv))
+    {
+      g_error ("Could not initialize oaf / Bonobo");
+    }
 
-        obj_id = "OAFIID:Accessibility_Registry:proto0.1";
+  obj_id = "OAFIID:Accessibility_Registry:proto0.1";
 
-        registry = spi_registry_new ();
+  registry = spi_registry_new ();
 
-        bonobo_activation_active_server_register (
-                obj_id,
-                bonobo_object_corba_objref (bonobo_object (registry)));
+  ret = bonobo_activation_active_server_register (
+         obj_id,
+         bonobo_object_corba_objref (bonobo_object (registry)));
 
+  if (ret != Bonobo_ACTIVATION_REG_SUCCESS)
+    {
 #ifdef AT_SPI_DEBUG
-        fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon is running.\n");
+      fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon was already running.\n");
 #endif
-  
-        g_timeout_add_full (G_PRIORITY_HIGH_IDLE, 200, registry->kbd_event_hook, registry, NULL);
-        bonobo_main ();
+    }
+  else
+    {
+#ifdef AT_SPI_DEBUG
+      fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon is running.\n");
+#endif
+      g_timeout_add_full (G_PRIORITY_HIGH_IDLE, 200, registry->kbd_event_hook, registry, NULL);
+      bonobo_main ();
+    }
 
-        return 0;
+  return 0;
 }
 
-
-
index 91cb7e5..61f3c31 100644 (file)
@@ -1,9 +1,9 @@
 NULL=
 
-noinst_PROGRAMS = at app simple-at keysynth-demo accessx-gui
+noinst_PROGRAMS = test-simple at app simple-at keysynth-demo accessx-gui
 
 at_SOURCES = at.c 
+
 app_SOURCES = app.c
 
 simple_at_SOURCES = simple-at.c 
@@ -12,6 +12,8 @@ keysynth_demo_SOURCES = keysynth-demo.c
 
 accessx_gui_SOURCES = accessx-gui.c 
 
+test_simple_SOURCES = test-simple.c 
+
 INCLUDES = -I$(top_srcdir)           \
            -I$(top_builddir)         \
            -I$(top_srcdir)/libspi    \
@@ -26,5 +28,4 @@ CFLAGS += $(TESTS_CFLAGS) $(DEBUG_CFLAGS)
 
 LDADD = ../util/libat-util.la ../libspi/libspi.la ../cspi/libcspi.la $(TESTS_LIBS)
 
-
-
+TESTS = test.sh
\ No newline at end of file
index 2ce035a..743045a 100644 (file)
@@ -20,6 +20,7 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <gtk/gtk.h>
index f7bed15..79b6f41 100644 (file)
@@ -40,8 +40,8 @@
 static AccessibleKeystrokeListener *key_listener;
 static AccessibleKeystrokeListener *switch_listener;
 
-static gboolean shift_latched = False;
-static gboolean caps_lock = False;
+static SPIBoolean shift_latched = False;
+static SPIBoolean caps_lock = False;
 static GtkButton **buttons[MAX_ROWS];
 
 typedef enum {
@@ -226,7 +226,7 @@ scan_stop (unsigned int timestamp)
 }
 
 static void
-label_buttons(gboolean shifted)
+label_buttons(SPIBoolean shifted)
 {
   int i, j;
   KeySym keysym;
@@ -265,7 +265,7 @@ label_buttons(gboolean shifted)
 }
 
 static void
-show_shift (GtkButton *button, gboolean *is_shifted)
+show_shift (GtkButton *button, SPIBoolean *is_shifted)
 {
  label_buttons (*is_shifted ^ caps_lock);      
 }
@@ -315,7 +315,7 @@ button_exit(GtkButton *notused, void *alsonotused)
 }
 
 static SPIBoolean
-is_command_key (AccessibleKeystroke *key)
+is_command_key (AccessibleKeystroke *key, void *user_data)
 {
   switch (key->keyID)
     {
@@ -328,9 +328,10 @@ is_command_key (AccessibleKeystroke *key)
 }
 
 static SPIBoolean
-switch_callback (AccessibleKeystroke *key)
+switch_callback (AccessibleKeystroke *key, void *user_data)
 {
-  static gboolean is_down = FALSE;
+  static SPIBoolean is_down = FALSE;
+
   if (key->type == SPI_KEY_RELEASED)
     {
       g_print ("spacebar up\n");
@@ -380,8 +381,8 @@ create_vkbd()
   GtkWidget *window, *container, *hbox;
   int i, j;
   KeyCode *keycodeptr, keycode = MIN_KEYCODE;
-  static gboolean true_val = True;
-  static gboolean false_val = False;
+  static SPIBoolean true_val = True;
+  static SPIBoolean false_val = False;
 
   window = g_object_connect (gtk_widget_new (gtk_window_get_type (),
                                             "user_data", NULL,
@@ -467,9 +468,9 @@ main(int argc, char **argv)
 
   gtk_init (&argc, &argv); /* must call, because this program uses GTK+ */
 
-  SPI_init ();
+  SPI_init (TRUE);
 
-  key_listener = createAccessibleKeystrokeListener (is_command_key);
+  key_listener = createAccessibleKeystrokeListener (is_command_key, NULL);
   /* will listen only to Alt-key combinations */
   registerAccessibleKeystrokeListener (key_listener,
                                       (AccessibleKeySet *) SPI_KEYSET_ALL_KEYS,
@@ -489,14 +490,14 @@ main(int argc, char **argv)
   switch_set.len = 1;
   switch_set.keysyms[0] = (unsigned long) 0;
   switch_set.keycodes[0] = (unsigned short) 0;
-  switch_listener = createAccessibleKeystrokeListener (switch_callback);
+  switch_listener = createAccessibleKeystrokeListener (switch_callback, NULL);
   registerAccessibleKeystrokeListener (switch_listener,
                                       &switch_set,
                                       SPI_KEYMASK_UNMODIFIED,
                                       (unsigned long) ( KeyPress | KeyRelease),
                                       SPI_KEYLISTENER_CANCONSUME);
   
-  SPI_event_main (TRUE);
+  SPI_event_main ();
 
   return 0;
 }
index a7baca9..b603f24 100644 (file)
 #include <sys/un.h>
 #include <cspi/spi.h>
 #include "../util/mag_client.h"
+#include "../cspi/spi-private.h" /* A hack for now */
 
-static void report_focus_event    (AccessibleEvent *event);
-static void report_button_press   (AccessibleEvent *event);
-static void check_property_change (AccessibleEvent *event);
-static SPIBoolean report_command_key_event  (AccessibleKeystroke *stroke);
-static SPIBoolean report_ordinary_key_event (AccessibleKeystroke *stroke);
+static void report_focus_event    (AccessibleEvent *event, void *user_data);
+static void report_button_press   (AccessibleEvent *event, void *user_data);
+static void check_property_change (AccessibleEvent *event, void *user_data);
+static SPIBoolean report_command_key_event  (AccessibleKeystroke *stroke, void *user_data);
+static SPIBoolean report_ordinary_key_event (AccessibleKeystroke *stroke, void *user_data);
 static void get_environment_vars (void);
 
 static int _festival_init ();
@@ -50,7 +51,7 @@ static AccessibleKeystrokeListener *command_key_listener;
 static AccessibleKeystrokeListener *ordinary_key_listener;
 
 int
-main(int argc, char **argv)
+main (int argc, char **argv)
 {
   int i, j;
   int n_desktops;
@@ -66,11 +67,11 @@ main(int argc, char **argv)
     exit(0);
   }
 
-  SPI_init();
+  SPI_init(TRUE);
 
-  focus_listener = createAccessibleEventListener (report_focus_event);
-  property_listener = createAccessibleEventListener (check_property_change); 
-  button_listener = createAccessibleEventListener (report_button_press);
+  focus_listener = createAccessibleEventListener (report_focus_event, NULL);
+  property_listener = createAccessibleEventListener (check_property_change, NULL); 
+  button_listener = createAccessibleEventListener (report_button_press, NULL);
   registerGlobalEventListener (focus_listener, "focus:");
   registerGlobalEventListener (property_listener, "object:property-change:accessible-selection"); 
   registerGlobalEventListener (button_listener, "Gtk:GtkWidget:button-press-event");
@@ -95,8 +96,8 @@ main(int argc, char **argv)
     }
 
   /* prepare the keyboard snoopers */
-  command_key_listener = createAccessibleKeystrokeListener (report_command_key_event);
-  ordinary_key_listener = createAccessibleKeystrokeListener (report_ordinary_key_event);
+  command_key_listener = createAccessibleKeystrokeListener (report_command_key_event, NULL);
+  ordinary_key_listener = createAccessibleKeystrokeListener (report_ordinary_key_event, NULL);
   
   /* will listen only to Alt-key combinations, and only to KeyPress events */
   registerAccessibleKeystrokeListener(command_key_listener,
@@ -121,24 +122,26 @@ main(int argc, char **argv)
 
   get_environment_vars();
 
-  SPI_event_main(TRUE);
+  SPI_event_main();
 }
 
 static void
-get_environment_vars()
+get_environment_vars (void)
 {
-  if (getenv ("FESTIVAL"))
-  {
-    use_festival = TRUE;
-    if (getenv ("FESTIVAL_CHATTY"))
+  if (g_getenv ("FESTIVAL"))
     {
-      festival_chatty = TRUE;
+      fprintf (stderr, "Using festival\n");
+      use_festival = TRUE;
+      if (g_getenv ("FESTIVAL_CHATTY"))
+        {
+          festival_chatty = TRUE;
+       }
     }
-  }
-  if (getenv("MAGNIFIER"))
-  {
-    use_magnifier = TRUE;
-  }  
+  if (g_getenv ("MAGNIFIER"))
+    {
+      fprintf (stderr, "Using magnifier\n");
+      use_magnifier = TRUE;
+    }  
 }
 
 void
@@ -146,6 +149,9 @@ report_focussed_accessible (Accessible *obj, SPIBoolean shutup_previous_speech)
 {
   char *s;
   int len;
+
+  g_warning ("Report focused !");
+
   if (use_festival)
     {
     if (festival_chatty)           
@@ -194,18 +200,33 @@ report_focussed_accessible (Accessible *obj, SPIBoolean shutup_previous_speech)
 }
 
 void
-report_focus_event (AccessibleEvent *event)
+report_focus_event (AccessibleEvent *event, void *user_data)
 {
-  char *s = Accessible_getName (event->source);
-  fprintf (stderr, "%s event from %s\n", event->type, s);
-  SPI_freeString (s);
-  report_focussed_accessible (event->source, TRUE);
+  char *s;
+
+  g_warning ("report focus event");
+
+  g_return_if_fail (event->source != NULL);
+
+  s = Accessible_getName (event->source);
+  if (cspi_warn_ev (cspi_ev (), "Foobar"))
+    {
+      fprintf (stderr, "%s event from %s\n", event->type, s);
+      SPI_freeString (s);
+      report_focussed_accessible (event->source, TRUE);
+    }
+  Accessible_getParent (event->source);
 }
 
 void
-report_button_press (AccessibleEvent *event)
+report_button_press (AccessibleEvent *event, void *user_data)
 {
-  char *s = Accessible_getName (event->source);
+  char *s;
+
+  g_return_if_fail (event->source != NULL);
+
+  s = Accessible_getName (event->source);
+
   fprintf (stderr, "%s event from %s\n", event->type, s);
   SPI_freeString (s);
   s = Accessible_getDescription (event->source);
@@ -213,9 +234,8 @@ report_button_press (AccessibleEvent *event)
   SPI_freeString (s);
 }
 
-
 void
-check_property_change (AccessibleEvent *event)
+check_property_change (AccessibleEvent *event, void *user_data)
 {
   AccessibleSelection *selection = Accessible_getSelection (event->source);
   int n_selections;
@@ -242,7 +262,7 @@ check_property_change (AccessibleEvent *event)
 }
 
 static void
-simple_at_exit()
+simple_at_exit ()
 {
   deregisterGlobalEventListenerAll (focus_listener);
   deregisterGlobalEventListenerAll (property_listener);
@@ -280,7 +300,7 @@ is_command_key (AccessibleKeystroke *key)
 }
 
 static SPIBoolean
-report_command_key_event (AccessibleKeystroke *key)
+report_command_key_event (AccessibleKeystroke *key, void *user_data)
 {
   fprintf (stderr, "Command KeyEvent %s%c (keycode %d)\n",
          (key->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
@@ -292,7 +312,7 @@ report_command_key_event (AccessibleKeystroke *key)
 
 
 static SPIBoolean
-report_ordinary_key_event (AccessibleKeystroke *key)
+report_ordinary_key_event (AccessibleKeystroke *key, void *user_data)
 {
   fprintf (stderr, "Received key event:\tsym %ld\n\tmods %x\n\tcode %d\n\ttime %ld\n",
           (long) key->keyID,
@@ -302,7 +322,8 @@ report_ordinary_key_event (AccessibleKeystroke *key)
   return FALSE;
 }
 
-static int _festival_init ()
+static int
+_festival_init ()
 {
   int fd;
   struct sockaddr_in name;
@@ -326,7 +347,8 @@ static int _festival_init ()
   return fd;
 }
 
-static void _festival_say (const char *text, const char *voice, SPIBoolean shutup)
+static void 
+_festival_say (const char *text, const char *voice, SPIBoolean shutup)
 {
   static int fd = 0;
   gchar *quoted;
@@ -371,7 +393,8 @@ static void _festival_say (const char *text, const char *voice, SPIBoolean shutu
   g_free(quoted);
 }
 
-static void _festival_write (const gchar *command_string, int fd)
+static void
+_festival_write (const gchar *command_string, int fd)
 {
   fprintf(stderr, command_string);
   if (fd < 0) {
diff --git a/test/test-simple.c b/test/test-simple.c
new file mode 100644 (file)
index 0000000..24957af
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * test-simple.c: A set of simple regression tests
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2001 Ximian, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * ******** Do not copy this code as an example *********
+ */
+
+/* UGLY HACK for (unutterable_horror) */
+#include <libspi/libspi.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <cspi/spi.h>
+#include <libbonobo.h>
+
+static void validate_accessible (Accessible *accessible,
+                                gboolean    has_parent,
+                                gboolean    recurse_down);
+
+#define WINDOW_MAGIC 0x123456a
+#define TEST_STRING_A "A test string"
+#define TEST_STRING_B "Another test string"
+
+static int      print_tree_depth = 0;
+static gboolean print_tree = FALSE;
+
+typedef struct {
+       gulong     magic;
+       GtkWidget *window;
+} TestWindow;
+
+static gboolean
+focus_me (GtkWidget *widget)
+{
+       AtkObject *aobject = atk_implementor_ref_accessible (
+               ATK_IMPLEMENTOR (widget));
+
+       /* Force a focus event - even if the WM focused
+        * us before our at-bridge's idle handler registered
+        * our interest */
+       if (!GTK_WIDGET_HAS_FOCUS (widget))
+               gtk_widget_grab_focus (widget);
+/*     else: FIXME - gtk_widget_grab_focus should send a notify */
+               atk_focus_tracker_notify (aobject);
+       
+       g_object_unref (G_OBJECT (aobject));
+
+       /* Pull focus away and then back - thus sucks */
+       return FALSE;
+}
+
+static TestWindow *
+create_test_window (void)
+{
+       TestWindow *win = g_new0 (TestWindow, 1);
+       GtkWidget  *widget, *vbox;
+
+       win->magic  = WINDOW_MAGIC;
+       win->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+       gtk_widget_show (win->window);
+
+       vbox = gtk_vbox_new (0, 0);
+       gtk_container_add (GTK_CONTAINER (win->window), vbox);
+       gtk_widget_show (vbox);
+
+       widget = gtk_entry_new ();
+       gtk_entry_set_text (GTK_ENTRY (widget), TEST_STRING_A);
+       gtk_container_add (GTK_CONTAINER (vbox), widget);
+       gtk_widget_show (widget);
+
+       g_idle_add ((GSourceFunc) focus_me, win->window);
+
+       return win;
+}
+
+static void
+test_window_destroy (TestWindow *win)
+{
+       gtk_widget_destroy (win->window);
+       g_free (win);
+}
+
+static void
+test_roles (void)
+{
+       int i;
+
+       fprintf (stderr, "Testing roles...\n");
+       for (i = -1; i < 1000; i++)
+               g_assert (AccessibleRole_getName (i) != NULL);
+
+       g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_FILE_CHOOSER), "file chooser"));
+       g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_RADIO_BUTTON), "radiobutton"));
+       g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_TABLE), "table"));
+       g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_WINDOW), "window"));
+}
+
+static void
+test_desktop (void)
+{
+       Accessible *desktop;
+       Accessible *application;
+
+       fprintf (stderr, "Testing desktop...\n");
+
+       g_assert (getDesktop (-1) == NULL);
+       desktop = getDesktop (0);
+       g_assert (desktop != NULL);
+
+       validate_accessible (desktop, FALSE, FALSE);
+
+       application = Accessible_getChildAtIndex (desktop, 0);
+       g_assert (application != NULL);
+
+       Accessible_unref (desktop);
+}
+
+static void
+test_application (Accessible *application)
+{
+       char *str;
+
+       fprintf (stderr, "Testing application ...\n");
+       g_assert (Accessible_isApplication (application));
+       g_assert (Accessible_getApplication (application) ==
+                 application);
+       AccessibleApplication_unref (application);
+
+       str = AccessibleApplication_getToolkitName (application);
+       g_assert (str != NULL);
+       g_assert (!strcmp (str, "GAIL"));
+       SPI_freeString (str);
+
+       str = AccessibleApplication_getVersion (application);
+       g_assert (str != NULL);
+       SPI_freeString (str);
+
+       AccessibleApplication_getID (application);
+}
+
+static void
+test_editable_text (AccessibleEditableText *etext)
+{
+       char *str;
+       AccessibleText *text;
+
+       fprintf (stderr, "Testing editable text ...\n");
+       
+       g_assert (Accessible_isText (etext));
+       text = Accessible_getText (etext);
+
+       AccessibleEditableText_setTextContents (
+               etext, TEST_STRING_B);
+
+       str = AccessibleText_getText (text, 0, -1);
+       g_assert (!strcmp (str, TEST_STRING_B));
+
+       SPI_freeString (str);
+
+       /* FIXME: lots more editing here */
+
+       AccessibleEditableText_setTextContents (
+               etext, TEST_STRING_A);
+
+       AccessibleText_unref (text);
+}
+
+static void
+test_text (AccessibleText *text)
+{
+       char *str;
+
+       fprintf (stderr, "Testing text ...\n");
+
+       g_assert (AccessibleText_getCharacterCount (text) ==
+                 strlen (TEST_STRING_A));
+
+       str = AccessibleText_getText (text, 0, -1);
+       g_assert (!strcmp (str, TEST_STRING_A));
+       SPI_freeString (str);
+
+       str = AccessibleText_getText (text, 0, 5);
+       g_assert (!strncmp (str, TEST_STRING_A, 5));
+       SPI_freeString (str);
+
+       AccessibleText_setCaretOffset (text, 7);
+       g_assert (AccessibleText_getCaretOffset (text) == 7);
+
+       /* FIXME: lots more tests - selections etc. etc. */
+}
+
+static void
+test_component (AccessibleComponent *component)
+{
+       long x, y, width, height;
+
+       fprintf (stderr, "Testing component...\n");
+
+       AccessibleComponent_getExtents (
+               component, &x, &y, &width, &height, SPI_COORD_TYPE_SCREEN);
+
+       AccessibleComponent_getPosition (
+               component, &x, &y, SPI_COORD_TYPE_SCREEN);
+
+       AccessibleComponent_getSize (component, &width, &height);
+
+       if (width > 0 && height > 0) {
+#ifdef FIXME
+               Accessible *accessible, *componentb;
+#endif
+
+               g_assert (AccessibleComponent_contains (
+                       component, x, y, SPI_COORD_TYPE_SCREEN));
+
+               g_assert (AccessibleComponent_contains (
+                       component, x + width - 1, y, SPI_COORD_TYPE_SCREEN));
+
+               g_assert (AccessibleComponent_contains (
+                       component, x + width - 1, y + height - 1,
+                       SPI_COORD_TYPE_SCREEN));
+
+#ifdef FIXME
+               accessible = AccessibleComponent_getAccessibleAtPoint (
+                       component, x, y, SPI_COORD_TYPE_SCREEN);
+
+               g_assert (Accessible_isComponent (accessible));
+               componentb = Accessible_getComponent (accessible);
+               g_assert (componentb == component);
+
+               AccessibleComponent_unref (componentb);
+               Accessible_unref (accessible);
+#endif
+       }
+
+       AccessibleComponent_getLayer (component);
+       AccessibleComponent_getMDIZOrder (component);
+/*     AccessibleComponent_grabFocus (component); */
+}
+
+static void
+validate_tree (Accessible *accessible,
+              gboolean    has_parent,
+              gboolean    recurse_down)
+{
+       Accessible  *parent;
+       long         len, i;
+
+       parent = Accessible_getParent (accessible);
+       if (has_parent) {
+               long        index;
+               Accessible *child_at_index;
+
+               g_assert (parent != NULL);
+
+               index = Accessible_getIndexInParent (accessible);
+               g_assert (index >= 0);
+
+               child_at_index = Accessible_getChildAtIndex (parent, index);
+
+               g_assert (child_at_index == accessible);
+
+               Accessible_unref (child_at_index);
+               Accessible_unref (parent);
+       }
+
+       len = Accessible_getChildCount (accessible);
+       print_tree_depth++;
+       for (i = 0; i < len; i++) {
+               Accessible *child;
+
+               child = Accessible_getChildAtIndex (accessible, i);
+#ifdef ROPEY
+               if (!child)
+                       fprintf (stderr, "Unusual - ChildGone at %ld\n", i);
+
+               g_assert (Accessible_getIndexInParent (child) == i);
+               g_assert (Accessible_getParent (child) == accessible);
+#endif
+
+               if (recurse_down && child)
+                       validate_accessible (child, has_parent, recurse_down);
+
+               Accessible_unref (child);
+       }
+       print_tree_depth--;
+}
+
+static void
+validate_accessible (Accessible *accessible,
+                    gboolean    has_parent,
+                    gboolean    recurse_down)
+{
+       Accessible *tmp;
+       char       *name, *descr;
+       const char *role;
+
+       name = Accessible_getName (accessible);
+       g_assert (name != NULL);
+       
+       descr = Accessible_getDescription (accessible);
+       g_assert (descr != NULL);
+
+       role = Accessible_getRole (accessible);
+       g_assert (role != NULL);
+
+       if (print_tree) {
+               int i;
+
+               for (i = 0; i < print_tree_depth; i++)
+                       fputc (' ', stderr);
+               fputs ("|-> [ ", stderr);
+       }
+
+       if (Accessible_isAction (accessible)) {
+               tmp = Accessible_getAction (accessible);
+               g_assert (tmp != NULL);
+               if (print_tree)
+                       fprintf (stderr, "At");
+               AccessibleAction_unref (tmp);
+       }
+
+       if (Accessible_isApplication (accessible)) {
+               tmp = Accessible_getApplication (accessible);
+               if (print_tree)
+                       fprintf (stderr, "Ap");
+               else
+                       test_application (tmp);
+               AccessibleApplication_unref (tmp);
+       }
+
+       if (Accessible_isComponent (accessible)) {
+               tmp = Accessible_getComponent (accessible);
+               g_assert (tmp != NULL);
+               if (print_tree)
+                       fprintf (stderr, "Co");
+               else
+                       test_component (tmp);
+               AccessibleComponent_unref (tmp);
+       }
+
+       if (Accessible_isEditableText (accessible)) {
+               tmp = Accessible_getEditableText (accessible);
+               g_assert (tmp != NULL);
+               if (print_tree)
+                       fprintf (stderr, "Et");
+               else
+                       test_editable_text (tmp);
+               AccessibleEditableText_unref (tmp);
+       }
+
+       if (Accessible_isHypertext (accessible)) {
+               tmp = Accessible_getHypertext (accessible);
+               g_assert (tmp != NULL);
+               if (print_tree)
+                       fprintf (stderr, "Ht");
+               AccessibleHypertext_unref (tmp);
+       }
+
+       if (Accessible_isImage (accessible)) {
+               tmp = Accessible_getImage (accessible);
+               g_assert (tmp != NULL);
+               if (print_tree)
+                       fprintf (stderr, "Im");
+               AccessibleImage_unref (accessible);
+       }
+
+       if (Accessible_isSelection (accessible)) {
+               tmp = Accessible_getSelection (accessible);
+               g_assert (tmp != NULL);
+               if (print_tree)
+                       fprintf (stderr, "Se");
+               AccessibleSelection_unref (tmp);
+       }
+
+       if (Accessible_isTable (accessible)) {
+               tmp = Accessible_getTable (accessible);
+               g_assert (tmp != NULL);
+               if (print_tree)
+                       fprintf (stderr, "Ta");
+               AccessibleTable_unref (tmp);
+       }
+
+       if (Accessible_isText (accessible)) {
+               tmp = Accessible_getText (accessible);
+               g_assert (tmp != NULL);
+               if (print_tree)
+                       fprintf (stderr, "Te");
+               else
+                       test_text (tmp);
+               AccessibleText_unref (tmp);
+       }
+
+       if (print_tree)
+               fprintf (stderr, " ] '%s' (%s) - %s:\n", name, descr, role);
+
+       SPI_freeString (name);
+       SPI_freeString (descr);
+
+       validate_tree (accessible, has_parent, recurse_down);
+}
+
+static void
+test_misc (void)
+{
+       fprintf (stderr, "Testing misc bits ...\n");
+
+       g_assert (!Accessible_isComponent (NULL));
+       g_assert (Accessible_getComponent (NULL) == NULL);
+       SPI_freeString (NULL);
+}
+
+#ifdef UNUTTERABLY_HORRIFIC
+static void
+unutterable_horror (void)
+{
+       /* Brutal ugliness to de-register ourself and exit cleanly */
+       CORBA_Environment ev;
+       Accessible        *desktop;
+       Accessible        *app_access;
+       Accessibility_Accessible app;
+       Accessibility_Registry   registry;
+
+       fprintf (stderr, "Unutterable horror ...\n");
+
+       /* First get the application ! - gack */
+       desktop = getDesktop (0);
+       app_access = Accessible_getChildAtIndex (desktop, 0);
+
+       /* Good grief */
+       app = *(Accessibility_Accessible *) app_access;
+
+       CORBA_exception_init (&ev);
+
+       registry = bonobo_activation_activate_from_id (
+               "OAFIID:Accessibility_Registry:proto0.1", 0, NULL, &ev);
+
+       Accessibility_Registry_deregisterApplication (
+               registry, app, &ev);
+
+       bonobo_object_release_unref (registry, &ev); /* the original ref */
+       bonobo_object_release_unref (registry, &ev); /* taken by the bridge */
+       bonobo_object_release_unref (registry, &ev); /* taken by spi_main.c */
+
+       Accessible_unref (desktop);
+       Accessible_unref (app_access);
+
+       /* Urgh ! - get a pointer to app */
+       bonobo_object_unref (bonobo_object (ORBit_small_get_servant (app)));
+}
+#endif
+
+static void
+utterable_normal_derefs (void)
+{
+        /* Normal cleanup to exit cleanly */
+        CORBA_Environment ev;
+        Accessibility_Registry   registry;
+
+        CORBA_exception_init (&ev);
+
+        registry = bonobo_activation_activate_from_id (
+                "OAFIID:Accessibility_Registry:proto0.1", 0, NULL, &ev);
+
+        bonobo_object_release_unref (registry, &ev); /* the ref above */
+        bonobo_object_release_unref (registry, &ev); /* taken by spi_main.c */
+
+        /* Yes, it would be nicer to have both SPI_main_quit and SPI_shutdown,
+           then the above code could be dispensed with */
+}
+
+static void
+global_listener_cb (AccessibleEvent     *event,
+                   void                *user_data)
+{
+       TestWindow *win = user_data;
+       Accessible *desktop;
+       AccessibleApplication *application;
+
+       g_assert (win->magic == WINDOW_MAGIC);
+       g_assert (!strcmp (event->type, "focus:"));
+
+       fprintf (stderr, "Fielded focus event ...\n");
+
+       /* The application is now registered - this happens idly */
+
+       desktop = getDesktop (0);
+       application = Accessible_getChildAtIndex (desktop, 0);
+       g_assert (application != NULL);
+       Accessible_unref (desktop);
+
+       test_application (application);
+       
+       AccessibleApplication_unref (application);
+
+       print_tree = TRUE;
+       validate_accessible (event->source, TRUE, TRUE);
+       print_tree = FALSE;
+       validate_accessible (event->source, TRUE, TRUE);
+
+       gtk_main_quit ();
+}
+
+int
+main (int argc, char **argv)
+{
+       TestWindow *win;
+       AccessibleEventListener *global_listener;
+
+       gtk_init (&argc, &argv);
+
+       if (!g_getenv ("GTK_MODULES") ||
+           !strstr (g_getenv ("GTK_MODULES"), "gail:at-bridge")) {
+               g_error ("You need to export GTK_MODULES='gail:at-bridge'");
+       }
+
+       g_assert (!SPI_init (TRUE));
+       g_assert (SPI_init (TRUE));
+       g_assert (getDesktopCount () == 1);
+
+       test_roles ();
+       test_misc ();
+       test_desktop ();
+
+       win = create_test_window ();
+
+       global_listener = createAccessibleEventListener (global_listener_cb, win);
+       g_assert (registerGlobalEventListener (global_listener, "focus:"));
+
+       fprintf (stderr, "Waiting for focus event ...\n");
+       gtk_main ();
+
+       /* First de-register myself - we only want the toplevel of ourself */
+       g_assert (deregisterGlobalEventListenerAll (global_listener));
+
+       test_window_destroy (win);
+
+/* FIXME: we need to resolve the exit / quit mainloop function */
+/*     SPI_exit ();
+       SPI_exit (); */
+/*     unutterable_horror ();  ! */
+       utterable_normal_derefs ();
+
+       fprintf (stderr, "All tests passed\n");
+
+       return bonobo_debug_shutdown ();
+}