From: Mike Gorse Date: Mon, 23 Jun 2008 22:20:04 +0000 (-0400) Subject: Initial cspi commit X-Git-Tag: AT_SPI2_ATK_2_12_0~666 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6e37a9ea253974a02f72cb65f88007aed0b3c77a;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git Initial cspi commit --- diff --git a/Makefile.am b/Makefile.am index d92ac75..0ac4523 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS=xml idl tests tools droute spi-common atk-adaptor registryd +SUBDIRS=xml idl tools droute spi-common atk-adaptor registryd dbind cspi tests diff --git a/configure.ac b/configure.ac index 72f533c..15a9fec 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,30 @@ AC_INIT([at-spi], [1.9.0], [accessibility-atspi@lists.linux-foundation.org]) + +AT_SPI_MAJOR_VERSION=1 +AT_SPI_MINOR_VERSION=23 +AT_SPI_MICRO_VERSION=3 +AT_SPI_INTERFACE_AGE=0 +AT_SPI_BINARY_AGE=0 +AT_SPI_VERSION="$AT_SPI_MAJOR_VERSION.$AT_SPI_MINOR_VERSION.$AT_SPI_MICRO_VERSION" +AC_SUBST(AT_SPI_MAJOR_VERSION) +AC_SUBST(AT_SPI_MINOR_VERSION) +AC_SUBST(AT_SPI_MICRO_VERSION) +AC_SUBST(AT_SPI_INTERFACE_AGE) +AC_SUBST(AT_SPI_BINARY_AGE) + +# libtool versioning +LT_RELEASE=$AT_SPI_MAJOR_VERSION.$AT_SPI_MINOR_VERSION +LT_CURRENT=10 +LT_REVISION=11 +LT_AGE=10 +LT_VERSION_INFO='-version-info ${LT_CURRENT}:${LT_REVISION}:${LT_AGE}' +AC_SUBST(LT_VERSION_INFO) +AC_SUBST(LT_RELEASE) +AC_SUBST(LT_CURRENT) +AC_SUBST(LT_REVISION) +AC_SUBST(LT_AGE) + AM_INIT_AUTOMAKE([-Wall foreign]) AC_PROG_CC @@ -10,6 +35,14 @@ PKG_PROG_PKG_CONFIG AC_CONFIG_HEADERS([config.h]) +PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.0]) +AC_SUBST(DBUS_LIBS) +AC_SUBST(DBUS_CFLAGS) + +PKG_CHECK_MODULES(GLIB, [glib-2.0]) +AC_SUBST(GLIB_LIBS) +AC_SUBST(GLIB_CFLAGS) + PKG_CHECK_MODULES(DBUS_GLIB, [dbus-glib-1 >= 0.7.0]) AC_SUBST(DBUS_GLIB_LIBS) AC_SUBST(DBUS_GLIB_CFLAGS) @@ -110,9 +143,26 @@ if test -z "$GTK_MODULE_DIR"; then GTK_MODULE_DIR=gtk-2.0/modules fi +dnl find sizes & alignments +orig_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS" +DBIND_CHECK_ALIGNOF(char) +DBIND_CHECK_ALIGNOF(dbus_bool_t) +DBIND_CHECK_ALIGNOF(dbus_int16_t) +DBIND_CHECK_ALIGNOF(dbus_int32_t) +DBIND_CHECK_ALIGNOF(dbus_int64_t) +DBIND_CHECK_ALIGNOF(double) +DBIND_CHECK_ALIGNOF(dbind_pointer) +DBIND_CHECK_ALIGNOF(dbind_struct) +CPPFLAGS=$orig_CPPFLAGS + +#libtool option to strip symbols starting with cspi +# +LIBTOOL_EXPORT_OPTIONS='-export-symbols-regex "^[[^cspi]].*"' +AC_SUBST(LIBTOOL_EXPORT_OPTIONS) + AC_CONFIG_FILES([Makefile xml/Makefile - idl/Makefile tests/Makefile tools/Makefile droute/Makefile @@ -121,6 +171,9 @@ AC_CONFIG_FILES([Makefile atk-adaptor/Makefile tests/dummyatk/Makefile tests/clients/Makefile - tests/apps/Makefile]) + tests/apps/Makefile + dbind/Makefile + cspi/Makefile + dbind-config.h]) AC_OUTPUT diff --git a/cspi/Makefile.am b/cspi/Makefile.am new file mode 100644 index 0000000..c251fc0 --- /dev/null +++ b/cspi/Makefile.am @@ -0,0 +1,43 @@ +NULL= + +lib_LTLIBRARIES = libcspi.la + +libcspi_la_LDFLAGS = @LDFLAGS@ @LT_VERSION_INFO@ @LIBTOOL_EXPORT_OPTIONS@ -no-undefined + +libcspi_la_CFLAGS = $(DBUS_GLIB_CFLAGS) $(ATK_CFLAGS) -I$(top_srcdir) + +LDADD = $(DBUS_GLIB_LIBS) \ + $(top_builddir)/spi-common/libspicommon.la + +libcspidir = $(includedir)/at-spi-1.0/cspi +libcspi_HEADERS = \ + spi.h \ + spi-impl.h \ + spi-listener.h \ + spi-roletypes.h \ + spi-statetypes.h + +libcspi_la_SOURCES = \ + cspi-lowlevel.h \ + spi_accessible.c \ + spi_action.c \ + spi_component.c \ + spi_editabletext.c \ + spi_event.c \ + spi_hyperlink.c \ + spi_hypertext.c \ + spi_listener.c \ + spi_main.c \ + spi_registry.c \ + spi_selection.c \ + spi_stateset.c \ + spi_streamablecontent.c \ + spi_table.c \ + spi_text.c \ + spi_value.c \ + spi-private.h + +libcspi_la_LIBADD = \ + $(top_builddir)/spi-common/libspicommon.la \ + $(top_builddir)/dbind/libdbind.la\ + $(LIBCSPI_LIBS) $(X_LIBS) diff --git a/cspi/spi-impl.h b/cspi/spi-impl.h new file mode 100644 index 0000000..60049b3 --- /dev/null +++ b/cspi/spi-impl.h @@ -0,0 +1,100 @@ +/* + * 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. + * + * 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. + */ + +/* + * A load of opaque handles that people can't poke at. + */ +#ifndef _SPI_IMPL_H_ +#define _SPI_IMPL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _Accessible AccessibleUnknown; +typedef AccessibleUnknown Accessible; + +typedef Accessible AccessibleAction; +typedef Accessible AccessibleApplication; +typedef Accessible AccessibleCollection; +typedef Accessible AccessibleComponent; +typedef Accessible AccessibleDocument; +typedef Accessible AccessibleEditableText; +typedef Accessible AccessibleHyperlink; +typedef Accessible AccessibleHypertext; +typedef Accessible AccessibleImage; +typedef Accessible AccessibleMatchRule; + +typedef struct _AccessibleRelation AccessibleRelation; +struct _AccessibleRelation +{ + gint ref_count; + Accessibility_RelationType type; + GArray *targets; +}; + +typedef Accessible AccessibleSelection; +typedef Accessible AccessibleStreamableContent; +typedef Accessible AccessibleTable; +typedef Accessible AccessibleText; +typedef Accessible AccessibleValue; +typedef Accessible AccessibilityRegistry; + +/** + * AccessibleStateSet: + * @ref_count: private + * @states: private + * + * An opaque structure representing an accessible object's state, + * which can then be queried via AccessibleStateSet APIs. + **/ +typedef void AccessibleStateSet; +typedef void AccessibleEventListener; +typedef void AccessibleKeystrokeListener; +typedef void AccessibleDeviceListener; + +typedef unsigned int SPIBoolean; +#define SPI_FALSE (0) +#define SPI_TRUE (!SPI_FALSE) + +/** + * SPIRect: + * @x: The position of the minimum x value of the rectangle (i.e. left hand corner) + * @y: The position of the minimum y value of the rectangle's bounds. + * @width: Width of the rectangle in pixels. + * @height: Height of the rectangle in pixels. + * + * A structure encapsulating a rectangle. + **/ +typedef struct { + long x; + long y; + long width; + long height; +} SPIRect; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cspi/spi-listener.h b/cspi/spi-listener.h new file mode 100644 index 0000000..862a646 --- /dev/null +++ b/cspi/spi-listener.h @@ -0,0 +1,220 @@ +/* + * 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. + * + * 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. + */ + +#ifndef _SPI_LISTENER_H_ +#define _SPI_LISTENER_H_ + +#include +#include +#include "spi-common/spi-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + EVENT_DATA_STRING, + EVENT_DATA_OBJECT, + EVENT_DATA_RECT +} EVENT_DATA_TYPE; + +/** + * AccessibleEvent: + * @type: a string representing the type of the event, with increasing specificity + * from left to right, delimited by colons. Leftmost token represents event source type, + * next token represents event category, and next token represents the subcategory + * of the event, for instance the specific property, state, or attribute being notified. + * @source: The #Accessible from which the event originated. + * @detail1: an event-type-specific integer value. + * @detail2: an event-type-specific integer value. + * + * A structure used to encapsulate event information. + **/ +typedef struct { + const char *type; + Accessible *source; + long detail1; + long detail2; + EVENT_DATA_TYPE v_type; + union + { + char *text; + Accessible *accessible; + SPIRect rect; + } v; +} AccessibleEvent; + +/** + *AccessibleDeviceEventType: + *@SPI_KEY_PRESSED: A device key has been pressed. + *@SPI_KEY_RELEASED: A device key has been released. + *@SPI_BUTTON_PRESSED: A device button or switch (other than a keyboard key) + * has been pressed. + *@SPI_BUTTON_RELEASED: A device button or switch has been released. + * + *The type of an AccessibleDeviceEvent. + **/ +typedef enum { + SPI_KEY_PRESSED = 1<<0, + SPI_KEY_RELEASED = 1<<1, + SPI_BUTTON_PRESSED = 1<<2, + SPI_BUTTON_RELEASED = 1<<3 +} AccessibleDeviceEventType; + +/** + *AccessibleKeyEventType: + * + *This is a synonym for AccessibleDeviceEventType + **/ +typedef AccessibleDeviceEventType AccessibleKeyEventType; + +/** + * AccessibleDeviceEvent: + * @keyID: Symbolic representation for the key or switch generating the event, e.g. keysym or button number. + * @keystring: A symbolic name for the key or switch, or, if is_text is true, a string approximating the + * inserted text characters which would result from this event, if a text entry field has keyboard focus. + * @timestamp: A time in ms when this event occurred, relative to some unspecified starting point. + * Timestamp values should therefore be used to compare events but should not be tested against a + * fixed time. + * @type: The #AccessibleDeviceEventType identifying the specific type of event. + * @is_text: A boolean value indicating whether the event represents 'printable' text (i.e. whether it + * changes the current insertion buffer of a focussed text entry component or not). Whitespace + * is considered "printable" in this context, since it typically inserts characters into the buffer. + * + * A structure encapsulating information relevant to a device event notification. + **/ +typedef struct { + long keyID; + short keycode; + char * keystring; + long timestamp; + AccessibleDeviceEventType type; + unsigned short modifiers; + SPIBoolean is_text; +} AccessibleDeviceEvent; + +typedef AccessibleDeviceEvent AccessibleKeystroke; + +/* + * Function prototype typedefs for Event Listener Callbacks. + * (see libspi/accessibleeventlistener.h for definition of SpiVoidEventListenerCB). + * + * usage: signatures should be + * void (*AccessibleEventListenerCB) (AccessibleEvent *event); + * + * SPIBoolean (*AccessibleKeystrokeListenerCB) (AccessibleKeystrokeEvent *Event); + * Note that AccessibleKeystrokeListeners may consume the event received + * if one of their callbacks returns TRUE (see SPI_registerAccessibleKeystrokeListener) + */ + +/** + * AccessibleEventListenerCB: + * @event: The event for which notification is sent. + * @user_data: User data which is passed to the callback each time a notification takes place. + * + * A function prototype for callbacks via which clients are notified of AT-SPI events. + * + **/ +typedef void (*AccessibleEventListenerCB) (const AccessibleEvent *event, + void *user_data); +/** + * AccessibleKeystrokeListenerCB: + * @stroke: the #AccessibleKeystroke event for which notification is taking place. + * @user_data: data passed to the callback each time it is notified, according to the data + * which was passed in when the listener/callback was registered. + * + * A function prototype for a callback function called when a key event notification takes place. + * + * Returns: %TRUE if the client wishes to consume the event and prevent its + * dispatch to other listeners or the currently focussed application, if + * the relevant callback was registered with the #SPI_KEYLISTENER_CANCONSUME flag. + **/ +typedef SPIBoolean (*AccessibleKeystrokeListenerCB) (const AccessibleKeystroke *stroke, + void *user_data); +/** + * AccessibleDeviceListenerCB: + * @stroke: The #AccessibleDeviceEvent for which notification is being received. + * @user_data: Data which is passed to the client each time this callback is notified. + * + * A callback function prototype via which clients receive device event notifications. + * + * Returns: %TRUE if the client wishes to consume/preempt the event, preventing it from being + * relayed to the currently focussed application, %FALSE if the event delivery should proceed as normal. + **/ +typedef SPIBoolean (*AccessibleDeviceListenerCB) (const AccessibleDeviceEvent *stroke, + void *user_data); + +#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)) +#define CSPI_EVENT_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CSPI_EVENT_LISTENER_TYPE, CSpiEventListenerClass)) + +typedef struct { + GObject parent; + GList *callbacks; +} CSpiEventListener; + +typedef struct { + GObjectClass parent_class; + + /* signals */ + void (*event) (CSpiEventListener *listener, + AccessibleEvent *e); +} CSpiEventListenerClass; + +GType cspi_event_listener_get_type (void); + +#define CSPI_DEVICE_LISTENER_TYPE (cspi_device_listener_get_type ()) +#define CSPI_DEVICE_LISTENER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_DEVICE_LISTENER_TYPE, CSpiDeviceListener)) +#define CSPI_DEVICE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CSPI_DEVICE_LISTENER_TYPE, CSpiDeviceListenerClass)) +#define CSPI_IS_DEVICE_LISTENER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_DEVICE_LISTENER_TYPE)) +#define CSPI_IS_DEVICE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_DEVICE_LISTENER_TYPE)) +#define CSPI_DEVICE_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CSPI_DEVICE_LISTENER_TYPE, CSpiDeviceListenerClass)) + +typedef struct { + GObject parent; + guint id; + GList *callbacks; +} CSpiDeviceListener; + +typedef struct { + GObjectClass parent_class; + gboolean (*device_event) (CSpiDeviceListener *listener, const Accessibility_DeviceEvent *key); +} CSpiDeviceListenerClass; + +GType cspi_device_listener_get_type (void); +gpointer cspi_device_listener_new (void); +void cspi_device_listener_add_cb (AccessibleDeviceListener *al, + AccessibleDeviceListenerCB callback, + void *user_data); +void cspi_device_listener_remove_cb (AccessibleDeviceListener *al, + AccessibleDeviceListenerCB callback); +void cspi_device_listener_unref (AccessibleDeviceListener *listener); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cspi/spi-private.h b/cspi/spi-private.h new file mode 100644 index 0000000..3e8926c --- /dev/null +++ b/cspi/spi-private.h @@ -0,0 +1,122 @@ +/* + * AT-SPI - Assistive Technology Service Provider Interface + * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) + * + * Copyright 2002 Ximian, Inc. + * 2002 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 + * 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. + */ + +#ifndef _SPI_PRIVATE_H_ +#define _SPI_PRIVATE_H_ + +/* Private internal implementation details of at-spi. */ + +#include +#include +#include +#include "cspi/cspi-lowlevel.h" +#include "cspi/spi-listener.h" +#include "dbind/dbind.h" +#include + +typedef struct _CSpiApplication CSpiApplication; +struct _CSpiApplication +{ + GHashTable *hash; + char *bus_name; +}; + +struct _Accessible { + gint ref_count; + Accessible *parent; + GList *children; + CSpiApplication *app; + union + { + gint id; + char *path; + } v; + gint role : 8; + gint interfaces : 24; + char *name; + char *description; +}; + +struct _AccessibleStateSet { + guint ref_count; + GArray *states; +}; + +#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; +} InternalEvent; + +struct _SPIException { + SPIExceptionType type; + Accessible *source; + DBusError *error; + SPIExceptionCode code; + char * desc; +}; + +DBusConnection *spi_bus (void); +SPIBoolean cspi_exception (void); +Accessible *cspi_object_add (Accessible *accessible); +void cspi_object_ref (Accessible *accessible); +void cspi_object_unref (Accessible *accessible); +SPIBoolean cspi_accessible_is_a (Accessible *accessible, + const char *interface_name); +AccessibleRole cspi_role_from_spi_role (Accessibility_Role role); +void cspi_streams_close_all (void); +gboolean cspi_exception_throw (DBusError *error, char *desc_prefix); + +AccessibleAttributeSet + *_cspi_attribute_set_from_sequence (const GArray *seq); +#define cspi_return_if_fail(val) \ + if (!(val)) \ + return +#define cspi_return_val_if_fail(val, ret) \ + if (!(val)) \ + return (ret) + +#define cspi_return_if_ev(err) \ + if (cspi_exception ()) \ + return; +#define cspi_return_val_if_ev(err, ret) \ + if (cspi_exception ()) \ + return (ret); + +typedef struct _Accessibility_BoundingBox Accessibility_BoundingBox; +struct _Accessibility_BoundingBox +{ + dbus_uint32_t x; + dbus_uint32_t y; + dbus_uint32_t width; + dbus_uint32_t height; +}; + +#endif /* _SPI_PRIVATE_H_ */ diff --git a/cspi/spi.h b/cspi/spi.h new file mode 100644 index 0000000..619b59b --- /dev/null +++ b/cspi/spi.h @@ -0,0 +1,1230 @@ +/* + * 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. + * + * 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. + */ + +#ifndef _SPI_H +#define _SPI_H + +#include +/* + * Definitions for AccessibleRole, AccessibleState, + * and event listeners. + */ +#include +#include +#include + + +/* + * Auxiliary typedefs and mask definitions + */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + *AccessibleCollectionMatchType: + * + *@SPI_COLLECTION_MATCH_INVALID + *@SPI_COLLECTION_MATCH_ALL TRUE if all of the criteria are met + *@SPI_COLLECTION_MATCH_ANY TRUE if any of the criteria are met + *@SPI_COLLECTION_MATCH_NONE TRUE if none of the criteria are met + *@SPI_COLLECTION_MATCH_EMPTY Same as MATCH_ALL if the criteria is non-empty; + * for empty criteria this rule requires returned value to also have empty set. + *@SPI_COLLECTION_MATCH_LAST_DEFINED + * + **/ +typedef enum +{ + SPI_COLLECTION_MATCH_INVALID, + SPI_COLLECTION_MATCH_ALL, + SPI_COLLECTION_MATCH_ANY, + SPI_COLLECTION_MATCH_NONE, + SPI_COLLECTION_MATCH_EMPTY, + SPI_COLLECTION_MATCH_LAST_DEFINED +}AccessibleCollectionMatchType; + + +/** + *AccessibleTextBoundaryType: + *@SPI_TEXT_BOUNDARY_CHAR: Delimiter is the current character's bounds. + *@SPI_TEXT_BOUNDARY_CURSOR_POS: Delimiter is the current text caret position. + *@SPI_TEXT_BOUNDARY_WORD_START: Bounds run from the first character of a word to the first + * character of the following word (i.e. including trailing whitespace, if any) within the text object. + *@SPI_TEXT_BOUNDARY_WORD_END: Bounds run from the last character of a word to the last + * character of the following word (i.e. including leading whitespace) within the text object. + *@SPI_TEXT_BOUNDARY_SENTENCE_START: Bounds run from the first character of a sentence to the first + * character of the next sentence in the text object. + *@SPI_TEXT_BOUNDARY_SENTENCE_END: Bounds run from the last character of a sentence to the last + * character of the next sentence in the text object. + *@SPI_TEXT_BOUNDARY_LINE_START: Bounds span one line of text, with the line delimiter at the end of the + * bounds, if present, within the current text object. + *@SPI_TEXT_BOUNDARY_LINE_END: Bounds span one line of text, including a preceding line delimiter + * if present within the current text object. + *@SPI_TEXT_BOUNDARY_ATTRIBUTE_RANGE: Bounds span the run, relative to the specified offset and + * text accessor API rules, over which the attributes of the text object are invariant. + * + *Text boundary types used for specifying boundaries for regions of text. + **/ +typedef enum +{ + SPI_TEXT_BOUNDARY_CHAR, + SPI_TEXT_BOUNDARY_CURSOR_POS, + SPI_TEXT_BOUNDARY_WORD_START, + SPI_TEXT_BOUNDARY_WORD_END, + SPI_TEXT_BOUNDARY_SENTENCE_START, + SPI_TEXT_BOUNDARY_SENTENCE_END, + SPI_TEXT_BOUNDARY_LINE_START, + SPI_TEXT_BOUNDARY_LINE_END, + SPI_TEXT_BOUNDARY_ATTRIBUTE_RANGE +} AccessibleTextBoundaryType; + +/** + *AccessibleTextClipType + *@SPI_TEXT_CLIP_NONE: No clipping to be done + *@SPI_TEXT_CLIP_MIN: Text clipped by min coordinate is omitted + *@SPI_TEXT_CLIP_MAX: Text clipped by max coordinate is omitted + *@SPI_TEXT_CLIP_BOTH: Only text fully within mix/max bound is retained + * + *Describes the type of clipping required. + **/ +typedef enum +{ + SPI_TEXT_CLIP_NONE, + SPI_TEXT_CLIP_MIN, + SPI_TEXT_CLIP_MAX, + SPI_TEXT_CLIP_BOTH +} AccessibleTextClipType; + +/** + *AccessibleRelationType: + *@SPI_RELATION_NULL: Not used, this is an invalid value for this enumeration. + *@SPI_RELATION_LABEL_FOR: Indicates an object is a label for one or more target objects. + *@SPI_RELATION_LABELED_BY: Indicates an object is labelled by one or more target objects. + *@SPI_RELATION_CONTROLLED_BY: Indicates an object controlled by one or more target objects. + *@SPI_RELATION_CONTROLLER_FOR: Indicates an object is an controller for one or more target objects. + *@SPI_RELATION_MEMBER_OF: Indicates an object is a member of a group of one or +more target objects. + *@SPI_RELATION_NODE_CHILD_OF: Indicates an object is a cell in a treetable which is displayed because a cell in the same column is expanded and identifies that cell. + *@SPI_RELATION_EXTENDED: This value indicates that a relation other than those pre-specified by this version of AT-SPI + * is present. + *@SPI_RELATION_FLOWS_TO: Indicates that the object has content that flows logically to another + * AtkObject in a sequential way, (for instance text-flow). + *@SPI_RELATION_FLOWS_FROM: Indicates that the object has content that flows logically from + * another AtkObject in a sequential way, (for instance text-flow). + *@SPI_RELATION_SUBWINDOW_OF: Indicates a subwindow attached to a component but otherwise has no connection in the UI heirarchy to that component. + *@SPI_RELATION_EMBEDS: Indicates that the object visually embeds + * another object's content, i.e. this object's content flows around + * another's content. + *@SPI_RELATION_EMBEDDED_BY: Inverse of %SPI_RELATION_EMBEDS, indicates that + * this object's content is visualy embedded in another object. + *@SPI_RELATION_POPUP_FOR: Indicates that an object is a popup for another object. + *@SPI_RELATION_PARENT_WINDOW_OF: Indicates that an object is a parent window of another object. + *@SPI_RELATION_DESCRIBED_BY: Indicates that another object provides descriptive information about this object; more verbose than %SPI_RELATION_LABELLED_BY. + *@SPI_RELATION_DESCRIPTION_FOR: Indicates that an object provides descriptive information about another object; more verbose than %SPI_RELATION_LABEL_FOR. + *@SPI_RELATION_LAST_DEFINED: Do not use, this is an implementation detail used + * to identify the size of this enumeration. + * + *Describes the type of the relation + **/ +typedef enum +{ + SPI_RELATION_NULL, + SPI_RELATION_LABEL_FOR, + SPI_RELATION_LABELED_BY, + SPI_RELATION_CONTROLLER_FOR, + SPI_RELATION_CONTROLLED_BY, + SPI_RELATION_MEMBER_OF, + SPI_RELATION_NODE_CHILD_OF, + SPI_RELATION_EXTENDED, + SPI_RELATION_FLOWS_TO, + SPI_RELATION_FLOWS_FROM, + SPI_RELATION_SUBWINDOW_OF, + SPI_RELATION_EMBEDS, + SPI_RELATION_EMBEDDED_BY, + SPI_RELATION_POPUP_FOR, + SPI_RELATION_PARENT_WINDOW_OF, + SPI_RELATION_DESCRIPTION_FOR, + SPI_RELATION_DESCRIBED_BY, + SPI_RELATION_LAST_DEFINED +} AccessibleRelationType; + + +/* don't change the order of these ! */ +/** + *AccessibleCoordType: + *@SPI_COORD_TYPE_SCREEN: specifies xy coordinates relative to the screen + *@SPI_COORD_TYPE_WINDOW: specifies xy coordinates relative to an object's + * top-level window + * + *Specifies how xy coordinates are to be interpreted. Used by functions such + *as AccessibleComponent_getPosition() and AccessibleText_getCharacterExtents() + **/ +typedef enum { + SPI_COORD_TYPE_SCREEN, + SPI_COORD_TYPE_WINDOW +} AccessibleCoordType; + +/** + *AccessibleKeySynthType: + *@SPI_KEY_PRESS: Generates a keypress event (requires a subsequent #SPI_KEY_RELEASE event) + *@SPI_KEY_RELEASE: Generates a key-release event + *@SPI_KEY_PRESSRELEASE: Generates a key press/release event pair. + *@SPI_KEY_SYM: Injects a "keysym" event into the stream, as if a press/release pair occurred; allows + * the user to specify the key via its symbolic name, as opposed to simulating a hardware press of a + * specific key. + *@SPI_KEY_STRING: Injects one or more keysym events into the keyboard buffer, or directly inserts + * a string value into the currently focussed text widget, if the widgets supports this. + * #SPI_KEY_STRING synthesis provides a shortcut for text substring insertion, and also allows the + * insertion of text which is not currently available via the current keyboard's keymap. + * + * Specifies the type of a generated event. + **/ +typedef enum { + SPI_KEY_PRESS, + SPI_KEY_RELEASE, + SPI_KEY_PRESSRELEASE, + SPI_KEY_SYM, + SPI_KEY_STRING +} AccessibleKeySynthType; + +/** + *AccessibleKeyListenerSyncType: + *@SPI_KEYLISTENER_NOSYNC: Events may be delivered asynchronously, + * which means in some cases they may already have been delivered to the + * application before the AT client receives the notification. + *@SPI_KEYLISTENER_SYNCHRONOUS: Events are delivered synchronously, before the + * currently focussed application sees them. + *@SPI_KEYLISTENER_CANCONSUME: Events may be consumed by the AT client. Presumes and + * requires #SPI_KEYLISTENER_SYNCHRONOUS, incompatible with #SPI_KEYLISTENER_NOSYNC. + *@SPI_KEYLISTENER_ALL_WINDOWS: Events are received not from the application toolkit layer, but + * from the device driver or windowing system subsystem; such notifications are 'global' in the + * sense that they are not broken or defeated by applications that participate poorly + * in the accessibility APIs, or not at all; however because of the intrusive nature of + * such snooping, it can have side-effects on certain older platforms. If unconditional + * event notifications, even when inaccessible or "broken" applications have focus, are not + * required, it may be best to avoid this enum value/flag. + * + *Specified the tyupe of a key listener event. + * Certain of the values above can and should be bitwise-'OR'ed + * together, observing the compatibility limitations specified in the description of + * each value. For instance, #SPI_KEYLISTENER_ALL_WINDOWS | #SPI_KEYLISTENER_CANCONSUME is + * a commonly used combination which gives the AT complete control over the delivery of matching + * events. However, such filters should be used sparingly as they may have a negative impact on + * system performance. + **/ +typedef enum { + SPI_KEYLISTENER_NOSYNC = 0, + SPI_KEYLISTENER_SYNCHRONOUS = 1, + SPI_KEYLISTENER_CANCONSUME = 2, + SPI_KEYLISTENER_ALL_WINDOWS = 4 +} AccessibleKeyListenerSyncType; + + +/** + *AccessibleStreamableContentSeekType + *@SPI_STREAM_SEEK_SET: seek from the 'top' of the streamable + *@SPI_STREAM_SEEK_CUR: seek from the current position in the stream + *@SPI_STREAM_SEEK_END: seek from the end of the stream (if known) + * + *The seek type for a specified offset in AccessibleStreamableContent_seek. + **/ +typedef enum +{ + SPI_STREAM_SEEK_SET, + SPI_STREAM_SEEK_CUR, + SPI_STREAM_SEEK_END +} AccessibleStreamableContentSeekType; + +/** + * SPIException: + * @type: private + * @source: private + * @ev: private + * @code: private + * @desc: private + * + * An opaque object encapsulating information about thrown exceptions. + **/ +typedef struct _SPIException SPIException; + +/** + * SPIExceptionHandler: + * @err: points to the SPIException opaque object. + * @is_fatal: indicates whether the exception is a fatal error or not. + * + * A function type for functions to be called when exceptions occur. + * + * Returns + **/ +typedef SPIBoolean (*SPIExceptionHandler) (SPIException *err, SPIBoolean is_fatal); + +/** + * SPIExceptionCode: + * @SPI_EXCEPTION_UNSPECIFIED: An exception of unknown type, or which doesn't fit the other types. + * @SPI_EXCEPTION_DISCONNECT: Communication with the object or service has been disconnected; + * this usually means that the object or service has died or exited. + * @SPI_EXCEPTION_NO_IMPL: The object or service is missing the implementation for a request. + * @SPI_EXCEPTION_IO: The communications channel has become corrupted, blocked, or is otherwise in a bad state. + * @SPI_EXCEPTION_BAD_DATA: The data received or sent over the interface has been identified as + * improperly formatted or otherwise fails to match the expectations. + * + * Exception codes indicating what's gone wrong in an AT-SPI call. + **/ +typedef enum { + SPI_EXCEPTION_UNSPECIFIED, + SPI_EXCEPTION_DISCONNECT, + SPI_EXCEPTION_NO_IMPL, + SPI_EXCEPTION_IO, + SPI_EXCEPTION_BAD_DATA +} SPIExceptionCode; + +/** + * SPIExceptionType: + * @SPI_EXCEPTION_SOURCE_UNSPECIFIED: Don't know or can't tell where the problem is + * @SPI_EXCEPTION_SOURCE_ACCESSIBLE: The source of an event or query (i.e. an app) has thrown the exception. + * @SPI_EXCEPTION_SOURCE_REGISTRY: The AT-SPI registry has thrown the exception or cannot be reached. + * @SPI_EXCEPTION_SOURCE_DEVICE: The device event subsystem has encountered an error condition. + * + * The general source of the failure, i.e. whether the app, registry, or device system has encountered trouble. + **/ +typedef enum { + SPI_EXCEPTION_SOURCE_UNSPECIFIED, + SPI_EXCEPTION_SOURCE_ACCESSIBLE, + SPI_EXCEPTION_SOURCE_REGISTRY, + SPI_EXCEPTION_SOURCE_DEVICE +} SPIExceptionType; + +typedef unsigned long AccessibleKeyEventMask; +typedef unsigned long AccessibleDeviceEventMask; + +/** + *AccessibleComponentLayer: + *@SPI_LAYER_INVALID: The layer cannot be determined or is somehow undefined. + *@SPI_LAYER_BACKGROUND: Component belongs to the destop background. + *@SPI_LAYER_CANVAS: Component is a canvas backdrop or drawing area. + *@SPI_LAYER_WIDGET: Component is a 'normal' widget. + *@SPI_LAYER_MDI: Component is drawn in the MDI layer and may have valid + * Z-information relative to other MDI-layer components. + *@SPI_LAYER_POPUP: Component is in the popup layer, above other widgets and + * MDI components. + *@SPI_LAYER_OVERLAY: Component is in the overlay plane - this value is reserved + * for future use. + *@SPI_LAYER_WINDOW: Component is in the window layer and have valid Z-information + * relative to other window-layer components. + *@SPI_LAYER_LAST_DEFINED: Used to determine the last valid value in the enum, + * should not be encountered. + * + * Describes the layer of a component. + * + * These enumerated "layer values" are used when determining which UI + * rendering layer a component is drawn into, which can help in making + * determinations of when components occlude one another. + **/ +typedef enum { + SPI_LAYER_INVALID, + SPI_LAYER_BACKGROUND, + SPI_LAYER_CANVAS, + SPI_LAYER_WIDGET, + SPI_LAYER_MDI, + SPI_LAYER_POPUP, + SPI_LAYER_OVERLAY, + SPI_LAYER_WINDOW, + SPI_LAYER_LAST_DEFINED +} AccessibleComponentLayer; + + +/** + * AccessibleTextRange: + * @start: the first nominal character position within the range. + * @end: the first nominal character position following the range. + * @content: The actual text content between @start and @end, as a UTF-8 string. + * + * Structure which encapsulates a text range - must be associated with an + * AccessibleText-implementing object. + **/ +typedef struct _AccessibleTextRange +{ + long int start; + long int end; + char *contents; +} AccessibleTextRange; + +/** + * AccessibleKeySet: + * @keysyms: + * @keycodes: + * @len: + * + * Structure containing identifying information about a set of keycode or + * keysyms. + **/ +typedef struct _AccessibleKeySet +{ + unsigned long *keysyms; + unsigned short *keycodes; + char **keystrings; + short len; +} AccessibleKeySet; + +/* + * A special value for an AccessibleKeySet type, which tacitly + * includes all keycodes and keyvals for the specified modifier set. + */ +#define SPI_KEYSET_ALL_KEYS NULL + +typedef unsigned long AccessibleModifierMaskType; +/** + *AccessibleKeyMaskType: + * + *AccessibleKeyMaskType is a mask which is a set of key event modifiers + *which is specified in SPI_registerAccessibleKeystrokeListener. + **/ + +typedef AccessibleModifierMaskType AccessibleKeyMaskType; + +typedef struct _AccessibleAttributeSet +{ + int len; + char **attributes; +} AccessibleAttributeSet; + +typedef struct _AccessibleRoleSet +{ + int len; + AccessibleRole *roles; +} AccessibleRoleSet; + + + +/* Basic SPI initialization and event loop function prototypes */ + +int SPI_init (void); +void SPI_event_main (void); +void SPI_event_quit (void); +SPIBoolean SPI_eventIsReady (void); +AccessibleEvent *SPI_nextEvent (SPIBoolean waitForEvent); +int SPI_exit (void); + +/* Event Listener creation and support. */ + +void SPI_freeAccessibleKeySet ( + AccessibleKeySet *keyset); +AccessibleKeySet * SPI_createAccessibleKeySet ( + int len, + const char *keysyms, + short *keycodes, + const char **keystrings); +AccessibleEventListener * SPI_createAccessibleEventListener ( + AccessibleEventListenerCB callback, + void *user_data); +SPIBoolean AccessibleEventListener_addCallback ( + AccessibleEventListener *listener, + AccessibleEventListenerCB callback, + void *user_data); +SPIBoolean AccessibleEventListener_removeCallback ( + AccessibleEventListener *listener, + AccessibleEventListenerCB callback); +void AccessibleEventListener_unref ( + AccessibleEventListener *listener); + +/* Device Event Listener creation and support. */ + +/* First four are deprecated in favor of the last four; really just a re-name */ + +AccessibleKeystrokeListener * SPI_createAccessibleKeystrokeListener ( + AccessibleKeystrokeListenerCB callback, + void *user_data); +SPIBoolean AccessibleKeystrokeListener_addCallback ( + AccessibleKeystrokeListener *listener, + AccessibleKeystrokeListenerCB callback, + void *user_data); +SPIBoolean AccessibleKeystrokeListener_removeCallback ( + AccessibleKeystrokeListener *listener, + AccessibleKeystrokeListenerCB callback); +void AccessibleKeystrokeListener_unref ( + AccessibleKeystrokeListener *listener); + +AccessibleDeviceListener * SPI_createAccessibleDeviceListener ( + AccessibleDeviceListenerCB callback, + void *user_data); +SPIBoolean AccessibleDeviceListener_addCallback ( + AccessibleDeviceListener *listener, + AccessibleDeviceListenerCB callback, + void *user_data); +SPIBoolean AccessibleDeviceListener_removeCallback ( + AccessibleDeviceListener *listener, + AccessibleDeviceListenerCB callback); +void AccessibleDeviceListener_unref ( + AccessibleDeviceListener *listener); + +/* Global functions serviced by the registry */ + +SPIBoolean SPI_registerGlobalEventListener ( + AccessibleEventListener *listener, + const char *eventType); +SPIBoolean SPI_deregisterGlobalEventListener ( + AccessibleEventListener *listener, + const char *eventType); +SPIBoolean SPI_deregisterGlobalEventListenerAll ( + AccessibleEventListener *listener); +SPIBoolean SPI_registerAccessibleKeystrokeListener ( + AccessibleKeystrokeListener *listener, + AccessibleKeySet *keys, + AccessibleKeyMaskType modmask, + AccessibleKeyEventMask eventmask, + AccessibleKeyListenerSyncType sync_type); +SPIBoolean SPI_deregisterAccessibleKeystrokeListener ( + AccessibleKeystrokeListener *listener, + AccessibleKeyMaskType modmask); + +SPIBoolean SPI_registerDeviceEventListener ( + AccessibleDeviceListener *listener, + AccessibleDeviceEventMask eventmask, + void *filter); +SPIBoolean SPI_deregisterDeviceEventListener ( + AccessibleDeviceListener *listener, + void *filter); + +int SPI_getDesktopCount (void); +Accessible *SPI_getDesktop (int i); +int SPI_getDesktopList (Accessible ***desktop_list); +void SPI_freeDesktopList (Accessible **desktop_list); + +SPIBoolean SPI_generateKeyboardEvent (long int keyval, + char *keystring, + AccessibleKeySynthType synth_type); + +SPIBoolean SPI_generateMouseEvent (long int x, long int y, char *name); + +/* Accessible function prototypes */ + +void Accessible_ref (Accessible *obj); +void Accessible_unref (Accessible *obj); +char * Accessible_getName (Accessible *obj); +char * Accessible_getDescription (Accessible *obj); +Accessible * Accessible_getParent (Accessible *obj); +long Accessible_getChildCount (Accessible *obj); +Accessible * Accessible_getChildAtIndex (Accessible *obj, + long int childIndex); +long Accessible_getIndexInParent (Accessible *obj); +AccessibleRelation **Accessible_getRelationSet (Accessible *obj); +AccessibleRole Accessible_getRole (Accessible *obj); +char * Accessible_getRoleName (Accessible *obj); +char * Accessible_getLocalizedRoleName (Accessible *obj); +AccessibleStateSet * Accessible_getStateSet (Accessible *obj); +AccessibleAttributeSet *Accessible_getAttributes (Accessible *obj); +AccessibleApplication *Accessible_getHostApplication (Accessible *obj); + +/* Interface query methods */ + +SPIBoolean Accessible_isAction (Accessible *obj); +SPIBoolean Accessible_isApplication (Accessible *obj); +SPIBoolean Accessible_isCollection (Accessible *obj); +SPIBoolean Accessible_isComponent (Accessible *obj); +SPIBoolean Accessible_isDocument (Accessible *obj); +SPIBoolean Accessible_isEditableText (Accessible *obj); +SPIBoolean Accessible_isHypertext (Accessible *obj); +SPIBoolean Accessible_isImage (Accessible *obj); +SPIBoolean Accessible_isMatchRule (Accessible *obj); +SPIBoolean Accessible_isSelection (Accessible *obj); +SPIBoolean Accessible_isStreamableContent (Accessible *obj); +SPIBoolean Accessible_isTable (Accessible *obj); +SPIBoolean Accessible_isText (Accessible *obj); +SPIBoolean Accessible_isValue (Accessible *obj); + +AccessibleAction * Accessible_getAction (Accessible *obj); +AccessibleApplication * Accessible_getApplication (Accessible *obj); +AccessibleCollection * Accessible_getCollection (Accessible *obj); +AccessibleComponent * Accessible_getComponent (Accessible *obj); +AccessibleDocument * Accessible_getDocument (Accessible *obj); +AccessibleEditableText * Accessible_getEditableText (Accessible *obj); +AccessibleHypertext * Accessible_getHypertext (Accessible *obj); +AccessibleImage * Accessible_getImage (Accessible *obj); +AccessibleMatchRule * Accessible_getMatchRule (Accessible *obj); +AccessibleSelection * Accessible_getSelection (Accessible *obj); +AccessibleStreamableContent * Accessible_getStreamableContent (Accessible *obj); +AccessibleTable * Accessible_getTable (Accessible *obj); +AccessibleText * Accessible_getText (Accessible *obj); +AccessibleValue * Accessible_getValue (Accessible *obj); +AccessibleUnknown * Accessible_queryInterface (Accessible *obj, + const char *interface_name); + +/* AccessibleAction function prototypes */ + +void AccessibleAction_ref (AccessibleAction *obj); +void AccessibleAction_unref (AccessibleAction *obj); +long AccessibleAction_getNActions (AccessibleAction *obj); +char *AccessibleAction_getName (AccessibleAction *obj, + long int i); +char *AccessibleAction_getDescription (AccessibleAction *obj, + long int i); +SPIBoolean AccessibleAction_doAction (AccessibleAction *obj, + long int i); +char *AccessibleAction_getKeyBinding (AccessibleAction *obj, + long int i); + +/* AccessibleApplication function prototypes */ + +void AccessibleApplication_ref (AccessibleApplication *obj); +void AccessibleApplication_unref (AccessibleApplication *obj); +char *AccessibleApplication_getToolkitName (AccessibleApplication *obj); +char *AccessibleApplication_getVersion (AccessibleApplication *obj); +long AccessibleApplication_getID (AccessibleApplication *obj); +char *AccessibleApplication_getLocale (AccessibleApplication *obj, int lc_category); +SPIBoolean AccessibleApplication_pause (AccessibleApplication *obj); +SPIBoolean AccessibleApplication_resume (AccessibleApplication *obj); + +/* AccessibleCollection function prototypes */ +void AccessibleCollection_ref (AccessibleCollection *obj); +void AccessibleCollection_unref (AccessibleCollection *obj); +AccessibleMatchRule * +AccessibleCollection_createMatchRule (AccessibleCollection *obj, + AccessibleStateSet *states, + AccessibleCollectionMatchType statematchtype, + AccessibleAttributeSet *attributes, + AccessibleCollectionMatchType attributematchtype, + AccessibleRoleSet *roles, + AccessibleCollectionMatchType rolematchtype, + char *interfaces, + AccessibleCollectionMatchType interfacematchtype, + long int invert); +void +AccessibleCollection_freeMatchRule (AccessibleCollection *obj, + AccessibleMatchRule *matchrule); +/* AccessibleComponent function prototypes */ + +void AccessibleComponent_ref (AccessibleComponent *obj); +void AccessibleComponent_unref (AccessibleComponent *obj); +SPIBoolean AccessibleComponent_contains (AccessibleComponent *obj, + long int x, + long int y, + AccessibleCoordType ctype); +Accessible *AccessibleComponent_getAccessibleAtPoint ( + AccessibleComponent *obj, + long int x, + long int y, + AccessibleCoordType ctype); +void AccessibleComponent_getExtents (AccessibleComponent *obj, + long int *x, + long int *y, + long int *width, + long int *height, + AccessibleCoordType ctype); +void AccessibleComponent_getPosition (AccessibleComponent *obj, + long int *x, + long int *y, + AccessibleCoordType ctype); +void AccessibleComponent_getSize (AccessibleComponent *obj, + long int *width, + long int *height); +AccessibleComponentLayer + AccessibleComponent_getLayer (AccessibleComponent *obj); +SPIBoolean AccessibleComponent_grabFocus (AccessibleComponent *obj); +short AccessibleComponent_getMDIZOrder(AccessibleComponent *obj); +double AccessibleComponent_getAlpha (AccessibleComponent *obj); + +/* AccessibleDocument function prototypes */ + +void AccessibleDocument_ref (AccessibleDocument *obj); +void AccessibleDocument_unref (AccessibleDocument *obj); +char *AccessibleDocument_getLocale (AccessibleDocument *obj); +char *AccessibleDocument_getAttributeValue (AccessibleDocument *obj, + char *attribute); +AccessibleAttributeSet *AccessibleDocument_getAttributes (AccessibleDocument *obj); + +/* AccessibleEditableText function prototypes */ + +void +AccessibleEditableText_ref (AccessibleEditableText *obj); + +void +AccessibleEditableText_unref (AccessibleEditableText *obj); + +SPIBoolean +AccessibleEditableText_setAttributes (AccessibleEditableText *obj, + const char *attributes, + long int startOffset, + long int endOffset); + +SPIBoolean +AccessibleEditableText_setTextContents (AccessibleEditableText *obj, + const char *newContents); + +SPIBoolean +AccessibleEditableText_insertText (AccessibleEditableText *obj, + long int position, + const char *text, + long int length); + +SPIBoolean +AccessibleEditableText_copyText (AccessibleText *obj, + long int startPos, + long int endPos); + +SPIBoolean +AccessibleEditableText_cutText (AccessibleEditableText *obj, + long int startPos, + long int endPos); + +SPIBoolean +AccessibleEditableText_deleteText (AccessibleEditableText *obj, + long int startPos, + long int endPos); + +SPIBoolean +AccessibleEditableText_pasteText (AccessibleEditableText *obj, + long int position); + +/* + * + * AccessibleHyperlink function prototypes + * + */ +void +AccessibleHyperlink_ref (AccessibleHyperlink *obj); +void +AccessibleHyperlink_unref (AccessibleHyperlink *obj); + +long +AccessibleHyperlink_getNAnchors (AccessibleHyperlink *obj); + +char * +AccessibleHyperlink_getURI (AccessibleHyperlink *obj, + long int i); + +Accessible * +AccessibleHyperlink_getObject (AccessibleHyperlink *obj, + long int i); + +void +AccessibleHyperlink_getIndexRange (AccessibleHyperlink *obj, + long int *startIndex, + long int *endIndex); + +SPIBoolean +AccessibleHyperlink_isValid (AccessibleHyperlink *obj); + +/* + * + * AccessibleHypertext function prototypes + * + */ + +void +AccessibleHypertext_ref (AccessibleHypertext *obj); + +void +AccessibleHypertext_unref (AccessibleHypertext *obj); + +long +AccessibleHypertext_getNLinks (AccessibleHypertext *obj); + +AccessibleHyperlink * +AccessibleHypertext_getLink (AccessibleHypertext *obj, + long int linkIndex); + +long +AccessibleHypertext_getLinkIndex (AccessibleHypertext *obj, + long int characterOffset); + +/* + * + * AccessibleImage function prototypes + * + */ + +void +AccessibleImage_ref (AccessibleImage *obj); + +void +AccessibleImage_unref (AccessibleImage *obj); + +char * +AccessibleImage_getImageDescription (AccessibleImage *obj); + +void +AccessibleImage_getImageSize (AccessibleImage *obj, + long int *width, + long int *height); + +void +AccessibleImage_getImagePosition (AccessibleImage *obj, + long int *x, + long int *y, + AccessibleCoordType ctype); + +void +AccessibleImage_getImageExtents (AccessibleImage *obj, + long int *x, + long int *y, + long int *width, + long int *height, + AccessibleCoordType ctype); +char * +AccessibleImage_getImageLocale (AccessibleImage *obj); + +/* + * + * AccessibleMatchRule function prototypes + * + */ +void AccessibleMatchRule_ref (AccessibleMatchRule *obj); +void AccessibleMatchRule_unref (AccessibleMatchRule *obj); + +/* + * + * AccessibleRelation function prototypes + * + */ + +void AccessibleRelation_ref (AccessibleRelation *obj); +void AccessibleRelation_unref (AccessibleRelation *obj); + +AccessibleRelationType +AccessibleRelation_getRelationType (AccessibleRelation *obj); + +int +AccessibleRelation_getNTargets (AccessibleRelation *obj); + +Accessible * +AccessibleRelation_getTarget (AccessibleRelation *obj, int i); + + +/* + * + * AccessibleSelection function prototypes + * + */ + +void AccessibleSelection_ref (AccessibleSelection *obj); +void AccessibleSelection_unref (AccessibleSelection *obj); + +long +AccessibleSelection_getNSelectedChildren (AccessibleSelection *obj); + +Accessible * +AccessibleSelection_getSelectedChild (AccessibleSelection *obj, + long int selectedChildIndex); + +SPIBoolean +AccessibleSelection_selectChild (AccessibleSelection *obj, + long int childIndex); + +SPIBoolean +AccessibleSelection_deselectSelectedChild (AccessibleSelection *obj, + long int selectedChildIndex); + +SPIBoolean +AccessibleSelection_deselectChild (AccessibleSelection *obj, + long int childIndex); + +SPIBoolean +AccessibleSelection_isChildSelected (AccessibleSelection *obj, + long int childIndex); + +SPIBoolean +AccessibleSelection_selectAll (AccessibleSelection *obj); + +SPIBoolean +AccessibleSelection_clearSelection (AccessibleSelection *obj); + + +/* + * + * AccessibleStateSet function prototypes + * + */ + +void AccessibleStateSet_ref (AccessibleStateSet *obj); +void AccessibleStateSet_unref (AccessibleStateSet *obj); + +SPIBoolean +AccessibleStateSet_contains (AccessibleStateSet *obj, + AccessibleState state); + +void +AccessibleStateSet_add (AccessibleStateSet *obj, + AccessibleState state); + +void +AccessibleStateSet_remove (AccessibleStateSet *obj, + AccessibleState state); + +SPIBoolean +AccessibleStateSet_equals (AccessibleStateSet *obj, + AccessibleStateSet *obj2); + +AccessibleStateSet * +AccessibleStateSet_compare (AccessibleStateSet *obj, + AccessibleStateSet *obj2); + +SPIBoolean +AccessibleStateSet_isEmpty (AccessibleStateSet *obj); + +void +AccessibleStreamableContent_ref (AccessibleStreamableContent *obj); +void +AccessibleStreamableContent_unref (AccessibleStreamableContent *obj); +char ** +AccessibleStreamableContent_getContentTypes (AccessibleStreamableContent *obj); + +void +AccessibleStreamableContent_freeContentTypesList (AccessibleStreamableContent *obj, + char **content_types); +#define AccessibleStreamableContent_freeContentTypeList(a, b) AccessibleStreamableContent_freeContentTypesList(a,b) + +SPIBoolean +AccessibleStreamableContent_open (AccessibleStreamableContent *obj, + const char *content_type); +SPIBoolean +AccessibleStreamableContent_close (AccessibleStreamableContent *obj); + +long +AccessibleStreamableContent_seek (AccessibleStreamableContent *obj, + long int offset, + AccessibleStreamableContentSeekType seek_type); +SPIBoolean +AccessibleStreamableContent_read (AccessibleStreamableContent *obj, + void *buff, + long int nbytes, + unsigned int read_type); +/* + * + * AccessibleTable function prototypes + * + */ + +void AccessibleTable_ref (AccessibleTable *obj); +void AccessibleTable_unref (AccessibleTable *obj); + +Accessible * +AccessibleTable_getCaption (AccessibleTable *obj); + +Accessible * +AccessibleTable_getSummary (AccessibleTable *obj); + +long +AccessibleTable_getNRows (AccessibleTable *obj); + +long +AccessibleTable_getNColumns (AccessibleTable *obj); + +Accessible * +AccessibleTable_getAccessibleAt (AccessibleTable *obj, + long int row, + long int column); + +long +AccessibleTable_getIndexAt (AccessibleTable *obj, + long int row, + long int column); + +long +AccessibleTable_getRowAtIndex (AccessibleTable *obj, + long int index); + +long +AccessibleTable_getColumnAtIndex (AccessibleTable *obj, + long int index); + +char * +AccessibleTable_getRowDescription (AccessibleTable *obj, + long int row); + +char * +AccessibleTable_getColumnDescription (AccessibleTable *obj, + long int column); + +long +AccessibleTable_getRowExtentAt (AccessibleTable *obj, + long int row, + long int column); + +long +AccessibleTable_getColumnExtentAt (AccessibleTable *obj, + long int row, + long int column); + +SPIBoolean +AccessibleTable_getRowColumnExtentsAtIndex (AccessibleTable *obj, + long int index, long int *row, long int *col, + long int *row_extents, long int *col_extents, + long int *is_selected); + +Accessible * +AccessibleTable_getRowHeader (AccessibleTable *obj, + long int row); + +Accessible * +AccessibleTable_getColumnHeader (AccessibleTable *obj, + long int column); + +long +AccessibleTable_getNSelectedRows (AccessibleTable *obj); + +long +AccessibleTable_getSelectedRows (AccessibleTable *obj, + long int **selectedRows); + +long +AccessibleTable_getNSelectedColumns (AccessibleTable *obj); + +long +AccessibleTable_getSelectedColumns (AccessibleTable *obj, + long int **selectedColumns); + +SPIBoolean +AccessibleTable_isRowSelected (AccessibleTable *obj, + long int row); + +SPIBoolean +AccessibleTable_isColumnSelected (AccessibleTable *obj, + long int column); + +SPIBoolean +AccessibleTable_isSelected (AccessibleTable *obj, + long int row, + long int column); + +SPIBoolean +AccessibleTable_addRowSelection (AccessibleTable *obj, + long int row); +SPIBoolean +AccessibleTable_addColumnSelection (AccessibleTable *obj, + long int column); + +SPIBoolean +AccessibleTable_removeRowSelection (AccessibleTable *obj, + long int row); +SPIBoolean +AccessibleTable_removeColumnSelection (AccessibleTable *obj, + long int column); + +/* + * + * AccessibleText function prototypes + * + */ + +void AccessibleText_ref (AccessibleText *obj); +void AccessibleText_unref (AccessibleText *obj); + +long +AccessibleText_getCharacterCount (AccessibleText *obj); + +char * +AccessibleText_getText (AccessibleText *obj, + long int startOffset, + long int endOffset); + +long +AccessibleText_getCaretOffset (AccessibleText *obj); + +char * +AccessibleText_getAttributes (AccessibleText *obj, + long int offset, + long int *startOffset, + long int *endOffset); + +char * +AccessibleText_getDefaultAttributes (AccessibleText *obj); + +SPIBoolean +AccessibleText_setCaretOffset (AccessibleText *obj, + long int newOffset); + +char * +AccessibleText_getTextBeforeOffset (AccessibleText *obj, + long int offset, + AccessibleTextBoundaryType type, + long int *startOffset, + long int *endOffset); + +char * +AccessibleText_getTextAtOffset (AccessibleText *obj, + long int offset, + AccessibleTextBoundaryType type, + long int *startOffset, + long int *endOffset); + +char * +AccessibleText_getTextAfterOffset (AccessibleText *obj, + long int offset, + AccessibleTextBoundaryType type, + long int *startOffset, + long int *endOffset); + +unsigned long +AccessibleText_getCharacterAtOffset (AccessibleText *obj, + long int offset); + +void +AccessibleText_getCharacterExtents (AccessibleText *obj, + long int offset, + long int *x, + long int *y, + long int *width, + long int *height, + AccessibleCoordType type); + +void +AccessibleText_getRangeExtents (AccessibleText *obj, + long int startOffset, + long int endOffset, + long int *x, + long int *y, + long int *width, + long int *height, + AccessibleCoordType type); + +AccessibleTextRange ** +AccessibleText_getBoundedRanges (AccessibleText *obj, + long int x, + long int y, + long int width, + long int height, + AccessibleCoordType type, + AccessibleTextClipType clipTypeX, + AccessibleTextClipType clipTypeY); + +void +AccessibleTextRange_freeRanges (AccessibleTextRange **ranges); + +long +AccessibleText_getOffsetAtPoint (AccessibleText *obj, + long int x, + long int y, + AccessibleCoordType type); + +long +AccessibleText_getNSelections (AccessibleText *obj); + +void +AccessibleText_getSelection (AccessibleText *obj, + long int selectionNum, + long int *startOffset, + long int *endOffset); + + +SPIBoolean +AccessibleText_addSelection (AccessibleText *obj, + long int startOffset, + long int endOffset); + +SPIBoolean +AccessibleText_removeSelection (AccessibleText *obj, + long int selectionNum); + +SPIBoolean +AccessibleText_setSelection (AccessibleText *obj, + long int selectionNum, + long int startOffset, + long int endOffset); +AccessibleAttributeSet * +AccessibleText_getAttributeRun (AccessibleText *obj, + long int offset, + long int *startOffset, + long int *endOffset, + long int includeDefaults); +AccessibleAttributeSet * +AccessibleText_getDefaultAttributeSet (AccessibleText *obj); + +/* AccessibleValue Function Prototypes: */ + +void AccessibleValue_ref (AccessibleValue *obj); +void AccessibleValue_unref (AccessibleValue *obj); +double AccessibleValue_getMinimumValue (AccessibleValue *obj); +double AccessibleValue_getCurrentValue (AccessibleValue *obj); +double AccessibleValue_getMaximumValue (AccessibleValue *obj); +SPIBoolean AccessibleValue_setCurrentValue (AccessibleValue *obj, + double newValue); +double AccessibleValue_getMinimumIncrement (AccessibleValue *obj); + +/* 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. + */ + +char* AccessibleEvent_getSourceName (const AccessibleEvent *e); +AccessibleRole AccessibleEvent_getSourceRole (const AccessibleEvent *e); +AccessibleApplication* AccessibleEvent_getSourceApplication (const AccessibleEvent *e); +SPIBoolean AccessibleEvent_getSourceDetails (const AccessibleEvent *e, char **name, + AccessibleRole *role, + AccessibleApplication **app); + +char* AccessibleTextChangedEvent_getChangeString (const AccessibleEvent *e); +Accessible * AccessibleChildChangedEvent_getChildAccessible (const AccessibleEvent *e); + +Accessible * AccessibleParentChangedEvent_getParentAccessible (const AccessibleEvent *e); + +char* AccessibleTextSelectionChangedEvent_getSelectionString (const AccessibleEvent *e); + +char* AccessibleWindowEvent_getTitleString (const AccessibleEvent *e); + +Accessible * AccessibleActiveDescendantChangedEvent_getActiveDescendant (const AccessibleEvent *e); + +Accessible * AccessibleTableSummaryChangedEvent_getSummaryAccessible (const AccessibleEvent *e); + +Accessible * AccessibleTableHeaderChangedEvent_getHeaderAccessible (const AccessibleEvent *e); + +char * AccessibleTableCaptionChangedEvent_getCaptionString (const AccessibleEvent *e); + +char * AccessibleTableRowDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e); + +char * AccessibleTableColumnDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e); + +char * AccessibleDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e); + +char * AccessibleNameChangedEvent_getNameString (const AccessibleEvent *e); +SPIRect * AccessibleBoundsChangedEvent_getNewBounds (const AccessibleEvent *e); + +/* Misc methods and error handling */ +void SPI_freeString (char *s); + +char* SPI_dupString (char *s); + +void SPI_freeRect (SPIRect *r); + +SPIBoolean SPI_exceptionHandlerPush (SPIExceptionHandler *handler); + +SPIExceptionHandler* SPI_exceptionHandlerPop (void); + +SPIExceptionType SPIException_getSourceType (SPIException *err); + +SPIExceptionCode SPIException_getExceptionCode (SPIException *err); + +Accessible* SPIAccessibleException_getSource (SPIException *err); + +char* SPIException_getDescription (SPIException *err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cspi/spi_accessible.c b/cspi/spi_accessible.c new file mode 100644 index 0000000..958c20c --- /dev/null +++ b/cspi/spi_accessible.c @@ -0,0 +1,1471 @@ +/* + * 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. + * + * 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. + */ + +#include /* for malloc */ +#include "spi-stateset.h" +#include + +static const char *role_names [] = +{ + "invalid", + "accel-label", + "alert", + "animation", + "arrow", + "calendar", + "canvas", + "check-box", + "check-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", + "frame", + "glass-pane", + "html-container", + "icon", + "image", + "internalframe", + "label", + "layered-pane", + "list", + "list-item", + "menu", + "menu-bar", + "menu-item", + "option-pane", + "page-tab", + "page-tab-list", + "panel", + "password-text", + "popup-menu", + "progress-bar", + "push-button", + "radio-button", + "radio-menu-item", + "root-pane", + "row-header", + "scroll-bar", + "scroll-pane", + "separator", + "slider", + "spin-button", + "split-pane", + "statusbar", + "table", + "table-cell", + "table-column-header", + "table-row-header", + "tear-off-menu-item", + "terminal", + "text", + "toggle-button", + "tool-bar", + "tool-tip", + "tree", + "tree-table", + "unknown", + "viewport", + "window", + NULL, + "header", + "fooler", + "paragraph", + "ruler", + "application", + "autocomplete", + "editbar", + "embedded", + "entry", + "chart", + "caption", + "document_frame", + "heading", + "page", + "section", + "form", + "redundant object", + "link", + "input method window" +}; + +#define MAX_ROLES (sizeof (role_names) / sizeof (char *)) + +static SPIBoolean +cspi_init_role_table (AccessibleRole *role_table) +{ + int i; + for (i = 0; i < Accessibility_ROLE_LAST_DEFINED; ++i) + { + role_table [i] = SPI_ROLE_UNKNOWN; + } + role_table [Accessibility_ROLE_INVALID] = SPI_ROLE_INVALID; + role_table [Accessibility_ROLE_ACCELERATOR_LABEL] = SPI_ROLE_ACCEL_LABEL; + role_table [Accessibility_ROLE_ALERT] = SPI_ROLE_ALERT; + role_table [Accessibility_ROLE_ANIMATION] = SPI_ROLE_ANIMATION; + role_table [Accessibility_ROLE_ARROW] = SPI_ROLE_ARROW; + role_table [Accessibility_ROLE_CALENDAR] = SPI_ROLE_CALENDAR; + role_table [Accessibility_ROLE_CANVAS] = SPI_ROLE_CANVAS; + role_table [Accessibility_ROLE_CHECK_BOX] = SPI_ROLE_CHECK_BOX; + role_table [Accessibility_ROLE_CHECK_MENU_ITEM] = SPI_ROLE_CHECK_MENU_ITEM; + role_table [Accessibility_ROLE_COLOR_CHOOSER] = SPI_ROLE_COLOR_CHOOSER; + role_table [Accessibility_ROLE_COLUMN_HEADER] = SPI_ROLE_COLUMN_HEADER; + role_table [Accessibility_ROLE_COMBO_BOX] = SPI_ROLE_COMBO_BOX; + role_table [Accessibility_ROLE_DATE_EDITOR] = SPI_ROLE_DATE_EDITOR; + role_table [Accessibility_ROLE_DESKTOP_ICON] = SPI_ROLE_DESKTOP_ICON; + role_table [Accessibility_ROLE_DESKTOP_FRAME] = SPI_ROLE_DESKTOP_FRAME; + role_table [Accessibility_ROLE_DIAL] = SPI_ROLE_DIAL; + role_table [Accessibility_ROLE_DIALOG] = SPI_ROLE_DIALOG; + role_table [Accessibility_ROLE_DIRECTORY_PANE] = SPI_ROLE_DIRECTORY_PANE; + role_table [Accessibility_ROLE_DRAWING_AREA] = SPI_ROLE_DRAWING_AREA; + role_table [Accessibility_ROLE_FILE_CHOOSER] = SPI_ROLE_FILE_CHOOSER; + role_table [Accessibility_ROLE_FILLER] = SPI_ROLE_FILLER; + role_table [Accessibility_ROLE_FONT_CHOOSER] = SPI_ROLE_FONT_CHOOSER; + role_table [Accessibility_ROLE_FRAME] = SPI_ROLE_FRAME; + role_table [Accessibility_ROLE_GLASS_PANE] = SPI_ROLE_GLASS_PANE; + role_table [Accessibility_ROLE_HTML_CONTAINER] = SPI_ROLE_HTML_CONTAINER; + role_table [Accessibility_ROLE_ICON] = SPI_ROLE_ICON; + role_table [Accessibility_ROLE_IMAGE] = SPI_ROLE_IMAGE; + role_table [Accessibility_ROLE_INTERNAL_FRAME] = SPI_ROLE_INTERNAL_FRAME; + role_table [Accessibility_ROLE_LABEL] = SPI_ROLE_LABEL; + role_table [Accessibility_ROLE_LAYERED_PANE] = SPI_ROLE_LAYERED_PANE; + role_table [Accessibility_ROLE_LIST] = SPI_ROLE_LIST; + role_table [Accessibility_ROLE_LIST_ITEM] = SPI_ROLE_LIST_ITEM; + role_table [Accessibility_ROLE_MENU] = SPI_ROLE_MENU; + role_table [Accessibility_ROLE_MENU_BAR] = SPI_ROLE_MENU_BAR; + role_table [Accessibility_ROLE_MENU_ITEM] = SPI_ROLE_MENU_ITEM; + role_table [Accessibility_ROLE_OPTION_PANE] = SPI_ROLE_OPTION_PANE; + role_table [Accessibility_ROLE_PAGE_TAB] = SPI_ROLE_PAGE_TAB; + role_table [Accessibility_ROLE_PAGE_TAB_LIST] = SPI_ROLE_PAGE_TAB_LIST; + role_table [Accessibility_ROLE_PANEL] = SPI_ROLE_PANEL; + role_table [Accessibility_ROLE_PASSWORD_TEXT] = SPI_ROLE_PASSWORD_TEXT; + role_table [Accessibility_ROLE_POPUP_MENU] = SPI_ROLE_POPUP_MENU; + role_table [Accessibility_ROLE_PROGRESS_BAR] = SPI_ROLE_PROGRESS_BAR; + role_table [Accessibility_ROLE_PUSH_BUTTON] = SPI_ROLE_PUSH_BUTTON; + role_table [Accessibility_ROLE_RADIO_BUTTON] = SPI_ROLE_RADIO_BUTTON; + role_table [Accessibility_ROLE_RADIO_MENU_ITEM] = SPI_ROLE_RADIO_MENU_ITEM; + role_table [Accessibility_ROLE_ROOT_PANE] = SPI_ROLE_ROOT_PANE; + role_table [Accessibility_ROLE_ROW_HEADER] = SPI_ROLE_ROW_HEADER; + role_table [Accessibility_ROLE_SCROLL_BAR] = SPI_ROLE_SCROLL_BAR; + role_table [Accessibility_ROLE_SCROLL_PANE] = SPI_ROLE_SCROLL_PANE; + role_table [Accessibility_ROLE_SEPARATOR] = SPI_ROLE_SEPARATOR; + role_table [Accessibility_ROLE_SLIDER] = SPI_ROLE_SLIDER; + role_table [Accessibility_ROLE_SPIN_BUTTON] = SPI_ROLE_SPIN_BUTTON; + role_table [Accessibility_ROLE_SPLIT_PANE] = SPI_ROLE_SPLIT_PANE; + role_table [Accessibility_ROLE_STATUS_BAR] = SPI_ROLE_STATUS_BAR; + role_table [Accessibility_ROLE_TABLE] = SPI_ROLE_TABLE; + role_table [Accessibility_ROLE_TABLE_CELL] = SPI_ROLE_TABLE_CELL; + role_table[Accessibility_ROLE_TABLE_COLUMN_HEADER] = SPI_ROLE_TABLE_COLUMN_HEADER; + role_table[Accessibility_ROLE_TABLE_ROW_HEADER] = SPI_ROLE_TABLE_ROW_HEADER; + role_table [Accessibility_ROLE_TEAROFF_MENU_ITEM] = SPI_ROLE_TEAROFF_MENU_ITEM; + role_table[Accessibility_ROLE_TERMINAL] = SPI_ROLE_TERMINAL; + role_table [Accessibility_ROLE_TEXT] = SPI_ROLE_TEXT; + role_table [Accessibility_ROLE_TOGGLE_BUTTON] = SPI_ROLE_TOGGLE_BUTTON; + role_table [Accessibility_ROLE_TOOL_BAR] = SPI_ROLE_TOOL_BAR; + role_table [Accessibility_ROLE_TOOL_TIP] = SPI_ROLE_TOOL_TIP; + role_table [Accessibility_ROLE_TREE] = SPI_ROLE_TREE; + role_table [Accessibility_ROLE_TREE_TABLE] = SPI_ROLE_TREE_TABLE; + role_table [Accessibility_ROLE_VIEWPORT] = SPI_ROLE_VIEWPORT; + role_table [Accessibility_ROLE_WINDOW] = SPI_ROLE_WINDOW; + role_table [Accessibility_ROLE_EXTENDED] = SPI_ROLE_EXTENDED; + role_table [Accessibility_ROLE_HEADER] = SPI_ROLE_HEADER; + role_table [Accessibility_ROLE_FOOTER] = SPI_ROLE_FOOTER; + role_table [Accessibility_ROLE_PARAGRAPH] = SPI_ROLE_PARAGRAPH; + role_table [Accessibility_ROLE_RULER] = SPI_ROLE_RULER; + role_table [Accessibility_ROLE_APPLICATION] = SPI_ROLE_APPLICATION; + role_table [Accessibility_ROLE_AUTOCOMPLETE] = SPI_ROLE_AUTOCOMPLETE; + role_table [Accessibility_ROLE_EDITBAR] = SPI_ROLE_EDITBAR; + role_table [Accessibility_ROLE_EMBEDDED] = SPI_ROLE_EMBEDDED; + role_table [Accessibility_ROLE_ENTRY] = SPI_ROLE_ENTRY; + role_table [Accessibility_ROLE_CHART] = SPI_ROLE_CHART; + role_table [Accessibility_ROLE_CAPTION] = SPI_ROLE_CAPTION; + role_table [Accessibility_ROLE_DOCUMENT_FRAME] = SPI_ROLE_DOCUMENT_FRAME; + role_table [Accessibility_ROLE_HEADING] = SPI_ROLE_HEADING; + role_table [Accessibility_ROLE_PAGE] = SPI_ROLE_PAGE; + role_table [Accessibility_ROLE_SECTION] = SPI_ROLE_SECTION; + role_table [Accessibility_ROLE_FORM] = SPI_ROLE_FORM; + role_table [Accessibility_ROLE_REDUNDANT_OBJECT] = SPI_ROLE_REDUNDANT_OBJECT; + role_table [Accessibility_ROLE_LINK] = SPI_ROLE_LINK; + role_table [Accessibility_ROLE_INPUT_METHOD_WINDOW] = SPI_ROLE_INPUT_METHOD_WINDOW; + + return TRUE; +} + +AccessibleRole +cspi_role_from_spi_role (Accessibility_Role role) +{ + /* array is sized according to IDL roles because IDL roles are the index */ + static AccessibleRole cspi_role_table [Accessibility_ROLE_LAST_DEFINED]; + static SPIBoolean is_initialized = FALSE; + AccessibleRole cspi_role; + if (!is_initialized) + { + is_initialized = cspi_init_role_table (cspi_role_table); + } + if (role >= 0 && role < Accessibility_ROLE_LAST_DEFINED) + { + cspi_role = cspi_role_table [role]; + } + else + { + cspi_role = SPI_ROLE_EXTENDED; + } + return cspi_role; +} + +AccessibleAttributeSet * +_cspi_attribute_set_from_sequence (const GArray *seq) +{ + AccessibleAttributeSet *set = g_new0 (AccessibleAttributeSet, 1); + int i; + + set->len = seq->len; + set->attributes = g_new0 (char *, set->len); + for (i = 0; i < set->len; ++i) + { + set->attributes[i] = g_array_index (seq, char *, i); + } + + g_array_free (seq, TRUE); + return set; +} + +/** + * AccessibleRole_getName: + * @role: an #AccessibleRole object to query. + * + * Get a localizeable string that indicates the name of an #AccessibleRole. + * DEPRECATED. + * + * Returns: a localizable string name for an #AccessibleRole enumerated type. + **/ +char * +AccessibleRole_getName (AccessibleRole role) +{ + if (role < MAX_ROLES && role_names [(int) role]) + { + return g_strdup (role_names [(int) role]); + } + else + { + return g_strdup (""); + } +} + +/** + * Accessible_ref: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Increment the reference count for an #Accessible object. + **/ +void +Accessible_ref (Accessible *obj) +{ + cspi_object_ref (obj); +} + +/** + * Accessible_unref: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Decrement the reference count for an #Accessible object. + **/ +void +Accessible_unref (Accessible *obj) +{ + cspi_object_unref (obj); +} + +/** + * Accessible_getName: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Get the name of an #Accessible object. + * + * Returns: a UTF-8 string indicating the name of the #Accessible object. + * or NULL on exception + **/ +char * +Accessible_getName (Accessible *obj) +{ + cspi_return_val_if_fail (obj != NULL, NULL); + return g_strdup (obj->name); +} + +/** + * Accessible_getDescription: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Get the description of an #Accessible object. + * + * Returns: a UTF-8 string describing the #Accessible object. + * or NULL on exception + **/ +char * +Accessible_getDescription (Accessible *obj) +{ + cspi_return_val_if_fail (obj != NULL, NULL); + + return g_strdup (obj->description); +} + +/** + * Accessible_getParent: + * @obj: a pointer to the #Accessible object to query. + * + * Get an #Accessible object's parent container. + * + * Returns: a pointer tothe #Accessible object which contains the given + * #Accessible instance, or NULL if the @obj has no parent container. + * + **/ +Accessible * +Accessible_getParent (Accessible *obj) +{ + cspi_return_val_if_fail (obj != NULL, NULL); + + return cspi_object_add (obj->parent); +} + +/** + * Accessible_getChildCount: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Get the number of children contained by an #Accessible object. + * + * Returns: a #long indicating the number of #Accessible children + * contained by an #Accessible object. or -1 on exception + * + **/ +long +Accessible_getChildCount (Accessible *obj) +{ + cspi_return_val_if_fail (obj != NULL, -1); + + return g_list_length (obj->children); +} + +/** + * Accessible_getChildAtIndex: + * @obj: a pointer to the #Accessible object on which to operate. + * @childIndex: a #long indicating which child is specified. + * + * Get the #Accessible child of an #Accessible object at a given index. + * + * Returns: a pointer to the #Accessible child object at index + * @childIndex. or NULL on exception + **/ +Accessible * +Accessible_getChildAtIndex (Accessible *obj, + long int childIndex) +{ + Accessible *child; + + cspi_return_val_if_fail (obj != NULL, NULL); + + child = g_list_nth_data (obj->children, childIndex); + return cspi_object_add(child); +} + +/** + * Accessible_getIndexInParent: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Get the index of an #Accessible object in its containing #Accessible. + * + * Returns: a #long indicating the index of the #Accessible object + * in its parent (i.e. containing) #Accessible instance, + * or -1 if @obj has no containing parent or on exception. + **/ +long +Accessible_getIndexInParent (Accessible *obj) +{ + GList *l; + gint i; + + cspi_return_val_if_fail (obj != NULL, -1); + if (!obj->parent) return -1; + l = obj->parent->children; + while (l) + { + if (l->data == obj) return i; + l = g_list_next (l); + i++; + } + return -1; +} + +typedef struct +{ + dbus_uint32_t type; + GArray *targets; +} Accessibility_Relation; + +/** + * Accessible_getRelationSet: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Get the set of #AccessibleRelation objects which describe this #Accessible object's + * relationships with other #Accessible objects. + * + * Returns: an array of #AccessibleRelation pointers. or NULL on exception + **/ +AccessibleRelation ** +Accessible_getRelationSet (Accessible *obj) +{ + int i; + int n_relations; + AccessibleRelation **relations; + GArray *relation_set; + DBusError error; + + cspi_return_val_if_fail (obj != NULL, NULL); + + g_assert (!cspi_exception ()); + + dbus_error_init (&error); + cspi_dbus_call (obj, spi_interface_accessible, "getAttributes", &error, "=>a(uao)", &relation_set); + + cspi_return_val_if_ev ("getRelationSet", NULL); + + n_relations = relation_set->len; + relations = malloc (sizeof (AccessibleRelation *) * (n_relations + 1)); + + for (i = 0; i < n_relations; ++i) + { + Accessibility_Relation *r = g_array_index (relation_set, Accessibility_Relation *, i); + relations[i] = g_new (AccessibleRelation, 1); + if (!relations[i]) continue; + relations[i]->ref_count = 1; + relations[i]->type = r->type; + relations[i]->targets = r->targets; + } + relations[i] = NULL; + + g_array_free (relation_set, TRUE); + + return relations; +} + +/** + * Accessible_getRole: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Get the UI role of an #Accessible object. + * A UTF-8 string describing this role can be obtained via Accessible_getRoleName (). + * + * Returns: the #AccessibleRole of the object. + * + **/ +AccessibleRole +Accessible_getRole (Accessible *obj) +{ + cspi_return_val_if_fail (obj != NULL, SPI_ROLE_INVALID); + + return obj->role; +} + +/** + * Accessible_getRoleName: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Get a UTF-8 string describing the role this object plays in the UI. + * This method will return useful values for roles that fall outside the + * enumeration used in Accessible_getRole (). + * + * Returns: a UTF-8 string specifying the role of this #Accessible object. + * + **/ +char * +Accessible_getRoleName (Accessible *obj) +{ + char *retval; + + cspi_return_val_if_fail (obj != NULL, g_strdup ("invalid")); + + cspi_dbus_call (obj, spi_interface_accessible, "getRoleName", NULL, "=>s", &retval); + + cspi_return_val_if_ev ("getRoleName", g_strdup ("invalid")); + + return retval; +} + +/** + * Accessible_getLocalizedRoleName: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Get a UTF-8 string describing the (localized) role this object plays in the UI. + * This method will return useful values for roles that fall outside the + * enumeration used in Accessible_getRole (). + * + * @Since: AT-SPI 1.4 + * + * Returns: a UTF-8 string specifying the role of this #Accessible object. + * + **/ +char * +Accessible_getLocalizedRoleName (Accessible *obj) +{ + char *retval; + + cspi_return_val_if_fail (obj != NULL, g_strdup ("invalid")); + + cspi_dbus_call (obj, spi_interface_accessible, "getLocalizedRoleName", NULL, "=>s", &retval); + + cspi_return_val_if_ev ("getLocalizedRoleName", g_strdup ("invalid")); + + return retval; +} + +/** + * Accessible_getStateSet: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Gets the current state of an object. + * + * Returns: a pointer to an #AccessibleStateSet representing the object's current state. + **/ +AccessibleStateSet * +Accessible_getStateSet (Accessible *obj) +{ + GArray *state_bitflags; + AccessibleStateSet *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_accessible, "getStateSet", NULL, "=>au", &state_bitflags); + cspi_return_val_if_ev ("getState", NULL); + + retval = spi_state_set_cache_new (state_bitflags); + + g_array_free (state_bitflags, TRUE); + + return retval; +} + +/** + * Accessible_getAttributes: + * @obj: The #Accessible being queried. + * + * Get the #AttributeSet representing any assigned + * name-value pair attributes or annotations for this object. + * For typographic, textual, or textually-semantic attributes, see + * AccessibleText_getAttributes instead. + * + * Returns: The name-value-pair attributes assigned to this object. + */ +AccessibleAttributeSet * +Accessible_getAttributes (Accessible *obj) +{ + AccessibleAttributeSet *retval; + GArray *dbus_seq; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_accessible, "getAttributes", NULL, "=>as", &dbus_seq); + + cspi_return_val_if_ev ("getAttributes", NULL); + + retval = _cspi_attribute_set_from_sequence (dbus_seq); + + return retval; +} + +/** + * Accessible_getHostApplication: + * @obj: The #Accessible being queried. + * + * Get the containing #AccessibleApplication for an object. + * + * Returns: the containing AccessibleApplication instance for this object. + */ +AccessibleApplication * +Accessible_getHostApplication (Accessible *obj) +{ + while (obj->parent) obj = obj->parent; + return obj; +} + +/* Interface query methods */ + +/** + * Accessible_isAction: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleAction. + * + * Returns: #TRUE if @obj implements the #AccessibleAction interface, + * #FALSE otherwise. + **/ +SPIBoolean +Accessible_isAction (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_action); +} + +/** + * 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, + spi_interface_application); +} + +/** + * Accessible_isCollection: * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleCollection. + * Returns: #TRUE if @obj implements the #AccessibleCollection interface, + * #FALSE otherwise. + **/ + +SPIBoolean +Accessible_isCollection (Accessible *obj) +{ +#if 0 + g_warning ("Collections not implemented"); + return cspi_accessible_is_a (obj, + spi_interface_collection); +#else + return FALSE; +#endif +} + +/** + * Accessible_isComponent: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleComponent. + * + * Returns: #TRUE if @obj implements the #AccessibleComponent interface, + * #FALSE otherwise. + **/ +SPIBoolean +Accessible_isComponent (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_component); +} + +/** + * Accessible_isDocument: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleDocument. + * + * Returns: #TRUE if @obj implements the #AccessibleDocument interface, + * #FALSE otherwise. + **/ +SPIBoolean +Accessible_isDocument (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_document); +} + +/** + * Accessible_isEditableText: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleEditableText. + * + * Returns: #TRUE if @obj implements the #AccessibleEditableText interface, + * #FALSE otherwise. + **/ +SPIBoolean +Accessible_isEditableText (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_editable_text); +} + +/** + * Accessible_isMatchRule: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleMatchRule. + * + * Returns: #TRUE if @obj implements the #AccessibleMatchRule interface, + * #FALSE otherwise. + **/ +SPIBoolean +Accessible_isMatchRule (Accessible *obj) +{ +#if 0 + return cspi_accessible_is_a (obj, + spi_interface_match_rule); +#else + g_warning ("Match rules not implemented"); + return FALSE; +#endif +} + +/** + * Accessible_isHypertext: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleHypertext. + * + * Returns: #TRUE if @obj implements the #AccessibleHypertext interface, + * #FALSE otherwise. + **/ +SPIBoolean +Accessible_isHypertext (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_hypertext); +} + +/** + * Accessible_isImage: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleImage. + * + * Returns: #TRUE if @obj implements the #AccessibleImage interface, + * #FALSE otherwise. +**/ +SPIBoolean +Accessible_isImage (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_image); +} + +/** + * Accessible_isSelection: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleSelection. + * + * Returns: #TRUE if @obj implements the #AccessibleSelection interface, + * #FALSE otherwise. +**/ +SPIBoolean +Accessible_isSelection (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_selection); +} + +/** + * Accessible_isTable: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleTable. + * + * Returns: #TRUE if @obj implements the #AccessibleTable interface, + * #FALSE otherwise. +**/ +SPIBoolean +Accessible_isTable (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_table); +} + +/** + * Accessible_isStreamableContent: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements + * #AccessibleStreamableContent. + * + * Returns: #TRUE if @obj implements the #AccessibleStreamableContent interface, + * #FALSE otherwise. +**/ +SPIBoolean +Accessible_isStreamableContent (Accessible *obj) +{ +#if 0 + return cspi_accessible_is_a (obj, + spi_interface_streamable_content); +#else + g_warning ("Streamable content not implemented"); + return FALSE; +#endif +} + +/** + * Accessible_isText: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleText. + * + * Returns: #TRUE if @obj implements the #AccessibleText interface, + * #FALSE otherwise. +**/ +SPIBoolean +Accessible_isText (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_text); +} + +/** + * Accessible_isValue: + * @obj: a pointer to the #Accessible instance to query. + * + * Query whether the specified #Accessible implements #AccessibleValue. + * + * Returns: #TRUE if @obj implements the #AccessibleValue interface, + * #FALSE otherwise. +**/ +SPIBoolean +Accessible_isValue (Accessible *obj) +{ + return cspi_accessible_is_a (obj, + spi_interface_value); +} + +/** + * 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, spi_interface_application); +} + +/** + * 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) +{ + return (AccessibleAction *) Accessible_queryInterface ( + obj, spi_interface_action); +} + + +/** + * Accessible_getCollection: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleCollection interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleCollection interface instance, or + * NULL if @obj does not implement #AccessibleCollection. + **/ +AccessibleCollection * +Accessible_getCollection (Accessible *obj) +{ +#if 0 + return (AccessibleCollection *) Accessible_queryInterface ( + obj, spi_interface_collection); +#else + g_warning ("Collections not implemented"); +#endif +} + +/** + * Accessible_getComponent: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleComponent interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleComponent interface instance, or + * NULL if @obj does not implement #AccessibleComponent. + **/ +AccessibleComponent * +Accessible_getComponent (Accessible *obj) +{ + return (AccessibleComponent *) Accessible_queryInterface ( + obj, spi_interface_component); +} + +/** + * Accessible_getDocument: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleDocument interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleDocument interface instance, or + * NULL if @obj does not implement #AccessibleDocument. + **/ +AccessibleDocument * +Accessible_getDocument (Accessible *obj) +{ + return (AccessibleDocument *) Accessible_queryInterface ( + obj, spi_interface_document); +} + +/** + * Accessible_getEditableText: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleEditableText interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleEditableText interface instance, or + * NULL if @obj does not implement #AccessibleEditableText. + **/ +AccessibleEditableText * +Accessible_getEditableText (Accessible *obj) +{ + return (AccessibleEditableText *) Accessible_queryInterface ( + obj, spi_interface_editable_text); +} + + +/** + * Accessible_getHypertext: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleHypertext interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleHypertext interface instance, or + * NULL if @obj does not implement #AccessibleHypertext. + **/ +AccessibleHypertext * +Accessible_getHypertext (Accessible *obj) +{ + return (AccessibleHypertext *) Accessible_queryInterface ( + obj, spi_interface_hypertext); +} + + + +/** + * Accessible_getImage: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleImage interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleImage interface instance, or + * NULL if @obj does not implement #AccessibleImage. + **/ +AccessibleImage * +Accessible_getImage (Accessible *obj) +{ + return (AccessibleImage *) Accessible_queryInterface ( + obj, spi_interface_image); +} + +/** + * Accessible_getMatchRule: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleMatchRule interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleMatchRule interface instance, or + * NULL if @obj does not implement #AccessibleMatchRule. + **/ +AccessibleMatchRule * +Accessible_getMatchRule (Accessible *obj) +{ +#if 0 + return (AccessibleMatchRule *) Accessible_queryInterface ( + obj, spi_interface_match_rule); +#else + g_warning ("Match rules not supported"); +#endif +} + +/** + * Accessible_getSelection: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleSelection interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleSelection interface instance, or + * NULL if @obj does not implement #AccessibleSelection. + **/ +AccessibleSelection * +Accessible_getSelection (Accessible *obj) +{ + return (AccessibleSelection *) Accessible_queryInterface ( + obj, spi_interface_selection); +} + + + +/** + * Accessible_getStreamableContent: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleStreamableContent interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleStreamableContent interface instance, or + * NULL if @obj does not implement #AccessibleStreamableContent. + **/ +AccessibleStreamableContent * +Accessible_getStreamableContent (Accessible *obj) +{ +#if 0 + return (AccessibleStreamableContent *) Accessible_queryInterface ( + obj, spi_interface_streamable_content); +#else + g_warning ("Streamable content not supported"); +#endif +} + +/** + * Accessible_getTable: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleTable interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleTable interface instance, or + * NULL if @obj does not implement #AccessibleTable. + **/ +AccessibleTable * +Accessible_getTable (Accessible *obj) +{ + return (AccessibleTable *) Accessible_queryInterface ( + obj, spi_interface_table); +} + +/** + * Accessible_getText: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleText interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleText interface instance, or + * NULL if @obj does not implement #AccessibleText. + **/ +AccessibleText * +Accessible_getText (Accessible *obj) +{ + return (AccessibleText *) Accessible_queryInterface ( + obj, spi_interface_text); +} + + + +/** + * Accessible_getValue: + * @obj: a pointer to the #Accessible instance to query. + * + * Get the #AccessibleValue interface for an #Accessible. + * + * Returns: a pointer to an #AccessibleValue interface instance, or + * NULL if @obj does not implement #AccessibleValue. + **/ +AccessibleValue * +Accessible_getValue (Accessible *obj) +{ + return (AccessibleValue *) Accessible_queryInterface ( + obj, spi_interface_value); +} + + + +/** + * Accessible_queryInterface: + * @obj: a pointer to the #Accessible instance to query. + * @interface_name: a UTF-8 character string specifiying the requested interface. + * + * Query an #Accessible object to for a named interface. + * + * Returns: an instance of the named interface object, if it is implemented + * by @obj, or NULL otherwise. + * + **/ +AccessibleUnknown * +Accessible_queryInterface (Accessible *obj, + const char *interface_name) +{ + if (cspi_accessible_is_a (obj, interface_name)) + { + /* The original code called cspi_object_add(obj) instead, but gok and + * simple-at don't treat interfaces as references, so I'm confused + * and not going to replicate this bit of code */ + return obj; + } + return NULL; +} + + +/** + * AccessibleRelation_ref: + * @obj: a pointer to the #AccessibleRelation object on which to operate. + * + * Increment the reference count for an #AccessibleRelation object. + * + **/ +void +AccessibleRelation_ref (AccessibleRelation *obj) +{ + obj->ref_count++; +} + +/** + * AccessibleRelation_unref: + * @obj: a pointer to the #AccessibleRelation object on which to operate. + * + * Decrement the reference count for an #AccessibleRelation object. + * + **/ +void +AccessibleRelation_unref (AccessibleRelation *obj) +{ + obj->ref_count--; + if (obj->ref_count <= 0) + { + g_array_free (obj->targets, TRUE); + g_free (obj); + } +} + +static SPIBoolean +cspi_init_relation_type_table (AccessibleRelationType *relation_type_table) +{ + int i; + for (i = 0; i < Accessibility_RELATION_LAST_DEFINED; ++i) + { + relation_type_table [i] = SPI_RELATION_NULL; + } + relation_type_table [Accessibility_RELATION_NULL] = SPI_RELATION_NULL; + relation_type_table [Accessibility_RELATION_LABEL_FOR] = SPI_RELATION_LABEL_FOR; + relation_type_table [Accessibility_RELATION_LABELLED_BY] = SPI_RELATION_LABELED_BY; + relation_type_table [Accessibility_RELATION_CONTROLLER_FOR] = SPI_RELATION_CONTROLLER_FOR; + relation_type_table [Accessibility_RELATION_CONTROLLED_BY] = SPI_RELATION_CONTROLLED_BY; + relation_type_table [Accessibility_RELATION_MEMBER_OF] = SPI_RELATION_MEMBER_OF; + relation_type_table [Accessibility_RELATION_TOOLTIP_FOR] = SPI_RELATION_NULL; + relation_type_table [Accessibility_RELATION_NODE_CHILD_OF] = SPI_RELATION_NODE_CHILD_OF; + relation_type_table [Accessibility_RELATION_EXTENDED] = SPI_RELATION_EXTENDED; + relation_type_table [Accessibility_RELATION_FLOWS_TO] = SPI_RELATION_FLOWS_TO; + relation_type_table [Accessibility_RELATION_FLOWS_FROM] = SPI_RELATION_FLOWS_FROM; + relation_type_table [Accessibility_RELATION_SUBWINDOW_OF] = SPI_RELATION_SUBWINDOW_OF; + relation_type_table [Accessibility_RELATION_EMBEDS] = SPI_RELATION_EMBEDS; + relation_type_table [Accessibility_RELATION_EMBEDDED_BY] = SPI_RELATION_EMBEDDED_BY; + relation_type_table [Accessibility_RELATION_POPUP_FOR] = SPI_RELATION_POPUP_FOR; + relation_type_table [Accessibility_RELATION_PARENT_WINDOW_OF] = SPI_RELATION_PARENT_WINDOW_OF; + relation_type_table [Accessibility_RELATION_DESCRIBED_BY] = SPI_RELATION_DESCRIBED_BY; + relation_type_table [Accessibility_RELATION_DESCRIPTION_FOR] = SPI_RELATION_DESCRIPTION_FOR; + return TRUE; +} + +static AccessibleRelationType +cspi_relation_type_from_spi_relation_type (Accessibility_RelationType type) +{ + /* array is sized according to IDL RelationType because IDL RelationTypes are the index */ + static AccessibleRelationType cspi_relation_type_table [Accessibility_RELATION_LAST_DEFINED]; + static SPIBoolean is_initialized = FALSE; + AccessibleRelationType cspi_type; + if (!is_initialized) + { + is_initialized = cspi_init_relation_type_table (cspi_relation_type_table); + } + if (type >= 0 && type < Accessibility_RELATION_LAST_DEFINED) + { + cspi_type = cspi_relation_type_table [type]; + } + else + { + cspi_type = SPI_RELATION_NULL; + } + return cspi_type; +} +/** + * AccessibleRelation_getRelationType: + * @obj: a pointer to the #AccessibleRelation object to query. + * + * Get the type of relationship represented by an #AccessibleRelation. + * + * Returns: an #AccessibleRelationType indicating the type of relation + * encapsulated in this #AccessibleRelation object. + * + **/ +AccessibleRelationType +AccessibleRelation_getRelationType (AccessibleRelation *obj) +{ + cspi_return_val_if_fail (obj, SPI_RELATION_NULL); + return cspi_relation_type_from_spi_relation_type (obj->type); +} + +/** + * AccessibleRelation_getNTargets: + * @obj: a pointer to the #AccessibleRelation object to query. + * + * Get the number of objects which this relationship has as its + * target objects (the subject is the #Accessible from which this + * #AccessibleRelation originated). + * + * Returns: a short integer indicating how many target objects which the + * originating #Accessible object has the #AccessibleRelation + * relationship with. + **/ +int +AccessibleRelation_getNTargets (AccessibleRelation *obj) +{ + cspi_return_val_if_fail (obj, -1); + return obj->targets->len; +} + +/** + * AccessibleRelation_getTarget: + * @obj: a pointer to the #AccessibleRelation object to query. + * @i: a (zero-index) integer indicating which (of possibly several) target is requested. + * + * Get the @i-th target of a specified #AccessibleRelation relationship. + * + * Returns: an #Accessible which is the @i-th object with which the + * originating #Accessible has relationship specified in the + * #AccessibleRelation object. + * + **/ +Accessible * +AccessibleRelation_getTarget (AccessibleRelation *obj, int i) +{ + cspi_return_val_if_fail (obj, NULL); + + if (i < 0 || i >= obj->targets->len) return NULL; + return cspi_object_add ( + g_array_index (obj->targets, Accessible *, i)); +} + +/** + * AccessibleStateSet_ref: + * @obj: a pointer to the #AccessibleStateSet object on which to operate. + * + * Increment the reference count for an #AccessibleStateSet object. + * + **/ +void +AccessibleStateSet_ref (AccessibleStateSet *obj) +{ + spi_state_set_cache_ref (obj); +} + +/** + * AccessibleStateSet_unref: + * @obj: a pointer to the #AccessibleStateSet object on which to operate. + * + * Decrement the reference count for an #AccessibleStateSet object. + * + **/ +void +AccessibleStateSet_unref (AccessibleStateSet *obj) +{ + spi_state_set_cache_unref (obj); +} + +static Accessibility_StateType +spi_state_to_dbus (AccessibleState state) +{ +#define MAP_STATE(a) \ + case SPI_STATE_##a: \ + return Accessibility_STATE_##a + + switch (state) + { + MAP_STATE (INVALID); + MAP_STATE (ACTIVE); + MAP_STATE (ARMED); + MAP_STATE (BUSY); + MAP_STATE (CHECKED); + MAP_STATE (DEFUNCT); + MAP_STATE (EDITABLE); + MAP_STATE (ENABLED); + MAP_STATE (EXPANDABLE); + MAP_STATE (EXPANDED); + MAP_STATE (FOCUSABLE); + MAP_STATE (FOCUSED); + MAP_STATE (HORIZONTAL); + MAP_STATE (ICONIFIED); + MAP_STATE (MODAL); + MAP_STATE (MULTI_LINE); + MAP_STATE (MULTISELECTABLE); + MAP_STATE (OPAQUE); + MAP_STATE (PRESSED); + MAP_STATE (RESIZABLE); + MAP_STATE (SELECTABLE); + MAP_STATE (SELECTED); + MAP_STATE (SENSITIVE); + MAP_STATE (SHOWING); + MAP_STATE (SINGLE_LINE); + MAP_STATE (STALE); + MAP_STATE (TRANSIENT); + MAP_STATE (VERTICAL); + MAP_STATE (VISIBLE); + MAP_STATE (MANAGES_DESCENDANTS); + MAP_STATE (INDETERMINATE); + MAP_STATE (TRUNCATED); + MAP_STATE (REQUIRED); + MAP_STATE (INVALID_ENTRY); + MAP_STATE (SUPPORTS_AUTOCOMPLETION); + MAP_STATE (SELECTABLE_TEXT); + MAP_STATE (IS_DEFAULT); + MAP_STATE (VISITED); + default: + return Accessibility_STATE_INVALID; + } +#undef MAP_STATE +} + +/** + * AccessibleStateSet_contains: + * @obj: a pointer to the #AccessibleStateSet object on which to operate. + * @state: an #AccessibleState for which the specified #AccessibleStateSet + * will be queried. + * + * Determine whether a given #AccessibleStateSet includes a given state; that is, + * whether @state is true for the stateset in question. + * + * Returns: #TRUE if @state is true/included in the given #AccessibleStateSet, + * otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleStateSet_contains (AccessibleStateSet *obj, + AccessibleState state) +{ + return spi_state_set_cache_contains (obj, spi_state_to_dbus (state)); +} + +/** + * AccessibleStateSet_add: + * @obj: a pointer to the #AccessibleStateSet object on which to operate. + * @state: an #AccessibleState to be added to the specified #AccessibleStateSet + * + * Add a particular #AccessibleState to an #AccessibleStateSet (i.e. set the + * given state to #TRUE in the stateset. + * + **/ +void +AccessibleStateSet_add (AccessibleStateSet *obj, + AccessibleState state) +{ + spi_state_set_cache_add (obj, spi_state_to_dbus (state)); +} + +/** + * AccessibleStateSet_remove: + * @obj: a pointer to the #AccessibleStateSet object on which to operate. + * @state: an #AccessibleState to be removed from the specified #AccessibleStateSet + * + * Remove a particular #AccessibleState to an #AccessibleStateSet (i.e. set the + * given state to #FALSE in the stateset.) + * + **/ +void +AccessibleStateSet_remove (AccessibleStateSet *obj, + AccessibleState state) +{ + spi_state_set_cache_remove (obj, spi_state_to_dbus (state)); +} + +/** + * AccessibleStateSet_equals: + * @obj: a pointer to the first #AccessibleStateSet object on which to operate. + * @obj2: a pointer to the second #AccessibleStateSet object on which to operate. + * + * Determine whether two instances of #AccessibleStateSet are equivalent (i.e. + * consist of the same #AccessibleStates). Useful for checking multiple + * state variables at once; construct the target state then compare against it. + * + * @see AccessibleStateSet_compare(). + * + * Returns: #TRUE if the two #AccessibleStateSets are equivalent, + * otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleStateSet_equals (AccessibleStateSet *obj, + AccessibleStateSet *obj2) +{ + SPIBoolean eq; + AtkStateSet *cmp; + + if (obj == obj2) + { + return TRUE; + } + + cmp = spi_state_set_cache_xor (obj, obj2); + eq = spi_state_set_cache_is_empty (cmp); + spi_state_set_cache_unref (cmp); + + return eq; +} + +/** + * AccessibleStateSet_compare: + * @obj: a pointer to the first #AccessibleStateSet object on which to operate. + * @obj2: a pointer to the second #AccessibleStateSet object on which to operate. + * + * Determine the differences between two instances of #AccessibleStateSet. + * Not Yet Implemented. + *. + * @see AccessibleStateSet_equals(). + * + * Returns: an #AccessibleStateSet object containing all states contained on one of + * the two sets but not the other. + * + **/ +AccessibleStateSet * +AccessibleStateSet_compare (AccessibleStateSet *obj, + AccessibleStateSet *obj2) +{ + return spi_state_set_cache_xor (obj, obj2); +} + +/** + * AccessibleStateSet_isEmpty: + * @obj: a pointer to the #AccessibleStateSet object on which to operate. + * + * Determine whether a given #AccessibleStateSet is the empty set. + * + * Returns: #TRUE if the given #AccessibleStateSet contains no (true) states, + * otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleStateSet_isEmpty (AccessibleStateSet *obj) +{ + return spi_state_set_cache_is_empty (obj); +} + diff --git a/cspi/spi_action.c b/cspi/spi_action.c new file mode 100644 index 0000000..7136b45 --- /dev/null +++ b/cspi/spi_action.c @@ -0,0 +1,190 @@ +/* + * 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. + * + * 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. + */ + +#include + +/** + * AccessibleAction_ref: + * @obj: a pointer to the #AccessibleAction on which to operate. + * + * Increment the reference count for an #AccessibleAction. + **/ +void +AccessibleAction_ref (AccessibleAction *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleAction_unref: + * @obj: a pointer to the #AccessibleAction on which to operate. + * + * Decrement the reference count for an #AccessibleAction. + **/ +void +AccessibleAction_unref (AccessibleAction *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleAction_getNActions: + * @obj: a pointer to the #AccessibleAction to query. + * + * Get the number of actions invokable on an #AccessibleAction implementor. + * + * Returns: a #long integer indicatin the number of invokable actions. + **/ +long +AccessibleAction_getNActions (AccessibleAction *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_action, "nActions", NULL, "i", &retval); + + cspi_return_val_if_ev ("getNActions", -1); + + return retval; +} + +/** + * AccessibleAction_getDescription: + * @obj: a pointer to the #AccessibleAction implementor to query. + * @i: a long integer indicating which action to query. + * + * Get the description of '@i-th' action invokable on an + * object implementing #AccessibleAction. + * + * Returns: a UTF-8 string describing the '@i-th' invokable action. + **/ +char * +AccessibleAction_getDescription (AccessibleAction *obj, + long int i) +{ + dbus_int32_t d_i = i; + char *retval; + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_action, "getDescription", NULL, "i=>s", d_i, &retval); + + cspi_return_val_if_ev ("getDescription", NULL); + + return retval; +} + +/** + * AccessibleAction_getKeyBinding: + * @obj: a pointer to the #AccessibleAction implementor to query. + * @i: a long integer indicating which action to query. + * + * Get the keybindings for the @i-th action invokable on an + * object implementing #AccessibleAction, if any are defined. + * The keybindings string format is as follows: + * there are multiple parts to a keybinding string (typically 3). + * They are delimited with ";". The first is the action's + * keybinding which is usable if the object implementing the action + * is currently posted to the screen, e.g. if a menu is posted + * then these keybindings for the corresponding menu-items are + * available. The second keybinding substring is the full key sequence + * necessary to post the action's widget and activate it, e.g. for + * a menu item such as "File->Open" it would both post the menu and + * activate the item. Thus the second keybinding string is available + * during the lifetime of the containing toplevel window as a whole, + * whereas the first keybinding string only works while the object + * implementing AtkAction is posted. The third (and optional) + * keybinding string is the "keyboard shortcut" which invokes the + * action without posting any menus. + * Meta-keys are indicated by the conventional strings + * "", "", "", "", + * etc. (we use the same string as gtk_accelerator_name() in + * gtk+-2.X. + * + * Returns: a UTF-8 string which can be parsed to determine the @i-th + * invokable action's keybindings. + **/ +char * +AccessibleAction_getKeyBinding (AccessibleAction *obj, + long int i) +{ + dbus_int32_t d_i = i; + char *retval; + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_action, "getKeyBinding", NULL, "i=>s", d_i, &retval); + + cspi_return_val_if_ev ("getKeyBinding", NULL); + + return retval; +} + +/** + * AccessibleAction_getName: + * @obj: a pointer to the #AccessibleAction implementor to query. + * @i: a long integer indicating which action to query. + * + * Get the name of the '@i-th' action invokable on an + * object implementing #AccessibleAction. + * + * Returns: the 'event type' name of the action, as a UTF-8 string. + **/ +char * +AccessibleAction_getName (AccessibleAction *obj, + long int i) +{ + dbus_int32_t d_i = i; + char *retval; + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_action, "getName", NULL, "i=>s", d_i, &retval); + + cspi_return_val_if_ev ("getName", NULL); + + return retval; +} + +/** + * AccessibleAction_doAction: + * @obj: a pointer to the #AccessibleAction to query. + * @i: an integer specifying which action to invoke. + * + * Invoke the action indicated by #index. + * + * Returns: #TRUE if the action is successfully invoked, otherwise #FALSE. + **/ +SPIBoolean +AccessibleAction_doAction (AccessibleAction *obj, + long int i) +{ + dbus_int32_t d_i = i; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_action, "doAction", NULL, "i=>b", d_i, &retval); + + cspi_return_val_if_ev ("doAction", FALSE); + + return retval; +} diff --git a/cspi/spi_component.c b/cspi/spi_component.c new file mode 100644 index 0000000..93a30c5 --- /dev/null +++ b/cspi/spi_component.c @@ -0,0 +1,346 @@ +/* + * 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. + * + * 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. + */ + +/* + * + * AccessibleComponent function implementations + * + */ + +#include + +/** + * AccessibleComponent_ref: + * @obj: a pointer to an object implementing #AccessibleComponent on which to operate. + * + * Increment the reference count for an #AccessibleComponent. + **/ +void +AccessibleComponent_ref (AccessibleComponent *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleComponent_unref: + * @obj: a pointer to the object implementing #AccessibleComponent on which to operate. + * + * Decrement the reference count for an #AccessibleComponent. + **/ +void +AccessibleComponent_unref (AccessibleComponent *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleComponent_contains: + * @obj: a pointer to the #AccessibleComponent to query. + * @x: a #long specifying the x coordinate in question. + * @y: a #long specifying the y coordinate in question. + * @ctype: the desired coordinate system of the point (@x, @y) + * (e.g. CSPI_COORD_TYPE_WINDOW, CSPI_COORD_TYPE_SCREEN). + * + * Query whether a given #AccessibleComponent contains a particular point. + * + * Returns: a #TRUE if the specified component contains the point (@x, @y), + * otherwise #FALSE. + **/ +SPIBoolean +AccessibleComponent_contains (AccessibleComponent *obj, + long int x, + long int y, + AccessibleCoordType ctype) +{ + dbus_bool_t retval; + dbus_int32_t d_x = x, d_y = y; + dbus_uint16_t d_ctype = ctype; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_component, "contains", NULL, "iin=>b", d_x, d_y, d_ctype, &retval); + + cspi_return_val_if_ev ("contains", FALSE); + + return retval; +} + +/** + * AccessibleComponent_getAccessibleAtPoint: + * @obj: a pointer to the #AccessibleComponent to query. + * @x: a #long specifying the x coordinate of the point in question. + * @y: a #long specifying the y coordinate of the point in question. + * @ctype: the coordinate system of the point (@x, @y) + * (e.g. CSPI_COORD_TYPE_WINDOW, CSPI_COORD_TYPE_SCREEN). + * + * Get the accessible child at a given coordinate within an #AccessibleComponent. + * + * Returns: a pointer to an #Accessible child of the specified component which + * contains the point (@x, @y), or NULL of no child contains the point. + **/ +Accessible * +AccessibleComponent_getAccessibleAtPoint (AccessibleComponent *obj, + long int x, + long int y, + AccessibleCoordType ctype) +{ + dbus_int32_t d_x = x, d_y = y; + dbus_uint16_t d_ctype = ctype; + char *path = NULL; + Accessible *retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_component, "getAccessibleAtPoint", NULL, "iin=>o", d_x, d_y, d_ctype, &path); + + retval = cspi_ref_related_accessible (obj, path); + g_free (path); + return retval; +} + +/** + * AccessibleComponent_getExtents: + * @obj: a pointer to the #AccessibleComponent to query. + * @x: a pointer to a #long into which the minimum x coordinate will be returned. + * @y: a pointer to a #long into which the minimum y coordinate will be returned. + * @width: a pointer to a #long into which the x extents (width) will be returned. + * @height: a pointer to a #long into which the y extents (height) will be returned. + * @ctype: the desired coordinate system into which to return the results, + * (e.g. CSPI_COORD_TYPE_WINDOW, CSPI_COORD_TYPE_SCREEN). + * + * Get the bounding box of the specified #AccessibleComponent. + * + **/ +void +AccessibleComponent_getExtents (AccessibleComponent *obj, + long int *x, + long int *y, + long int *width, + long int *height, + AccessibleCoordType ctype) +{ + dbus_int16_t d_ctype = ctype; + Accessibility_BoundingBox bbox; + + cspi_return_if_fail (obj != NULL); + + cspi_dbus_call (obj, spi_interface_component, "getExtents", NULL, "n=>(iiii)", d_ctype, &bbox); + if (!cspi_check_ev ("getExtents")) + { + *x = *y = *width = *height = 0; + } + else + { + *x = bbox.x; + *y = bbox.y; + *width = bbox.width; + *height = bbox.height; + } +} + +/** + * AccessibleComponent_getPosition: + * @obj: a pointer to the #AccessibleComponent to query. + * @x: a pointer to a #long into which the minimum x coordinate will be returned. + * @y: a pointer to a #long into which the minimum y coordinate will be returned. + * @ctype: the desired coordinate system into which to return the results, + * (e.g. CSPI_COORD_TYPE_WINDOW, CSPI_COORD_TYPE_SCREEN). + * + * Get the minimum x and y coordinates of the specified #AccessibleComponent. + * + **/ +void +AccessibleComponent_getPosition (AccessibleComponent *obj, + long int *x, + long int *y, + AccessibleCoordType ctype) +{ + dbus_int32_t d_x, d_y; + dbus_uint16_t d_ctype = ctype; + + cspi_return_if_fail (obj != NULL); + + cspi_dbus_call (obj, spi_interface_component, "getPosition", NULL, "n=>ii", d_ctype, &d_x, &d_y); + + if (!cspi_check_ev ("getPosition")) + { + *x = *y = 0; + } + else + { + *x = d_x; + *y = d_y; + } +} + +/** + * AccessibleComponent_getSize: + * @obj: a pointer to the #AccessibleComponent to query. + * @width: a pointer to a #long into which the x extents (width) will be returned. + * @height: a pointer to a #long into which the y extents (height) will be returned. + * + * Get the size of the specified #AccessibleComponent. + * + **/ +void +AccessibleComponent_getSize (AccessibleComponent *obj, + long int *width, + long int *height) +{ + dbus_int32_t d_w, d_h; + + cspi_return_if_fail (obj != NULL); + + cspi_dbus_call (obj, spi_interface_component, "getSize", NULL, "=>ii", &d_w, &d_h); + if (cspi_check_ev ("getSize")) + { + *width = *height = 0; + } + else + { + *width = d_w; + *height = d_h; + } +} + +/** + * AccessibleComponent_getLayer: + * @obj: a pointer to the #AccessibleComponent to query. + * + * Query which layer the component is painted into, to help determine its + * visibility in terms of stacking order. + * + * Returns: the #AccessibleComponentLayer into which this component is painted. + **/ +AccessibleComponentLayer +AccessibleComponent_getLayer (AccessibleComponent *obj) +{ + AccessibleComponentLayer retval; + dbus_uint32_t zlayer; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_component, "getLayer", NULL, "=>u", &zlayer); + + cspi_return_val_if_ev ("getLayer", SPI_LAYER_INVALID); + + switch (zlayer) + { + case Accessibility_LAYER_BACKGROUND: + retval = SPI_LAYER_BACKGROUND; + break; + case Accessibility_LAYER_CANVAS: + retval = SPI_LAYER_CANVAS; + break; + case Accessibility_LAYER_WIDGET: + retval = SPI_LAYER_WIDGET; + break; + case Accessibility_LAYER_MDI: + retval = SPI_LAYER_MDI; + break; + case Accessibility_LAYER_POPUP: + retval = SPI_LAYER_POPUP; + break; + case Accessibility_LAYER_OVERLAY: + retval = SPI_LAYER_OVERLAY; + break; + case Accessibility_LAYER_WINDOW: + retval = SPI_LAYER_WINDOW; + break; + default: + retval = SPI_LAYER_INVALID; + break; + } + + return retval; +} + +/** + * AccessibleComponent_getMDIZOrder: + * @obj: a pointer to the #AccessibleComponent to query. + * + * Query the z stacking order of a component which is in the MDI or window + * layer. (Bigger z-order numbers mean nearer the top) + * + * Returns: a short integer indicating the stacking order of the component + * in the MDI layer, or -1 if the component is not in the MDI layer. + **/ +short +AccessibleComponent_getMDIZOrder (AccessibleComponent *obj) +{ + dbus_uint16_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_component, "getMDIZOrder", NULL, "=>n", &retval); + + cspi_return_val_if_ev ("getMDIZOrder", FALSE); + + return retval; +} + +/** + * AccessibleComponent_grabFocus: + * @obj: a pointer to the #AccessibleComponent on which to operate. + * + * Attempt to set the keyboard input focus to the specified + * #AccessibleComponent. + * + * Returns: #TRUE if successful, #FALSE otherwise. + * + **/ +SPIBoolean +AccessibleComponent_grabFocus (AccessibleComponent *obj) +{ + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_component, "grabFocus", NULL, "=>b", &retval); + + cspi_return_val_if_ev ("grabFocus", FALSE); + + return retval; +} + +/** + * AccessibleComponent_getAlpha: + * @obj: The #AccessibleComponent to be queried. + * + * Get the opacity/alpha value of a component, if alpha blending is in use. + * + * Returns: the opacity value of a component, as a double between 0.0 and 1.0. + **/ +double +AccessibleComponent_getAlpha (AccessibleComponent *obj) +{ + double retval; + + cspi_return_val_if_fail (obj != NULL, 1.0); + + cspi_dbus_call (obj, spi_interface_component, "getAlpha", NULL, "=>d", &retval); + + cspi_return_val_if_ev ("getAlpha", 1.0); + + return retval; +} diff --git a/cspi/spi_editabletext.c b/cspi/spi_editabletext.c new file mode 100644 index 0000000..31ae429 --- /dev/null +++ b/cspi/spi_editabletext.c @@ -0,0 +1,264 @@ +/* + * 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. + * + * 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. + */ + +#include + +/** + * AccessibleEditableText_ref: + * @obj: a pointer to the #AccessibleEditableText object on which to operate. + * + * Increment the reference count for an #AccessibleEditableText object. + * Since AccessibleEditableText is derived from AccessibleText, + * this is the same as AccessibleText_ref(). + **/ +void +AccessibleEditableText_ref (AccessibleEditableText *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleEditableText_unref: + * @obj: a pointer to the #AccessibleEditableText object on which to operate. + * + * Decrement the reference count for an #AccessibleEdiitableText object. + * Since AccessibleEditableText is derived from AccessibleText, + * this is the same as AccessibleText_unref(). + **/ +void +AccessibleEditableText_unref (AccessibleEditableText *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleEditableText_setAttributes: + * @obj: a pointer to the #AccessibleEditableText object to modify. + * @attributes: a character string indicating the attributes to apply to the range, + * delimited by ':'. + * @startOffset: a #long indicating the start of the desired text range. + * @endOffset: a #long indicating the first character past the desired range. + * + * Set the attributes applied to a range of text from an #AccessibleEditableText + * object, and the bounds of the range. + * + * Returns: #TRUE if the operation was successful, otherwise #FALSE. + **/ +SPIBoolean +AccessibleEditableText_setAttributes (AccessibleEditableText *obj, + const char *attributes, + long int startPos, + long int endPos) +{ + dbus_int32_t d_startPos = startPos, d_endPos = endPos; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_editable_text, "setAttributes", NULL, "sii=>b", attributes, d_startPos, d_endPos, &retval); + + cspi_return_val_if_ev ("setAttributes", FALSE); + + return retval; +} + +/** + * AccessibleEditableText_setTextContents: + * @obj: a pointer to the #AccessibleEditableText object to modify. + * @newContents: a character string, encoded in UTF-8, which is to + * become the new text contents of the #AccessibleEditableText object. + * + * Replace the entire text contents of an #AccessibleEditableText object. + * + * Returns: #TRUE if the operation was successful, otherwise #FALSE. + **/ +SPIBoolean +AccessibleEditableText_setTextContents (AccessibleEditableText *obj, + const char *newContents) +{ + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_editable_text, "setTextContents", NULL, "s=>b", newContents, &retval); + + cspi_return_val_if_ev ("setTextContents", FALSE); + + return retval; +} + +/** + * AccessibleEditableText_insertText: + * @obj: a pointer to the #AccessibleEditableText object to modify. + * @position: an integer indicating the character offset at which to insert + * the new text. + * @text: a char* pointer to the text to insert, in UTF-8 encoding. + * @length: (frankly I'm not sure this parameter should be here) + * + * Insert text into an #AccessibleEditableText object. + * As with all character offsets, the specified @position may not be the + * same as the resulting byte offset, since the text is in a + * variable-width encoding. + * + * Returns: #TRUE if the operation was successful, otherwise #FALSE. + **/ +SPIBoolean +AccessibleEditableText_insertText (AccessibleEditableText *obj, + long int position, + const char *text, + long int length) +{ + dbus_int32_t d_position = position, d_length = length; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_editable_text, "insertText", NULL, "isi=>b", d_position, text, d_length, &retval); + + cspi_return_val_if_ev ("insertText", FALSE); + + return retval; +} + +/** + * AccessibleEditableText_copyText: + * @obj: a pointer to the #AccessibleEditableText object to modify. + * @startPos: an integer indicating the starting character offset + * of the text to copy. + * @endPos: an integer indicating the offset of the first character + * past the end of the text section to be copied. + * + * Copy text from an #AccessibleEditableText object into the clipboard. + * + * @see: AccessibleEditableText_pasteText + * + * Returns: #TRUE if the operation was successful, otherwise #FALSE. + **/ +SPIBoolean +AccessibleEditableText_copyText (AccessibleText *obj, + long int startPos, + long int endPos) +{ + dbus_int32_t d_startPos = startPos, d_endPos = endPos; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_editable_text, "copyText", NULL, "ii", startPos, endPos); + + cspi_return_val_if_ev ("copyText", FALSE); + + return TRUE; +} + +/** + * AccessibleEditableText_cutText: + * @obj: a pointer to the #AccessibleEditableText object to modify. + * @startPos: an integer indicating the starting character offset + * of the text to cut. + * @endPos: an integer indicating the offset of the first character + * past the end of the text section to be cut. + * + * Delete text from an #AccessibleEditableText object, copying the + * excised portion into the clipboard. + * + * @see: AccessibleEditableText_pasteText + * + * Returns: #TRUE if operation was successful, #FALSE otherwise. + **/ +SPIBoolean +AccessibleEditableText_cutText (AccessibleEditableText *obj, + long int startPos, + long int endPos) +{ + dbus_int32_t d_startPos = startPos, d_endPos = endPos; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_editable_text, "cutText", NULL, "ii=>b", d_startPos, d_endPos, &retval); + + cspi_return_val_if_ev ("cutText", FALSE); + + return retval; +} + +/** + * AccessibleEditableText_deleteText: + * @obj: a pointer to the #AccessibleEditableText object to modify. + * @startPos: an integer indicating the starting character offset + * of the text to delete. + * @endPos: an integer indicating the offset of the first character + * past the end of the text section to be deleted. + * + * Delete text from an #AccessibleEditableText object, without copying the + * excised portion into the clipboard. + * + * @see: AccessibleEditableText_cutText + * + * Returns: #TRUE if the operation was successful, otherwise #FALSE. + **/ +SPIBoolean +AccessibleEditableText_deleteText (AccessibleEditableText *obj, + long startPos, + long endPos) +{ + dbus_int32_t d_startPos = startPos, d_endPos = endPos; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_editable_text, "deleteText", NULL, "ii=>b", d_startPos, d_endPos, &retval); + + cspi_return_val_if_ev ("deleteText", FALSE); + + return retval; +} + +/** + * AccessibleEditableText_pasteText: + * @obj: a pointer to the #AccessibleEditableText object to modify. + * @position: an integer indicating the character offset at which to insert + * the new text. + * + * Insert text from the clipboard into an #AccessibleEditableText object. + * As with all character offsets, the specified @position may not be the + * same as the resulting byte offset, since the text is in a + * variable-width encoding. + * + * Returns: #TRUE if the operation was successful, otherwise #FALSE. + **/ +SPIBoolean +AccessibleEditableText_pasteText (AccessibleEditableText *obj, + long int position) +{ + dbus_int32_t d_position = position; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_editable_text, "pasteText", NULL, "i=>b", d_position, &retval); + + cspi_return_val_if_ev ("pasteText", FALSE); + + return retval; +} diff --git a/cspi/spi_event.c b/cspi/spi_event.c new file mode 100644 index 0000000..32719b7 --- /dev/null +++ b/cspi/spi_event.c @@ -0,0 +1,1230 @@ +/* + * AT-SPI - Assistive Technology Service Provider Interface + * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) + * + * 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 + * 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. + */ + +#include + +static GSList *_cspi_event_queue = NULL; + +/** + * SPI_freeAccessibleKeySet: + * @keyset: An AccessibleKeyset to free. + * + * Release the memory used by an AccessibleKeySet. + * + **/ +void +SPI_freeAccessibleKeySet (AccessibleKeySet *keyset) +{ + int i = 0; + g_free (keyset->keysyms); + g_free (keyset->keycodes); + while (keyset->keystrings [i]) + { + g_free (keyset->keystrings [i++]); + } + g_free (keyset->keystrings); + g_free (keyset); +} + +/** + * SPI_createAccessibleKeySet: + * @len: the number of key values in the key set. + * @keysyms: a UTF-8 string containing symbolic key values to be matched, or NULL if + * matching is performed against other key values instead. + * @keycodes: an array of unsigned short values which are the hardware keycodes + * to be matched, or NULL if the keyset is specified solely by keysyms + * and/or keystrings. + * @keystrings: an array of null-terminated character strings which specify key + * name values to match, or NULL if the keyset is specified solely by + * keycodes and/or keysyms. + * + * Create a new #AccessibleKeySet of a specified length. + * A KeySet is used typically to match key event values, and a matches are made + * using the following criteria: a match exists with a key event if all non-null + * i-th members of the keyset match the key event. + * If both keystring and keysym values are NULL, a keycode value match is + * forced, thus the match for keysym=0, keycode=0, keystring=NULL is + * keycode 0. + * + * Returns: a pointer to a newly-created #AccessibleKeySet. + * + **/ +AccessibleKeySet * +SPI_createAccessibleKeySet (int len, const char *keysyms, short *keycodes, + const char **keystrings) +{ + AccessibleKeySet *keyset = g_new0 (AccessibleKeySet, 1); + int i, keysym_len = 0; + const char *keysym_ptr = keysyms; + keyset->len = len; + keyset->keysyms = g_new0 (unsigned long, len); + keyset->keycodes = g_new0 (unsigned short, len); + keyset->keystrings = g_new0 (char *, len); + if (keysyms) + { + keysym_len = g_utf8_strlen (keysyms, -1); + } + for (i = 0; i < len; ++i) + { + if (i < keysym_len) + { + keyset->keysyms [i] = (unsigned long) g_utf8_get_char (keysym_ptr); + keysym_ptr = g_utf8_find_next_char (keysym_ptr, NULL); + } + else + { + keyset->keysyms [i] = 0; + } + if (keycodes) + { + keyset->keycodes [i] = keycodes [i]; + } + if (keystrings) + { + keyset->keystrings [i] = g_strdup (keystrings [i]); + } + } + return keyset; +} + +/** + * SPI_createAccessibleEventListener: + * @callback : an #AccessibleEventListenerCB callback function, or NULL. + * @user_data: a pointer to data which will be passed to the callback when invoked. + * + * Create a new #AccessibleEventListener with a specified (in-process) callback function. + * + * Returns: a pointer to a newly-created #AccessibleEventListener. + * + **/ +AccessibleEventListener * +SPI_createAccessibleEventListener (AccessibleEventListenerCB callback, + void *user_data) +{ + AccessibleEventListener *listener = cspi_event_listener_new (); + if (callback) + { + AccessibleEventListener_addCallback (listener, callback, user_data); + } + return listener; +} + +/** + * AccessibleEventListener_addCallback: + * @listener: the #AccessibleEventListener instance to modify. + * @callback: an #AccessibleEventListenerCB function pointer. + * @user_data: a pointer to data which will be passed to the callback when invoked. + * + * Add an in-process callback function to an existing AccessibleEventListener. + * Note that the callback function must live in the same address + * space as the AccessibleEventListener implementation code, thus one should not + * use this function to attach callbacks to a 'remote' event listener + * (that is, one that was not created by a client call to + * createAccessibleEventListener (); + * + * Returns: #TRUE if successful, otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleEventListener_addCallback (AccessibleEventListener *listener, + AccessibleEventListenerCB callback, + void *user_data) +{ + cspi_event_listener_add_cb (listener, callback, user_data); + return TRUE; +} + +/** + * AccessibleEventListener_unref: + * @listener: a pointer to the #AccessibleEventListener being operated on. + * + * Decrements an #AccessibleEventListener's reference count. + **/ +void +AccessibleEventListener_unref (AccessibleEventListener *listener) +{ + cspi_event_listener_unref (listener); +} + +/** + * AccessibleEventListener_removeCallback: + * @listener: the #AccessibleEventListener instance to modify. + * @callback: an #AccessibleEventListenerCB function pointer. + * + * Remove an in-process callback function from an existing AccessibleEventListener. + * + * Returns: #TRUE if successful, otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleEventListener_removeCallback (AccessibleEventListener *listener, + AccessibleEventListenerCB callback) +{ + cspi_event_listener_remove_cb (listener, callback); + return TRUE; +} + +/** + * SPI_createAccessibleKeystrokeListener: + * @callback : an #AccessibleKeystrokeListenerCB callback function, or NULL. + * @user_data: a pointer to data which will be passed to the callback when invoked. + * + * Create a new #AccessibleKeystrokeListener with a specified callback function. + * + * Returns: a pointer to a newly-created #AccessibleKeystrokeListener. + * + **/ +AccessibleKeystrokeListener * +SPI_createAccessibleKeystrokeListener (AccessibleKeystrokeListenerCB callback, + void *user_data) +{ + AccessibleDeviceListener *listener = cspi_device_listener_new (); + if (callback) + { + AccessibleDeviceListener_addCallback (listener, callback, user_data); + } + return listener; +} + +/** + * AccessibleKeystrokeListener_addCallback: + * @listener: the #AccessibleKeystrokeListener instance to modify. + * @callback: an #AccessibleKeystrokeListenerCB function pointer. + * @user_data: a pointer to data which will be passed to the callback when invoked. + * + * Add an in-process callback function to an existing #AccessibleKeystrokeListener. + * + * Returns: #TRUE if successful, otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleKeystrokeListener_addCallback (AccessibleKeystrokeListener *listener, + AccessibleKeystrokeListenerCB callback, + void *user_data) +{ + cspi_device_listener_add_cb (listener, callback, user_data); + return TRUE; +} + +/** + * AccessibleKeystrokeListener_removeCallback: + * @listener: the #AccessibleKeystrokeListener instance to modify. + * @callback: an #AccessibleKeystrokeListenerCB function pointer. + * + * Remove an in-process callback function from an existing #AccessibleKeystrokeListener. + * + * Returns: #TRUE if successful, otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleKeystrokeListener_removeCallback (AccessibleKeystrokeListener *listener, + AccessibleKeystrokeListenerCB callback) +{ + cspi_device_listener_remove_cb (listener, callback); + return TRUE; +} + +/** + * AccessibleKeystrokeListener_unref: + * @listener: a pointer to the #AccessibleKeystrokeListener being operated on. + * + * Decrements an #AccessibleKeystrokeListener's reference count. + **/ +void +AccessibleKeystrokeListener_unref (AccessibleKeystrokeListener *listener) +{ + cspi_device_listener_unref (listener); +} + +/** + * SPI_createAccessibleDeviceListener: + * @callback : an #AccessibleDeviceListenerCB callback function, or NULL. + * @user_data: a pointer to data which will be passed to the callback when invoked. + * + * Create a new #AccessibleDeviceListener with a specified callback function. + * + * Returns: a pointer to a newly-created #AccessibleDeviceListener. + * + **/ +AccessibleDeviceListener * +SPI_createAccessibleDeviceListener (AccessibleDeviceListenerCB callback, + void *user_data) +{ + AccessibleDeviceListener *listener = cspi_device_listener_new (); + if (callback) + { + AccessibleDeviceListener_addCallback (listener, callback, user_data); + } + return listener; +} + +/** + * AccessibleDeviceListener_addCallback: + * @listener: the #AccessibleDeviceListener instance to modify. + * @callback: an #AccessibleDeviceListenerCB function pointer. + * @user_data: a pointer to data which will be passed to the callback when invoked. + * + * Add an in-process callback function to an existing #AccessibleDeviceListener. + * + * Returns: #TRUE if successful, otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleDeviceListener_addCallback (AccessibleDeviceListener *listener, + AccessibleDeviceListenerCB callback, + void *user_data) +{ + cspi_device_listener_add_cb (listener, callback, user_data); + return TRUE; +} + +/** + * AccessibleDeviceListener_removeCallback: + * @listener: the #AccessibleDeviceListener instance to modify. + * @callback: an #AccessibleDeviceListenerCB function pointer. + * + * Remove an in-process callback function from an existing #AccessibleDeviceListener. + * + * Returns: #TRUE if successful, otherwise #FALSE. + * + **/ +SPIBoolean +AccessibleDeviceListener_removeCallback (AccessibleDeviceListener *listener, + AccessibleDeviceListenerCB callback) +{ + cspi_device_listener_remove_cb (listener, callback); + return TRUE; +} + +/** + * AccessibleDeviceListener_unref: + * @listener: a pointer to the #AccessibleDeviceListener being operated on. + * + * Decrements an #AccessibleDeviceListener's reference count. + **/ +void +AccessibleDeviceListener_unref (AccessibleDeviceListener *listener) +{ + cspi_device_listener_unref (listener); +} + +static char * +cspi_internal_event_get_text (const InternalEvent *e) +{ + g_return_val_if_fail (e, NULL); + if (e->event.v_type == EVENT_DATA_STRING) + { + return g_strdup (e->event.v.text? e->event.v.text: ""); + } + return NULL; +} + +static Accessible * +cspi_internal_event_get_object (const InternalEvent *e) +{ + g_return_val_if_fail (e, NULL); + if (e->event.v_type == EVENT_DATA_OBJECT) + { + cspi_object_ref (e->event.v.accessible); + return e->event.v.accessible; + } + return NULL; +} + +static SPIRect * +cspi_internal_event_get_rect (const InternalEvent *e) +{ + g_return_val_if_fail (e, NULL); + if (e->event.v_type == EVENT_DATA_RECT) + { + SPIRect *rect = g_new (SPIRect, 1); + if (rect) memcpy (rect, &e->event.v.rect, sizeof(*rect)); + return rect; + } + return NULL; +} + +/** + * AccessibleEvent_getSourceName: + * @e: an #AccessibleEvent to be queried. + * + * Get the 'accessible-name' of the object emitting the event. + * + * Returns: The name of the event source, or NULL if the event source cannot be identified + * or does not report a name. + */ +char* AccessibleEvent_getSourceName (const AccessibleEvent *e) +{ + if (e && e->source) + { + return Accessible_getName (e->source); + } + return NULL; +} + +/** + * AccessibleEvent_getSourceRole: + * @e: an #AccessibleEvent to be queried. + * + * Get the #AccessibleRole of the object emitting the event. + * + * Returns: #AccessibleRole of the event source, or SPI_ROLE_UNKNOWN + * if the event source's role is unknown or unspecified. + * (Some kinds of events, such as 'mouse:' events or + * toolkit events, don't have associated object roles.) + */ +AccessibleRole AccessibleEvent_getSourceRole (const AccessibleEvent *e) +{ + if (e && e->source) + { + return Accessible_getRole (e->source); + } + return SPI_ROLE_UNKNOWN; +} + +/** + * AccessibleEvent_getSourceApplication: + * @e: an #AccessibleEvent to be queried. + * + * Get the #Application hosting the object which emitted the event. + * + * Returns: A pointer to the host #Application contining the event source + * component. + */ +#if 0 +AccessibleApplication* AccessibleEvent_getSourceApplication (const AccessibleEvent *e) +{ +xyzzy + InternalEvent *ie = (InternalEvent *)e; + CORBA_any *any = ((ie && ie->data) ? (CORBA_any *)ie->data : NULL); + if (any && + CORBA_TypeCode_equivalent (any->_type, + TC_Accessibility_EventDetails, NULL)) + { + Accessibility_EventDetails *details = (Accessibility_EventDetails *) any->_value; + return cspi_object_take (details->host_application); + } + else + return NULL; +} +#endif + +/** + * AccessibleEvent_getSourceDetails: + * @e: an #AccessibleEvent to be queried. + * @name: a pointer to a character string which will point to the name of the event source + * on successful completion of the call. + * @role: a pointer to an #AccessibleRole which will point to the role of the event source + * on successful completion of the call. + * @app: A pointer to an #AccessibleApplication which points to the host application for this event + * on successful completion of the call. + * + * Get the host #Application, "accessible name", and #AccessibleRole + * of the object which emitted the event. + * + * Returns: TRUE if the source details were successfully retrieved, + * FALSE if they were not, either due to error, incomplete data, + * or the fact that the event did not encapsulate the required data. + */ +#if 0 +SPIBoolean AccessibleEvent_getSourceDetails (const AccessibleEvent *e, + char **name, AccessibleRole *role, + AccessibleApplication **app) +{ + InternalEvent *ie = (InternalEvent *)e; + CORBA_any *any = ((ie && ie->data) ? (CORBA_any *)ie->data : NULL); + if (any && + CORBA_TypeCode_equivalent (any->_type, + TC_Accessibility_EventDetails, NULL)) + { + Accessibility_EventDetails *details = (Accessibility_EventDetails *) any->_value; + *name = CORBA_string_dup (details->source_name); + *role = cspi_role_from_spi_role (details->source_role); + *app = cspi_object_take (details->host_application); + return TRUE; + } + else + { + *name = NULL; + *role = SPI_ROLE_UNKNOWN; + *app = NULL; + return FALSE; + } +} +#endif + +/** + * 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. */ + return cspi_internal_event_get_text (foo); +} + +/** + * AccessibleTextSelectionChangedEvent_getSelectionString: + * @e: a pointer to the #AccessibleEvent being queried. + * + * 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. */ + return cspi_internal_event_get_text (foo); +} + +/** + * AccessibleWindowEvent_getTitleString: + * @e: 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. */ + return cspi_internal_event_get_text (foo); +} + +/** + * AccessibleChildChangedEvent_getChildAccessible: + * @e: 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 longer a valid context #Accessible + * object for the event. + **/ +Accessible * +AccessibleChildChangedEvent_getChildAccessible (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + return (Accessible *) cspi_internal_event_get_object (foo); +} + +/** + * AccessibleParentChangedEvent_getParentAccessible: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type "object:property-change:accessible-parent" + * 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); +} + +/** + * AccessibleActiveDescendantChangedEvent_getActiveDescendant: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type "object:active-descendant-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 active descendant. + **/ +Accessible * +AccessibleActiveDescendantChangedEvent_getActiveDescendant (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + return (Accessible *) cspi_internal_event_get_object (foo); +} + +/** + * AccessibleTableSummaryChangedEvent_getSummaryAccessible: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type "object:property-changed:accessible-table-summary" + * 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 table summary. + **/ +Accessible * +AccessibleTableSummaryChangedEvent_getSummaryAccessible (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + return (Accessible *) cspi_internal_event_get_object (foo); +} + +/** + * AccessibleTableHeaderChangedEvent_getHeaderAccessible: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type + * "object:property-changed:accessible-table-row-header" or + * "object:property-changed:accessible-table-column-header" + * 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 table header. + **/ +Accessible * +AccessibleTableHeaderChangedEvent_getHeaderAccessible (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + return (Accessible *) cspi_internal_event_get_object (foo); +} + + +/** + * AccessibleTableCaptionChangedEvent_getCaptionString: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type + * "object:property-changed:accessible-table-caption-object" + * returning the text in the caption, if present. + * + * Returns: a UTF-8 text string indicating the text in the caption. + **/ +char * +AccessibleTableCaptionChangedEvent_getCaptionString (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + /* TODO: check the event type. */ + return cspi_internal_event_get_text (foo); +} + +/** + * AccessibleTableRowDescriptionChangedEvent_getDescriptionString: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type + * "object:property-changed:accessible-table-row-description" + * returning the new table row description. + * + * Returns: a UTF-8 text string representing the recently changed + * table row description + **/ +char * +AccessibleTableRowDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + /* TODO: check the event type. */ + return cspi_internal_event_get_text (foo); +} + +/** + * AccessibleTableColumnDescriptionChangedEvent_getDescriptionString: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type + * "object:property-changed:accessible-table-column-description" + * returning the new table column description. + * + * Returns: a UTF-8 text string representing the recently changed + * table column description + **/ +char * +AccessibleTableColumnDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + /* TODO: check the event type. */ + return cspi_internal_event_get_text (foo); +} + +/** + * AccessibleDescriptionChangedEvent_getDescriptionString: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type + * "object:property-changed:accessible-description" + * returning the new description. + * + * Returns: a UTF-8 text string representing the recently changed + * description + **/ +char * +AccessibleDescriptionChangedEvent_getDescriptionString (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + /* TODO: check the event type. */ + return cspi_internal_event_get_text (foo); +} + +/** + * AccessibleBoundsChangedEvent_getNewBounds: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type "object:bounds-changed", + * returning a pointer to an SPIRect structure containing the + * new bounds, or NULL on error. + * The returned structure should be freed with SPI_freeRect when + * the caller has finished referencing it. + * + * @Since: AT-SPI 1.6 + * + * Returns: a pointer to an SPIRect defining the new object bounds. + **/ +SPIRect * +AccessibleBoundsChangedEvent_getNewBounds (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + /* TODO: check the event type. */ + return cspi_internal_event_get_rect (foo); +} + +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); +} + +/** + * AccessibleNameChangedEvent_getNameString: + * @e: a pointer to the #AccessibleEvent being queried. + * + * Queries an #AccessibleEvent of type "object:property-change:accessible_name:", + * returning the name. + * + * Returns: a UTF-8 text string representing the name of the + * object which recently changed. + **/ +char * +AccessibleNameChangedEvent_getNameString (const AccessibleEvent *e) +{ + const InternalEvent *foo = (InternalEvent *) e; + return cspi_internal_event_get_text (foo); +} + +/** + * AccessibleEvent_ref: + * @e: a pointer to the #AccessibleEvent being referenced. + * + * Increments by 1 the reference count of the event + * + * Returns: TRUE if the function succeeded; FALSE if the pointer is not a + * valid event. + **/ +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; +} + +/** + * AccessibleEvent_unref: + * @e: a pointer to the #AccessibleEvent being referenced. + * + * Decrements by 1 the reference count of the event. The event is destroyed + * when the reference count recahes zero. + * + **/ +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); + g_free ((gpointer)e->type); + Accessible_unref (e->source); + if (event->event.v_type == EVENT_DATA_OBJECT) + { + Accessible_unref (event->event.v.accessible); + } + g_free ((gpointer)e); + } + } + } +} + +typedef struct +{ + CSpiEventListener *listener; + char *event; + char *detail; +} CSpiEventListenerEntry; + +static GList *event_listeners = NULL; + +static dbus_bool_t +demarshal_rect (DBusMessageIter *iter, SPIRect *rect) +{ + dbus_int32_t x, y, width, height; + DBusMessageIter iter_struct; + + dbus_message_iter_recurse (iter, &iter_struct); + if (dbus_message_iter_get_arg_type (&iter_struct) != DBUS_TYPE_INT32) return FALSE; + dbus_message_iter_get_basic (&iter_struct, &x); + dbus_message_iter_next (&iter_struct); + if (dbus_message_iter_get_arg_type (&iter_struct) != DBUS_TYPE_INT32) return FALSE; + dbus_message_iter_get_basic (&iter_struct, &y); + dbus_message_iter_next (&iter_struct); + if (dbus_message_iter_get_arg_type (&iter_struct) != DBUS_TYPE_INT32) return FALSE; + dbus_message_iter_get_basic (&iter_struct, &width); + dbus_message_iter_next (&iter_struct); + if (dbus_message_iter_get_arg_type (&iter_struct) != DBUS_TYPE_INT32) return FALSE; + dbus_message_iter_get_basic (&iter_struct, &height); + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; + return TRUE; +} + +static gboolean +parse_eventType (const char *eventType, char **type, char **detail, char **matchrule) +{ + char *p, *q; + char *t, *d; + + p = strchr (eventType, ':'); + if (!p) return FALSE; + p = strchr (p + 1, ':'); + if (!p) p = eventType + strlen (eventType); + t = g_malloc (p - eventType + 1); + if (t) + { + memcpy (t, eventType, p - eventType); + t[p - eventType] = '\0'; + } + else return FALSE; + if (*p == ':') + { + d = g_strdup (p + 1); + if (!d) + { + g_free (t); + return FALSE; + } + } + else d = NULL; + if ((p = strchr (t, ':'))) + { + *p = (p[1] == '\0'? '\0': '_'); + } + while ((p = strchr (t, '-'))) *p = '_'; + if (matchrule) + { + *matchrule = g_strdup_printf ("type='signal',interface='%s',member='%s'", spi_interface_accessible, t); + if (!*matchrule) + { + g_free (t); + if (d) g_free (d); + return FALSE; + } + } + if (type) *type = t; + if (detail) *detail = d; + return TRUE; +} + +static void listener_data_free (CSpiEventListenerEntry *e) +{ + g_free (e->event); + if (e->detail) g_free (e->detail); + g_free (e); +} + +/** + * SPI_registerGlobalEventListener: + * @listener: the #AccessibleEventListener to be registered against an + * event type. + * @eventType: a character string indicating the type of events for which + * notification is requested. Format is + * EventClass:major_type:minor_type:detail + * where all subfields other than EventClass are optional. + * EventClasses include "object", "window", "mouse", + * and toolkit events (e.g. "Gtk", "AWT"). + * Examples: "focus:", "Gtk:GtkWidget:button_press_event". + * + * Legal object event types: + * + * (property change events) + * + * object:property-change + * object:property-change:accessible-name + * object:property-change:accessible-description + * object:property-change:accessible-parent + * object:property-change:accessible-value + * object:property-change:accessible-role + * object:property-change:accessible-table-caption + * object:property-change:accessible-table-column-description + * object:property-change:accessible-table-column-header + * object:property-change:accessible-table-row-description + * object:property-change:accessible-table-row-header + * object:property-change:accessible-table-summary + * + * (other object events) + * + * object:state-changed + * object:children-changed + * object:visible-data-changed + * object:selection-changed + * object:text-selection-changed + * object:text-changed + * object:text-caret-moved + * object:row-inserted + * object:row-reordered + * object:row-deleted + * object:column-inserted + * object:column-reordered + * object:column-deleted + * object:model-changed + * object:active-descendant-changed + * + * (window events) + * + * window:minimize + * window:maximize + * window:restore + * window:close + * window:create + * window:reparent + * window:desktop-create + * window:desktop-destroy + * window:activate + * window:deactivate + * window:raise + * window:lower + * window:move + * window:resize + * window:shade + * window:unshade + * window:restyle + * + * (other events) + * + * focus: + * mouse:abs + * mouse:rel + * mouse:b1p + * mouse:b1r + * mouse:b2p + * mouse:b2r + * mouse:b3p + * mouse:b3r + * + * NOTE: this string may be UTF-8, but should not contain byte value 56 + * (ascii ':'), except as a delimiter, since non-UTF-8 string + * delimiting functions are used internally. + * In general, listening to + * toolkit-specific events is not recommended. + * + * Add an in-process callback function to an existing AccessibleEventListener. + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_registerGlobalEventListener (AccessibleEventListener *listener, + const char *eventType) +{ + CSpiEventListenerEntry *e; + char *matchrule; + DBusError error; + GList *new_list; + + if (!listener) + { + return FALSE; + } + + e = g_new (CSpiEventListenerEntry, 1); + if (!e) return FALSE; + e->listener = listener; + parse_eventType (eventType, &e->event, &e->detail, &matchrule); + new_list = g_list_prepend (event_listeners, e); + if (!new_list) + { + listener_data_free (e); + return FALSE; + } + event_listeners = new_list; + dbus_error_init (&error); + dbus_bus_add_match (cspi_bus(), matchrule, &error); + if (error.message) + { + g_warning ("Adding match: %s", error.message); + } + return TRUE; +} + +/** + * SPI_deregisterGlobalEventListenerAll: + * @listener: the #AccessibleEventListener to be registered against + * an event type. + * + * deregisters an AccessibleEventListener from the registry, for all + * event types it may be listening to. Use + * AccessibleEventListener_unref to release the + * listener reference. + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_deregisterGlobalEventListenerAll (AccessibleEventListener *listener) +{ + GList *l; + + if (!listener) + { + return FALSE; + } + + for (l = event_listeners; l;) + { + CSpiEventListenerEntry *e = l->data; + if (e->listener == listener) + { + listener_data_free (e); + l = g_list_remove (l, e); + } + else l = g_list_next (l); + } + return TRUE; +} + +/** + * SPI_deregisterGlobalEventListener: + * @listener: the #AccessibleEventListener registered against an event type. + * @eventType: a string specifying the event type for which this + * listener is to be deregistered. + * + * deregisters an AccessibleEventListener from the registry, for a specific + * event type. + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_deregisterGlobalEventListener (AccessibleEventListener *listener, + const char *eventType) +{ + char *type, *detail, *matchrule; + GList *l; + + if (!parse_eventType (eventType, &type, &detail, &matchrule)) + { + return FALSE; + } + if (!listener) + { + return FALSE; + } + + for (l = event_listeners; l;) + { + CSpiEventListenerEntry *e = l->data; + if (e->listener == listener && !strcmp (e->event, type) && (e->detail == detail || !strcmp (e->detail, detail))) + { + DBusError error; + listener_data_free (e); + l = g_list_remove (l, e); + dbus_error_init (&error); + dbus_bus_remove_match (cspi_bus(), matchrule, &error); + } + else l = g_list_next (l); + } + g_free (type); + if (detail) g_free (detail); + g_free (matchrule); + return TRUE; +} + +void +cspi_dispatch_event (AccessibleEvent *e) +{ + char *event, *detail; + GList *l; + + parse_eventType (e->type, &event, &detail, NULL); + for (l = event_listeners; l; l = g_list_next (l)) + { + CSpiEventListenerEntry *entry = l->data; + if (!strcmp (event, entry->event) && + (entry->detail == NULL || !strcmp (detail, entry->detail))) + { + CSpiEventListenerClass *klass = CSPI_EVENT_LISTENER_GET_CLASS (entry->listener); + if (klass->event) (*klass->event)(entry->listener, e); + } + } + if (detail) g_free (detail); + g_free (event); +} + +DBusHandlerResult +cspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data) +{ + char *detail = NULL; + const char *event = dbus_message_get_member (message); + DBusMessageIter iter, iter_variant; + dbus_message_iter_init (message, &iter); + AccessibleEvent e; + dbus_int32_t detail1, detail2; + char *p; + + g_return_if_fail (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic (&iter, &detail); + dbus_message_iter_next (&iter); + g_return_if_fail (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_INT32); + dbus_message_iter_get_basic (&iter, &detail1); + e.detail1 = detail1; + dbus_message_iter_next (&iter); + g_return_if_fail (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_INT32); + dbus_message_iter_get_basic (&iter, &detail2); + e.detail2 = detail2; + dbus_message_iter_next (&iter); +printf("event: %s %s\n", event, detail); + e.type = g_strdup (event); + p = strchr (e.type, '_'); + if (p) *p = ':'; + p = g_strconcat (e.type, ":", detail, NULL); + if (p) + { + g_free (e.type); + e.type = p; + } + while ((p = strchr (p, '_'))) *p = '-'; + e.source = cspi_ref_accessible (dbus_message_get_sender(message), dbus_message_get_path(message)); + dbus_message_iter_recurse (&iter, &iter_variant); + switch (dbus_message_iter_get_arg_type (&iter_variant)) + { + case DBUS_TYPE_OBJECT_PATH: + { + char *p; + dbus_message_iter_get_basic (&iter_variant, &p); + e.v_type = EVENT_DATA_OBJECT; + e.v.accessible = cspi_ref_accessible (dbus_message_get_sender(message), p); + break; + } + case DBUS_TYPE_STRING: + { + char *p; + dbus_message_iter_get_basic (&iter_variant, &p); + e.v_type = EVENT_DATA_STRING; + e.v.text = g_strdup (p); + break; + } + case DBUS_TYPE_STRUCT: + { + if (demarshal_rect (&iter_variant, &e.v.rect)) + { + e.v_type = EVENT_DATA_RECT; + } + break; + } + default: + break; + } + cspi_dispatch_event (&e); + return DBUS_HANDLER_RESULT_HANDLED; +} diff --git a/cspi/spi_hyperlink.c b/cspi/spi_hyperlink.c new file mode 100644 index 0000000..45f7256 --- /dev/null +++ b/cspi/spi_hyperlink.c @@ -0,0 +1,179 @@ +/* + * 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. + * + * 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. + */ + +#include + +/** + * AccessibleHyperlink_ref: + * @obj: a pointer to the #AccessibleHyperlink object on which to operate. + * + * Increment the reference count for an #AccessibleHyperlink object. + **/ +void +AccessibleHyperlink_ref (AccessibleHyperlink *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleHyperlink_unref: + * @obj: a pointer to the #AccessibleHyperlink object on which to operate. + * + * Decrement the reference count for an #AccessibleHyperlink object. + **/ +void +AccessibleHyperlink_unref (AccessibleHyperlink *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleHyperlink_getNAnchors: + * @obj: a pointer to the #AccessibleHyperlink object on which to operate. + * + * Get the total number of anchors which an #AccessibleHyperlink implementor has. + * Though typical hyperlinks have only one anchor, client-side image maps and + * other hypertext objects may potentially activate or refer to multiple + * URIs. For each anchor there is a corresponding URI and object. + * @see AccessibleHyperlink_getURI() and AccessibleHyperlink_getObject(). + * + * Returns: a #long indicating the number of anchors in this hyperlink. + **/ +long +AccessibleHyperlink_getNAnchors (AccessibleHyperlink *obj) +{ + dbus_int16_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_hyperlink, "nAnchors", NULL, "n", &retval); + + cspi_return_val_if_ev ("getNAnchors", -1); + + return retval; +} + +/** + * AccessibleHyperlink_getURI: + * @obj: a pointer to the #AccessibleHyperlink implementor on which to operate. + * @i: a (zero-index) long integer indicating which hyperlink anchor to query. + * + * Get the URI associated with a particular hyperlink anchor. + * + * Returns: a UTF-8 string giving the URI of the @ith hyperlink anchor. + **/ +char * +AccessibleHyperlink_getURI (AccessibleHyperlink *obj, + long int i) +{ + dbus_int32_t d_i = i; + char *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_hyperlink, "getURI", NULL, "i=>s", d_i, &retval); + + cspi_return_val_if_ev ("getURI", NULL); + + return retval; +} + +/** + * AccessibleHyperlink_getObject: + * @obj: a pointer to the #AccessibleHyperlink implementor on which to operate. + * @i: a (zero-index) long integer indicating which hyperlink anchor to query. + * + * Get the object associated with a particular hyperlink anchor, as an #Accessible. + * + * Returns: an #Accessible that represents the object associated with the @ith anchor + * of the specified #AccessibleHyperlink. + **/ +Accessible* +AccessibleHyperlink_getObject (AccessibleHyperlink *obj, + long int i) +{ + dbus_int32_t d_i = i; + char *path; + Accessible *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_hyperlink, "getObject", NULL, "i=>o", d_i, &path); + retval = cspi_ref_related_accessible (obj, path); + g_free (path); +} + +/** + * AccessibleHyperlink_getIndexRange: + * @obj: a pointer to the #AccessibleHyperlink implementor on which to operate. + * @startIndex: a pointer to a long integer into which the starting + * offset of the text associated with this #AccessibleHyperlink is returned. + * @endIndex: a pointer to a long integer into which the offset of the first character + * after the text associated with this #AccessibleHyperlink is returned. + * + * + * Get the starting and ending character offsets of the text range associated with + * a #AccessibleHyperlink, in its originating #AccessibleHypertext. + **/ +void +AccessibleHyperlink_getIndexRange (AccessibleHyperlink *obj, + long int *startIndex, + long int *endIndex) +{ + dbus_int32_t si, ei; + + cspi_return_if_fail (obj != NULL); + + cspi_dbus_get_property (obj, spi_interface_hyperlink, "startIndex", NULL, "i", &si); + cspi_return_if_ev ("startIndex"); + cspi_dbus_get_property (obj, spi_interface_hyperlink, "endIndex", NULL, "i", &ei); + cspi_return_if_ev ("endIndex"); + *startIndex = si; + *endIndex = ei; +} + +/** + * AccessibleHyperlink_isValid: + * @obj: a pointer to the #AccessibleHyperlink on which to operate. + * + * Tell whether an #AccessibleHyperlink object is still valid with respect to its + * originating hypertext object. + * + * Returns: #TRUE of the specified #AccessibleHyperlink is still valid with respect + * to its originating #AccessibleHypertext object, #FALSE otherwise. + **/ +SPIBoolean +AccessibleHyperlink_isValid (AccessibleHyperlink *obj) +{ + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_hyperlink, "isValid", NULL, "=>b", &retval); + + cspi_return_val_if_ev ("isValid", FALSE); + + return retval; +} + + diff --git a/cspi/spi_hypertext.c b/cspi/spi_hypertext.c new file mode 100644 index 0000000..e6f7a7b --- /dev/null +++ b/cspi/spi_hypertext.c @@ -0,0 +1,138 @@ +/* + * 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. + * + * 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. + */ + +#include + +/** + * AccessibleHypertext_ref: + * @obj: a pointer to the #AccessibleHypertext object on which to operate. + * + * Increment the reference count for an #AccessibleHypertext object. + * Since AccessibleHypertext is derived from AccessibleText, + * this is the same as AccessibleText_unref(). + **/ +void +AccessibleHypertext_ref (AccessibleHypertext *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleHypertext_unref: + * @obj: a pointer to the #AccessibleHypertext object on which to operate. + * + * Decrement the reference count for an #AccessibleHypertext object. + * Since AccessibleHypertext is derived from AccessibleText, + * this is the same as AccessibleText_unref(). + **/ +void +AccessibleHypertext_unref (AccessibleHypertext *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleHypertext_getNLinks: + * @obj: a pointer to the #AccessibleHypertext implementor on which to operate. + * + * Get the total number of #AccessibleHyperlinks which an + * #AccessibleHypertext implementor has. + * + * Returns: a #long indicating the number of #AccessibleHyperlinks + * of the #AccessibleHypertext implementor, or -1 if + * the number cannot be determined (for example, if the + * #AccessibleHypertext object is so large that it is not + * all currently in the memory cache). + **/ +long +AccessibleHypertext_getNLinks (AccessibleHypertext *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_hypertext, "getNLinks", NULL, "=>i", &retval); + + cspi_return_val_if_ev ("getNLinks", -1); + + return retval; +} + +/** + * AccessibleHypertext_getLink: + * @obj: a pointer to the #AccessibleHypertext implementor on which to operate. + * @linkIndex: a (zero-index) long integer indicating which hyperlink to query. + * + * Get the #AccessibleHyperlink object at a specified index. + * + * Returns: the #AccessibleHyperlink object specified by #linkIndex. + **/ +AccessibleHyperlink * +AccessibleHypertext_getLink (AccessibleHypertext *obj, + long int linkIndex) +{ + dbus_int32_t d_linkIndex = linkIndex; + char *path; + AccessibleHyperlink *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_hypertext, "getLink", NULL, "i=>o", d_linkIndex, &path); + + cspi_return_val_if_ev ("getLink", NULL); + + retval = cspi_ref_related_accessible (obj, path); + g_free (path); + + return retval; +} + +/** + * AccessibleHypertext_getLinkIndex: + * @obj: a pointer to the #AccessibleHypertext implementor on which to operate. + * @characterOffset: an integer specifying the character offset to query. + * + * Get the index of the #AccessibleHyperlink object at a specified + * character offset. + * + * Returns: the linkIndex of the #AccessibleHyperlink active at + * character offset @characterOffset, or -1 if there is + * no hyperlink at the specified character offset. + **/ +long +AccessibleHypertext_getLinkIndex (AccessibleHypertext *obj, + long int characterOffset) +{ + dbus_int32_t d_characterOffset = characterOffset; + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_hypertext, "getLinkIndex", NULL, "i=>i", d_characterOffset, &retval); + + cspi_return_val_if_ev ("getLinkIndex", -1); + + return retval; +} + + diff --git a/cspi/spi_listener.c b/cspi/spi_listener.c new file mode 100644 index 0000000..3429386 --- /dev/null +++ b/cspi/spi_listener.c @@ -0,0 +1,406 @@ +/* + * AT-SPI - Assistive Technology Service Provider Interface + * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) + * + * Copyright 2002 Ximian Inc. + * Copyright 2002 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 + * 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. + */ + +#include "spi-private.h" +#include + +typedef struct +{ + union + { + AccessibleEventListenerCB event; + AccessibleDeviceListenerCB device_event; + gpointer method; + } cb; + gpointer user_data; +} EventHandler; + +GObjectClass *event_parent_class; +GObjectClass *device_parent_class; + +static guint32 _e_id = 0; + +/* + * Misc. helpers. + */ + +static EventHandler * +cspi_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 +cspi_event_handler_free (EventHandler *handler) +{ + g_free (handler); +} + +static GList * +cspi_event_list_remove_by_cb (GList *list, gpointer callback) +{ + GList *l, *next; + + for (l = list; l; l = next) + { + EventHandler *eh = l->data; + next = l->next; + + if (eh->cb.method == callback) + { + list = g_list_delete_link (list, l); + cspi_event_handler_free (eh); + } + } + + return list; +} + +/* + * Standard event dispatcher + */ + +G_DEFINE_TYPE (CSpiEventListener, cspi_event_listener, + G_TYPE_OBJECT) + +static void +cspi_event (CSpiEventListener *listener, + AccessibleEvent *event) +{ + GList *l; + CSpiEventListener *clistener = (CSpiEventListener *) listener; + InternalEvent *ievent; + AccessibleEvent *aevent; + + ievent = g_new0(InternalEvent, 1); + ievent->event.type = g_strdup (event->type); + ievent->event.source = event->source; + ievent->event.detail1 = event->detail1; + ievent->event.detail2 = event->detail2; + ievent->event.v_type = event->v_type; + if (event->v_type == EVENT_DATA_STRING) + { + ievent->event.v.text = g_strdup (event->v.text); + } + else memcpy (&ievent->event.v, &event->v, sizeof(event->v)); + ievent->id = _e_id++; + ievent->magic = SPI_INTERNAL_EVENT_MAGIC; + ievent->ref_count = 0; + aevent = (AccessibleEvent *)ievent; + Accessible_ref (aevent->source); + AccessibleEvent_ref (aevent); + + /* FIXME: re-enterancy hazard on this list */ + for (l = clistener->callbacks; l; l = l->next) + { + EventHandler *eh = l->data; + /* cast hides our private stuff from client handlers */ + eh->cb.event (aevent, eh->user_data); + } + + AccessibleEvent_unref (aevent); +} + +static guint listener_id = 0; +static GList *device_listeners = NULL; + +static gboolean +id_is_free (guint id) +{ + GList *l; + + for (l = device_listeners; l; l = g_list_next (l)) + { + CSpiDeviceListener *listener = l->data; + if (listener->id == id) return FALSE; + } + return TRUE; +} + +static void remove_listener (GObject *obj, gpointer data) +{ + device_listeners = g_list_remove (device_listeners, obj); +} + +static void +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) + { + cspi_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; +} + +gpointer +cspi_event_listener_new (void) +{ + CSpiEventListener *listener; + + listener = g_object_new (cspi_event_listener_get_type (), NULL); + + return listener; +} + +static void +cspi_event_listener_init (CSpiEventListener *listener) +{ +} + +void +cspi_event_listener_add_cb (AccessibleEventListener *al, + AccessibleEventListenerCB callback, + void *user_data) +{ + CSpiEventListener *listener = al; + + g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener)); + + listener->callbacks = g_list_prepend (listener->callbacks, + cspi_event_handler_new ((void *) callback, user_data)); +} + +void +cspi_event_listener_remove_cb (AccessibleEventListener *al, + AccessibleEventListenerCB callback) +{ + CSpiEventListener *listener = al; + + g_return_if_fail (CSPI_IS_EVENT_LISTENER (listener)); + + listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, (void *) callback); +} + +/* + * Device event handler + */ +static gboolean +cspi_device_event (CSpiDeviceListener *listener, + const Accessibility_DeviceEvent *event) +{ + GList *l; + CSpiDeviceListener *clistener = (CSpiDeviceListener *) listener; + AccessibleDeviceEvent anevent; + gboolean handled = FALSE; + + switch (event->type) + { + case Accessibility_KEY_PRESSED_EVENT: + anevent.type = SPI_KEY_PRESSED; + break; + case Accessibility_KEY_RELEASED_EVENT: + anevent.type = SPI_KEY_RELEASED; + break; + case Accessibility_BUTTON_PRESSED_EVENT: + anevent.type = SPI_BUTTON_PRESSED; + break; + case Accessibility_BUTTON_RELEASED_EVENT: + anevent.type = SPI_BUTTON_RELEASED; + break; + default: + anevent.type = 0; + break; + } + anevent.keyID = event->id; + anevent.keycode = event->hw_code; + anevent.timestamp = event->timestamp; + anevent.keystring = g_strdup (event->event_string); + anevent.modifiers = event->modifiers; + anevent.is_text = event->is_text; + + /* FIXME: re-enterancy hazard on this list */ + for (l = clistener->callbacks; l; l = l->next) + { + EventHandler *eh = l->data; + + if ((handled = eh->cb.device_event (&anevent, eh->user_data))) + { + break; + } + } + g_free (anevent.keystring); + + return handled; +} + +static void +cspi_device_listener_init (CSpiDeviceListener *listener) +{ + GList *new_list; + + do + { + listener->id = listener_id++; + } while (!id_is_free (listener->id)); + new_list = g_list_append (device_listeners, listener); + if (new_list) device_listeners = new_list; +} + +static void +cspi_device_listener_finalize (GObject *object) +{ + CSpiDeviceListener *listener = (CSpiDeviceListener *) object; + GList *l; + + for (l = listener->callbacks; l; l = l->next) + { + cspi_event_handler_free (l->data); + } + + g_list_free (listener->callbacks); + + device_parent_class->finalize (object); +} + +static void +cspi_device_listener_class_init (CSpiDeviceListenerClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + + device_parent_class = g_type_class_peek_parent (klass); + object_class->finalize = cspi_device_listener_finalize; + + klass->device_event = cspi_device_event; +} + +G_DEFINE_TYPE (CSpiDeviceListener, cspi_device_listener, + G_TYPE_OBJECT) + +gpointer +cspi_device_listener_new (void) +{ + CSpiEventListener *listener = g_object_new (cspi_device_listener_get_type (), NULL); + + return listener; +} + +void +cspi_device_listener_add_cb (AccessibleDeviceListener *al, + AccessibleDeviceListenerCB callback, + void *user_data) +{ + CSpiDeviceListener *listener = al; + + g_return_if_fail (CSPI_IS_DEVICE_LISTENER (listener)); + + listener->callbacks = g_list_prepend (listener->callbacks, + cspi_event_handler_new ((void *)callback, user_data)); +} + +void +cspi_device_listener_remove_cb (AccessibleDeviceListener *al, + AccessibleDeviceListenerCB callback) +{ + CSpiDeviceListener *listener = al; + + g_return_if_fail (CSPI_IS_DEVICE_LISTENER (listener)); + + listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, (void *) callback); +} + +void +cspi_event_listener_unref (AccessibleEventListener *listener) +{ + g_object_unref (G_OBJECT (listener)); +} + +void +cspi_device_listener_unref (AccessibleDeviceListener *listener) +{ + g_object_unref (G_OBJECT (listener)); +} + +static const char *deviceEvent_type = "(uinnisb)"; + +DBusHandlerResult +cspi_dbus_handle_deviceEvent (DBusConnection *bus, DBusMessage *message, void *data) +{ + const char *path = dbus_message_get_path (message); + int id; + Accessibility_DeviceEvent event; + CSpiDeviceListener *listener; + DBusMessageIter iter; + CSpiDeviceListenerClass *klass; + dbus_bool_t retval = FALSE; + GList *l; + DBusMessage *reply; + void *p = &event; + + if (sscanf (path, "/org/freedesktop/atspi/listeners/%d", &id) != 1) + { + g_warning ("Bad listener path: %s\n", path); + goto done; + } + for (l = device_listeners; l; l = g_list_next (l)) + { + listener = l->data; + if (listener->id == id) break; + } + if (!l) + { + goto done; + } + dbus_message_iter_init (message, &iter); + dbind_any_demarshal (iter, &deviceEvent_type, &p); + klass = CSPI_DEVICE_LISTENER_GET_CLASS (listener); + if (klass->device_event) + { + retval = (*klass->device_event) (listener, &event); + } +done: + reply = dbus_message_new_method_return (message); + if (reply) + { + dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &retval, DBUS_TYPE_INVALID); + dbus_connection_send (cspi_bus(), reply, NULL); + dbus_message_unref (reply); + } + return DBUS_HANDLER_RESULT_HANDLED; +} diff --git a/cspi/spi_main.c b/cspi/spi_main.c new file mode 100644 index 0000000..17c394e --- /dev/null +++ b/cspi/spi_main.c @@ -0,0 +1,1085 @@ +/* + * 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. + * + * 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. + */ + +/* + * + * Basic SPI initialization and event loop function prototypes + * + */ + +#include +#include +#include +#include +#include "spi.h" + +#undef DEBUG_OBJECTS + +static DBusConnection *bus = NULL; +static GHashTable *apps = NULL; +static GHashTable *live_refs = NULL; +static GQueue *exception_handlers = NULL; +static DBusError exception; + +static void +cspi_object_release (gpointer value) +{ +} + +gboolean +cspi_exception_throw (DBusError *error, char *desc_prefix) +{ + SPIExceptionHandler *handler = NULL; + SPIException ex; + if (exception_handlers) handler = g_queue_peek_head (exception_handlers); + + ex.type = SPI_EXCEPTION_SOURCE_UNSPECIFIED; + ex.source = NULL; + ex.code = SPI_EXCEPTION_UNSPECIFIED; + ex.error = error; + // TODO: Fill in description + + if (handler) + return (*handler) (&ex, FALSE); + else + return FALSE; /* means exception was not handled */ +} + +const char *spi_path_dec = SPI_DBUS_PATH_DEC; +const char *spi_path_registry = SPI_DBUS_PATH_REGISTRY; +const char *spi_bus_registry = SPI_DBUS_NAME_REGISTRY; +const char *spi_path_desktop = SPI_DBUS_PATH_DESKTOP; +const char *spi_interface_accessible = SPI_DBUS_INTERFACE_ACCESSIBLE; +const char *spi_interface_action = SPI_DBUS_INTERFACE_ACTION; +const char *spi_interface_application = SPI_DBUS_INTERFACE_APPLICATION; +const char *spi_interface_component = SPI_DBUS_INTERFACE_COMPONENT; +const char *spi_interface_dec = SPI_DBUS_INTERFACE_DEC; +const char *spi_interface_desktop = SPI_DBUS_INTERFACE_DESKTOP; +const char *spi_interface_device_event_listener = SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER; +const char *spi_interface_document = SPI_DBUS_INTERFACE_DOCUMENT; +const char *spi_interface_editable_text = SPI_DBUS_INTERFACE_EDITABLE_TEXT; +const char *spi_interface_hyperlink = SPI_DBUS_INTERFACE_HYPERLINK; +const char *spi_interface_hypertext = SPI_DBUS_INTERFACE_HYPERTEXT; +const char *spi_interface_image = SPI_DBUS_INTERFACE_IMAGE; +const char *spi_interface_registry = SPI_DBUS_INTERFACE_REGISTRY; +const char *spi_interface_selection = SPI_DBUS_INTERFACE_SELECTION; +const char *spi_interface_table = SPI_DBUS_INTERFACE_TABLE; +const char *spi_interface_text = SPI_DBUS_INTERFACE_TEXT; +const char *spi_interface_tree = SPI_DBUS_INTERFACE_TREE; +const char *spi_interface_value = SPI_DBUS_INTERFACE_VALUE; + +static const char *interfaces[] = +{ + SPI_DBUS_INTERFACE_ACCESSIBLE, + SPI_DBUS_INTERFACE_ACTION, + SPI_DBUS_INTERFACE_APPLICATION, + SPI_DBUS_INTERFACE_COMPONENT, + SPI_DBUS_INTERFACE_DOCUMENT, + SPI_DBUS_INTERFACE_EDITABLE_TEXT, + SPI_DBUS_INTERFACE_HYPERLINK, + SPI_DBUS_INTERFACE_HYPERTEXT, + SPI_DBUS_INTERFACE_IMAGE, + "org.freedesktop.atspi.LoginHelper", + SPI_DBUS_INTERFACE_SELECTION, + "org.freedesktop.atspi.Selector", + SPI_DBUS_INTERFACE_TABLE, + SPI_DBUS_INTERFACE_TEXT, + SPI_DBUS_INTERFACE_VALUE, + NULL +}; + +static gint get_iface_num (const char *iface) +{ + // TODO: Use a binary search or hash to improve performance + int i; + + for (i = 0; interfaces[i]; i++) + { + if (!strcmp(iface, interfaces[i])) return i; + } + return -1; +} + +SPIBoolean +cspi_accessible_is_a (Accessible *accessible, + const char *interface_name) +{ + int n; + + if (accessible == NULL) + { + return FALSE; + } + + n = get_iface_num (interface_name); + if (n == -1) return FALSE; + return (SPIBoolean)((accessible->interfaces & (1 << n))? TRUE: FALSE); +} + +static GHashTable * +cspi_get_live_refs (void) +{ + if (!live_refs) + { + live_refs = g_hash_table_new (g_direct_hash, g_direct_equal); + } + return live_refs; +} + +DBusConnection * +cspi_bus (void) +{ + return bus; +} + +SPIBoolean +cspi_exception (void) +{ + if (dbus_error_is_set (&exception)) + { + dbus_error_free (&exception); + return TRUE; + } + return FALSE; +} + +SPIBoolean cspi_check_ev (const char *error_string) +{ + // TODO: Store exception + return FALSE; +} + +Accessible * +cspi_object_add (Accessible *accessible) +{ + if (accessible) cspi_object_ref (accessible); + return accessible; +} + +void +cspi_object_ref (Accessible *accessible) +{ + g_return_if_fail (accessible != NULL); + +printf("ref: %p (%d)\n", accessible, accessible->ref_count);fflush(stdout); + accessible->ref_count++; + g_hash_table_insert (live_refs, accessible, accessible); +} + +#define APP_IS_REGISTRY(app) (!strcmp (app->bus_name, "org.freedesktop.atspi.registry")) + +static void +cspi_object_unref_internal (Accessible *accessible, gboolean defunct) +{ + gboolean cached; + + if (accessible == NULL) + { + return; + } + +printf("unref: %p (%d)\n", accessible, accessible->ref_count - 1);fflush(stdout); + if (--accessible->ref_count == 0 || (accessible->ref_count == 1 && !defunct) && g_hash_table_lookup (live_refs, accessible)) + { + AccessibleEvent e; + memset (&e, 0, sizeof(e)); + e.type = "object:state-change:defunct"; + e.source = accessible; + e.detail1 = 1; + cspi_dispatch_event (&e); + g_hash_table_remove (live_refs, accessible); + } + if (accessible->ref_count == 0) + { + if (APP_IS_REGISTRY (accessible->app)) + { + g_free (accessible->v.path); + } + g_free(accessible); + } +} + +void +cspi_object_unref (Accessible *accessible) +{ + cspi_object_unref_internal (accessible, FALSE); +} + +static void +cspi_cleanup (void) +{ + GHashTable *refs; + + cspi_streams_close_all (); + + refs = live_refs; + live_refs = NULL; + if (refs) + { + g_hash_table_destroy (refs); + } +} + +static gboolean SPI_inited = FALSE; + +static GHashTable *app_hash = NULL; + +static Accessible * +ref_accessible (CSpiApplication *app, const char *path) +{ + int id; + guint *id_val; + + if (sscanf (path, "/org/freedesktop/atspi/accessible/%d", &id) != 1) + { + return NULL; + } + Accessible *a = g_hash_table_lookup (app->hash, &id); + if (a) + { + cspi_object_ref (a); +printf("Got %p from %p for %d\n", a, app->hash, id);fflush(stdout); + return a; + } + id_val = g_new (guint, 1); + if (!id_val) return NULL; + *id_val = id; + a = g_new0 (Accessible, 1); + if (!a) + { + g_free (id_val); + return NULL; + } +printf("Inserting %p into %p for %d\n", a, app->hash, *id_val); + g_hash_table_insert (app->hash, id_val, a); + a->app = app; + a->v.id = id; + a->ref_count = 2; /* one for the caller, one for the hash */ + return a; +} + +static CSpiApplication * +cspi_get_application (const char *bus_name) +{ + CSpiApplication *app = NULL; + char *bus_name_dup; + + if (!app_hash) + { + app_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_unref); + if (!app_hash) return; + } + app = g_hash_table_lookup (app_hash, bus_name); + if (app) return app; + bus_name_dup = g_strdup (bus_name); + if (!bus_name_dup) return NULL; + // TODO: change below to something that will send state-change:defunct notification if necessary */ + app = g_new (CSpiApplication, 1); + if (!app) return NULL; + app->bus_name = bus_name_dup; + if (APP_IS_REGISTRY (app)) + { + app->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, cspi_object_unref); + } + else + { + app->hash = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, cspi_object_unref); + } + g_hash_table_insert (app_hash, bus_name_dup, app); + return app; +} + +typedef struct +{ + char *path; + char *parent; + GArray *children; + GArray *interfaces; + char *name; + dbus_uint32_t role; + char *description; +} CACHE_ADDITION; + +/* Update the cache with added/modified objects and free the array */ +static void +handle_additions (CSpiApplication*app, GArray *additions) +{ + gint i, j; + GList *l, *new_list; + + if (!additions) + { + return; + } + for (i = 0; i < additions->len; i++) + { + CACHE_ADDITION *ca = &g_array_index (additions, CACHE_ADDITION, i); + Accessible *a = ref_accessible (app, ca->path); + /* Note: children don't hold refs for their parents or vice versa */ + a->parent = ref_accessible (app, ca->parent); + if (a->parent) cspi_object_unref (a->parent); + if (a->children) + { + g_list_free (a->children); + a->children = NULL; + } + for (j = 0; j < ca->children->len; j++) + { + const char *child_path = g_array_index (ca->children, const char *, j); + Accessible *child = ref_accessible (app, child_path); + new_list = g_list_append (a->children, child); + if (new_list) a->children = new_list; + cspi_object_unref (child); + } + a->interfaces = 0; + for (j = 0; j < ca->interfaces->len; j++) + { + const char *iface = g_array_index (ca->interfaces, const char *, j); + if (!strcmp (iface, "org.freedesktop.DBus.Introspectable")) continue; + gint n = get_iface_num (iface); + if (n == -1) + { + g_warning ("Unknown interface %s", iface); + } + else a->interfaces |= (1 << n); + g_free (iface); + } + if (a->name) g_free (a->name); + a->name = ca->name; + a->role = ca->role; + if (a->description) g_free (a->description); + a->description = ca->description; + g_array_free (ca->interfaces, TRUE); + g_array_free (ca->children, TRUE); + /* This is a bit of a hack since ref_accessible sets ref_count to 2 + * for a new object, one of the refs being for the cache */ + cspi_object_unref (a); + } + g_array_free (additions, TRUE); +} + +static void +handle_removals (CSpiApplication *app, GArray *removals) +{ + gint j; + + if (!removals) return; + for (j = 0; j < removals->len; j++) + { + const char *path = g_array_index (removals, const char *, j); + Accessible *a = ref_accessible (app, path); + if (a->parent && g_list_find (a->parent->children, a)) + { + a->parent->children = g_list_remove (a->parent->children, a); + /* Note: children don't hold refs for their parents or vice versa */ + } + g_hash_table_remove (app->hash, &a->v.id); + cspi_object_unref_internal (a, TRUE); /* unref our own ref */ + } + g_array_free (removals, TRUE); +} + +static gboolean +add_app_to_desktop (Accessible *a, const char *bus_name) +{ + DBusError error; + char *root_path; + + dbus_error_init (&error); + if (dbind_connection_method_call (bus, bus_name, "/org/freedesktop/atspi/tree", spi_interface_tree, "getRoot", &error, "=>o", &root_path)) + { + Accessible *obj = cspi_ref_accessible (bus_name, root_path); + if (obj) + { + GList *new_list = g_list_append (a->children, obj); + if (new_list) + { + a->children = new_list; + return TRUE; + } + } + g_free (root_path); + } + else + { + g_warning ("Error calling getRoot for %s: %s", bus_name, error.message); + } + return FALSE; +} + +static void +send_children_change (Accessible *parent, Accessible *child, gboolean add) +{ + AccessibleEvent e; + + memset (&e, 0, sizeof(e)); + e.type = (add? "object:children-change:add": "object:children-change:remove"); + e.source = parent; + e.detail1 = g_list_index (parent->children, child); + cspi_dispatch_event (&e); +} + +static void +unref_object_and_children (Accessible *obj) +{ + GList *l; + + for (l = obj->children; l; l = l->next) + { + unref_object_and_children (l->data); + } + cspi_object_unref_internal (obj, TRUE); +} + +static gboolean +remove_app_from_desktop (Accessible *a, const char *bus_name) +{ + GList *l; + Accessible *child; + + for (l = a->children; l; l = l->next) + { + child = l->data; + if (!strcmp (bus_name, child->app->bus_name)) break; + } + if (!l) + { + g_warning ("Removing unregistered app %s; doing nothing\n", bus_name); + return FALSE; + } + send_children_change (a, child, FALSE); + a->children = g_list_remove (a->children, child); + unref_object_and_children (child); + return TRUE; +} + +static Accessible * +ref_accessible_desktop (CSpiApplication *app, const char *path) +{ + char *path_dup; + DBusError error; + GArray *apps = NULL; + GArray *additions; + gint i; + + Accessible *a = g_hash_table_lookup (app->hash, path); +printf("got %p from %p for %s\n", a, app_hash, path); + if (a) + { + cspi_object_ref (a); + return a; + } + path_dup = g_strdup (path); + if (!path_dup) return NULL; + a = g_new0 (Accessible, 1); + if (!a) + { + g_free (path_dup); + return NULL; + } +printf("Inserting %p into %p for %s\n", a, app->hash, path_dup); + g_hash_table_insert (app->hash, path_dup, a); + a->app = app; + a->v.path = path_dup; + a->ref_count = 2; /* one for the caller, one for the hash */ + cspi_dbus_get_property (a, SPI_DBUS_INTERFACE_ACCESSIBLE, "name", NULL, "s", &a->name); + dbus_error_init (&error); + if (!dbind_connection_method_call (bus, spi_bus_registry, a->v.path, spi_interface_desktop, "getChildren", &error, "=>as", &apps)) + { + g_error ("Couldn't get desktop children: %s", error.message); + } + for (i = 0; i < apps->len; i++) + { + const char *app_name = g_array_index (apps, char *, i); + if (app_name[0] == '\0') + { + g_warning ("Got empty app name"); + continue; + } + CSpiApplication *app = cspi_get_application (app_name); + additions = NULL; + dbus_error_init (&error); + dbind_connection_method_call (bus, app_name, "/org/freedesktop/atspi/tree", spi_interface_tree, "getTree", &error, "=>a(ooaoassus)", &additions); + if (error.message) + { + g_warning ("getTree (%s): %s", app_name, error.message); + } + handle_additions (app, additions); + add_app_to_desktop (a, app_name); + } + g_array_free (apps, TRUE); + return a; +} + +Accessible * +cspi_ref_accessible (const char *app, const char *path) +{ + CSpiApplication *a = cspi_get_application (app); + if (!a) return NULL; + if ( APP_IS_REGISTRY(a)) + { + return ref_accessible_desktop (a, path); + } + return ref_accessible (a, path); +} + +Accessible * +cspi_ref_related_accessible (Accessible *obj, const char *path) +{ + return ref_accessible (obj->app, path); +} + +typedef struct +{ + GArray *additions; + GArray *removals; +} CacheSignalData; + +static const char *cacheSignalType = "a(ooaoassus)ao"; + +static DBusHandlerResult +cspi_dbus_handle_update_tree (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + DBusMessageIter iter; + CacheSignalData cd; + void *p = &cd; + const char *sender = dbus_message_get_sender (message); + CSpiApplication *app = cspi_get_application (sender); + const char *type = cacheSignalType; + +printf("update tree: %p\n", app); + if (!app) + { + g_warning ("UpdateTree from unknown app. Should we add it?", sender); + return; + } + dbus_message_iter_init (message, &iter); + // TODO: Check signature + dbind_any_demarshal (&iter, &type, &p); /* additions */ + dbind_any_demarshal (&iter, &type, &p); /* removals */ + handle_additions (app, cd.additions); + handle_removals (app, cd.removals); +} + +static DBusHandlerResult +cspi_dbus_handle_add_application (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + DBusError error; + dbus_uint32_t v; + Accessible *a; + char *bus_name; + + dbus_error_init (&error); + if (!dbus_message_get_args (message, NULL, DBUS_TYPE_UINT32, &v, DBUS_TYPE_STRING, &bus_name, DBUS_TYPE_INVALID)) + { + g_warning ("Error processing %s: %s\n", dbus_message_get_member(message), error.message); + dbus_error_free (&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + a = cspi_ref_accessible ("org.freedesktop.atspi.registry", dbus_message_get_path(message)); +printf("Adding %s to %p\n", bus_name, a); + if (add_app_to_desktop (a, bus_name)) + { + send_children_change (a, g_list_last (a->children)->data, TRUE); + } + cspi_object_unref (a); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +cspi_dbus_handle_remove_application (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + DBusError error; + dbus_uint32_t v; + Accessible *a; + char *bus_name; + + dbus_error_init (&error); + if (!dbus_message_get_args (message, NULL, DBUS_TYPE_UINT32, &v, DBUS_TYPE_STRING, &bus_name, DBUS_TYPE_INVALID)) + { + g_warning ("Error processing %s: %s\n", dbus_message_get_member(message), error.message); + dbus_error_free (&error); + return DBUS_HANDLER_RESULT_HANDLED; + } + a = cspi_ref_accessible ("org.freedesktop.atspi.registry", dbus_message_get_path(message)); +printf("Removing %s from %p\n", bus_name, a); + remove_app_from_desktop (a, bus_name); + cspi_object_unref (a); + return DBUS_HANDLER_RESULT_HANDLED; +} + + +static DBusHandlerResult +cspi_dbus_filter (DBusConnection *bus, DBusMessage *message, void *data) +{ + int type = dbus_message_get_type (message); + const char *interface = dbus_message_get_interface (message); + const char *member = dbus_message_get_member (message); + dbus_uint32_t v; + char *bus_name; + + if (type == DBUS_MESSAGE_TYPE_SIGNAL && + !strcmp (interface, SPI_DBUS_INTERFACE_ACCESSIBLE)) + { + return cspi_dbus_handle_event (bus, message, data); + } + if (dbus_message_is_method_call (message, spi_interface_device_event_listener, "notifyEvent")) + { + return cspi_dbus_handle_deviceEvent (bus, message, data); + } + if (dbus_message_is_signal (message, spi_interface_tree, "updateTree")) + { + return cspi_dbus_handle_update_tree (bus, message, data); + } + if (dbus_message_is_signal (message, spi_interface_registry, "applicationAdd")) + { + return cspi_dbus_handle_add_application (bus, message, data); + } + if (dbus_message_is_signal (message, spi_interface_registry, "applicationRemove")) + { + return cspi_dbus_handle_remove_application (bus, message, data); + } +if (type == DBUS_MESSAGE_TYPE_SIGNAL) printf("got %s of %s from %s\n", dbus_message_get_member (message), dbus_message_get_interface(message), dbus_message_get_sender(message)); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/** + * SPI_init: + * + * Connects to the accessibility registry and initializes the SPI. + * + * Returns: 0 on success, otherwise an integer error code. + **/ +int +SPI_init (void) +{ + DBusError error; + char *match; + + if (SPI_inited) + { + return 1; + } + + SPI_inited = TRUE; + + g_type_init (); + + cspi_get_live_refs(); + g_atexit (cspi_cleanup); + + dbus_error_init (&error); + bus = dbus_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) + { + g_error ("Couldn't get session bus"); + return 2; + } + dbus_bus_register (bus, &error); + dbus_connection_setup_with_g_main(bus, g_main_context_default()); + dbus_connection_add_filter (bus, cspi_dbus_filter, NULL, NULL); + match = g_strdup_printf ("type='signal',interface='%s',member='updateTree'", spi_interface_tree); + dbus_error_init (&error); + dbus_bus_add_match (bus, match, &error); + g_free (match); + match = g_strdup_printf ("type='signal',sender='%s'", SPI_DBUS_NAME_REGISTRY); + dbus_bus_add_match (bus, match, &error); + g_free (match); + return 0; +} + + static GMainLoop *mainloop; + +/** + * SPI_event_main: + * + * 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_event_quit () from within an event handler). + * + **/ +void +SPI_event_main (void) +{ + + mainloop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (mainloop); +} + +/** + * SPI_event_quit: + * + * Quits the last main event loop for the SPI services, + * see SPI_event_main + **/ +void +SPI_event_quit (void) +{ + g_main_loop_quit (mainloop); +} + +/** + * SPI_eventIsReady: + * + * Checks to see if an SPI event is waiting in the event queue. + * Used by clients that don't wish to use SPI_event_main(). + * + * Not Yet Implemented. + * + * Returns: #TRUE if an event is waiting, otherwise #FALSE. + * + **/ +SPIBoolean +SPI_eventIsReady (void) +{ + return FALSE; +} + +/** + * SPI_nextEvent: + * @waitForEvent: a #SPIBoolean indicating whether to block or not. + * + * Gets the next event in the SPI event queue; blocks if no event + * is pending and @waitForEvent is #TRUE. + * Used by clients that don't wish to use SPI_event_main(). + * + * Not Yet Implemented. + * + * Returns: the next #AccessibleEvent in the SPI event queue. + **/ +AccessibleEvent * +SPI_nextEvent (SPIBoolean waitForEvent) +{ + return NULL; +} + +#ifdef PRINT_LEAKS +static void +report_leaked_ref (gpointer key, gpointer val, gpointer user_data) +{ + char *name, *role; + Accessible *a = (Accessible *) val; + + name = Accessible_getName (a); + if (cspi_exception ()) + { + name = NULL; + } + + role = Accessible_getRoleName (a); + if (cspi_exception ()) + { + role = NULL; + } + + fprintf (stderr, "leaked %d references to object %s, role %s %p\n", + a->ref_count, name ? name : "", role ? role : "", a); + + SPI_freeString (name); +} +#endif + +/** + * SPI_exit: + * + * Disconnects from the Accessibility Registry and releases + * any floating resources. Call only once at exit. + * + * Returns: 0 if there were no leaks, otherwise non zero. + **/ +int +SPI_exit (void) +{ + int leaked; + + if (!SPI_inited) + { + return 0; + } + + SPI_inited = FALSE; + + if (live_refs) + { + leaked = g_hash_table_size (live_refs); +#ifdef DEBUG_OBJECTS + fprintf (stderr, "Leaked %d SPI handles\n", leaked); + +#define PRINT_LEAKS +#ifdef PRINT_LEAKS + g_hash_table_foreach (live_refs, report_leaked_ref, NULL); +#endif + +#endif + } + else + { + leaked = 0; + } + + cspi_cleanup (); + + return leaked; +} + +/** + * SPI_freeString: + * @s: a character string returned from another at-spi call. + * + * Free a character string returned from an at-spi call. Clients of + * at-spi should use this function instead of free () or g_free(). + * A NULL string @s will be silently ignored. + * This API should not be used to free strings + * from other libraries or allocated by the client. + **/ +void +SPI_freeString (char *s) +{ + if (s) + { + g_free (s); + } +} + +/** + * SPI_freeRect: + * @r: a pointer to an SPIRect returned from another at-spi call. + * + * Free a SPIRect structure returned from an at-spi call. Clients of + * at-spi should use this function instead of free () or g_free(). + * A NULL rect @r will be silently ignored. + * This API should not be used to free data + * from other libraries or allocated by the client. + * + * @Since: AT-SPI 1.6 + **/ +void +SPI_freeRect (SPIRect *r) +{ + if (r) + { + /* err, okay, in this case the client _could_ + have called g_free, but we don't want to guarantee it */ + g_free (r); + } +} + +/** + * SPI_dupString: + * @s: a UTF-8 string to be duplicated + * + * @Since: AT-SPI 1.4 + * + * Returns: a duplicate of the string passed as a parameter, which should + * be freed via SPI_freeString after use. + **/ +char * +SPI_dupString (char *s) +{ + if (s) + { + return g_strdup (s); + } + else + return NULL; +} + +/** + * SPI_exceptionHandlerPush: + * @handler: an #SPIExceptionHandler to install as the first code to deal with exceptions. + * + * Install a client-side handler for #SPIException instances, which can see and handle any + * exceptions before chaining them to the next exception handler in the stack. + * + * @Since: AT-SPI 1.4 + * + * Returns %TRUE if the result succeeded, %FALSE if @hander could not be registered. + **/ +SPIBoolean SPI_exceptionHandlerPush (SPIExceptionHandler *handler) +{ + if (!exception_handlers) + exception_handlers = g_queue_new (); + g_queue_push_head (exception_handlers, handler); + return TRUE; +} + +/** + * SPI_exceptionHandlerPop: + * + * Remove/pop an #SPIExceptionHandler off the error handler stack and return the new handler. + * + * @Since: AT-SPI 1.4 + * + * Returns the #SPIExceptionHandler which is now at the top of the error handler stack after the call. + **/ +SPIExceptionHandler* SPI_exceptionHandlerPop (void) +{ + return (SPIExceptionHandler *) g_queue_pop_head (exception_handlers); +} + +/** + * SPIException_getSourceType: + * @err: the exception being queried + * + * Get the #SPIExceptionType of an exception which has been thrown. + * + * @Since: AT-SPI 1.4 + * + * Returns: the #SPIExceptionType corresponding to exception @err. + **/ +SPIExceptionType SPIException_getSourceType (SPIException *err) +{ + if (err) + return err->type; + else + return SPI_EXCEPTION_SOURCE_UNSPECIFIED; +} + +/** + * SPIException_getExceptionCode: + * @err: the #SPIException being queried. + * + * Get the #SPIExceptionCode telling what type of exception condition has occurred. + * + * @Since: AT-SPI 1.4 + * + * Returns: the #SPIExceptionCode corresponding to exception @err. + **/ +SPIExceptionCode SPIException_getExceptionCode (SPIException *err) +{ + return err->code; +} + +/** + * SPIAccessibleException_getSource: + * @err: the #SPIException being queried. + * + * Get the identity of the object which threw an exception. + * + * @Since: AT-SPI 1.4 + * + * Returns: a pointer to the #Accessible object which threw the exception. + **/ +Accessible* SPIAccessibleException_getSource (SPIException *err) +{ + if (err->type == SPI_EXCEPTION_SOURCE_ACCESSIBLE) + cspi_object_ref (err->source); + return err->source; + return NULL; +} + +/** + * SPIException_getDescription: + * @err: the #SPIException being queried. + * + * Get a text description of the exception that has been thrown. + * Unfortunately these descriptions tend to be terse and limited in + * the detail which they can provide. + * + * Returns: a brief character string describing the exception. + **/ +char* SPIException_getDescription (SPIException *err) +{ + /* TODO: friendlier error messages? */ + if (err->error) + return err->error->message; + return NULL; +} + +static char * +get_path (Accessible *obj) +{ + if (APP_IS_REGISTRY (obj->app)) + { + return g_strdup_printf (SPI_DBUS_PATH_DESKTOP); + } + return g_strdup_printf ("/org/freedesktop/atspi/accessible/%d", obj->v.id); +} + +dbus_bool_t +cspi_dbus_call (Accessible *obj, const char *interface, const char *method, DBusError *error, const char *type, ...) +{ + va_list args; + char *path = get_path (obj); + dbus_bool_t retval; + DBusError err; + + if (!error) error = &err; + dbus_error_init (error); + va_start (args, type); + retval = dbind_connection_method_call_va (cspi_bus(), obj->app->bus_name, path, interface, method, error, type, args); + va_end (args); + g_free (path); + if (dbus_error_is_set (error)) + { + if (!dbus_error_is_set (&exception)) + { + // TODO: Should we call cspi_exception_throw? + dbus_move_error (error, &exception); + } + else if (error == &err) dbus_error_free (error); + } + return retval; +} + +dbus_bool_t +cspi_dbus_get_property (Accessible *obj, const char *interface, const char *name, DBusError *error, const char *type, void *data) +{ + DBusMessage *message, *reply; + char *path = get_path (obj); + DBusMessageIter iter, iter_variant; + DBusError err; + dbus_bool_t retval = FALSE; + + message = dbus_message_new_method_call (obj->app->bus_name, path, "org.freedesktop.DBus.Properties", "Get"); + if (!message) + { + // TODO: throw exception + goto done; + } + dbus_message_append_args (message, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); + if (!error) error = &err; + dbus_error_init (error); + reply = dbus_connection_send_with_reply_and_block (cspi_bus(), message, 1000, error); + dbus_message_unref (message); + if (!reply) + { + // TODO: throw exception + goto done; + } + dbus_message_iter_init (reply, &iter); + dbus_message_iter_recurse (&iter, &iter_variant); + if (dbus_message_iter_get_arg_type (&iter_variant) != type[0]) + { + g_warning ("cspi_dbus_get_property: Wrong type: expected %s, got %c\n", type, dbus_message_iter_get_arg_type (&iter_variant)); + goto done; + } + dbus_message_iter_get_basic (&iter_variant, data); + dbus_message_unref (reply); + if (type[0] == 's') *(char **)data = g_strdup (*(char **)data); + retval = TRUE; +done: + g_free (path); + return retval; +} diff --git a/cspi/spi_registry.c b/cspi/spi_registry.c new file mode 100644 index 0000000..98f3779 --- /dev/null +++ b/cspi/spi_registry.c @@ -0,0 +1,438 @@ +/* + * 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. + * + * 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. + */ + +/* spi_registry.c: Global functions wrapping the registry */ + +#include + +static GArray *desktops; + +/** + * SPI_getDesktopCount: + * + * Get the number of virtual desktops. + * NOTE: currently multiple virtual desktops are not implemented, this + * function always returns '1'. + * + * Returns: an integer indicating the number of active virtual desktops. + **/ +int +SPI_getDesktopCount () +{ + if (!desktops) SPI_getDesktopList (NULL); + if (!desktops) return -1; + return desktops->len; +} + +/** + * SPI_getDesktop: + * @i: an integer indicating which of the accessible desktops is to be returned. + * + * Get the virtual desktop indicated by index @i. + * NOTE: currently multiple virtual desktops are not implemented, this + * function always returns '1'. + * + * Returns: a pointer to the 'i-th' virtual desktop's #Accessible representation. + **/ +Accessible* +SPI_getDesktop (int i) +{ + if (!desktops) SPI_getDesktopList (NULL); + if (!desktops) return NULL; + return cspi_ref_accessible (spi_bus_registry, g_array_index (desktops, char *, i)); +} + +/** + * SPI_getDesktopList: + * @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, NULL terminated array of virtual desktop + * pointers. + * It is the responsibility of the caller to free this array when + * it is no longer needed. + * + * Not Yet Implemented : this implementation always returns a single + * #Accessible desktop. + * + * Returns: an integer indicating how many virtual desktops have been + * placed in the list pointed to by parameter @list. + **/ +int +SPI_getDesktopList (Accessible ***desktop_list) +{ + int i; + Accessible **list; + + if (desktop_list) *desktop_list = NULL; + + if (!desktops) + { + dbind_connection_method_call (cspi_bus(), spi_bus_registry, spi_path_registry, spi_interface_registry, "getDesktopList", NULL, "=>ao", &desktops); + if (!desktops) return 0; + } + + list = g_new0 (Accessible *, desktops->len + 1); + + if (!desktop_list) return desktops->len; + for (i = 0; i < desktops->len; i++) + { + list [i] = cspi_ref_accessible (spi_bus_registry, g_array_index (desktops, char *, i)); + } + list [i] = NULL; + + *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); +} + +/** + * SPI_KEYSET_ALL_KEYS: + * @SPI_KEYSET_ALL_KEYS: A special value for an AccessibleKeySet type, which tacitly + * includes all keycodes and keyvals for the specified modifier set. + **/ + +/** + * SPI_registerAccessibleKeystrokeListener: + * @listener: a pointer to the #AccessibleKeystrokeListener for which + * keystroke events are requested. + * @keys: a pointer to the #AccessibleKeySet indicating which + * keystroke events are requested, or #SPI_KEYSET_ALL_KEYS + * to indicate that all keycodes and keyvals for the specified + * modifier set are to be included. + * @modmask: an #AccessibleKeyMaskType mask indicating which + * key event modifiers must be set in combination with @keys, + * events will only be reported for key events for which all + * modifiers in @modmask are set. If you wish to listen for + * events with multiple modifier combinations you must call + * registerAccessibleKeystrokeListener() once for each combination. + * @eventmask: an #AccessibleKeyMaskType mask indicating which + * types of key events are requested (#SPI_KEY_PRESSED, etc.). + * @sync_type: a #AccessibleKeyListenerSyncType parameter indicating + * the behavior of the notification/listener transaction. + * + * Register a listener for keystroke events, either pre-emptively for + * all windows (SPI_KEYLISTENER_ALL_WINDOWS), + * non-preemptively (SPI_KEYLISTENER_NOSYNC), or + * pre-emptively at the toolkit level (SPI_KEYLISTENER_CANCONSUME). + * If ALL_WINDOWS or CANCONSUME are used, the event is consumed + * upon receipt if one of @listener's callbacks returns #TRUE. + * ( Other sync_type values may be available in the future ) + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener, + AccessibleKeySet *keys, + AccessibleKeyMaskType modmask, + AccessibleKeyEventMask eventmask, + AccessibleKeyListenerSyncType sync_type) +{ + gchar *path = cspi_device_listener_get_path (listener); + gint i; + GArray *key_set; + dbus_uint32_t key_events = 0; + Accessibility_ControllerEventMask controller_event_mask; + Accessibility_EventListenerMode listener_mode; + DBusError error; + SPIBoolean retval = FALSE; + + if (!listener) + { + return retval; + } + + /* copy the keyval filter values from the C api into the DBind KeySet */ + if (keys) + { + key_set = g_array_sized_new (FALSE, TRUE, sizeof (Accessibility_KeyDefinition), keys->len); + key_set->len = keys->len; + for (i = 0; i < keys->len; ++i) + { + Accessibility_KeyDefinition *kd = ((Accessibility_KeyDefinition *) key_set->data) + i; + kd->keycode = keys->keycodes[i]; + kd->keysym = keys->keysyms[i]; + if (keys->keystrings && keys->keystrings[i]) + { + kd->keystring = keys->keystrings[i]; + } + else + { + kd->keystring = ""; + } + } + } + else + { + key_set = g_array_sized_new (FALSE, TRUE, sizeof (Accessibility_KeyDefinition), 0); + } + + /* copy the event filter values from the C api into the DBus key_events */ + if (eventmask & SPI_KEY_PRESSED) + { + key_events |= (1 << Accessibility_KEY_PRESSED_EVENT); + } + if (eventmask & SPI_KEY_RELEASED) + { + key_events |= (1 << Accessibility_KEY_RELEASED_EVENT); + } + + controller_event_mask = (dbus_uint32_t) modmask; + + listener_mode.synchronous = + (dbus_bool_t) ((sync_type & SPI_KEYLISTENER_SYNCHRONOUS)!=0); + listener_mode.preemptive = + (dbus_bool_t) ((sync_type & SPI_KEYLISTENER_CANCONSUME)!=0); + listener_mode.global = + (dbus_bool_t) ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0); + + dbus_error_init (&error); + dbind_connection_method_call (cspi_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "registerKeystrokeListener", &error, "oa(iisi)uu(bbb)=>b", path, key_set, key_events, controller_event_mask, &listener_mode, &retval); + + g_array_free (key_set, TRUE); + g_free (path); + + return retval; +} + +/** + * SPI_deregisterAccessibleKeystrokeListener: + * @listener: a pointer to the #AccessibleKeystrokeListener for which + * keystroke events are requested. + * @modmask: the key modifier mask for which this listener is to be + * 'deregistered' (of type #AccessibleeyMaskType). + * + * Removes a keystroke event listener from the registry's listener queue, + * ceasing notification of events with modifiers matching @modmask. + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener, + AccessibleKeyMaskType modmask) +{ + gchar *path = cspi_device_listener_get_path (listener); + Accessibility_ControllerEventMask controller_event_mask; + GArray *key_set; + dbus_uint32_t key_events = 0; + DBusError error; + + if (!listener) + { + return FALSE; + } + + + controller_event_mask = (dbus_uint32_t) modmask; + + key_set = g_array_sized_new (FALSE, TRUE, sizeof (Accessibility_KeyDefinition), 0); + dbind_connection_method_call (cspi_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "deregisterKeystrokeListener", &error, "oa(iisi)uu", path, &key_set, key_events, controller_event_mask); + g_free (path); + return TRUE; +} + +/** + * SPI_registerDeviceEventListener: + * @listener: a pointer to the #AccessibleDeviceListener which requests + * the events. + * @eventmask: an #AccessibleDeviceEventMask mask indicating which + * types of key events are requested (#SPI_KEY_PRESSED, etc.). + * @filter: Unused parameter. + * + * Register a listener for device events, for instance button events. + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_registerDeviceEventListener (AccessibleDeviceListener *listener, + AccessibleDeviceEventMask eventmask, + void *filter) +{ + SPIBoolean retval = FALSE; + dbus_uint32_t event_types = 0; + gint i; + gchar *path = cspi_device_listener_get_path (listener); + DBusError error; + + if (!listener) + { + return retval; + } + + /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */ + + if (eventmask & SPI_BUTTON_PRESSED) + { + event_types |= (1 << Accessibility_BUTTON_PRESSED_EVENT); + } + if (eventmask & SPI_BUTTON_RELEASED) + { + event_types |= (1 << Accessibility_BUTTON_RELEASED_EVENT); + } + + dbus_error_init (&error); + dbind_connection_method_call (cspi_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "registerDeviceEventListener", &error, "ou=>b", path, &event_types, &retval); + g_free (path); + return retval; +} + +/** + * SPI_deregisterDeviceEventListener: + * @listener: a pointer to the #AccessibleDeviceListener for which + * device events are requested. + * @filter: Unused parameter. + * + * Removes a device event listener from the registry's listener queue, + * ceasing notification of events of the specified type. + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_deregisterDeviceEventListener (AccessibleDeviceListener *listener, + void *filter) +{ + dbus_uint32_t event_types = 0; + gchar *path = cspi_device_listener_get_path (listener); + DBusError error; + + if (!listener) + { + return FALSE; + } + + event_types |= (1 << Accessibility_BUTTON_PRESSED_EVENT); + event_types |= (1 << Accessibility_BUTTON_RELEASED_EVENT); + + dbus_error_init (&error); + dbind_connection_method_call (cspi_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "deregisterDeviceEventListener", &error, "ou", path, &event_types); + g_free (path); + return TRUE; +} + +/** + * SPI_generateKeyboardEvent: + * @keyval: a long integer indicating the keycode or keysym of the key event + * being synthesized. + * @keystring: an (optional) UTF-8 string which, if @keyval is NULL, + * indicates a 'composed' keyboard input string which is + * being synthesized; this type of keyboard event synthesis does + * not emulate hardware keypresses but injects the string + * as though a composing input method (such as XIM) were used. + * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval + * is to be interpreted as a keysym rather than a keycode + * (CSPI_KEYSYM), or whether to synthesize + * SPI_KEY_PRESS, SPI_KEY_RELEASE, or both (SPI_KEY_PRESSRELEASE). + * + * Synthesize a keyboard event (as if a hardware keyboard event occurred in the + * current UI context). + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_generateKeyboardEvent (long int keyval, + char *keystring, + AccessibleKeySynthType synth_type) +{ + dbus_uint32_t keysynth_type; + dbus_int16_t keycode = keyval; + DBusError error; + + switch (synth_type) + { + case SPI_KEY_PRESS: + keysynth_type = Accessibility_KEY_PRESS; + break; + case SPI_KEY_RELEASE: + keysynth_type = Accessibility_KEY_RELEASE; + break; + case SPI_KEY_PRESSRELEASE: + keysynth_type = Accessibility_KEY_PRESSRELEASE; + break; + case SPI_KEY_SYM: + keysynth_type = Accessibility_KEY_SYM; + break; + case SPI_KEY_STRING: + keysynth_type = Accessibility_KEY_STRING; + break; + default: + return FALSE; + } + + if (!keystring) keystring = ""; + dbus_error_init (&error); + dbind_connection_method_call (cspi_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "generateKeyboardEvent", &error, "isu", &keycode, &keystring, &keysynth_type); + + return TRUE; +} + +/** + * SPI_generateMouseEvent: + * @x: a #long indicating the screen x coordinate of the mouse event. + * @y: a #long indicating the screen y coordinate of the mouse event. + * @name: a string indicating which mouse event to be synthesized + * (e.g. "b1p", "b1c", "b2r", "rel", "abs"). + * + * Synthesize a mouse event at a specific screen coordinate. + * Most AT clients should use the #AccessibleAction interface when + * tempted to generate mouse events, rather than this method. + * Event names: b1p = button 1 press; b2r = button 2 release; + * b3c = button 3 click; b2d = button 2 double-click; + * abs = absolute motion; rel = relative motion. + * + * Returns: #TRUE if successful, otherwise #FALSE. + **/ +SPIBoolean +SPI_generateMouseEvent (long x, long y, char *name) +{ + dbus_int32_t dbus_x = x, dbus__y = y; + DBusError error; + + dbus_error_init (&error); + dbind_connection_method_call (cspi_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "generateMouseEvent", &error, "iis", &x, &y, &name); + return TRUE; +} + +char * +cspi_device_listener_get_path (CSpiDeviceListener *listener) +{ + return g_strdup_printf ("/org/freedesktop/atspi/listeners/%d", listener->id); +} diff --git a/cspi/spi_selection.c b/cspi/spi_selection.c new file mode 100644 index 0000000..d369070 --- /dev/null +++ b/cspi/spi_selection.c @@ -0,0 +1,274 @@ +/* + * 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. + * + * 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. + */ + +#include + +/** + * AccessibleSelection_ref: + * @obj: a pointer to the #AccessibleSelection implementor on which to operate. + * + * Increment the reference count for an #AccessibleSelection object. + * + **/ +void +AccessibleSelection_ref (AccessibleSelection *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleSelection_unref: + * @obj: a pointer to the #AccessibleSelection implementor on which to operate. + * + * Decrement the reference count for an #Accessible object. + * + **/ +void +AccessibleSelection_unref (AccessibleSelection *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleSelection_getNSelectedChildren: + * @obj: a pointer to the #AccessibleSelection implementor on which to operate. + * + * Get the number of children of an #AccessibleSelection implementor which are + * currently selected. + * + * Returns: a #long indicating the number of #Accessible children + * of the #AccessibleSelection implementor which are currently selected. + * + **/ +long +AccessibleSelection_getNSelectedChildren (AccessibleSelection *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_selection, "nSelectedChildren", NULL, "i", &retval); + + cspi_return_val_if_ev ("getNSelectedChildren", -1); + + return retval; +} + +/** + * AccessibleSelection_getSelectedChild: + * @obj: a pointer to the #AccessibleSelection on which to operate. + * @selectedChildIndex: a #long indicating which of the selected + * children is specified. + * + * Get the i-th selected #Accessible child of an #AccessibleSelection. + * Note that @childIndex refers to the index in the list of 'selected' + * children and generally differs from that used in + * #Accessible_getChildAtIndex() or returned by + * #Accessible_getIndexInParent(). @selectedChildIndex must lie between 0 + * and #AccessibleSelection_getNSelectedChildren()-1, inclusive. + * + * Returns: a pointer to a selected #Accessible child object, + * specified by @childIndex. + * + **/ +Accessible * +AccessibleSelection_getSelectedChild (AccessibleSelection *obj, + long int selectedChildIndex) +{ + dbus_int32_t d_selectedChildIndex = selectedChildIndex; + char *path; + Accessible *child; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_selection, "getSelectedChild", NULL, "i=>o", &d_selectedChildIndex, &path); + child = cspi_ref_related_accessible (obj, path); + g_free (path); + return child; +} + +/** + * AccessibleSelection_selectChild: + * @obj: a pointer to the #AccessibleSelection on which to operate. + * @childIndex: a #long indicating which child of the #Accessible + * is to be selected. + * + * Add a child to the selected children list of an #AccessibleSelection. + * For #AccessibleSelection implementors that only allow + * single selections, this may replace the (single) current + * selection. + * + * Returns: #TRUE if the child was successfully selected, #FALSE otherwise. + **/ +SPIBoolean +AccessibleSelection_selectChild (AccessibleSelection *obj, + long int childIndex) +{ + dbus_int32_t d_childIndex = childIndex; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_selection, "selectChild", NULL, "i=>b", &d_childIndex, &retval); + + cspi_return_val_if_ev ("selectChild", FALSE); + + return retval; +} + +/** + * AccessibleSelection_deselectSelectedChild: + * @obj: a pointer to the #AccessibleSelection on which to operate. + * @selectedChildIndex: a #long indicating which of the selected children + * of the #Accessible is to be selected. + * + * Remove a child to the selected children list of an #AccessibleSelection. + * Note that @childIndex is the index in the selected-children list, + * not the index in the parent container. @selectedChildIndex in this + * method, and @childIndex in #AccessibleSelection_selectChild + * are asymmettric. + * + * Returns: #TRUE if the child was successfully deselected, #FALSE otherwise. + **/ +SPIBoolean +AccessibleSelection_deselectSelectedChild (AccessibleSelection *obj, + long int selectedChildIndex) +{ + dbus_int32_t d_selectedChildIndex = selectedChildIndex; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_selection, "deselectSelectedChild", NULL, "i=>b", &d_selectedChildIndex, &retval); + + cspi_return_val_if_ev ("deselectSelectedChild", FALSE); + + return retval; +} + +/** + * AccessibleSelection_deselectChild: + * @obj: a pointer to the #AccessibleSelection on which to operate. + * @childIndex: a #long indicating which of the children + * of the #Accessible is to be de-selected. + * + * Deselect a specific child of an #AccessibleSelection. + * Note that @childIndex is the index of the child + * in the parent container. + * + * See #AccessibleSelection_deselectSelectedChild + * + * Since AT-SPI 1.8.0 + * + * Returns: #TRUE if the child was successfully deselected, #FALSE otherwise. + **/ +SPIBoolean +AccessibleSelection_deselectChild (AccessibleSelection *obj, + long int childIndex) +{ + dbus_int32_t d_childIndex = childIndex; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_selection, "deselectChild", NULL, "i=>b", &d_childIndex, &retval); + + cspi_return_val_if_ev ("deselectChild", FALSE); + + return retval; +} + +/** + * AccessibleSelection_isChildSelected: + * @obj: a pointer to the #AccessibleSelection implementor on which to operate. + * @childIndex: an index into the #AccessibleSelection's list of children. + * + * Determine whether a particular child of an #AccessibleSelection implementor + * is currently selected. Note that @childIndex is the index into the + * standard #Accessible container's list of children. + * + * Returns: #TRUE if the specified child is currently selected, + * #FALSE otherwise. + **/ +SPIBoolean +AccessibleSelection_isChildSelected (AccessibleSelection *obj, + long int childIndex) +{ + dbus_int32_t d_childIndex = childIndex; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_selection, "isChildSelected", NULL, "i=>b", &d_childIndex, &retval); + + cspi_return_val_if_ev ("isChildSelected", FALSE); + + return retval; +} + +/** + * AccessibleSelection_selectAll: + * @obj: a pointer to the #AccessibleSelection implementor on which to operate. + * + * Attempt to select all of the children of an #AccessibleSelection implementor. + * Not all #AccessibleSelection implementors support this operation. + * + * Returns: #TRUE if successful, #FALSE otherwise. + * + **/ +SPIBoolean +AccessibleSelection_selectAll (AccessibleSelection *obj) +{ + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_selection, "selectAll", NULL, "=>b", &retval); + + cspi_return_val_if_ev ("selectAll", FALSE); + + return retval; +} + +/** + * AccessibleSelection_clearSelection: + * @obj: a pointer to the #AccessibleSelection implementor on which to operate. + * + * Clear the current selection, removing all selected children from the + * specified #AccessibleSelection implementor's selection list. + * + * Returns: #TRUE if successful, #FALSE otherwise. + * + **/ +SPIBoolean +AccessibleSelection_clearSelection (AccessibleSelection *obj) +{ + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_selection, "clearSelection", NULL, "=>b", &retval); + + return retval; +} + diff --git a/cspi/spi_streamablecontent.c b/cspi/spi_streamablecontent.c new file mode 100644 index 0000000..2bb1632 --- /dev/null +++ b/cspi/spi_streamablecontent.c @@ -0,0 +1,429 @@ +/* + * 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. + * + * 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. + */ + +#include +#include + +#define CORBA_BLOCK_SIZE 65536 /* see libbonobo, dunno where this is officially dictated */ + +#if 0 // TODO +struct StreamCacheItem { + Accessibility_ContentStream stream; + gchar *mimetype; +}; + +static gboolean +streams_equal_func (gconstpointer a, gconstpointer b) +{ + const struct StreamCacheItem *c1 = a, *c2 = b; + return CORBA_Object_is_equivalent (c1->stream, c2->stream, cspi_ev ()); +} + +static void +stream_cache_item_free (gpointer a) +{ + struct StreamCacheItem *cache_item = a; + + cspi_release_unref (cache_item->stream); + SPI_freeString (cache_item->mimetype); + g_free (cache_item); +} + +static GHashTable *streams = NULL; + +static GHashTable * +get_streams (void) +{ + if (streams == NULL) + streams = g_hash_table_new_full (g_direct_hash, streams_equal_func, + NULL, stream_cache_item_free); + return streams; +} + +static CORBA_long +accessible_content_stream_client_seek (const Accessibility_ContentStream stream, + CORBA_long offset, + Accessibility_ContentStream_SeekType seek_type, + CORBA_Environment *opt_ev) +{ + CORBA_Environment *ev, temp_ev; + CORBA_long ret_offset; + + if (!opt_ev) { + CORBA_exception_init (&temp_ev); + ev = &temp_ev; + } else + ev = opt_ev; + + ret_offset = Accessibility_ContentStream_seek (stream, offset, seek_type, ev); + if (BONOBO_EX (ev)) + ret_offset = -1; + + if (!opt_ev) + CORBA_exception_free (&temp_ev); + + return ret_offset; +} + +static guint8* +accessible_content_stream_client_read (const Accessibility_ContentStream stream, + const size_t size, + CORBA_long *length_read, + CORBA_Environment *ev) +{ + size_t pos; + guint8 *mem; + size_t length; + + g_return_val_if_fail (ev != NULL, NULL); + + if (length_read) + *length_read = size; + + length = size; + + if (length == 0) + return NULL; + + mem = g_try_malloc (length); + if (!mem) { + CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY, + CORBA_COMPLETED_NO); + return NULL; + } + + *length_read = 0; + + for (pos = 0; pos < length;) { + Accessibility_ContentStream_iobuf *buf; + CORBA_long len; + + len = (pos + CORBA_BLOCK_SIZE < length) ? + CORBA_BLOCK_SIZE : length - pos; + + Accessibility_ContentStream_read (stream, len, &buf, ev); + + if (BONOBO_EX (ev) || !buf) + goto io_error; + + if (buf->_length > 0) { + memcpy (mem + pos, buf->_buffer, buf->_length); + pos += buf->_length; + *length_read += buf->_length; + /* we assume a short read equals EOF ... is that right? */ + if (buf->_length < len || *length_read == size) + return mem; + } else { + g_warning ("Buffer length %d", buf->_length); + goto io_error; + } + *length_read += buf->_length; + + CORBA_free (buf); + } + + return mem; + + io_error: + return NULL; +} +#endif // TODO + +/* internal use only, declared in cspi-private.h */ +void +cspi_streams_close_all (void) +{ +#if 0 // TODO + if (streams) + { + g_hash_table_destroy (streams); + streams = NULL; + } +#else + g_warning ("Streams not implemented yet"); +#endif // TODO +} + +#if 0 // TODO +/** + * AccessibleStreamableContent_ref: + * @obj: a pointer to the #AccessibleStreamableContent implementor on which to + * operate. + * + * Increment the reference count for an #AccessibleStreamableContent object. + * + * @Since: AT-SPI 1.4 + **/ +void +AccessibleStreamableContent_ref (AccessibleStreamableContent *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleStreamableContent_unref: + * @obj: a pointer to the #AccessibleStreamableContent implementor + * on which to operate. + * + * Decrement the reference count for an #AccessibleStreamableContent object. + * + * @Since: AT-SPI 1.4 + **/ +void +AccessibleStreamableContent_unref (AccessibleStreamableContent *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleStreamableContent_getContentTypes: + * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate. + * + * Get a list of strings containing the content mimetypes available from an + * #AccessibleStreamableContent implementor. + * + * @Since: AT-SPI 1.4 + * + * Returns: an array of strings, terminated by a NULL string, specifying the + * mimetypes for which the streamed content is available. + * + **/ + +char ** +AccessibleStreamableContent_getContentTypes (AccessibleStreamableContent *obj) +{ + Accessibility_StringSeq *mimeseq; + char **content_types; + int i; + + g_return_val_if_fail (obj != NULL, NULL); + + mimeseq = Accessibility_StreamableContent_getContentTypes (CSPI_OBJREF (obj), + cspi_ev ()); + cspi_return_val_if_ev ("getContentTypes", NULL); + content_types = g_new0 (char *, mimeseq->_length + 1); + for (i = 0; i < mimeseq->_length; ++i) + content_types[i] = g_strdup (mimeseq->_buffer[i]); + content_types [mimeseq->_length] = NULL; + CORBA_free (mimeseq); + + return content_types; +} +/** +* AccessibleStreamableContent_freeContentTypesList: +* @obj: the AccessibleStreamableContent implementor on which to operate. +* @content_types: a list of content types previously returned by +* #AccessibleStreamableContent_getContentTypes. +* +* Free the memory associated with a call to #AccessibleStreamableContent_getContentTypes, once +* the result has been used. +* +* Since: AT-SPI 1.4 +**/ +void +AccessibleStreamableContent_freeContentTypesList (AccessibleStreamableContent *obj, + char **content_types) +{ + if (content_types) + { + gint i = 0; + while (content_types[i]) + { + g_free (content_types[i]); + i++; + } + g_free (content_types); + } +} + +/** + * AccessibleStreamableContent_open: + * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate. + * @content_type: a string specifying the content type to retrieve (should match one + * of the return strings from #AccessibleStreamableContent_getContentTypes ()). + * + * Open a streaming connection to an AccessibleStreamableContent implementor, + * of a particular content type. Note that a client may only have one + * open stream per streamable interface instance in the current + * implementation. + * + * @Since: AT-SPI 1.4 + * + * Returns: #TRUE if successful, #FALSE if unsuccessful. + * + **/ +SPIBoolean +AccessibleStreamableContent_open (AccessibleStreamableContent *obj, + const char *content_type) +{ + Accessibility_ContentStream stream; + struct StreamCacheItem *cache; + stream = Accessibility_StreamableContent_getStream (CSPI_OBJREF (obj), + content_type, + cspi_ev ()); + cspi_return_val_if_ev ("getContent", FALSE); + + if (stream != CORBA_OBJECT_NIL) { + cache = g_new0 (struct StreamCacheItem, 1); + cache->stream = stream; + cache->mimetype = CORBA_string_dup (content_type); + + g_hash_table_replace (get_streams (), CSPI_OBJREF (obj), cache); + /* FIXME + * This limits us to one concurrent stream per streamable interface + * for a given client. + * It might be reasonable for a client to open more than one stream + * to content, in different mime-types, at the same time. + */ + + return TRUE; + } + return FALSE; +} + +/** + * AccessibleStreamableContent_close: + * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate. + * + * Close the current streaming connection to an AccessibleStreamableContent implementor. + * This must be called before any subsequent AccessibleStreamableContent_open + * calls on the same object. + * + * @Since: AT-SPI 1.4 + * + * Returns: #TRUE if successful, #FALSE if unsuccessful. + * + **/ +SPIBoolean +AccessibleStreamableContent_close (AccessibleStreamableContent *obj) +{ + if (CSPI_OBJREF (obj) != CORBA_OBJECT_NIL) { + if (g_hash_table_remove (get_streams (), CSPI_OBJREF (obj))) + return TRUE; + } + return FALSE; +} + +/** + * AccessibleStreamableContent_seek: + * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate. + * @offset: a long int specifying the offset into the stream. + * @seek_type: an enum indicating the seek offset type, may be SEEK_SET, + * SEEK_CUR, SEEK_END (as in the lseek() libc command). + * + * Cause the current streamable content connection (obtained via + * #AccessibleStreamableContent_open()) to seek to a particular offset in the + * stream. + * + * @Since: AT-SPI 1.4 + * + * Returns: #TRUE if successful, #FALSE if unsuccessful. + * + **/ +long int +AccessibleStreamableContent_seek (AccessibleStreamableContent *obj, + long int offset, + AccessibleStreamableContentSeekType seek_type) +{ + Accessibility_ContentStream stream; + long int ret_offset = 0; + struct StreamCacheItem *cached; + Accessibility_ContentStream_SeekType content_seek_type; + + cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj)); + if (cached) + { + stream = cached->stream; + if (stream != CORBA_OBJECT_NIL) + { + switch (seek_type) { + case SPI_STREAM_SEEK_SET: + content_seek_type = Accessibility_ContentStream_SEEK_SET; + break; + case SPI_STREAM_SEEK_END: + content_seek_type = Accessibility_ContentStream_SEEK_END; + break; + case SPI_STREAM_SEEK_CUR: + default: + content_seek_type = Accessibility_ContentStream_SEEK_CURRENT; + break; + } + ret_offset = accessible_content_stream_client_seek (stream, offset, + content_seek_type, cspi_ev ()); + cspi_return_val_if_ev ("seek", FALSE); + } + } + return ret_offset; +} + +/** + * AccessibleStreamableContent_read: + * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate. + * @buff: a pointer to a buffer into which the resulting bytes read from the stream + * are to be written. + * @nbytes: a long integer indicating the number of bytes to read/write. + * @read_type: currently unused, specifies behavior of reads for streamed content + * if blocking is not allowed, etc. + * + * Copy (read) bytes from the currently open streamable content connection + * to a buffer. This is a blocking API, in the sense that it does not + * return until the bytes have been read, or an error condition is + * detected. + * + * @Since: AT-SPI 1.4 + * + * Returns: an integer indicating the number of bytes read, or -1 on error. + * + **/ +SPIBoolean +AccessibleStreamableContent_read (AccessibleStreamableContent *obj, + void *buff, + long int nbytes, + unsigned int read_type) +{ + Accessibility_ContentStream stream; + struct StreamCacheItem *cached; + cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj)); + if (cached) + { + CORBA_long len_read = 0; + stream = cached->stream; + if (stream != CORBA_OBJECT_NIL) + { + guint8 *mem; + + mem = accessible_content_stream_client_read (stream, (size_t) nbytes, &len_read, cspi_ev ()); + cspi_return_val_if_ev ("read", FALSE); + if (mem) + { + memcpy (buff, mem, len_read); + g_free (mem); + if ((nbytes == -1) || (len_read == nbytes)) + return TRUE; + } + } + } + else g_message ("no matching stream was opened..."); + return FALSE; +} +#endif // TODO diff --git a/cspi/spi_table.c b/cspi/spi_table.c new file mode 100644 index 0000000..e45408c --- /dev/null +++ b/cspi/spi_table.c @@ -0,0 +1,815 @@ +/* + * 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. + * + * 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. + */ + +#include /* for malloc */ +#include + +/** + * AccessibleTable_ref: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * + * Increment the reference count for an #AccessibleTable object. + **/ +void +AccessibleTable_ref (AccessibleTable *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleTable_unref: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * + * Decrement the reference count for an #AccessibleTable object. + **/ +void +AccessibleTable_unref (AccessibleTable *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleTable_getCaption: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * + * Get an accessible representation of the caption for an #AccessibleTable. + * + * Returns: an #Accessible object that serves as the table's caption. + **/ +Accessible * +AccessibleTable_getCaption (AccessibleTable *obj) +{ + char *path; + Accessible *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_get_property (obj, spi_interface_table, "caption", NULL, "o", &path); + cspi_return_val_if_ev ("getCaption", NULL); + retval = cspi_ref_related_accessible (obj, path); + g_free (path); + return retval; +} + +/** + * AccessibleTable_getSummary: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * + * Get an accessible object which summarizes the contents of an #AccessibleTable. + * + * Returns: an #Accessible object that serves as the table's summary (often a + * reduced #AccessibleTable). + **/ +Accessible * +AccessibleTable_getSummary (AccessibleTable *obj) +{ + char *path; + Accessible *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_get_property (obj, spi_interface_table, "summary", NULL, "o", &path); + cspi_return_val_if_ev ("getSummary", NULL); + retval = cspi_ref_related_accessible (obj, path); + g_free (path); + return retval; +} + +/** + * AccessibleTable_getNRows: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * + * Get the number of rows in an #AccessibleTable, + * exclusive of any rows that are programmatically hidden, but inclusive + * of rows that may be outside of the current scrolling window or viewport. + * + * Returns: a #long integer indicating the number of rows in the table. + **/ +long +AccessibleTable_getNRows (AccessibleTable *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_table, "nRows", NULL, "i", &retval); + + cspi_return_val_if_ev ("getNRows", -1); + + return retval; + +} + +/** + * AccessibleTable_getNColumns: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * + * Get the number of columns in an #AccessibleTable, + * exclusive of any columns that are programmatically hidden, but inclusive + * of columns that may be outside of the current scrolling window or viewport. + * + * Returns: a #long integer indicating the number of columns in the table. + **/ +long +AccessibleTable_getNColumns (AccessibleTable *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_table, "nColumns", NULL, "i", &retval); + + cspi_return_val_if_ev ("getNColumns", -1); + + return retval; +} + +/** + * AccessibleTable_getAccessibleAt: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the specified table row, zero-indexed. + * @column: the specified table column, zero-indexed. + * + * Get the table cell at the specified row and column indices. + * To get the accessible object at a particular (x, y) screen coordinate, + * use #Accessible_getAccessibleAtPoint (). + * + * Returns: an #Accessible object representing the specified table cell. + **/ +Accessible * +AccessibleTable_getAccessibleAt (AccessibleTable *obj, + long int row, + long int column) +{ + dbus_int32_t d_row = row, d_column = column; + char *path; + Accessible *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_table, "getAccessibleAt", NULL, "ii=>o", &d_row, &d_column, &path); + cspi_return_val_if_ev ("getAccessibleAt", NULL); + retval = cspi_ref_related_accessible (obj, path); + g_free (path); + return retval; +} + +/** + * AccessibleTable_getIndexAt: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the specified table row, zero-indexed. + * @column: the specified table column, zero-indexed. + * + * Get the 1-D child index corresponding to the specified 2-D row and column indices. + * To get the accessible object at a particular (x, y) screen coordinate, + * use #Accessible_getAccessibleAtPoint (). + * @see #AccessibleTable_getRowAtIndex(), #AccessibleTable_getColumnAtIndex() + * + * Returns: a long integer which serves as the index of a specified cell in the + * table, in a form usable by #Accessible_getChildAtIndex(). + **/ +long +AccessibleTable_getIndexAt (AccessibleTable *obj, + long int row, + long int column) +{ + dbus_int32_t d_row = row, d_column = column; + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_table, "getIndexAt", NULL, "ii=>i", d_row, d_column, &retval); + + cspi_return_val_if_ev ("getIndexAt", -1); + + return retval; +} + +/** + * AccessibleTable_getRowAtIndex: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @index: the specified child index, zero-indexed. + * + * Get the table row index occupied by the child at a particular 1-D child index. + * + * @see #AccessibleTable_getIndexAt(), #AccessibleTable_getColumnAtIndex() + * + * Returns: a long integer indicating the first row spanned by the child of a + * table, at the specified 1-D (zero-offset) @index. + **/ +long +AccessibleTable_getRowAtIndex (AccessibleTable *obj, + long index) +{ + dbus_int32_t d_index = index; + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_table, "getRowAtIndex", NULL, "i=>i", d_index, &retval); + + cspi_return_val_if_ev ("getRowAtIndex", -1); + + return retval; +} + +/** + * AccessibleTable_getColumnAtIndex: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @index: the specified child index, zero-indexed. + * + * Get the table column index occupied by the child at a particular 1-D child index. + * + * @see #AccessibleTable_getIndexAt(), #AccessibleTable_getRowAtIndex() + * + * Returns: a long integer indicating the first column spanned by the child of a + * table, at the specified 1-D (zero-offset) @index. + **/ +long +AccessibleTable_getColumnAtIndex (AccessibleTable *obj, + long index) +{ + dbus_int32_t d_index = index; + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_table, "getColumnAtIndex", NULL, "i=>i", d_index, &retval); + + cspi_return_val_if_ev ("getColumnAtIndex", -1); + + return retval; +} + +/** + * AccessibleTable_getRowDescription: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the specified table row, zero-indexed. + * + * Get a text description of a particular table row. This differs from + * AccessibleTable_getRowHeader, which returns an #Accessible. + * + * Returns: a UTF-8 string describing the specified table row, if available. + **/ +char * +AccessibleTable_getRowDescription (AccessibleTable *obj, + long int row) +{ + dbus_int32_t d_row = row; + char *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_table, "getRowDescription", NULL, "i=>s", d_row, &retval); + + cspi_return_val_if_ev ("getRowDescription", NULL); + + return retval; +} + +/** + * AccessibleTable_getColumnDescription: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @column: the specified table column, zero-indexed. + * + * Get a text description of a particular table column. This differs from + * AccessibleTable_getColumnHeader, which returns an #Accessible. + * + * Returns: a UTF-8 string describing the specified table column, if available. + **/ +char * +AccessibleTable_getColumnDescription (AccessibleTable *obj, + long int column) +{ + dbus_int32_t d_column = column; + char *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_table, "getColumnDescription", NULL, "i=>s", d_column, &retval); + + cspi_return_val_if_ev ("getColumnDescription", NULL); + + return retval; +} + +/** + * AccessibleTable_getRowExtentAt: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the specified table row, zero-indexed. + * @column: the specified table column, zero-indexed. + * + * Get the number of rows spanned by the table cell at the specific row and column. + * (some tables can have cells which span multiple rows and/or columns). + * + * Returns: a long integer indicating the number of rows spanned by the specified cell. + **/ +long +AccessibleTable_getRowExtentAt (AccessibleTable *obj, + long int row, + long int column) +{ + dbus_int32_t d_row = row, d_column = column; + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_table, "getRowExtentAt", NULL, "ii=>i", d_row, d_column, &retval); + + cspi_return_val_if_ev ("getRowExtentAt", -1); + + return retval; +} + +/** + * AccessibleTable_getColumnExtentAt: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the specified table row, zero-indexed. + * @column: the specified table column, zero-indexed. + * + * Get the number of columns spanned by the table cell at the specific row and column. + * (some tables can have cells which span multiple rows and/or columns). + * + * Returns: a long integer indicating the number of columns spanned by the specified cell. + **/ +long +AccessibleTable_getColumnExtentAt (AccessibleTable *obj, + long int row, + long int column) +{ + dbus_int32_t d_row = row, d_column = column; + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_table, "getColumnExtentAt", NULL, "ii=>i", d_row, d_column, &retval); + + cspi_return_val_if_ev ("getColumnExtentAt", -1); + + return retval; +} + +/** + * AccessibleTable_getRowHeader: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the specified table row, zero-indexed. + * + * Get the header associated with a table row, if available. This differs from + * AccessibleTable_getRowDescription, which returns a string. + * + * Returns: a #Accessible representatin of the specified table row, if available. + **/ +Accessible * +AccessibleTable_getRowHeader (AccessibleTable *obj, + long int row) +{ + dbus_int32_t d_row = row; + char *path; + Accessible *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_table, "getRowHeader", NULL, "i=>o", d_row, &path); + cspi_return_val_if_ev ("getRowHeader", NULL); + retval = cspi_ref_related_accessible (obj, path); + g_free (path); + + return retval; +} + +/** + * AccessibleTable_getColumnHeader: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @column: the specified table column, zero-indexed. + * + * Get the header associated with a table column, if available. This differs from + * AccessibleTable_getColumnDescription, which returns a string. + * + * Returns: a #Accessible representatin of the specified table column, if available. + **/ +Accessible * +AccessibleTable_getColumnHeader (AccessibleTable *obj, + long int column) +{ + dbus_int32_t d_column = column; + char *path; + Accessible *retval; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_table, "getColumnHeader", NULL, "i=>o", d_column, &path); + cspi_return_val_if_ev ("getColumnHeader", NULL); + retval = cspi_ref_related_accessible (obj, path); + g_free (path); + + return retval; +} + +/** + * AccessibleTable_getNSelectedRows: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * + * Query a table to find out how many rows are currently selected. Not all tables + * support row selection. + * + * Returns: a long integer indicating the number of rows currently selected. + **/ +long +AccessibleTable_getNSelectedRows (AccessibleTable *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_table, "nSelectedRows", NULL, "i", &retval); + + cspi_return_val_if_ev ("getNSelectedRows", -1); + + return retval; +} + +static long +cspi_long_seq_to_array (GArray *seq, long int **array) +{ + long *j; + long length, i; + + if (!cspi_check_ev ("getSelectionItems")) + { + *array = NULL; + return 0; + } + + length = seq->len; + + j = *array = malloc (sizeof (long) * length); + + for (i = 0; i < length; i++) + { + j[i] = g_array_index (seq, long, i); + } + + g_array_free (seq, TRUE); + + return length; +} + +/** + * AccessibleTable_getSelectedRows: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @selectedRows: a doubly indirected pointer which will be set to the address + * of an array of long integers, specifying which rows are currently selected. + * + * Query a table for a list of indices of rows which are currently selected. + * + * Returns: a long integer indicating the length of the array returned in @selectedRows. + **/ +long +AccessibleTable_getSelectedRows (AccessibleTable *obj, + long int **selectedRows) +{ + GArray *rows; + + *selectedRows = NULL; + + cspi_return_val_if_fail (obj != NULL, 0); + + cspi_dbus_call (obj, spi_interface_table, "getSelectedRows", NULL, "=>ai", &rows); + + cspi_return_val_if_ev ("getSelectedRows", -1); + + return cspi_long_seq_to_array (rows, selectedRows); +} + +/** + * AccessibleTable_getNSelectedColumns: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * + * Query a table to find out how many columns are currently selected. Not all tables + * support column selection. + * + * Returns: a long integer indicating the number of columns currently selected. + **/ +long +AccessibleTable_getNSelectedColumns (AccessibleTable *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_table, "nSelectedColumns", NULL, "i", &retval); + + cspi_return_val_if_ev ("getNSelectedColumns", -1); + + return retval; +} + +/** + * AccessibleTable_getSelectedColumns: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @selectedColumns: a doubly indirected pointer which will be set to the address + * of an array of long integers, specifying which columns are currently selected. + * + * Query a table for a list of indices of columns which are currently selected. + * Not all tables support column selection. + * + * Returns: a long integer indicating the length of the array returned in @selectedColumns. + **/ +long +AccessibleTable_getSelectedColumns (AccessibleTable *obj, + long int **selectedColumns) +{ + GArray *columns; + + *selectedColumns = NULL; + + cspi_return_val_if_fail (obj != NULL, 0); + + cspi_dbus_call (obj, spi_interface_table, "getSelectedColumns", NULL, "=>ai", &columns); + + cspi_return_val_if_ev ("getSelectedColumns", -1); + return cspi_long_seq_to_array (columns, selectedColumns); +} + +/** + * AccessibleTable_isRowSelected: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the zero-indexed row number of the row being queried. + * + * Determine whether a table row is selected. Not all tables support row selection. + * + * Returns: #TRUE if the specified row is currently selected, #FALSE if not. + **/ +SPIBoolean +AccessibleTable_isRowSelected (AccessibleTable *obj, + long int row) +{ + dbus_int32_t d_row = row; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_table, "isRowSelected", NULL, "i=>b", d_row, &retval); + + cspi_return_val_if_ev ("isRowSelected", FALSE); + + return retval; +} + +/** + * AccessibleTable_isColumnSelected: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @column: the zero-indexed column number of the column being queried. + * + * Determine whether specified table column is selected. + * Not all tables support column selection. + * + * Returns: #TRUE if the specified column is currently selected, #FALSE if not. + **/ +SPIBoolean +AccessibleTable_isColumnSelected (AccessibleTable *obj, + long int column) +{ + dbus_int32_t d_column = column; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_table, "isColumnSelected", NULL, "i=>b", d_column, &retval); + + cspi_return_val_if_ev ("isColumnSelected", FALSE); + + return retval; +} + +/** + * AccessibleTable_addRowSelection: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the zero-indexed row number of the row being selected. + * + * Select the specified row, adding it to the current row selection. + * Not all tables support row selection. + * + * Returns: #TRUE if the specified row was successfully selected, #FALSE if not. + **/ +SPIBoolean +AccessibleTable_addRowSelection (AccessibleTable *obj, + long int row) +{ + dbus_int32_t d_row = row; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_table, "addRowSelection", NULL, "i=>b", d_row, &retval); + + cspi_return_val_if_ev ("addRowSelection", FALSE); + + return retval; +} + +/** + * AccessibleTable_addColumnSelection: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @column: the zero-indexed column number of the column being selected. + * + * Select the specified column, adding it to the current column selection. + * Not all tables support column selection. + * + * Returns: #TRUE if the specified column was successfully selected, #FALSE if not. + **/ +SPIBoolean +AccessibleTable_addColumnSelection (AccessibleTable *obj, + long int column) +{ + dbus_int32_t d_column = column; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_table, "addColumnSelection", NULL, "i=>b", d_column, &retval); + + cspi_return_val_if_ev ("addColumnSelection", FALSE); + + return retval; +} + +/** + * AccessibleTable_removeRowSelection: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the zero-indexed number of the row being deselected. + * + * De-select the specified row, removing it to the current row selection. + * Not all tables support row selection. + * + * Returns: #TRUE if the specified row was successfully de-selected, #FALSE if not. + **/ +SPIBoolean +AccessibleTable_removeRowSelection (AccessibleTable *obj, + long int row) +{ + dbus_int32_t d_row = row; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_table, "removeRowSelection", NULL, "i=>b", d_row, &retval); + + cspi_return_val_if_ev ("removeRowSelection", FALSE); + + return retval; +} + +/** + * AccessibleTable_removeColumnSelection: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @column: the zero-indexed column number of the column being de-selected. + * + * De-select the specified column, removing it to the current column selection. + * Not all tables support column selection. + * + * Returns: #TRUE if the specified column was successfully de-selected, #FALSE if not. + **/ +SPIBoolean +AccessibleTable_removeColumnSelection (AccessibleTable *obj, + long int column) +{ + dbus_int32_t d_column = column; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_table, "removeColumnSelection", NULL, "i=>b", d_column, &retval); + + cspi_return_val_if_ev ("removeColumnSelection", FALSE); + + return retval; +} + +/** + * AccessibleTable_getRowColumnExtentsAtIndex: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @index: the index of the Table child whose row/column + * extents are requested. + * @row: back-filled with the first table row associated with + * the cell with child index \c index. + * @col: back-filled with the first table column associated + * with the cell with child index \c index. + * @row_extents: back-filled with the number of table rows + * across which child \c i extends. + * @col_extents: back-filled with the number of table columns + * across which child \c i extends. + * @is_selected: a boolean which is back-filled with \c True + * if the child at index \c i corresponds to a selected table cell, + * \c False otherwise. + * + * Given a child index, determine the row and column indices and + * extents, and whether the cell is currently selected. If + * the child at \c index is not a cell (for instance, if it is + * a summary, caption, etc.), \c False is returned. + * + * Example: + * If the Table child at index '6' extends across columns 5 and 6 of + * row 2 of a Table instance, and is currently selected, then + * + * retval = table::getRowColumnExtentsAtIndex (6, row, col, + * row_extents, + * col_extents, + * is_selected); + * + * will return True, and after the call + * row, col, row_extents, col_extents, + * and \c is_selected will contain 2, 5, 1, 2, and + * True, respectively. + * + * Returns: \c True if the index is associated with a valid table + * cell, \c False if the index does not correspond to a cell. If + * \c False is returned, the values of the out parameters are + * undefined. + * + * Since AT-SPI 1.7.0 + **/ +SPIBoolean +AccessibleTable_getRowColumnExtentsAtIndex (AccessibleTable *obj, + long int index, long int *row, long int *col, + long int *row_extents, long int *col_extents, + long int *is_selected) +{ + dbus_int32_t d_index = index; + dbus_bool_t retval; + dbus_int32_t d_row, d_col, d_row_extents, d_col_extents; + dbus_bool_t d_is_selected; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_table, "getRowColumnExtentsAtIndex", NULL, "i=>iiiibb", d_index, &d_row, &d_col, &d_row_extents, &d_col_extents, &d_is_selected, &retval); + + if (!cspi_check_ev ("getRowColumnExtentsAtIndex")){ + + *row = 0; + *col = 0; + *row_extents = 0; + *col_extents = 0; + *is_selected = FALSE; + retval = FALSE; + } + + else { + *row = d_row; + *col = d_col; + *row_extents = d_row_extents;; + *col_extents = d_col_extents; + *is_selected = d_is_selected;; + } + + return retval; +} + + +/** + * AccessibleTable_isSelected: + * @obj: a pointer to the #AccessibleTable implementor on which to operate. + * @row: the zero-indexed row of the cell being queried. + * @column: the zero-indexed column of the cell being queried. + * + * Determine whether the cell at a specific row and column is selected. + * + * Returns: #TRUE if the specified cell is currently selected, #FALSE if not. + **/ +SPIBoolean +AccessibleTable_isSelected (AccessibleTable *obj, + long int row, + long int column) +{ + dbus_int32_t d_row = row, d_column = column; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_table, "isSelected", NULL, "ii=>b", d_row, d_column, &retval); + + cspi_return_val_if_ev ("isSelected", FALSE); + + return retval; +} + diff --git a/cspi/spi_text.c b/cspi/spi_text.c new file mode 100644 index 0000000..5339a39 --- /dev/null +++ b/cspi/spi_text.c @@ -0,0 +1,967 @@ +/* + * 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. + * + * 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. + */ + +#include + +static Accessibility_TEXT_BOUNDARY_TYPE +get_accessible_text_boundary_type (AccessibleTextBoundaryType type) +{ + switch (type) + { + case SPI_TEXT_BOUNDARY_CHAR: + return Accessibility_TEXT_BOUNDARY_CHAR; + break; + case SPI_TEXT_BOUNDARY_CURSOR_POS: + /* FixME */ + return Accessibility_TEXT_BOUNDARY_CHAR; + break; + case SPI_TEXT_BOUNDARY_WORD_START: + return Accessibility_TEXT_BOUNDARY_WORD_START; + break; + case SPI_TEXT_BOUNDARY_WORD_END: + return Accessibility_TEXT_BOUNDARY_WORD_END; + break; + case SPI_TEXT_BOUNDARY_SENTENCE_START: + return Accessibility_TEXT_BOUNDARY_SENTENCE_START; + break; + case SPI_TEXT_BOUNDARY_SENTENCE_END: + return Accessibility_TEXT_BOUNDARY_SENTENCE_END; + break; + case SPI_TEXT_BOUNDARY_LINE_START: + return Accessibility_TEXT_BOUNDARY_LINE_START; + break; + case SPI_TEXT_BOUNDARY_LINE_END: + return Accessibility_TEXT_BOUNDARY_LINE_END; + break; + case SPI_TEXT_BOUNDARY_ATTRIBUTE_RANGE: + /* Fixme */ + return Accessibility_TEXT_BOUNDARY_CHAR; + break; + default: + /* FIXME */ + return Accessibility_TEXT_BOUNDARY_CHAR; + } +} + +static Accessibility_TEXT_CLIP_TYPE +get_accessible_text_clip_type (AccessibleTextClipType type) +{ + switch (type) + { + case SPI_TEXT_CLIP_NONE: + return Accessibility_TEXT_CLIP_NONE; + break; + case SPI_TEXT_CLIP_MIN: + return Accessibility_TEXT_CLIP_MIN; + break; + case SPI_TEXT_CLIP_MAX: + return Accessibility_TEXT_CLIP_MAX; + break; + default: + return Accessibility_TEXT_CLIP_BOTH; + } +} + +typedef struct +{ + dbus_int32_t startOffset; + dbus_int32_t endOffset; + char *content; +} Accessibility_Range; + +static AccessibleTextRange ** +get_accessible_text_ranges_from_range_seq (GArray *range_seq) +{ + AccessibleTextRange **ranges = NULL; + AccessibleTextRange *array = NULL; + int i; + if (range_seq && range_seq->len > 0) + { + ranges = g_new0 (AccessibleTextRange *, range_seq->len + 1); + } + array = g_new0 (AccessibleTextRange, range_seq->len); + for (i = 0; i < range_seq->len; i++) + { + Accessibility_Range *r = g_array_index (range_seq, Accessibility_Range *, i); + AccessibleTextRange *range; + range = &array[i]; + range->start = r->startOffset; + range->end = r->endOffset; + range->contents = g_strdup (r->content); + ranges[i] = range; + } + ranges[i] = NULL; /* null-terminated list! */ + // TODO: Figure out whether we're leaking strings + g_array_free (range_seq, TRUE); + + return ranges; +} + + +/** + * AccessibleText_ref: + * @obj: a pointer to the #AccessibleText object on which to operate. + * + * Increment the reference count for an #AccessibleText object. + **/ +void +AccessibleText_ref (AccessibleText *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleText_unref: + * @obj: a pointer to the #Accessible object on which to operate. + * + * Decrement the reference count for an #AccessibleText object. + **/ +void +AccessibleText_unref (AccessibleText *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleText_getCharacterCount: + * @obj: a pointer to the #AccessibleText object to query. + * + * Get the character count of an #AccessibleText object. + * + * Returns: a long integer indicating the total number of + * characters in the #AccessibleText object. + **/ +long +AccessibleText_getCharacterCount (AccessibleText *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_text, "characterCount", NULL, "i", &retval); + + cspi_return_val_if_ev ("getCharacterCount", -1); + + return retval; +} + +/** + * AccessibleText_getText: + * @obj: a pointer to the #AccessibleText object to query. + * @startOffset: a #long indicating the start of the desired text range. + * @endOffset: a #long indicating the first character past the desired range. + * + * Get a range of text from an #AccessibleText object. The number of bytes + * in the returned string may exceed endOffset-startOffset, since + * UTF-8 is a variable-width encoding. + * + * Returns: a text string containing characters from @startOffset + * to @endOffset-1, inclusive, encoded as UTF-8. + **/ +char * +AccessibleText_getText (AccessibleText *obj, + long int startOffset, + long int endOffset) +{ + char *retval; + dbus_int32_t d_startOffset = startOffset, d_endOffset = endOffset; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_text, "getText", NULL, "ii=>s", startOffset, endOffset, &retval); + + cspi_return_val_if_ev ("getText", NULL); + + return retval; +} + +/** + * AccessibleText_getCaretOffset: + * @obj: a pointer to the #AccessibleText object to query. + * + * Get the current offset of the text caret in an #AccessibleText object. + * + * Returns: a long integer indicating the current position of the text caret. + **/ +long +AccessibleText_getCaretOffset (AccessibleText *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_get_property (obj, spi_interface_text, "caretOffset", NULL, "i", &retval); + + cspi_return_val_if_ev ("getCaretOffset", -1); + + return retval; +} + +/** + * AccessibleText_getAttributes: + * @obj: a pointer to the #AccessibleText object to query. + * @offset: a long integer indicating the offset from which the attribute + * search is based. + * @startOffset: a #long indicating the start of the desired text range. + * @endOffset: a #long indicating the first character past the desired range. + * + * Get the attributes applied to a range of text from an #AccessibleText + * object, and the bounds of the range. + * The text attributes correspond to CSS attributes where possible, + * keys and values are delimited from one another via ":", and + * the delimiter between key/value pairs is ";". Thus + * "font-size:10;foreground-color:0,0,0" would be a valid + * return string. + * + * Returns: a text string describing the attributes occurring within the + * attribute run containing @offset, encoded as UTF-8. + **/ +char * +AccessibleText_getAttributes (AccessibleText *obj, + long int offset, + long int *startOffset, + long int *endOffset) +{ + dbus_int32_t d_offset = offset; + dbus_int32_t retStartOffset, retEndOffset; + char *retval; + + if (obj == NULL) + { + *startOffset = *endOffset = -1; + return NULL; + } + + cspi_dbus_call (obj, spi_interface_text, "getAttributes", NULL, "i=>iis", d_offset, &retStartOffset, &retEndOffset, &retval); + + if (!cspi_check_ev ("getAttributes")) + { + *startOffset = *endOffset = -1; + retval = NULL; + } + else + { + *startOffset = retStartOffset; + *endOffset = retEndOffset; + } + + return retval; +} + +/** + * AccessibleText_getDefaultAttributes: + * @obj: a pointer to the #AccessibleText object to query. + * + * Get the default attributes applied to an #AccessibleText + * object. + * The text attributes correspond to CSS attributes where possible, + * keys and values are delimited from one another via ":", and + * the delimiter between key/value pairs is ";". Thus + * "font-size:10;foreground-color:0,0,0" would be a valid + * return string. The combination of this attribute set and + * the attributes reported by #AccessibleText_getAttributes + * describes the entire set of text attributes over a range. + * + * @Since: AT-SPI 1.4 + * + * Returns: a text string describing the default attributes + * applied to a text object, (exclusive of explicitly-set + * attributes), encoded as UTF-8. + **/ +char * +AccessibleText_getDefaultAttributes (AccessibleText *obj) +{ + char *retval; + + if (obj == NULL) + { + return NULL; + } + + cspi_dbus_call (obj, spi_interface_text, "getAttributes", NULL, "=>s", &retval); + + if (!cspi_check_ev ("getAttributes")) + { + retval = NULL; + } + + return retval; +} + +/** + * AccessibleText_setCaretOffset: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @newOffset: the offset to which the text caret is to be moved. + * + * Set the text caret position for an #AccessibleText object. + * + * Returns: #TRUE if successful, #FALSE otherwise. + **/ +SPIBoolean +AccessibleText_setCaretOffset (AccessibleText *obj, + long int newOffset) +{ + dbus_int32_t d_newOffset = newOffset; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_text, "setCaretOffset", NULL, "i=>b", d_newOffset, &retval); + + cspi_return_val_if_ev ("setCaretOffset", FALSE); + + return retval; +} + +/** + * AccessibleText_getTextBeforeOffset: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @offset: a long integer indicating the offset from which the delimiter + * search is based. + * @type: an #AccessibleTextBoundaryType indicating whether the desired + * text string is a word, sentence, line, or attribute run. + * @startOffset: a pointer to a long integer which is assigned the + * starting offset of the returned string, relative to the + * original #AccessibleText. + * @endOffset: a pointer to a long integer which is assigned the + * ending offset of the returned string, relative to the original + * #AccessibleText. + * + * Get delimited text from an #AccessibleText object which precedes a given + * text offset. + * + * Returns: a UTF-8 string representing the delimited text, both of whose + * delimiting boundaries are before the current offset, or + * an empty string if no such text exists. + **/ +char * +AccessibleText_getTextBeforeOffset (AccessibleText *obj, + long int offset, + AccessibleTextBoundaryType type, + long int *startOffset, + long int *endOffset) +{ + dbus_int32_t d_offset = offset; + dbus_uint32_t d_type = type; + dbus_int32_t retStartOffset, retEndOffset; + char *retval; + + if (obj == NULL) + { + *startOffset = *endOffset = -1; + return NULL; + } + + cspi_dbus_call (obj, spi_interface_text, "getTextBeforeOffset", NULL, "iu=>iis", d_offset, d_type, &retStartOffset, &retEndOffset, &retval); + if (!cspi_check_ev ("getTextBeforeOffset")) + { + *startOffset = *endOffset = -1; + retval = NULL; + } + else + { + *startOffset = retStartOffset; + *endOffset = retEndOffset; + } + return retval; +} + +/** + * AccessibleText_getTextAtOffset: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @offset: a long integer indicating the offset from which the delimiter + * search is based. + * @type: an #AccessibleTextBoundaryType indicating whether the desired + * text string is a word, sentence, line, or attribute run. + * @startOffset: a pointer to a long integer which is assigned the + * starting offset of the returned string, relative to the + * original #AccessibleText. + * @endOffset: a pointer to a long integer which is assigned the + * ending offset of the returned string, relative to the original + * #AccessibleText. + * + * Get delimited text from an #AccessibleText object which includes a given + * text offset. + * + * Returns: a UTF-8 string representing the delimited text, whose + * delimiting boundaries bracket the current offset, or + * an empty string if no such text exists. + **/ +char * +AccessibleText_getTextAtOffset (AccessibleText *obj, + long int offset, + AccessibleTextBoundaryType type, + long int *startOffset, long int *endOffset) +{ + dbus_int32_t d_offset = offset; + dbus_uint32_t d_type = type; + dbus_int32_t retStartOffset, retEndOffset; + char *retval; + + if (obj == NULL) + { + *startOffset = *endOffset = -1; + return NULL; + } + + cspi_dbus_call (obj, spi_interface_text, "getTextAtOffset", NULL, "iu=>iis", d_offset, d_type, &retStartOffset, &retEndOffset, &retval); + + if (!cspi_check_ev ("getTextAtOffset")) + { + *startOffset = *endOffset = -1; + retval = NULL; + } + else + { + *startOffset = retStartOffset; + *endOffset = retEndOffset; + } + return retval; +} + +/** + * AccessibleText_getTextAfterOffset: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @offset: a long integer indicating the offset from which the delimiter + * search is based. + * @type: an #AccessibleTextBoundaryType indicating whether the desired + * text string is a word, sentence, line, or attribute run. + * @startOffset: a pointer to a long integer which is assigned the + * starting offset of the returned string, relative to the + * original #AccessibleText. + * @endOffset: a pointer to a long integer which is assigned the + * ending offset of the returned string, relative to the original + * #AccessibleText. + * + * Get delimited text from an #AccessibleText object which follows a given + * text offset. + * + * Returns: a UTF-8 string representing the delimited text, both of whose + * delimiting boundaries are after or inclusive of the current + * offset, or an empty string if no such text exists. + **/ +char * +AccessibleText_getTextAfterOffset (AccessibleText *obj, + long int offset, + AccessibleTextBoundaryType type, + long int *startOffset, long int *endOffset) +{ + dbus_int32_t d_offset = offset; + dbus_uint32_t d_type = type; + dbus_int32_t retStartOffset, retEndOffset; + char *retval; + + if (obj == NULL) + { + *startOffset = *endOffset = -1; + return NULL; + } + + cspi_dbus_call (obj, spi_interface_text, "getTextAfterOffset", NULL, "iu=>iis", d_offset, d_type, &retStartOffset, &retEndOffset, &retval); + + if (!cspi_check_ev ("getTextAfterOffset")) + { + *startOffset = *endOffset = -1; + retval = NULL; + } + else + { + *startOffset = retStartOffset; + *endOffset = retEndOffset; + } + return retval; +} + +/** + * AccessibleText_getCharacterAtOffset: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @offset: a long integer indicating the text offset where the desired + * character is located. + * + * Get the character at a given offset for an #AccessibleText object. + * + * Returns: an #unsigned long integer which represents the + * UCS-4 unicode code point of the given character, or + * 0xFFFFFFFF if the character in question cannot be represented + * in the UCS-4 encoding. + **/ +unsigned long +AccessibleText_getCharacterAtOffset (AccessibleText *obj, + long int offset) +{ + dbus_int32_t d_offset = offset; + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_text, "getCharacterAtOffset", NULL, "i=>i", d_offset, &retval); + + cspi_return_val_if_ev ("getCharacterAtOffset", -1); + + return retval; +} + +/** + * AccessibleText_getCharacterExtents: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @offset: an integer indicating the offset of the text character for + * whom boundary information is requested. + * @x: a pointer to a long integer into which the nominal x coordinate + * of the corresponding glyph will be returned. + * @y:a pointer to a long integer into which the nominal y coordinate + * of the corresponding glyph will be returned. + * @width:a pointer to a long integer into which the width + * of the corresponding glyph will be returned. + * @height: a pointer to a long integer into which the height + * of the corresponding glyph will be returned. + * @type: an #AccessibleCoordType indicating the coordinate system to use + * for the returned values. + * + * Get the bounding box containing the glyph representing + * the character at a particular text offset. + **/ +void +AccessibleText_getCharacterExtents (AccessibleText *obj, + long int offset, + long int *x, + long int *y, + long int *width, + long int *height, + AccessibleCoordType type) +{ + dbus_int32_t d_offset = offset; + dbus_uint16_t d_type = type; + dbus_int32_t retX, retY, retWidth, retHeight; + + if (obj == NULL) + { + *x = *y = -1; + *width = *height = -1; + return; + } + + cspi_dbus_call (obj, spi_interface_text, "getCharacterExtents", NULL, "in=>iiii", d_offset, d_type, &retX, &retY, &retWidth, &retHeight); + + if (!cspi_check_ev ("getCharacterExtents")) + { + *x = *y = -1; + *width = *height = -1; + } + else + { + *x = retX; + *y = retY; + *width = retWidth; + *height = retHeight; + } +} + +/** + * AccessibleText_getOffsetAtPoint: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @x: the x coordinate of the point to be queried. + * @y: the y coordinate of the point to be queried. + * @type: an #AccessibleCoordType indicating the coordinate system in which + * the values should be returned. + * + * Get the bounding box for a glyph at a certain #AccessibleText offset. + * + * Returns: the offset (as a long integer) at the point (@x, @y) + * in the specified coordinate system. + * + **/ +long +AccessibleText_getOffsetAtPoint (AccessibleText *obj, + long int x, + long int y, + AccessibleCoordType type) +{ + dbus_int32_t d_x = x, d_y = y; + dbus_uint16_t d_type = type; + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_text, "getOffsetAtPoint", NULL, "iin=>i", d_x, d_y, d_type, &retval); + + cspi_return_val_if_ev ("getOffsetAtPoint", -1); + + return retval; +} + +/** + * AccessibleText_getRangeExtents: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @startOffset: an integer indicating the offset of the first text character for + * whom boundary information is requested. + * @endOffset: an integer indicating the offset of the text character + * after the last character for whom boundary information is requested. + * @x: a pointer to a long integer into which the nominal x coordinate + * of the corresponding bounding box will be returned. + * @y:a pointer to a long integer into which the nominal y coordinate + * of the corresponding bounding box will be returned. + * @width:a pointer to a long integer into which the width + * of the corresponding bounding box will be returned. + * @height: a pointer to a long integer into which the height + * of the corresponding bounding box will be returned. + * @type: an #AccessibleCoordType indicating the coordinate system to use + * for the returned values. + * + * Get the bounding box for text within a range in an #AccessibleText object. + * + * @Since: AT-SPI 1.2 + **/ +void +AccessibleText_getRangeExtents (AccessibleText *obj, + long int startOffset, + long int endOffset, + long int *x, + long int *y, + long int *width, + long int *height, + AccessibleCoordType type) +{ + dbus_int32_t d_startOffset = startOffset, d_endOffset = endOffset; + dbus_int16_t d_type = type; + dbus_int32_t retX, retY, retWidth, retHeight; + + if (obj == NULL) + { + *x = *y = -1; + *width = *height = -1; + return; + } + + cspi_dbus_call (obj, spi_interface_text, "getRangeExtents", NULL, "iin=>iiii", d_startOffset, d_endOffset, d_type, &retX, &retY, &retWidth, &retHeight); + + if (!cspi_check_ev ("getRangeExtents")) + { + *x = *y = -1; + *width = *height = -1; + } + else + { + *x = retX; + *y = retY; + *width = retWidth; + *height = retHeight; + } +} + +/** + * AccessibleText_getBoundedRanges: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @x: the 'starting' x coordinate of the bounding box. + * @y: the 'starting' y coordinate of the bounding box. + * @width: the x extent of the bounding box. + * @height: the y extent of the bounding box. + * @type: an #AccessibleCoordType indicating the coordinate system to use + * for the returned values. + * @clipTypeX: an #AccessibleTextClipType indicating how to treat characters that + * intersect the bounding box's x extents. + * @clipTypeY: an #AccessibleTextClipType indicating how to treat characters that + * intersect the bounding box's y extents. + * + * Get the ranges of text from an #AccessibleText object which lie within the + * bounds defined by (@x, @y) and (@x+@width, @y+@height). + * + * @Since: AT-SPI 1.2 + * + * Returns: a null-terminated list of pointers to AccessibleTextRange structs + * detailing the bounded text. + **/ +AccessibleTextRange ** +AccessibleText_getBoundedRanges (AccessibleText *obj, + long int x, + long int y, + long int width, + long int height, + AccessibleCoordType type, + AccessibleTextClipType clipTypeX, + AccessibleTextClipType clipTypeY) +{ + dbus_int32_t d_x = x, d_y = y, d_width = width, d_height = height; + dbus_uint16_t d_type = type; + dbus_uint32_t d_clipTypeX = clipTypeX, d_clipTypeY = clipTypeY; + GArray *range_seq; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_text, "getBoundedRanges", NULL, "iiiinuu=>a(iisv)", d_x, d_y, d_width, d_height, d_type, d_clipTypeX, d_clipTypeY, &range_seq); + + cspi_return_val_if_ev ("getBoundedRanges", NULL); + + return get_accessible_text_ranges_from_range_seq (range_seq); +} + +/** + * AccessibleTextRange_freeRanges: + * @ranges: a pointer to an array of AccessibleTextRange structs. + * + * Free the memory used by a list of AccessibleTextRange structs. + * The argument passed in should be an array of pointers + * AccessibleTextRange structs. + * + * @Since: AT-SPI 1.2 + **/ +void +AccessibleTextRange_freeRanges (AccessibleTextRange **ranges) +{ + /* this was a contiguously allocated block, only free the first element */ + g_free (ranges[0]); + g_free (ranges); +} + +/** + * AccessibleText_getNSelections: + * @obj: a pointer to the #AccessibleText object on which to operate. + * + * Get the number of active non-contiguous selections for an + * #AccessibleText object. + * + * Returns: a long integer indicating the current + * number of non-contiguous text selections active + * within an #AccessibleText object. + **/ +long +AccessibleText_getNSelections (AccessibleText *obj) +{ + dbus_int32_t retval; + + cspi_return_val_if_fail (obj != NULL, -1); + + cspi_dbus_call (obj, spi_interface_text, "getNSelections", NULL, "i", &retval); + + cspi_return_val_if_ev ("getNSelections", -1); + + return retval; +} + +/** + * AccessibleText_getSelection: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @selectionNum: an integer indicating which selection to query. + * @startOffset: a pointer to a long integer into which the start offset + * of the selection will be returned. + * @endOffset: a pointer to a long integer into which the start offset + * of the selection will be returned. + * + * Get the bounds of the @selectionNum-th active text selection for an + * #AccessibleText object. + **/ +void +AccessibleText_getSelection (AccessibleText *obj, + long int selectionNum, + long int *startOffset, + long int *endOffset) +{ + dbus_int32_t d_selectionNum = selectionNum; + dbus_int32_t retStartOffset, retEndOffset; + + if (obj == NULL) + { + *endOffset = *startOffset = -1; + return; + } + + cspi_dbus_call (obj, spi_interface_text, "getSelection", NULL, "i=>ii", d_selectionNum, &retStartOffset, &retEndOffset); + + if (!cspi_check_ev ("getSelection")) + { + *startOffset = *endOffset = -1; + } + else + { + *startOffset = retStartOffset; + *endOffset = retEndOffset; + } +} + +/** + * AccessibleText_addSelection: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @startOffset: the starting offset of the desired new selection. + * @endOffset: the offset of the first character after the new selection. + * + * Select some text (add a text selection) in an #AccessibleText object. + * + * Returns: #TRUE if successful, #FALSE otherwise. + **/ +SPIBoolean +AccessibleText_addSelection (AccessibleText *obj, + long int startOffset, long int endOffset) +{ + dbus_int32_t d_startOffset = startOffset, d_endOffset = endOffset; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_text, "addSelection", NULL, "ii=>b", d_startOffset, d_endOffset, &retval); + + cspi_return_val_if_ev ("addSelection", FALSE); + + return retval; +} + +/** + * AccessibleText_removeSelection: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @selectionNum: an integer indicating which (possibly of several) + * text selection to remove. + * + * De-select a text selection. + * + * Returns: #TRUE if successful, #FALSE otherwise. + **/ +SPIBoolean +AccessibleText_removeSelection (AccessibleText *obj, + long int selectionNum) +{ + dbus_int32_t d_selectionNum = selectionNum; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_text, "removeSelection", NULL, "i=>b", d_selectionNum, &retval); + + cspi_return_val_if_ev ("removeSelection", FALSE); + + return retval; +} + +/** + * AccessibleText_setSelection: + * @obj: a pointer to the #AccessibleText object on which to operate. + * @selectionNum: a zero-offset index indicating which text selection to modify. + * @startOffset: a long int, the new starting offset for the selection. + * @endOffset: a long int, the desired new offset of the first character + * after the selection. + * + * Change the bounds of an existing #AccessibleText text selection. + * + * Returns: #TRUE if successful, #FALSE otherwise. + **/ +SPIBoolean +AccessibleText_setSelection (AccessibleText *obj, + long int selectionNum, + long int startOffset, + long int endOffset) +{ + dbus_int32_t d_selectionNum = selectionNum, d_startOffset = startOffset, d_endOffset = endOffset; + dbus_bool_t retval; + + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_text, "setSelection", NULL, "iii=>b", d_selectionNum, d_startOffset, d_endOffset, &retval); + + cspi_return_val_if_ev ("setSelection", FALSE); + + return retval; +} + + +/** + * AccessibleText_getAttributeRun: + * @obj: a pointer to the #AccessibleText object to query. + * @offset: a long integer indicating the offset from which the attribute + * search is based. + * @startOffset: a #long indicating the start of the desired text range. + * @endOffset: a #long indicating the first character past the desired range. + * @includeDefaults: a #bool if False, the call should only return those + * attributes which are explicitly set on the current attribute + * run, omitting any attributes which are inherited from the + * default values. + * + * @Since: AT-SPI 1.7 + * + * Returns: the AttributeSet defined at offset, optionally including the 'default' attributes. + **/ + +AccessibleAttributeSet * +AccessibleText_getAttributeRun (AccessibleText *obj, + long int offset, + long int *startOffset, + long int *endOffset, + long int includeDefaults){ + + dbus_int32_t d_offset = offset; + dbus_bool_t d_includeDefaults = includeDefaults; + dbus_int32_t retStartOffset, retEndOffset; + AccessibleAttributeSet *retval; + GArray *attributes; + + if (obj == NULL) + { + *startOffset = *endOffset = -1; + return NULL; + } + + cspi_dbus_call (obj, spi_interface_text, "getAttributeRun", NULL, "ib=>iias", d_offset, d_includeDefaults, &retStartOffset, &retEndOffset, &attributes); + + if (!cspi_check_ev ("getAttributeRun")) + { + *startOffset = *endOffset = -1; + retval = NULL; + } + else + { + *startOffset = retStartOffset; + *endOffset = retEndOffset; + retval = _cspi_attribute_set_from_sequence (attributes); + } + + return retval; + +} + +/** + * AccessibleText_getDefaultAttributeSet: + * @obj: a pointer to the #AccessibleText object to query. + * + * + * @Since: AT-SPI 1.7 + * + * Returns: an AttributeSet containing the text attributes + * which apply to all text in the object by virtue of the + * default settings of the document, view, or user agent; e.g. + * those attributes which are implied rather than explicitly + * applied to the text object. For instance, an object whose + * entire text content has been explicitly marked as 'bold' + * will report the 'bold' attribute via getAttributeRun(), + * whereas an object whose text weight is inspecified may + * report the default or implied text weight in the default AttributeSet. + * + **/ + +AccessibleAttributeSet * +AccessibleText_getDefaultAttributeSet (AccessibleText *obj){ + AccessibleAttributeSet *retval; + GArray *attributes; + + cspi_return_val_if_fail (obj != NULL, NULL); + + cspi_dbus_call (obj, spi_interface_text, "getDefaultAttributes", NULL, "as", &attributes); + + retval = _cspi_attribute_set_from_sequence (attributes); + return retval; +} diff --git a/cspi/spi_value.c b/cspi/spi_value.c new file mode 100644 index 0000000..576eb06 --- /dev/null +++ b/cspi/spi_value.c @@ -0,0 +1,162 @@ +/* + * 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. + * + * 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. + */ + +#include + +/** + * AccessibleValue_ref: + * @obj: a pointer to the #AccessibleValue implementor on which to operate. + * + * Increment the reference count for an #AccessibleValue object. + **/ +void +AccessibleValue_ref (AccessibleValue *obj) +{ + cspi_object_ref (obj); +} + +/** + * AccessibleValue_unref: + * @obj: a pointer to the #AccessibleValue implementor on which to operate. + * + * Decrement the reference count for an #AccessibleValue object. + **/ +void +AccessibleValue_unref (AccessibleValue *obj) +{ + cspi_object_unref (obj); +} + +/** + * AccessibleValue_getMinimumValue: + * @obj: a pointer to the #AccessibleValue implementor on which to operate. + * + * Get the minimum allowed value for an #AccessibleValue. + * + * Returns: the minimum allowed value for this object. + * + **/ +double +AccessibleValue_getMinimumValue (AccessibleValue *obj) +{ + double retval; + + cspi_return_val_if_fail (obj != NULL, 0.0); + + cspi_dbus_get_property (obj, spi_interface_value, "minimumValue", NULL, "d", &retval); + + cspi_return_val_if_ev ("getMinimumValue", 0.0); + + return retval; +} + +/** + * AccessibleValue_getCurrentValue: + * @obj: a pointer to the #AccessibleValue implementor on which to operate. + * + * Get the current value for an #AccessibleValue. + * + * Returns: the current value for this object. + **/ +double +AccessibleValue_getCurrentValue (AccessibleValue *obj) +{ + double retval; + + cspi_return_val_if_fail (obj != NULL, 0.0); + + cspi_dbus_get_property (obj, spi_interface_value, "currentValue", NULL, "d", &retval); + + cspi_return_val_if_ev ("getCurrentValue", 0.0); + + return retval; +} + +/** + * AccessibleValue_getMaximumValue: + * @obj: a pointer to the #AccessibleValue implementor on which to operate. + * + * Get the maximum allowed value for an #AccessibleValue. + * + * Returns: the maximum allowed value for this object. + **/ +double +AccessibleValue_getMaximumValue (AccessibleValue *obj) +{ + double retval; + cspi_return_val_if_fail (obj != NULL, 0.0); + + cspi_dbus_get_property (obj, spi_interface_value, "maximumValue", NULL, "d", &retval); + + cspi_return_val_if_ev ("getMaximumValue", 0.0); + + return retval; +} + +/** + * AccessibleValue_setCurrentValue: + * @obj: a pointer to the #AccessibleValue implementor on which to operate. + * @newValue: a #float value which is the desired new value of the object. + * + * Set the current value of an #AccessibleValue. + * + * Returns: #TRUE if the value could be assigned the specified value, + * #FALSE otherwise. + **/ +SPIBoolean +AccessibleValue_setCurrentValue (AccessibleValue *obj, + double newValue) +{ + cspi_return_val_if_fail (obj != NULL, FALSE); + + cspi_dbus_call (obj, spi_interface_value, "setCurrentValue", NULL, "d", &newValue); + + cspi_return_val_if_ev ("setCurrentValue", FALSE); + + return TRUE; +} + +/** + * AccessibleValue_getMinimumIncrement: + * @obj: a pointer to the #AccessibleValue implementor on which to operate. + * + * Get the minimum increment by which an #AccessibleValue can be adjusted. + * + * Returns: the minimum increment by which the value may be changed, or + * zero if the minimum increment cannot be determined. + * + **/ +double +AccessibleValue_getMinimumIncrement (AccessibleValue *obj) +{ + double retval; + + cspi_return_val_if_fail (obj != NULL, 0.0); + + cspi_dbus_get_property (obj, spi_interface_value, "minimumIncrement", NULL, "d", &retval); + + cspi_return_val_if_ev ("getMinimumIncrement", 0.0); + + return retval; +} + diff --git a/tests/clients/Makefile.am b/tests/clients/Makefile.am index 5c96eae..a9db444 100644 --- a/tests/clients/Makefile.am +++ b/tests/clients/Makefile.am @@ -5,3 +5,17 @@ EXTRA_DIST = \ testutil.py CLEANFILES = *.pyc + +noinst_PROGRAMS = simple-at + +simple_at_SOURCES = simple-at.c + +INCLUDES = -I$(top_srcdir) \ + -I$(top_builddir) \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(ATK_CFLAGS) \ + $(DEBUG_CFLAGS) + +#LDADD = ../spi-common/libspicommon.la ../cspi/libcspi.la ../login-helper/libloginhelper.la $(TESTS_LIBS) $(X_LIBS) $(XINPUT_LIBS) +LDADD = ../../spi-common/libspicommon.la ../../cspi/libcspi.la $(TESTS_LIBS) $(X_LIBS) $(XINPUT_LIBS) $(ATK_LIBS)