diff options
author | Mike Gorse <mgorse@alum.wpi.edu> | 2019-05-05 16:20:08 -0500 |
---|---|---|
committer | Mike Gorse <mgorse@alum.wpi.edu> | 2019-05-05 16:20:08 -0500 |
commit | 218af4ee001d1093c0328a55a00e0ae9e4fc3262 (patch) | |
tree | ede93395199f76603d7a2c525ef67e05a134ac5c | |
parent | 2e14dcd16f43144222385b01157ab408f0a02a4c (diff) | |
download | at-spi2-core-218af4ee001d1093c0328a55a00e0ae9e4fc3262.tar.gz |
More updates related to reading position notifications
Allow a client to receive notifications through AtspiEventListeners. This
involves special casing, since the event is generated by the screen reader,
not the GUI, and is, thus, handled by a different DBus interface, but, from
the client's perspective, it looks like a normal AT-SPI event.
Also renamed atspi_text_notify_read_position to
atspi_text_notify_reading_position and fixed a few warnings.
-rw-r--r-- | atspi/atspi-constants.h | 2 | ||||
-rw-r--r-- | atspi/atspi-event-listener.c | 146 | ||||
-rw-r--r-- | atspi/atspi-misc.c | 11 | ||||
-rw-r--r-- | atspi/atspi-text.c | 15 | ||||
-rw-r--r-- | atspi/atspi-text.h | 2 | ||||
-rw-r--r-- | doc/libatspi/libatspi-sections.txt | 2 |
6 files changed, 114 insertions, 64 deletions
diff --git a/atspi/atspi-constants.h b/atspi/atspi-constants.h index 369235c7..ea95baf5 100644 --- a/atspi/atspi-constants.h +++ b/atspi/atspi-constants.h @@ -1463,7 +1463,7 @@ typedef enum { #define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket" #define ATSPI_DBUS_PATH_SCREEN_READER "/org/a11y/atspi/screenreader" -#define ATSPI_DBUS_INTERFACE_SCREEN_READER "org.a11y.Atspi.ScreenReader" +#define ATSPI_DBUS_INTERFACE_SCREEN_READER "org.a11y.atspi.ScreenReader" #ifdef __cplusplus } diff --git a/atspi/atspi-event-listener.c b/atspi/atspi-event-listener.c index ae4a7b47..a89464d7 100644 --- a/atspi/atspi-event-listener.c +++ b/atspi/atspi-event-listener.c @@ -170,12 +170,15 @@ static GList *event_listeners = NULL; static gchar * convert_name_from_dbus (const char *name, gboolean path_hack) { - gchar *ret = g_malloc (g_utf8_strlen (name, -1) * 2 + 1); + gchar *ret; const char *p = name; - gchar *q = ret; + gchar *q; - if (!ret) - return NULL; + if (!name) + return g_strdup (""); + + ret = g_malloc (g_utf8_strlen (name, -1) * 2 + 1); + q = ret; while (*p) { @@ -379,24 +382,32 @@ convert_event_type_to_dbus (const char *eventType, char **categoryp, char **name if (matchrule_array) { gchar *matchrule; - matchrule = g_strdup_printf ("type='signal',interface='org.a11y.atspi.Event.%s'", category); - if (name && name [0]) - { - gchar *new_str = g_strconcat (matchrule, ",member='", name, "'", NULL); - g_free (matchrule); - matchrule = new_str; - } (*matchrule_array) = g_ptr_array_new (); - if (detail && detail [0]) + if (!strcmp (eventType, "object:text-reading-position")) { - gchar *new_str = g_strconcat (matchrule, ",arg0='", detail, "'", NULL); - g_ptr_array_add (*matchrule_array, new_str); - new_str = g_strconcat (matchrule, ",arg0path='", detail, "/'", NULL); - g_ptr_array_add (*matchrule_array, new_str); - g_free (matchrule); + matchrule = g_strdup ("type='signal',interface='org.a11y.atspi.ScreenReader',member='ReadingPosition',sender='org.a11y.Atspi.ScreenReader'"); + g_ptr_array_add (*matchrule_array, matchrule); } else - g_ptr_array_add (*matchrule_array, matchrule); + { + matchrule = g_strdup_printf ("type='signal',interface='org.a11y.atspi.Event.%s'", category); + if (name && name [0]) + { + gchar *new_str = g_strconcat (matchrule, ",member='", name, "'", NULL); + g_free (matchrule); + matchrule = new_str; + } + if (detail && detail [0]) + { + gchar *new_str = g_strconcat (matchrule, ",arg0='", detail, "'", NULL); + g_ptr_array_add (*matchrule_array, new_str); + new_str = g_strconcat (matchrule, ",arg0path='", detail, "/'", NULL); + g_ptr_array_add (*matchrule_array, new_str); + g_free (matchrule); + } + else + g_ptr_array_add (*matchrule_array, matchrule); + } } if (categoryp) *categoryp = category; else g_free (category); @@ -459,6 +470,7 @@ listener_entry_free (EventListenerEntry *e) * object:text-selection-changed * object:text-changed * object:text-caret-moved + * object:text-reading-position * object:row-inserted * object:row-reordered * object:row-deleted @@ -507,6 +519,9 @@ listener_entry_free (EventListenerEntry *e) * In general, listening to * toolkit-specific events is not recommended. * + * Currently, object:text-reading-position needs to be specified explicitly + * (it is not implied by object:text), since it is generated by the screen + * reader and is thus a special case internally. * * Returns: #TRUE if successful, otherwise #FALSE. **/ @@ -962,11 +977,22 @@ _atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data) dbus_int32_t detail1, detail2; char *p; GHashTable *cache = NULL; + gboolean is_reading_position = 0; - if (strcmp (signature, "siiv(so)") != 0 && + if (dbus_message_is_signal (message, ATSPI_DBUS_INTERFACE_SCREEN_READER, + "ReadingPosition")) + { + if (strcmp (signature, "(so)ii") != 0) + { + g_warning ("Got invalid signature '%s' for ReadingPosition signal", signature); + return DBUS_HANDLER_RESULT_HANDLED; + } + is_reading_position = TRUE; + } + else if (strcmp (signature, "siiv(so)") != 0 && strcmp (signature, "siiva{sv}") != 0) { - g_warning ("Got invalid signature %s for signal %s from interface %s\n", signature, member, category); + g_warning ("Got invalid signature %s for signal %s from interface %s\n", signature, member, category); return DBUS_HANDLER_RESULT_HANDLED; } @@ -981,9 +1007,16 @@ _atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } category++; + if (!strcmp (category, "ScreenReader")) + category = "Object"; /* hack -- assume this is ReadingPosition */ + } + if (is_reading_position) + e.source = _atspi_dbus_return_accessible_from_iter (&iter); + else + { + dbus_message_iter_get_basic (&iter, &detail); + dbus_message_iter_next (&iter); } - dbus_message_iter_get_basic (&iter, &detail); - dbus_message_iter_next (&iter); dbus_message_iter_get_basic (&iter, &detail1); e.detail1 = detail1; dbus_message_iter_next (&iter); @@ -992,7 +1025,10 @@ _atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data) dbus_message_iter_next (&iter); converted_type = convert_name_from_dbus (category, FALSE); - name = convert_name_from_dbus (member, FALSE); + if (is_reading_position) + name = g_strdup ("text-reading-position"); + else + name = convert_name_from_dbus (member, FALSE); detail = convert_name_from_dbus (detail, TRUE); if (strcasecmp (category, name) != 0) @@ -1015,54 +1051,58 @@ _atspi_dbus_handle_event (DBusConnection *bus, DBusMessage *message, void *data) converted_type = p; } e.type = converted_type; - e.source = _atspi_ref_accessible (dbus_message_get_sender(message), dbus_message_get_path(message)); + if (!is_reading_position) + e.source = _atspi_ref_accessible (dbus_message_get_sender(message), dbus_message_get_path(message)); if (e.source == NULL) { - g_warning ("Got no valid source accessible for signal for signal %s from interface %s\n", member, category); + g_warning ("Got no valid source accessible for signal %s from interface %s\n", member, category); g_free (converted_type); g_free (name); g_free (detail); return DBUS_HANDLER_RESULT_HANDLED; } - dbus_message_iter_recurse (&iter, &iter_variant); - switch (dbus_message_iter_get_arg_type (&iter_variant)) + if (!is_reading_position) { - case DBUS_TYPE_STRUCT: + dbus_message_iter_recurse (&iter, &iter_variant); + switch (dbus_message_iter_get_arg_type (&iter_variant)) { - AtspiRect rect; - if (demarshal_rect (&iter_variant, &rect)) + case DBUS_TYPE_STRUCT: { - g_value_init (&e.any_data, ATSPI_TYPE_RECT); - g_value_set_boxed (&e.any_data, &rect); + AtspiRect rect; + if (demarshal_rect (&iter_variant, &rect)) + { + g_value_init (&e.any_data, ATSPI_TYPE_RECT); + g_value_set_boxed (&e.any_data, &rect); + } + else + { + AtspiAccessible *accessible; + accessible = _atspi_dbus_return_accessible_from_iter (&iter_variant); + g_value_init (&e.any_data, ATSPI_TYPE_ACCESSIBLE); + g_value_set_instance (&e.any_data, accessible); + if (accessible) + g_object_unref (accessible); /* value now owns it */ + } + break; } - else + case DBUS_TYPE_STRING: { - AtspiAccessible *accessible; - accessible = _atspi_dbus_return_accessible_from_iter (&iter_variant); - g_value_init (&e.any_data, ATSPI_TYPE_ACCESSIBLE); - g_value_set_instance (&e.any_data, accessible); - if (accessible) - g_object_unref (accessible); /* value now owns it */ + dbus_message_iter_get_basic (&iter_variant, &p); + g_value_init (&e.any_data, G_TYPE_STRING); + g_value_set_string (&e.any_data, p); + break; } + default: break; } - case DBUS_TYPE_STRING: + + dbus_message_iter_next (&iter); + if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY) { - dbus_message_iter_get_basic (&iter_variant, &p); - g_value_init (&e.any_data, G_TYPE_STRING); - g_value_set_string (&e.any_data, p); - break; + /* new form -- parse properties sent with event */ + cache = _atspi_dbus_update_cache_from_dict (e.source, &iter); } - default: - break; - } - - dbus_message_iter_next (&iter); - if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY) - { - /* new form -- parse properties sent with event */ - cache = _atspi_dbus_update_cache_from_dict (e.source, &iter); } if (!strncmp (e.type, "object:children-changed", 23)) diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c index fdc25bb4..f0c8fdc8 100644 --- a/atspi/atspi-misc.c +++ b/atspi/atspi-misc.c @@ -71,6 +71,7 @@ const char *atspi_interface_table = ATSPI_DBUS_INTERFACE_TABLE; const char *atspi_interface_table_cell = ATSPI_DBUS_INTERFACE_TABLE_CELL; const char *atspi_interface_text = ATSPI_DBUS_INTERFACE_TEXT; const char *atspi_interface_cache = ATSPI_DBUS_INTERFACE_CACHE; +const char *atspi_interface_screen_reader = ATSPI_DBUS_INTERFACE_SCREEN_READER; const char *atspi_interface_value = ATSPI_DBUS_INTERFACE_VALUE; static const char *interfaces[] = @@ -740,6 +741,11 @@ process_deferred_message (BusDataClosure *closure) { _atspi_dbus_handle_event (closure->bus, closure->message, closure->data); } + if (dbus_message_is_signal (closure->message, atspi_interface_screen_reader, + "ReadingPosition")) + { + _atspi_dbus_handle_event (closure->bus, closure->message, closure->data); + } if (dbus_message_is_method_call (closure->message, atspi_interface_device_event_listener, "NotifyEvent")) { _atspi_dbus_handle_DeviceEvent (closure->bus, @@ -837,6 +843,11 @@ atspi_dbus_filter (DBusConnection *bus, DBusMessage *message, void *data) { return defer_message (bus, message, data); } + if (dbus_message_is_signal (message, atspi_interface_screen_reader, + "ReadingPosition")) + { + return defer_message (bus, message, data); + } if (dbus_message_is_signal (message, "org.freedesktop.DBus", "NameOwnerChanged")) { defer_message (bus, message, data); diff --git a/atspi/atspi-text.c b/atspi/atspi-text.c index 24095606..2c50a5bc 100644 --- a/atspi/atspi-text.c +++ b/atspi/atspi-text.c @@ -963,7 +963,7 @@ atspi_text_scroll_substring_to_point (AtspiText *obj, } /** - * atspi_text_notify_read_position: + * atspi_text_notify_reading_position: * @obj: the #AtspiText object being read. * @offset: the offset of the text currently being read. * @@ -972,10 +972,9 @@ atspi_text_scroll_substring_to_point (AtspiText *obj, * the screen reader and highlight the text that is currently being read. */ void -atspi_text_notify_read_position (AtspiText *obj, - gint offset) +atspi_text_notify_reading_position (AtspiText *obj, + gint offset) { - DBusConnection *bus = _atspi_bus (); DBusMessage *signal; AtspiAccessible *accessible; gint len; @@ -994,14 +993,14 @@ atspi_text_notify_read_position (AtspiText *obj, if (!quark_text_len) quark_text_len = g_quark_from_string ("accessible-text-len"); - plen = g_object_get_qdata (accessible, quark_text_len); + plen = g_object_get_qdata (G_OBJECT (accessible), quark_text_len); if (plen) - len = (gint)plen; + len = (gint) (gint64)plen; else { len = atspi_text_get_character_count (obj, NULL); - plen = (gpointer)len; - g_object_set_qdata (accessible, quark_text_len, plen); + plen = (gpointer) (gint64)len; + g_object_set_qdata (G_OBJECT (accessible), quark_text_len, plen); } remaining = (len >= 0 ? len - offset : 0); diff --git a/atspi/atspi-text.h b/atspi/atspi-text.h index fcc4259c..3afc4dda 100644 --- a/atspi/atspi-text.h +++ b/atspi/atspi-text.h @@ -141,7 +141,7 @@ gboolean atspi_text_scroll_substring_to (AtspiText *obj, gint start_offset, gint gboolean atspi_text_scroll_substring_to_point (AtspiText *obj, gint start_offset, gint end_offset, AtspiCoordType coords, gint x, gint y, GError **error); -void atspi_text_notify_read_position (AtspiText *obj, gint offset); +void atspi_text_notify_reading_position (AtspiText *obj, gint offset); G_END_DECLS #endif /* _ATSPI_TEXT_H_ */ diff --git a/doc/libatspi/libatspi-sections.txt b/doc/libatspi/libatspi-sections.txt index 951e8013..af2ab719 100644 --- a/doc/libatspi/libatspi-sections.txt +++ b/doc/libatspi/libatspi-sections.txt @@ -32,7 +32,7 @@ atspi_text_get_text_attribute_value atspi_text_get_text_attributes atspi_text_scroll_substring_to atspi_text_scroll_substring_to_point -atspi_text_notify_read_position +atspi_text_notify_reading_position <SUBSECTION Standard> ATSPI_TEXT ATSPI_IS_TEXT |