* AT-SPI - Assistive Technology Service Provider Interface
* (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
*
- * Copyright 2001, 2002 Sun Microsystems Inc.,
- * Copyright 2001, 2002 Ximian, Inc.
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.,
+ * Copyright 2001, 2002, 2003 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 <cspi/spi-private.h>
#include <cspi/bonobo/cspi-bonobo-listener.h>
+static GSList *_cspi_event_queue = NULL;
+
/**
* SPI_freeAccessibleKeySet:
* @keyset: An AccessibleKeyset to free.
cspi_device_listener_unref (listener);
}
-/**
- * AccessibleEvent_getContextString:
- * @event: a pointer to the #AccessibleEvent being queried.
- *
- * Queries an #AccessibleEvent for a string whose meaning depends
- * on the event's context, that is, the event type and details.
- * Not all events have context strings, in which case this
- * query returns NULL.
- * Context strings may be returned by:
- * object:text-changed events,
- * in which case they represent the text inserted or deleted;
- * window: events, in which case they indicate the window title,
- * or other events.
- *
- * Returns: the context string for the event, or %NULL if
- * there is no context string for the event.
- **/
-char *
-AccessibleEvent_getContextString (const AccessibleEvent *e)
+static char *
+cspi_internal_event_get_text (const InternalEvent *e)
{
- InternalEvent *foo = (InternalEvent *) e;
CORBA_any *any;
- g_return_val_if_fail (foo, NULL);
- g_return_val_if_fail (foo->data, NULL);
- any = (CORBA_any *) foo->data;
+ g_return_val_if_fail (e, NULL);
+ g_return_val_if_fail (e->data, NULL);
+ any = (CORBA_any *) e->data;
if (CORBA_TypeCode_equivalent (any->_type, TC_CORBA_string, NULL))
{
- return * (char **) any->_value;
+ return g_strdup (* (char **) any->_value);
}
- else
+ else
{
#ifdef EVENT_CONTEXT_DEBUG
fprintf (stderr, "requested string, TC is not TC_CORBA_string! (%u)\n",
}
}
+static Accessible *
+cspi_internal_event_get_object (const InternalEvent *e)
+{
+ CORBA_any *any;
+
+ g_return_val_if_fail (e, NULL);
+ g_return_val_if_fail (e->data, NULL);
+
+ any = (CORBA_any *) e->data;
+ if (CORBA_TypeCode_equal (any->_type, TC_CORBA_Object, cspi_ev()))
+ return cspi_object_take (* (CORBA_Object *) any->_value);
+ else
+ return NULL;
+}
+
/**
- * AccessibleEvent_getContextObject:
+ * AccessibleTextChangedEvent_getChangeString:
+ * @e: a pointer to the #AccessibleEvent being queried.
+ *
+ * Queries an #AccessibleEvent of type "object:text-changed",
+ * returning the text inserted or deleted.
+ *
+ * Returns: a UTF-8 text string indicating the text inserted,
+ * deleted, or substituted by this event.
+ **/
+char *
+AccessibleTextChangedEvent_getChangeString (const AccessibleEvent *e)
+{
+ const InternalEvent *foo = (InternalEvent *) e;
+ /* TODO: check the event type? expensive... */
+ return cspi_internal_event_get_text (foo);
+}
+
+/**
+ * AccessibleTextSelectionChangedEvent_getSelectionString:
* @event: a pointer to the #AccessibleEvent being queried.
*
- * Queries an #AccessibleEvent for an #Accessible whose meaning depends
- * on the event's context, that is, the event type and details.
- * Not all events have context strings, in which case this
- * query returns NULL.
- * Context #Accessible objects may be returned by, for instance:
- * object:child-changed events,
- * in which case they represent the child added or deleted.
+ * Queries an #AccessibleEvent of type "object:text-selection-changed",
+ * returning the newly added, removed, or modified selection string.
+ *
+ * Returns: a UTF-8 text string indicating the recently changed selection.
+ **/
+char *
+AccessibleTextSelectionChangedEvent_getSelectionString (const AccessibleEvent *e)
+{
+ const InternalEvent *foo = (InternalEvent *) e;
+ /* TODO: check the event type? expensive... */
+ return cspi_internal_event_get_text (foo);
+}
+
+/**
+ * AccessibleWindowEvent_getTitleString:
+ * @event: a pointer to the #AccessibleEvent being queried.
+ *
+ * Queries an #AccessibleEvent of type "window:",
+ * returning the window title.
+ *
+ * Returns: a UTF-8 text string representing the title of the
+ * recently changed window.
+ **/
+char *
+AccessibleWindowEvent_getTitleString (const AccessibleEvent *e)
+{
+ const InternalEvent *foo = (InternalEvent *) e;
+ /* TODO: check the event type? expensive... */
+ return cspi_internal_event_get_text (foo);
+}
+
+/**
+ * AccessibleChildChangedEvent_getChildAccessible:
+ * @event: a pointer to the #AccessibleEvent being queried.
+ *
+ * Queries an #AccessibleEvent of type "object:children_changed"
+ * to get a reference to the changed #Accessible.
* Note that context #Accessibles are not guaranteed to outlive
* event delivery, in which case this call may return %NULL
* even if the object existed at the time of dispatch.
*
* Returns: the context #Accessible for the event, or %NULL if
- * there is no context #Accessible object for the event.
+ * there is no longer a valid context #Accessible
+ * object for the event.
**/
Accessible *
-AccessibleEvent_getContextObject (const AccessibleEvent *e)
+AccessibleChildChangedEvent_getChildAccessible (const AccessibleEvent *e)
{
- InternalEvent *foo = (InternalEvent *) e;
- CORBA_any *any;
- g_return_val_if_fail (foo, NULL);
- g_return_val_if_fail (foo->data, NULL);
- any = (CORBA_any *) foo->data;
- if (any->_type == TC_CORBA_Object)
- return cspi_object_add (* (CORBA_Object *) any->_value);
- else
+ const InternalEvent *foo = (InternalEvent *) e;
+ return (Accessible *) cspi_internal_event_get_object (foo);
+}
+
+/**
+ * AccessibleParentChangedEvent_getParentAccessible:
+ * @event: a pointer to the #AccessibleEvent being queried.
+ *
+ * Queries an #AccessibleEvent of type "object:parent_changed"
+ * to get a reference to the changed #Accessible.
+ * Note that context #Accessibles are not guaranteed to outlive
+ * event delivery, in which case this call may return %NULL
+ * even if the object existed at the time of dispatch.
+ *
+ * Returns: an #Accessible pointer representing the new parent object.
+ **/
+Accessible *
+AccessibleParentChangedEvent_getParentAccessible (const AccessibleEvent *e)
+{
+ const InternalEvent *foo = (InternalEvent *) e;
+ return (Accessible *) cspi_internal_event_get_object (foo);
+}
+
+/** NEED TO DOCUMENT THESE **/
+
+Accessible *
+AccessibleActiveDescendantChangedEvent_getActiveDescendant (const AccessibleEvent *e)
+{
+ const InternalEvent *foo = (InternalEvent *) e;
+ return (Accessible *) cspi_internal_event_get_object (foo);
+}
+
+Accessible *
+AccessibleTableSummaryChangedEvent_getSummaryAccessible (const AccessibleEvent *e)
+{
+ const InternalEvent *foo = (InternalEvent *) e;
+ return (Accessible *) cspi_internal_event_get_object (foo);
+}
+
+Accessible *
+AccessibleTableHeaderChangedEvent_getHeaderAccessible (const AccessibleEvent *e)
+{
+ return NULL;
+}
+
+
+char *
+AccessibleTableCaptionChangedEvent_getCaptionString (const AccessibleEvent *e)
+{
+ return NULL;
+}
+
+char *
+AccessibleTableRowDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e)
+{
+ return NULL;
+}
+
+char *
+AccessibleTableColumnDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e)
+{
+ return NULL;
+}
+
+char *
+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, (gpointer) 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);
+ }
+ }
+}