diff options
-rw-r--r-- | atspi/atspi-accessible.c | 78 | ||||
-rw-r--r-- | atspi/atspi-accessible.h | 2 | ||||
-rw-r--r-- | atspi/atspi-misc-private.h | 7 | ||||
-rw-r--r-- | atspi/atspi-misc.c | 84 |
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; +} |