From c139071b7cef3e8ea132abc5f994bd42e78e539c Mon Sep 17 00:00:00 2001 From: michael Date: Tue, 8 Jan 2002 09:11:47 +0000 Subject: [PATCH] 2002-01-08 Michael Meeks * registryd/registry.c (parse_event_type): remove strndup. * libspi/Makefile.am (libspi_la_SOURCES): remove sources already included in the headers section. * libspi/util.c: add. * libspi/spi-private.h: add. * registryd/registry.c: update to moved list iterators. 2002-01-05 Michael Meeks * test/simple-at.c (main): upd. auto-module set to atk-bridge * test/test-simple.c (main): ditto. 2002-01-04 Michael Meeks * libspi/accessible.c (spi_accessible_new): remove 2nd, redundant construct. * registryd/registry.c (get_listener_list): impl. (impl_accessibility_registry_register_global_event_listener): re-impl. to simplify using ~, remove dodgy const cast off. (parse_event_type): constify. (impl_accessibility_registry_deregister_global_event_listener_all): re-write, more efficiency and simplicity, kill re-enterancy hazard. (compare_listener_corbaref, compare_corba_objects), (compare_listener_quarks): define out. (impl_accessibility_registry_deregister_global_event_listener): re-write for effiency, and nail re-enterancy hazard. (impl_accessibility_registry_get_desktop_list): impl. (re_enterant_list_delete_link): impl. (re_enterant_list_foreach): impl. (remove_listener_cb): impl. (_registry_notify_listeners): kill. (notify_listeners_cb): impl. * cspi/spi_registry.c (SPI_freeDesktopList): impl. (SPI_getDesktopList): impl. * test/test-simple.c (test_desktop): test the methods. 2002-01-03 Michael Meeks * cspi/spi_event.c (SPI_createAccessibleKeySet): dup the keystrings since we free them (SPI_freeAccessibleKeySet): in here. * libspi/accessible.c (spi_accessible_new): kill warning, wonder what is going on with the constructor here. git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@203 e2bd861d-eb25-0410-b326-f6ed22b6b98c --- ChangeLog | 57 +++++ cspi/spi.h | 3 +- cspi/spi_event.c | 13 +- cspi/spi_registry.c | 56 ++++- docs/reference/cspi/tmpl/spi_registry.sgml | 4 +- libspi/Makefile.am | 102 ++++---- libspi/accessible.c | 4 +- libspi/spi-private.h | 23 ++ libspi/util.c | 81 +++++++ registryd/deviceeventcontroller.c | 8 +- registryd/registry.c | 370 +++++++++++++++-------------- test/simple-at.c | 2 +- test/test-simple.c | 14 +- 13 files changed, 482 insertions(+), 255 deletions(-) create mode 100644 libspi/spi-private.h create mode 100644 libspi/util.c diff --git a/ChangeLog b/ChangeLog index 1c35935..ae22c96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,60 @@ +2002-01-08 Michael Meeks + + * registryd/registry.c (parse_event_type): remove strndup. + + * libspi/Makefile.am (libspi_la_SOURCES): remove + sources already included in the headers section. + + * libspi/util.c: add. + + * libspi/spi-private.h: add. + + * registryd/registry.c: update to moved list iterators. + +2002-01-05 Michael Meeks + + * test/simple-at.c (main): upd. auto-module set to atk-bridge + + * test/test-simple.c (main): ditto. + +2002-01-04 Michael Meeks + + * libspi/accessible.c (spi_accessible_new): remove 2nd, + redundant construct. + + * registryd/registry.c + (get_listener_list): impl. + (impl_accessibility_registry_register_global_event_listener): + re-impl. to simplify using ~, remove dodgy const cast off. + (parse_event_type): constify. + (impl_accessibility_registry_deregister_global_event_listener_all): + re-write, more efficiency and simplicity, kill re-enterancy + hazard. + (compare_listener_corbaref, compare_corba_objects), + (compare_listener_quarks): define out. + (impl_accessibility_registry_deregister_global_event_listener): + re-write for effiency, and nail re-enterancy hazard. + (impl_accessibility_registry_get_desktop_list): impl. + (re_enterant_list_delete_link): impl. + (re_enterant_list_foreach): impl. + (remove_listener_cb): impl. + (_registry_notify_listeners): kill. + (notify_listeners_cb): impl. + + * cspi/spi_registry.c (SPI_freeDesktopList): impl. + (SPI_getDesktopList): impl. + + * test/test-simple.c (test_desktop): test the methods. + +2002-01-03 Michael Meeks + + * cspi/spi_event.c (SPI_createAccessibleKeySet): dup the + keystrings since we free them + (SPI_freeAccessibleKeySet): in here. + + * libspi/accessible.c (spi_accessible_new): kill warning, + wonder what is going on with the constructor here. + 2002-03-01 Bill Haneman * libspi/accessible.c (spi_accessible_new ()) : diff --git a/cspi/spi.h b/cspi/spi.h index 7ebe098..4afe11e 100644 --- a/cspi/spi.h +++ b/cspi/spi.h @@ -200,7 +200,8 @@ SPIBoolean SPI_deregisterAccessibleKeystrokeListener ( int SPI_getDesktopCount (void); Accessible *SPI_getDesktop (int i); -int SPI_getDesktopList (Accessible **list); +int SPI_getDesktopList (Accessible ***desktop_list); +void SPI_freeDesktopList (Accessible **desktop_list); SPIBoolean SPI_generateKeyboardEvent (long int keyval, char *keystring, diff --git a/cspi/spi_event.c b/cspi/spi_event.c index 8550a9a..469dedc 100644 --- a/cspi/spi_event.c +++ b/cspi/spi_event.c @@ -69,7 +69,8 @@ SPI_freeAccessibleKeySet (AccessibleKeySet *keyset) * **/ AccessibleKeySet * -SPI_createAccessibleKeySet (int len, const char *keysyms, short *keycodes, const char **keystrings) +SPI_createAccessibleKeySet (int len, const char *keysyms, short *keycodes, + const char **keystrings) { AccessibleKeySet *keyset = g_new0 (AccessibleKeySet, 1); int i, keysym_len = 0; @@ -93,8 +94,14 @@ SPI_createAccessibleKeySet (int len, const char *keysyms, short *keycodes, const { keyset->keysyms [i] = 0; } - if (keycodes) keyset->keycodes [i] = keycodes [i]; - if (keystrings) keyset->keystrings [i] = keystrings [i]; + if (keycodes) + { + keyset->keycodes [i] = keycodes [i]; + } + if (keystrings) + { + keyset->keystrings [i] = g_strdup (keystrings [i]); + } } return keyset; } diff --git a/cspi/spi_registry.c b/cspi/spi_registry.c index 6771576..287bc0e 100644 --- a/cspi/spi_registry.c +++ b/cspi/spi_registry.c @@ -219,10 +219,11 @@ SPI_getDesktop (int i) /** * SPI_getDesktopList: - * @list: a pointer to an array of #Accessible objects. + * @desktop_list: a pointer to an array of #Accessible references. * * Get the list of virtual desktops. On return, @list will point - * to a newly-created array of virtual desktop pointers. + * to a newly-created, NULL terminated array of virtual desktop + * pointers. * It is the responsibility of the caller to free this array when * it is no longer needed. * @@ -233,10 +234,55 @@ SPI_getDesktop (int i) * placed in the list pointed to by parameter @list. **/ int -SPI_getDesktopList (Accessible **list) +SPI_getDesktopList (Accessible ***desktop_list) { - *list = NULL; - return 0; + int i; + Accessible **list; + Accessibility_DesktopSeq *desktops; + + if (!desktop_list) + return 0; + + *desktop_list = NULL; + + desktops = Accessibility_Registry_getDesktopList (cspi_registry (), + cspi_ev ()); + + cspi_return_val_if_ev ("getting desktop list", 0); + + list = g_new0 (Accessible *, desktops->_length + 1); + + for (i = 0; i < desktops->_length; i++) + { + list [i] = cspi_object_add ( + CORBA_Object_duplicate (desktops->_buffer [i], cspi_ev ())); + } + list [i] = NULL; + + CORBA_free (desktops); + + *desktop_list = list; + + return i; +} + +/** + * SPI_freeDesktopList: + * @desktop_list: a pointer to an array of #Accessible objects + * as returned from @SPI_getDesktopList + * + * This routine frees the memory associated with the list. + **/ +void +SPI_freeDesktopList (Accessible **desktop_list) +{ + Accessible **p; + + for (p = desktop_list; p && *p; p++) + { + cspi_object_unref (*p); + } + g_free (desktop_list); } /** diff --git a/docs/reference/cspi/tmpl/spi_registry.sgml b/docs/reference/cspi/tmpl/spi_registry.sgml index 9b7abaf..e00a45f 100644 --- a/docs/reference/cspi/tmpl/spi_registry.sgml +++ b/docs/reference/cspi/tmpl/spi_registry.sgml @@ -47,8 +47,10 @@ Registry queries -@list: +@desktop_list: @Returns: + +@list: diff --git a/libspi/Makefile.am b/libspi/Makefile.am index 53235c3..2b51828 100644 --- a/libspi/Makefile.am +++ b/libspi/Makefile.am @@ -12,27 +12,28 @@ CFLAGS += $(DEBUG_CFLAGS) libspiincludedir = $(includedir)/at-spi-1.0/libspi -libspiinclude_HEADERS = Accessibility.h \ - accessible.h \ - eventlistener.h \ - action.h \ - application.h \ - base.h \ - component.h \ - editabletext.h\ - hyperlink.h\ - hypertext.h\ - image.h \ - keystrokelistener.h \ - keymasks.h \ - libspi.h \ - listener.h \ - relation.h \ - remoteobject.h \ - selection.h \ - table.h \ - text.h \ - value.h +libspiinclude_HEADERS = \ + Accessibility.h \ + accessible.h \ + eventlistener.h \ + action.h \ + application.h \ + base.h \ + component.h \ + editabletext.h \ + hyperlink.h \ + hypertext.h \ + image.h \ + keystrokelistener.h \ + keymasks.h \ + libspi.h \ + listener.h \ + relation.h \ + remoteobject.h \ + selection.h \ + table.h \ + text.h \ + value.h IDL_OUT = Accessibility.h Accessibility-stubs.c Accessibility-skels.c Accessibility-common.c @@ -59,46 +60,31 @@ IDL_DEPS = \ $(top_srcdir)/idl/Accessibility_Value.idl - BUILT_SOURCES = $(IDL_OUT) Accessibility-imodule.c CLEANFILES+=$(IDL_OUT) Accessibility-imodule.c -libspi_la_SOURCES = accessible.c \ - accessible.h \ - action.c\ - action.h\ - application.c \ - application.h \ - base.c \ - component.c \ - component.h \ - editabletext.c\ - editabletext.h\ - hyperlink.c\ - hyperlink.h\ - hypertext.c\ - hypertext.h\ - image.c\ - image.h\ - keystrokelistener.c\ - keystrokelistener.h\ - relation.c\ - relation.h\ - remoteobject.c\ - remoteobject.h\ - selection.c\ - selection.h\ - table.c\ - table.h\ - text.c\ - text.h\ - value.c\ - value.h\ - listener.c \ - listener.h \ - eventlistener.c \ - keymasks.h \ - $(IDL_OUT) +libspi_la_SOURCES = \ + accessible.c \ + action.c \ + application.c \ + base.c \ + component.c \ + editabletext.c \ + hyperlink.c \ + hypertext.c \ + image.c \ + keystrokelistener.c \ + relation.c \ + remoteobject.c \ + selection.c \ + spi-private.h \ + table.c \ + text.c \ + util.c \ + value.c \ + listener.c \ + eventlistener.c \ + $(IDL_OUT) IDLFLAGS = -I$(BONOBO_ACTIVATION_IDL_DIR) \ -I$(LIBBONOBO_IDL_DIR) \ diff --git a/libspi/accessible.c b/libspi/accessible.c index 4f408f2..445b5fd 100644 --- a/libspi/accessible.c +++ b/libspi/accessible.c @@ -454,7 +454,7 @@ spi_accessible_new (AtkObject *o) else if (SPI_IS_REMOTE_OBJECT (o)) { - retval = spi_remote_object_get_accessible (o); + retval = spi_remote_object_get_accessible (SPI_REMOTE_OBJECT (o)); } else { @@ -462,8 +462,6 @@ spi_accessible_new (AtkObject *o) spi_base_construct (SPI_BASE (retval), G_OBJECT(o)); - spi_base_construct (SPI_BASE (retval), G_OBJECT(o)); - /* aggregate appropriate SPI interfaces based on ATK interfaces */ if (ATK_IS_ACTION (o)) diff --git a/libspi/spi-private.h b/libspi/spi-private.h new file mode 100644 index 0000000..f69f8a8 --- /dev/null +++ b/libspi/spi-private.h @@ -0,0 +1,23 @@ +#ifndef SPI_PRIVATE_H_ +#define SPI_PRIVATE_H_ + +#include + +G_BEGIN_DECLS + +typedef enum { + SPI_RE_ENTERANT_CONTINUE = 0, + SPI_RE_ENTERANT_TERMINATE +} SpiReEnterantContinue; + +typedef SpiReEnterantContinue (*SpiReEnterantFn) (GList * const *list, + gpointer user_data); + +void spi_re_enterant_list_delete_link (GList * const *element_ptr); +void spi_re_enterant_list_foreach (GList **list, + SpiReEnterantFn func, + gpointer user_data); + +G_END_DECLS + +#endif /* SPI_PRIVATE_H_ */ diff --git a/libspi/util.c b/libspi/util.c new file mode 100644 index 0000000..ea6873c --- /dev/null +++ b/libspi/util.c @@ -0,0 +1,81 @@ +#include +#include + +#include "spi-private.h" + +typedef struct { + GList **list; + GList *iterator; +} Iteration; + +static GSList *working_list = NULL; /* of Iteration */ + +/* + * deletes an element from the list - in a re-enterant + * safe fashion; advances the element pointer to the next + * element. + */ +void +spi_re_enterant_list_delete_link (GList * const *element_ptr) +{ + GSList *l; + GList *next; + GList *element; + gboolean first_item; + + g_return_if_fail (element_ptr != NULL); + + element = *element_ptr; + g_return_if_fail (element != NULL); + + next = element->next; + first_item = (element->prev == NULL); + + g_list_remove_link (NULL, element); + + for (l = working_list; l; l = l->next) + { + Iteration *i = l->data; + + if (i->iterator == element) + { + i->iterator = next; + } + + if (first_item && *(i->list) == element) + { + *(i->list) = next; + } + } + + g_list_free_1 (element); +} + +void +spi_re_enterant_list_foreach (GList **list, + SpiReEnterantFn func, + gpointer user_data) +{ + Iteration i; + + if (!list) + { + return; + } + + i.list = list; + i.iterator = *list; + + working_list = g_slist_prepend (working_list, &i); + + while (i.iterator) { + GList *l = i.iterator; + + func (&i.iterator, user_data); + + if (i.iterator == l) + i.iterator = i.iterator->next; + } + + working_list = g_slist_remove (working_list, &i); +} diff --git a/registryd/deviceeventcontroller.c b/registryd/deviceeventcontroller.c index 16daff6..23587fa 100644 --- a/registryd/deviceeventcontroller.c +++ b/registryd/deviceeventcontroller.c @@ -370,8 +370,8 @@ spi_key_set_contains_key (Accessibility_KeySet *key_set, const Accessibility_Dev } static gboolean -spi_key_eventtype_seq_contains_event (Accessibility_KeyEventTypeSeq *type_seq, - const Accessibility_DeviceEvent *key_event) +spi_key_eventtype_seq_contains_event (Accessibility_KeyEventTypeSeq *type_seq, + const Accessibility_DeviceEvent *key_event) { gint i; gint len; @@ -400,8 +400,8 @@ spi_key_eventtype_seq_contains_event (Accessibility_KeyEventTypeSeq *type_seq, static gboolean spi_key_event_matches_listener (const Accessibility_DeviceEvent *key_event, - DEControllerKeyListener *listener, - CORBA_boolean is_system_global) + DEControllerKeyListener *listener, + CORBA_boolean is_system_global) { g_print ("checking keycode %d\n", (int) key_event->hw_code); if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask & 0xFFFF)) && diff --git a/registryd/registry.c b/registryd/registry.c index b482255..50b6aeb 100644 --- a/registryd/registry.c +++ b/registryd/registry.c @@ -29,6 +29,7 @@ # include #endif +#include #include "registry.h" /* Our parent GObject type */ @@ -58,17 +59,11 @@ typedef struct { typedef struct { Accessibility_EventListener listener; - GQuark event_type_quark; + GQuark event_type_quark; EventTypeCategory event_type_cat; } SpiListenerStruct; /* static function prototypes */ -static void _registry_notify_listeners (GList *listeners, - const Accessibility_Event *e, - CORBA_Environment *ev); - -static long _get_unique_id(); - static gboolean _device_event_controller_hook (gpointer source); SpiListenerStruct * @@ -79,6 +74,7 @@ spi_listener_struct_new (Accessibility_EventListener listener, CORBA_Environment return retval; } + void spi_listener_struct_free (SpiListenerStruct *ls, CORBA_Environment *ev) { @@ -86,15 +82,22 @@ spi_listener_struct_free (SpiListenerStruct *ls, CORBA_Environment *ev) g_free (ls); } -/* GObject::finalize */ + static void spi_registry_object_finalize (GObject *object) { - SpiRegistry *registry = SPI_REGISTRY (object); + printf ("spi_registry_object_finalize called\n"); - printf("spi_registry_object_finalize called\n"); - /* TODO: unref deviceeventcontroller, which disconnects key listener */ - G_OBJECT_CLASS (spi_registry_parent_class)->finalize (object); + /* TODO: unref deviceeventcontroller, which disconnects key listener */ + G_OBJECT_CLASS (spi_registry_parent_class)->finalize (object); +} + +static long +_get_unique_id (void) +{ + static long id = 0; + + return ++id; } /** @@ -117,7 +120,7 @@ impl_accessibility_registry_register_application (PortableServer_Servant servant #endif spi_desktop_add_application (registry->desktop, application); - Accessibility_Application__set_id (application, _get_unique_id(), ev); + Accessibility_Application__set_id (application, _get_unique_id (), ev); /* * TODO: change the implementation below to a WM-aware one; @@ -125,6 +128,7 @@ impl_accessibility_registry_register_application (PortableServer_Servant servant */ } +#ifdef USE_A_HASH_IN_FUTURE static gint compare_corba_objects (gconstpointer p1, gconstpointer p2) { @@ -139,6 +143,7 @@ compare_corba_objects (gconstpointer p1, gconstpointer p2) retval = !CORBA_Object_is_equivalent ((CORBA_Object) p1, (CORBA_Object) p2, &ev); return retval; } +#endif static void register_with_toolkits (SpiRegistry *spi_registry_bonobo_object, EventTypeStruct *etype, CORBA_Environment *ev) @@ -167,16 +172,18 @@ register_with_toolkits (SpiRegistry *spi_registry_bonobo_object, EventTypeStruct Accessibility_Application_registerToolkitEventListener (app, registry, CORBA_string_dup (etype->event_name), - ev); } } } +#ifdef USE_A_HASH_IN_FUTURE + static gint compare_listener_quarks (gconstpointer p1, gconstpointer p2) { - return (!((SpiListenerStruct *)p2)->event_type_quark == ((SpiListenerStruct *)p1)->event_type_quark); + return (((SpiListenerStruct *)p2)->event_type_quark != + ((SpiListenerStruct *)p1)->event_type_quark); } static gint @@ -185,15 +192,16 @@ compare_listener_corbaref (gconstpointer p1, gconstpointer p2) return compare_corba_objects (((SpiListenerStruct *)p2)->listener, ((SpiListenerStruct *)p1)->listener); } +#endif static void -parse_event_type (EventTypeStruct *etype, char *event_name) +parse_event_type (EventTypeStruct *etype, const char *event_name) { gchar **split_string; gchar *s; - split_string = g_strsplit(event_name, ":", 4); - etype->event_name = g_strndup(event_name, 255); + split_string = g_strsplit (event_name, ":", 4); + etype->event_name = g_strdup (event_name); if (!g_ascii_strncasecmp (event_name, "focus:", 6)) { @@ -273,134 +281,133 @@ impl_accessibility_registry_deregister_application (PortableServer_Servant serva #endif } +static GList ** +get_listener_list (SpiRegistry *registry, + EventTypeCategory cat) +{ + GList **ret; + + switch (cat) + { + case ETYPE_OBJECT: + case ETYPE_PROPERTY: + case ETYPE_FOCUS: + ret = ®istry->object_listeners; + break; + case ETYPE_WINDOW: + ret = ®istry->window_listeners; + break; + case ETYPE_TOOLKIT: + ret = ®istry->toolkit_listeners; + break; + case ETYPE_KEYBOARD: + default: + ret = NULL; + break; + } + return ret; +} + /* * CORBA Accessibility::Registry::registerGlobalEventListener method implementation */ static void impl_accessibility_registry_register_global_event_listener ( - PortableServer_Servant servant, - Accessibility_EventListener listener, - const CORBA_char *event_name, - CORBA_Environment *ev) + PortableServer_Servant servant, + Accessibility_EventListener listener, + const CORBA_char *event_name, + CORBA_Environment *ev) { SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); SpiListenerStruct *ls = spi_listener_struct_new (listener, ev); EventTypeStruct etype; + GList **list; fprintf(stderr, "registering for events of type %s\n", event_name); /* parse, check major event type and add listener accordingly */ - parse_event_type (&etype, (char*) event_name); + parse_event_type (&etype, event_name); ls->event_type_quark = etype.major; ls->event_type_cat = etype.type_cat; - switch (etype.type_cat) + list = get_listener_list (registry, etype.type_cat); + + if (list) + { + *list = g_list_prepend (*list, ls); + + if (etype.type_cat == ETYPE_TOOLKIT) + { + register_with_toolkits (registry, &etype, ev); + } + } + else { - case (ETYPE_FOCUS) : - case (ETYPE_OBJECT) : - case (ETYPE_PROPERTY) : - registry->object_listeners = - g_list_append (registry->object_listeners, ls); - break; - case (ETYPE_WINDOW) : - /* Support for Window Manager Events is not yet implemented */ - spi_listener_struct_free (ls, ev); - break; - case (ETYPE_TOOLKIT) : - registry->toolkit_listeners = - g_list_append (registry->toolkit_listeners, ls); - register_with_toolkits (registry, &etype, ev); - break; - default: spi_listener_struct_free (ls, ev); - break; } } +static void +remove_listener_cb (GList * const *list, gpointer user_data) +{ + SpiListenerStruct *ls = (SpiListenerStruct *) (*list)->data; + CORBA_Environment ev; + Accessibility_EventListener listener = user_data; + + CORBA_exception_init (&ev); + + if (CORBA_Object_is_equivalent (ls->listener, listener, &ev)) + { + spi_re_enterant_list_delete_link (list); + spi_listener_struct_free (ls, &ev); + } + + CORBA_exception_free (&ev); +} + /* * CORBA Accessibility::Registry::deregisterGlobalEventListenerAll method implementation */ static void impl_accessibility_registry_deregister_global_event_listener_all ( - PortableServer_Servant servant, - Accessibility_EventListener listener, - CORBA_Environment *ev) + PortableServer_Servant servant, + Accessibility_EventListener listener, + CORBA_Environment *ev) { + int i; + GList **lists[2]; SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - SpiListenerStruct *ls = spi_listener_struct_new (listener, ev); - GList *list; - list = g_list_find_custom (registry->object_listeners, ls, - compare_listener_corbaref); - /* - * TODO : de-register with toolkit if the last instance of a listener - * to a particular toolkit event type has been deregistered. - */ + lists[0] = ®istry->object_listeners; + lists[1] = ®istry->window_listeners; + lists[2] = ®istry->toolkit_listeners; - while (list) - { - spi_listener_struct_free ((SpiListenerStruct *) list->data, ev); - registry->object_listeners = g_list_delete_link (registry->object_listeners, list); - list = g_list_find_custom (registry->object_listeners, ls, compare_listener_corbaref); - } - list = g_list_find_custom (registry->toolkit_listeners, ls, compare_listener_corbaref); - while (list) + for (i = 0; i < sizeof (lists) / sizeof (lists[0]); i++) { - spi_listener_struct_free ((SpiListenerStruct *) list->data, ev); - registry->toolkit_listeners = g_list_delete_link (registry->toolkit_listeners, list); - list = g_list_find_custom (registry->toolkit_listeners, ls, compare_listener_corbaref); + spi_re_enterant_list_foreach (lists [i], remove_listener_cb, listener); } - spi_listener_struct_free (ls, ev); } + /* * CORBA Accessibility::Registry::deregisterGlobalEventListener method implementation */ static void impl_accessibility_registry_deregister_global_event_listener ( - PortableServer_Servant servant, - Accessibility_EventListener listener, - const CORBA_char * event_name, - CORBA_Environment *ev) + PortableServer_Servant servant, + Accessibility_EventListener listener, + const CORBA_char *event_name, + CORBA_Environment *ev) { - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - SpiListenerStruct ls; + SpiRegistry *registry; EventTypeStruct etype; - GList *list; - GList **listeners; - - parse_event_type (&etype, (char *) event_name); - switch (etype.type_cat) - { - case (ETYPE_OBJECT) : - case (ETYPE_PROPERTY) : - case (ETYPE_FOCUS) : - listeners = ®istry->object_listeners; - break; - case (ETYPE_WINDOW) : - /* Support for Window Manager Events is not yet implemented */ - listeners = NULL; - break; - case (ETYPE_TOOLKIT) : - listeners = ®istry->toolkit_listeners; - break; - default: - listeners = NULL; - break; - } - if (!listeners) - return; + registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - ls.event_type_quark = etype.major; - list = g_list_find_custom (*listeners, &ls, compare_listener_quarks); + parse_event_type (&etype, (char *) event_name); - while (list) - { - spi_listener_struct_free ((SpiListenerStruct *) list->data, ev); - *listeners = g_list_delete_link (*listeners, list); - list = g_list_find_custom (*listeners, &ls, compare_listener_quarks); - } + spi_re_enterant_list_foreach (get_listener_list (registry, etype.type_cat), + remove_listener_cb, listener); } @@ -422,6 +429,7 @@ impl_accessibility_registry_get_desktop_count (PortableServer_Servant servant, return n_desktops; } + /** * getDesktop: * @n: the index of the requested @Desktop. @@ -449,6 +457,7 @@ impl_accessibility_registry_get_desktop (PortableServer_Servant servant, } } + /** * getDesktopList: * return values: a sequence containing references to @@ -461,104 +470,115 @@ static Accessibility_DesktopSeq * impl_accessibility_registry_get_desktop_list (PortableServer_Servant servant, CORBA_Environment * ev) { - /* TODO: implement support for multiple virtual desktops */ - return (Accessibility_DesktopSeq *) NULL; + SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); + Accessibility_DesktopSeq *desktops; + + desktops = Accessibility_DesktopSeq__alloc (); + desktops->_length = desktops->_maximum = 1; + desktops->_buffer = Accessibility_DesktopSeq_allocbuf (desktops->_length); + desktops->_buffer [0] = bonobo_object_dup_ref (BONOBO_OBJREF (registry->desktop), ev); + + return desktops; } + static Accessibility_DeviceEventController impl_accessibility_registry_get_device_event_controller (PortableServer_Servant servant, - CORBA_Environment * ev) + CORBA_Environment *ev) { SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); + if (!registry->device_event_controller) - registry->device_event_controller = spi_device_event_controller_new (registry); + { + registry->device_event_controller = spi_device_event_controller_new (registry); + } return bonobo_object_dup_ref (BONOBO_OBJREF (registry->device_event_controller), ev); } +typedef struct { + CORBA_Environment *ev; + Bonobo_Unknown source; + EventTypeStruct etype; + Accessibility_Event e_out; +} NotifyContext; + static void -impl_registry_notify_event (PortableServer_Servant servant, - const Accessibility_Event *e, - CORBA_Environment *ev) +notify_listeners_cb (GList * const *list, gpointer user_data) { - SpiRegistry *registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - EventTypeStruct etype; + SpiListenerStruct *ls; + NotifyContext *ctx = user_data; +#ifdef SPI_DEBUG + CORBA_string s; +#endif - parse_event_type (&etype, e->type); + ls = (*list)->data; - switch (etype.type_cat) - { - case (ETYPE_OBJECT) : - case (ETYPE_PROPERTY) : - case (ETYPE_FOCUS) : - _registry_notify_listeners (registry->object_listeners, e, ev); - break; - case (ETYPE_WINDOW) : - _registry_notify_listeners (registry->window_listeners, e, ev); - break; - case (ETYPE_TOOLKIT) : - _registry_notify_listeners (registry->toolkit_listeners, e, ev); - break; - case (ETYPE_KEYBOARD) : - default: - break; - } - if (e->source != CORBA_OBJECT_NIL) +#ifdef SPI_LISTENER_DEBUG + fprintf (stderr, "event quarks: %lx %lx %lx\n", ls->event_type_quark, etype.major, etype.minor); + fprintf (stderr, "event name: %s\n", etype.event_name); +#endif + + if ((ls->event_type_quark == ctx->etype.major) || + (ls->event_type_quark == ctx->etype.minor)) { - Accessibility_Accessible_unref (e->source, ev); - } -} +#ifdef SPI_DEBUG + fprintf (stderr, "notifying listener %d\n", g_list_index (listeners, l->data)); + s = Accessibility_Accessible__get_name (ctx->source, ev); + fprintf (stderr, "event source name %s\n", s); + CORBA_free (s); +#endif + + ctx->e_out.source = bonobo_object_dup_ref (ctx->source, ctx->ev); + if (BONOBO_EX (ctx->ev)) + return; -static long -_get_unique_id () -{ - static long id = 0; - return ++id; + if ((*list) && (*list)->data == ls) + { + Accessibility_EventListener_notifyEvent ( + (Accessibility_EventListener) ls->listener, &ctx->e_out, ctx->ev); + if (ctx->ev->_major != CORBA_NO_EXCEPTION) + { + g_warning ("Accessibility app error: exception during " + "event notification: %s\n", + CORBA_exception_id (ctx->ev)); + } + } + else /* dup re-entered */ + { + bonobo_object_release_unref (ctx->e_out.source, ctx->ev); + } + } } static void -_registry_notify_listeners (GList *listeners, - const Accessibility_Event *e_in, - CORBA_Environment *ev) +impl_registry_notify_event (PortableServer_Servant servant, + const Accessibility_Event *e, + CORBA_Environment *ev) { - GList *l; - Accessibility_Event e_out; - SpiListenerStruct *ls; - EventTypeStruct etype; -#ifdef SPI_DEBUG - CORBA_string s; -#endif + SpiRegistry *registry; + GList **list; + NotifyContext ctx; + + registry = SPI_REGISTRY (bonobo_object_from_servant (servant)); - e_out = *e_in; - parse_event_type (&etype, e_in->type); + parse_event_type (&ctx.etype, e->type); - for (l = listeners; l; l = l->next) + list = get_listener_list (registry, ctx.etype.type_cat); + + if (list) { - ls = (SpiListenerStruct *) l->data; + ctx.ev = ev; + ctx.e_out = *e; + ctx.source = e->source; + parse_event_type (&ctx.etype, e->type); -#ifdef SPI_LISTENER_DEBUG - fprintf (stderr, "event quarks: %lx %lx %lx\n", ls->event_type_quark, etype.major, etype.minor); - fprintf (stderr, "event name: %s\n", etype.event_name); -#endif + spi_re_enterant_list_foreach (list, notify_listeners_cb, &ctx); + } - if ((ls->event_type_quark == etype.major) || (ls->event_type_quark == etype.minor)) - { -#ifdef SPI_DEBUG - 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.source = bonobo_object_dup_ref (e_in->source, ev); - Accessibility_EventListener_notifyEvent ((Accessibility_EventListener) ls->listener, - &e_out, - ev); - if (ev->_major != CORBA_NO_EXCEPTION) - { - g_warning ("Accessibility app error: exception during event notification: %s\n", - CORBA_exception_id (ev)); - } - } + if (e->source != CORBA_OBJECT_NIL) + { + Accessibility_Accessible_unref (e->source, ev); } } @@ -601,7 +621,7 @@ spi_registry_init (SpiRegistry *registry) registry->object_listeners = NULL; registry->window_listeners = NULL; registry->toolkit_listeners = NULL; - registry->desktop = spi_desktop_new(); + registry->desktop = spi_desktop_new (); registry->device_event_controller = NULL; registry->kbd_event_hook = _device_event_controller_hook; } diff --git a/test/simple-at.c b/test/simple-at.c index 149a5f4..8b2c94a 100644 --- a/test/simple-at.c +++ b/test/simple-at.c @@ -73,7 +73,7 @@ main (int argc, char **argv) modules = g_getenv ("GTK_MODULES"); if (!modules || modules [0] == '\0') { - putenv ("GTK_MODULES=gail:at-bridge"); + putenv ("GTK_MODULES=gail:atk-bridge"); } modules = NULL; diff --git a/test/test-simple.c b/test/test-simple.c index 47cad07..fa70a6b 100644 --- a/test/test-simple.c +++ b/test/test-simple.c @@ -174,7 +174,7 @@ test_action (AccessibleAction *action) fprintf (stderr, "%d: %s (%s); ", i, s, sd); SPI_freeString (s); SPI_freeString (sd); - /* g_assert (AccessibleAction_doAction (action, i)); */ + g_assert (AccessibleAction_doAction (action, i)); } fprintf (stderr, "\n"); } @@ -182,8 +182,10 @@ test_action (AccessibleAction *action) static void test_desktop (void) { - Accessible *desktop; - Accessible *application; + Accessible *desktop; + Accessible *application; + int length; + Accessible **list; fprintf (stderr, "Testing desktop...\n"); @@ -191,6 +193,10 @@ test_desktop (void) desktop = SPI_getDesktop (0); g_assert (desktop != NULL); + g_assert ((length = SPI_getDesktopList (&list)) > 0); + g_assert (list[0] == desktop); + SPI_freeDesktopList (list); + validate_accessible (desktop, FALSE, FALSE); application = Accessible_getChildAtIndex (desktop, 0); @@ -647,7 +653,7 @@ main (int argc, char **argv) modules = g_getenv ("GTK_MODULES"); if (!modules || modules [0] == '\0') - putenv ("GTK_MODULES=gail:at-bridge"); + putenv ("GTK_MODULES=gail:atk-bridge"); modules = NULL; for (i = 1; i < argc; i++) { -- 2.7.4