From 3f4e56a0a5514e74d2f753a9d04c7ba81f692ad6 Mon Sep 17 00:00:00 2001 From: billh Date: Fri, 6 Dec 2002 17:33:32 +0000 Subject: [PATCH] version 1.1.6. Added ref/unref for AccessibleEvents. Bugfixes for 99799 and 10530. git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@379 e2bd861d-eb25-0410-b326-f6ed22b6b98c --- ChangeLog | 52 +++++++++++++++++++++++ NEWS | 11 ++++- configure.in | 4 +- cspi/bonobo/cspi-bonobo-listener.c | 5 +++ cspi/bonobo/cspi-bonobo.c | 2 +- cspi/spi-private.h | 6 +++ cspi/spi.h | 4 ++ cspi/spi_event.c | 86 +++++++++++++++++++++++++++++++++++++- cspi/spi_main.c | 19 +++++++++ 9 files changed, 184 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3155916..ad1048f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +2002-12-06 Bill Haneman + + * 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 Removed some of the more dangerous workarounds from diff --git a/NEWS b/NEWS index 324472a..b73df4d 100644 --- 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. diff --git a/configure.in b/configure.in index b6d9abe..9f74708 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/cspi/bonobo/cspi-bonobo-listener.c b/cspi/bonobo/cspi-bonobo-listener.c index afa7660..61295a7 100644 --- a/cspi/bonobo/cspi-bonobo-listener.c +++ b/cspi/bonobo/cspi-bonobo-listener.c @@ -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 */ diff --git a/cspi/bonobo/cspi-bonobo.c b/cspi/bonobo/cspi-bonobo.c index 57ed06a..8c56407 100644 --- a/cspi/bonobo/cspi-bonobo.c +++ b/cspi/bonobo/cspi-bonobo.c @@ -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 diff --git a/cspi/spi-private.h b/cspi/spi-private.h index b9375d9..1b024ea 100644 --- a/cspi/spi-private.h +++ b/cspi/spi-private.h @@ -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); diff --git a/cspi/spi.h b/cspi/spi.h index a9ce4b0..2b3a511 100644 --- a/cspi/spi.h +++ b/cspi/spi.h @@ -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. diff --git a/cspi/spi_event.c b/cspi/spi_event.c index a819941..577f8e6 100644 --- a/cspi/spi_event.c +++ b/cspi/spi_event.c @@ -24,6 +24,8 @@ #include #include +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); + } + } +} diff --git a/cspi/spi_main.c b/cspi/spi_main.c index 56c731b..9a6b45d 100644 --- a/cspi/spi_main.c +++ b/cspi/spi_main.c @@ -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) { -- 2.7.4