summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--atspi/atspi-accessible.c78
-rw-r--r--atspi/atspi-accessible.h2
-rw-r--r--atspi/atspi-misc-private.h7
-rw-r--r--atspi/atspi-misc.c84
4 files changed, 139 insertions, 32 deletions
diff --git a/atspi/atspi-accessible.c b/atspi/atspi-accessible.c
index 81c67496..c6f0ebc0 100644
--- a/atspi/atspi-accessible.c
+++ b/atspi/atspi-accessible.c
@@ -512,6 +512,18 @@ atspi_accessible_get_localized_role_name (AtspiAccessible *obj, GError **error)
AtspiStateSet *
atspi_accessible_get_state_set (AtspiAccessible *obj)
{
+ if (!(obj->cached_properties & ATSPI_CACHE_STATES))
+ {
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible,
+ "GetState", NULL, "");
+ _ATSPI_DBUS_CHECK_SIG (reply, "au", NULL);
+ dbus_message_iter_init (reply, &iter);
+ _atspi_dbus_set_state (obj, &iter);
+ dbus_message_unref (reply);
+ }
+
return g_object_ref (obj->states);
}
@@ -1373,11 +1385,77 @@ _atspi_accessible_is_a (AtspiAccessible *accessible,
return FALSE;
}
+ if (!(accessible->cached_properties & ATSPI_CACHE_INTERFACES))
+ {
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ reply = _atspi_dbus_call_partial (accessible, atspi_interface_accessible,
+ "GetInterfaces", NULL, "");
+ _ATSPI_DBUS_CHECK_SIG (reply, "as", FALSE);
+ dbus_message_iter_init (reply, &iter);
+ _atspi_dbus_set_interfaces (accessible, &iter);
+ dbus_message_unref (reply);
+ }
+
n = _atspi_get_iface_num (interface_name);
if (n == -1) return FALSE;
return (gboolean) ((accessible->interfaces & (1 << n))? TRUE: FALSE);
}
+static void
+append_const_val (GArray *array, const gchar *val)
+{
+ gchar *dup = g_strdup (val);
+
+ if (dup)
+ g_array_append_val (array, dup);
+}
+
+/**
+ * atspi_accessible_get_interfaces:
+ *
+ * #obj: The #AtspiAccessible to query.
+ *
+ * Returns: (element-type gchar*) (transfer full): A #GArray of strings
+ * describing the interfaces supported by the object. Interfaces are
+ * denoted in short-hand (ie, "Component", "Text", etc.)
+ **/
+GArray *
+atspi_accessible_get_interfaces (AtspiAccessible *obj)
+{
+ GArray *ret = g_array_new (TRUE, TRUE, sizeof (gchar *));
+
+ if (!ret)
+ return NULL;
+
+ g_return_val_if_fail (obj != NULL, NULL);
+
+ if (atspi_accessible_is_action (obj))
+ append_const_val (ret, "Action");
+ if (atspi_accessible_is_collection (obj))
+ append_const_val (ret, "Collection");
+ if (atspi_accessible_is_component (obj))
+ append_const_val (ret, "Component");
+ if (atspi_accessible_is_document (obj))
+ append_const_val (ret, "Document");
+ if (atspi_accessible_is_editable_text (obj))
+ append_const_val (ret, "EditableText");
+ if (atspi_accessible_is_hypertext (obj))
+ append_const_val (ret, "Hypertext");
+ if (atspi_accessible_is_image (obj))
+ append_const_val (ret, "Image");
+ if (atspi_accessible_is_selection (obj))
+ append_const_val (ret, "Selection");
+ if (atspi_accessible_is_table (obj))
+ append_const_val (ret, "Table");
+ if (atspi_accessible_is_text (obj))
+ append_const_val (ret, "Text");
+ if (atspi_accessible_is_value (obj))
+ append_const_val (ret, "Value");
+
+ return ret;
+}
+
/* TODO: Move to a finalizer */
static void
cspi_object_destroyed (AtspiAccessible *accessible)
diff --git a/atspi/atspi-accessible.h b/atspi/atspi-accessible.h
index 7c3f1df0..1f4d577a 100644
--- a/atspi/atspi-accessible.h
+++ b/atspi/atspi-accessible.h
@@ -119,4 +119,6 @@ AtspiTable * atspi_accessible_get_table (AtspiAccessible *obj);
AtspiText * atspi_accessible_get_text (AtspiAccessible *obj);
AtspiValue * atspi_accessible_get_value (AtspiAccessible *obj);
+
+GArray * atspi_accessible_get_interfaces (AtspiAccessible *obj);
#endif /* _ATSPI_ACCESSIBLE_H_ */
diff --git a/atspi/atspi-misc-private.h b/atspi/atspi-misc-private.h
index 304f6a69..133e032e 100644
--- a/atspi/atspi-misc-private.h
+++ b/atspi/atspi-misc-private.h
@@ -38,7 +38,8 @@
#define ATSPI_CACHE_NAME 0x0004
#define ATSPI_CACHE_DESCRIPTION 0x0008
#define ATSPI_CACHE_STATES 0x0010
-#define ATSPI_CACHE_ROLE 0x0010
+#define ATSPI_CACHE_ROLE 0x0020
+#define ATSPI_CACHE_INTERFACES 0x0040
typedef struct _AtspiReference AtspiReference;
struct _AtspiReference
@@ -142,6 +143,10 @@ GArray *_atspi_dbus_attribute_array_from_iter (DBusMessageIter *iter);
gboolean _atspi_process_deferred_messages (gpointer data);
+void _atspi_dbus_set_interfaces (AtspiAccessible *accessible, DBusMessageIter *iter);
+
+void _atspi_dbus_set_state (AtspiAccessible *accessible, DBusMessageIter *iter);
+
#define _ATSPI_DBUS_CHECK_SIG(message, type, ret) \
if (!message) { \
g_warning ("at-spi: Got no message at %s line %d\n", __FILE__, __LINE__); \
diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c
index 9485be05..0135c233 100644
--- a/atspi/atspi-misc.c
+++ b/atspi/atspi-misc.c
@@ -355,8 +355,6 @@ add_accessible_from_iter (DBusMessageIter *iter)
AtspiAccessible *accessible;
const char *name, *description;
dbus_uint32_t role;
- dbus_uint32_t *states;
- int count;
dbus_message_iter_recurse (iter, &iter_struct);
@@ -385,23 +383,8 @@ add_accessible_from_iter (DBusMessageIter *iter)
}
/* interfaces */
- accessible->interfaces = 0;
dbus_message_iter_next (&iter_struct);
- dbus_message_iter_recurse (&iter_struct, &iter_array);
- while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
- {
- const char *iface;
- gint n;
- dbus_message_iter_get_basic (&iter_array, &iface);
- if (!strcmp (iface, "org.freedesktop.DBus.Introspectable")) continue;
- n = _atspi_get_iface_num (iface);
- if (n == -1)
- {
- g_warning ("Unknown interface %s", iface);
- }
- else accessible->interfaces |= (1 << n);
- dbus_message_iter_next (&iter_array);
- }
+ _atspi_dbus_set_interfaces (accessible, &iter_struct);
dbus_message_iter_next (&iter_struct);
/* name */
@@ -419,19 +402,7 @@ add_accessible_from_iter (DBusMessageIter *iter)
accessible->description = g_strdup (description);
dbus_message_iter_next (&iter_struct);
- dbus_message_iter_recurse (&iter_struct, &iter_array);
- dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
- if (count != 2)
- {
- g_warning ("at-spi: expected 2 values in states array; got %d\n", count);
- accessible->states = _atspi_state_set_new_internal (accessible, 0);
- }
- else
- {
- guint64 val = ((guint64)states [1]) << 32;
- val += states [0];
- accessible->states = _atspi_state_set_new_internal (accessible, val);
- }
+ _atspi_dbus_set_state (accessible, &iter_struct);
dbus_message_iter_next (&iter_struct);
/* This is a bit of a hack since the cache holds a ref, so we don't need
@@ -1165,3 +1136,54 @@ _atspi_dbus_attribute_array_from_iter (DBusMessageIter *iter)
return array;
}
+void
+_atspi_dbus_set_interfaces (AtspiAccessible *accessible, DBusMessageIter *iter)
+{
+ DBusMessageIter iter_array;
+
+ accessible->interfaces = 0;
+ dbus_message_iter_recurse (iter, &iter_array);
+ while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
+ {
+ const char *iface;
+ gint n;
+ dbus_message_iter_get_basic (&iter_array, &iface);
+ if (!strcmp (iface, "org.freedesktop.DBus.Introspectable")) continue;
+ n = _atspi_get_iface_num (iface);
+ if (n == -1)
+ {
+ g_warning ("at-spi: Unknown interface %s", iface);
+ }
+ else
+ accessible->interfaces |= (1 << n);
+ dbus_message_iter_next (&iter_array);
+ }
+ accessible->cached_properties |= ATSPI_CACHE_INTERFACES;
+}
+
+void
+_atspi_dbus_set_state (AtspiAccessible *accessible, DBusMessageIter *iter)
+{
+ DBusMessageIter iter_array;
+ gint count;
+ dbus_uint32_t *states;
+
+ dbus_message_iter_recurse (iter, &iter_array);
+ dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
+ if (count != 2)
+ {
+ g_warning ("at-spi: expected 2 values in states array; got %d\n", count);
+ if (!accessible->states)
+ accessible->states = _atspi_state_set_new_internal (accessible, 0);
+ }
+ else
+ {
+ guint64 val = ((guint64)states [1]) << 32;
+ val += states [0];
+ if (!accessible->states)
+ accessible->states = _atspi_state_set_new_internal (accessible, val);
+ else
+ accessible->states->states = val;
+ }
+ accessible->cached_properties |= ATSPI_CACHE_STATES;
+}