version 1.1.6. Added ref/unref for AccessibleEvents.
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 6 Dec 2002 17:33:32 +0000 (17:33 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 6 Dec 2002 17:33:32 +0000 (17:33 +0000)
Bugfixes for 99799 and 10530.

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

ChangeLog
NEWS
configure.in
cspi/bonobo/cspi-bonobo-listener.c
cspi/bonobo/cspi-bonobo.c
cspi/spi-private.h
cspi/spi.h
cspi/spi_event.c
cspi/spi_main.c

index 3155916..ad1048f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2002-12-06  Bill Haneman  <bill.haneman@sun.com>
+
+       * configure.in:
+       Revved to 1.1.6.
+       
+       * cspi/spi.h: 
+       (AccessibleEvent_ref, AccessibleEvent_unref):
+       New methods, for persisting an event outside the emission context.
+       Must be used if the new accessor methods are to be called
+       outside of the event listener's callback.
+
+       * cspi/bonobo/cspi-bonobo.c:
+       (cspi_dup_ref): Pass 'ev' to bonobo_object_dup_ref
+       as second parameter instead of NULL, so we can call
+       cspi_check_ev afterwards.
+       
+       * cspi/spi_main.c:
+       (cspi_object_take): New internal method, 
+       converts a CORBA_Object reference to a hard ref on
+       an Accessible if possible, returning NULL if the object
+       reference is invalid or an Accessible * otherwise.
+
+       * cspi/spi_event.c:
+       (AccessibleEvent_ref): 
+       Increment the event's internal private refcount, and 
+       add the event's internal struct to an internal cache 
+       if it's not already there.
+       (AccessibleEvent_unref): 
+       Decrement the event's refcount and remove it from
+       the cspi event cache if refcount==0.
+       (cspi_event_compare): New private method.
+       Compares two event structs via their ids. Used 
+       for queue lookup.
+       (cspi_internal_event_lookup): New private method.
+       (cspi_internal_event_check): New private method,
+       a 0-order sanity check for events to make sure their
+       private data is intact.
+       (cspi_internal_event_add, cspi_internal_event_remove):
+       New private methods for managiing the event cache.
+
+       * cspi/bonobo/cspi-bonobo-listener.c:
+       (cspi_event):
+       Initialize the new private data elements (id, magic, ref_count).
+       
+       * atk-bridge/bridge.c:
+       (spi_atk_bridge_signal_listener):
+       Fixed bug #100530, passing wrong params to emission func.
+
+       * registryd/deviceeventcontroller.c:
+       (spi_dec_button_update_and_emit): 
+       Fixed type in mask bit operations; fix for #99799.
+       
 2002-12-02  Bill Haneman  <bill.haneman@sun.com>
 
        Removed some of the more dangerous workarounds from
diff --git a/NEWS b/NEWS
index 324472a..b73df4d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,16 @@
 (top)
 in HEAD:
 
-What's new in at-spi-1.1.5:
+What's new in at-spi-1.1.6:
+
+* Fixes for #99799, #10530.
+
+* New methods in cspi:
+  'AccessibleEvent_ref' and 'AccessibleEvent_unref'
+  to allow lifecycle management of AccessibleEvents outside of
+  the emission handler.
+
+What's new in at-spi-1.1.6:
 
 * event struct in libspi is bigger, increased unimplemented
   slot count for sufficient future bincompatible expansion. 
index b6d9abe..9f74708 100644 (file)
@@ -2,9 +2,9 @@ AC_INIT(idl/Accessibility.idl)
 
 AT_SPI_MAJOR_VERSION=1
 AT_SPI_MINOR_VERSION=1
-AT_SPI_MICRO_VERSION=5
+AT_SPI_MICRO_VERSION=6
 AT_SPI_INTERFACE_AGE=0
-AT_SPI_BINARY_AGE=5
+AT_SPI_BINARY_AGE=6
 AT_SPI_VERSION="$AT_SPI_MAJOR_VERSION.$AT_SPI_MINOR_VERSION.$AT_SPI_MICRO_VERSION"
 AM_INIT_AUTOMAKE(at-spi, $AT_SPI_VERSION)
 AC_SUBST(AT_SPI_MAJOR_VERSION)
index afa7660..61295a7 100644 (file)
@@ -39,6 +39,8 @@ typedef struct
 GObjectClass *event_parent_class;
 GObjectClass *device_parent_class;
 
+static guint32 _e_id = 0;
+
 /*
  * Misc. helpers.
  */
@@ -98,6 +100,9 @@ cspi_event (SpiEventListener    *listener,
   aevent.event.source  = source;
   aevent.event.detail1 = event->detail1;
   aevent.event.detail2 = event->detail2;
+  aevent.id            = _e_id++;
+  aevent.magic         = SPI_INTERNAL_EVENT_MAGIC;
+  aevent.ref_count     = 0;
   aevent.data          = &event->any_data;
 
   /* FIXME: re-enterancy hazard on this list */
index 57ed06a..8c56407 100644 (file)
@@ -29,7 +29,7 @@
 CORBA_Object
 cspi_dup_ref (CORBA_Object object)
 {
-  return bonobo_object_dup_ref (object, NULL);
+  return bonobo_object_dup_ref (object, cspi_ev ());
 }
 
 void
index b9375d9..1b024ea 100644 (file)
@@ -39,11 +39,16 @@ struct _Accessible {
        guint        ref_count : 30;
 };
 
+#define SPI_INTERNAL_EVENT_MAGIC 0xc3
 /* 
  * For internal use by CSPI implementation only
  */
 typedef struct {
   AccessibleEvent event;
+  guint           id;
+  guchar          magic;
+  guchar          type;
+  guint16         ref_count;
   void           *data; 
 } InternalEvent;
 
@@ -56,6 +61,7 @@ Accessible            *cspi_object_add       (CORBA_Object corba_object);
 void                   cspi_object_ref       (Accessible  *accessible);
 void                   cspi_object_unref     (Accessible  *accessible);
 Accessible            *cspi_object_borrow    (CORBA_Object corba_object);
+Accessible            *cspi_object_take      (CORBA_Object corba_object);
 void                   cspi_object_return    (Accessible  *accessible);
 SPIBoolean             cspi_accessible_is_a  (Accessible  *accessible,
                                              const char  *interface_name);
index a9ce4b0..2b3a511 100644 (file)
@@ -793,6 +793,10 @@ double     AccessibleValue_getMaximumValue (AccessibleValue *obj);
 SPIBoolean AccessibleValue_setCurrentValue (AccessibleValue *obj,
                                            double           newValue);
 
+/* Persistance and lifecycle control for AccessibleEvents. */
+SPIBoolean AccessibleEvent_ref (const AccessibleEvent *e);
+void AccessibleEvent_unref (const AccessibleEvent *e);
+
 /*
  * Prototypes for accessor functions, to obtain context
  * information for accessible events.
index a819941..577f8e6 100644 (file)
@@ -24,6 +24,8 @@
 #include <cspi/spi-private.h>
 #include <cspi/bonobo/cspi-bonobo-listener.h>
 
+static GSList *_cspi_event_queue = NULL;
+
 /**
  * SPI_freeAccessibleKeySet:
  * @keyset: An AccessibleKeyset to free.
@@ -352,11 +354,12 @@ static Accessible *
 cspi_internal_event_get_object (const InternalEvent *e)
 {
   CORBA_any *any;
+  Accessible *accessible;
   g_return_val_if_fail (e, NULL);
   g_return_val_if_fail (e->data, NULL);
   any = (CORBA_any *) e->data;
   if (any->_type == TC_CORBA_Object) 
-    return cspi_object_add (* (CORBA_Object *) any->_value);
+    return cspi_object_take (* (CORBA_Object *) any->_value);
   else 
     return NULL;
 }
@@ -501,9 +504,90 @@ AccessibleDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e
   return NULL;
 }
 
+static gint
+cspi_event_compare (gconstpointer p1, gconstpointer p2)
+{
+  const InternalEvent *e1 = p1, *e2 = p2;
+  return (gint) ((long) e2->id  - (long) e1->id);
+}
+
+static InternalEvent *
+cspi_internal_event_lookup (const InternalEvent *e)
+{
+  InternalEvent *internal = NULL;
+  GSList *p =
+    g_slist_find_custom (_cspi_event_queue, e, cspi_event_compare);
+  if (p)
+    internal = p->data;
+  return internal;
+}
+
+static const InternalEvent *
+cspi_internal_event_check (const AccessibleEvent *e)
+{
+  InternalEvent *internal = (InternalEvent *) e;
+  if (internal->magic == SPI_INTERNAL_EVENT_MAGIC) 
+    return internal;
+  else
+    return NULL;
+}
+
+static InternalEvent *
+cspi_internal_event_add (const InternalEvent *e)
+{
+  _cspi_event_queue = g_slist_prepend (_cspi_event_queue, e);
+  return (InternalEvent *) e;
+}
+
+static void
+cspi_internal_event_remove (const InternalEvent *e)
+{
+  GSList *link = g_slist_find_custom (_cspi_event_queue, e, cspi_event_compare);
+  if (link)
+    _cspi_event_queue = g_slist_remove_link (_cspi_event_queue, link);
+}
+
 char *
 AccessibleNameChangedEvent_getNameString (const AccessibleEvent *e)
 {
   return NULL;
 }
 
+SPIBoolean
+AccessibleEvent_ref (const AccessibleEvent *e)
+{
+  const InternalEvent *private = cspi_internal_event_check (e);
+  if (private)
+    {
+      InternalEvent *event = cspi_internal_event_lookup (private);
+      /* 
+       * put event in the cache if it's not there already, 
+       * and increment refcount 
+       */
+      if (!event)
+       {
+         event = cspi_internal_event_add (private);
+       }
+      event->ref_count++;
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+void
+AccessibleEvent_unref (const AccessibleEvent *e)
+{
+  const InternalEvent *private = cspi_internal_event_check (e);
+  /* decrement refcount and remove if appropriate */
+  if (private)
+    {
+      InternalEvent *event = cspi_internal_event_lookup (private);
+      if (event) 
+       {
+         event->ref_count--;
+         if (event->ref_count < 1)
+           cspi_internal_event_remove (event);
+       }
+    }
+}
index 56c731b..9a6b45d 100644 (file)
@@ -243,6 +243,25 @@ cspi_object_return (Accessible *accessible)
     }
 }
 
+Accessible *
+cspi_object_take (CORBA_Object corba_object)
+{
+  Accessible *accessible;
+  accessible = cspi_object_borrow (corba_object);
+  cspi_object_ref (accessible->objref);
+  /* 
+   * if the remote object is dead, 
+   * cspi_object_return will throw an exception. 
+   */
+  cspi_object_return (accessible->objref);
+  if (cspi_exception ()) 
+    {
+      cspi_object_unref (accessible->objref);
+      accessible = NULL;
+    }
+  return accessible;
+}
+
 void
 cspi_object_ref (Accessible *accessible)
 {