Merge tag 'upstream/2.34.0' into tizen 02/224302/2 submit/tizen/20200213.221652
authorArtur Świgoń <a.swigon@samsung.com>
Fri, 7 Feb 2020 13:01:49 +0000 (14:01 +0100)
committerArtur Świgoń <a.swigon@samsung.com>
Tue, 11 Feb 2020 09:28:49 +0000 (10:28 +0100)
Change-Id: I480c8e572f5fe7d3d7d2d6f1f0aa2a76f009c9a8

22 files changed:
1  2 
atspi/atspi-accessible.c
atspi/atspi-accessible.h
atspi/atspi-action.c
atspi/atspi-action.h
atspi/atspi-collection.c
atspi/atspi-component.c
atspi/atspi-component.h
atspi/atspi-constants.h
atspi/atspi-event-listener.c
atspi/atspi-misc-private.h
atspi/atspi-misc.c
atspi/atspi-misc.h
atspi/atspi-registry.c
atspi/atspi-stateset.c
atspi/atspi-types.h
bus/at-spi-bus-launcher.c
bus/meson.build
meson.build
packaging/at-spi2-core.spec
registryd/deviceeventcontroller.c
registryd/meson.build
registryd/registry.c

diff --combined atspi/atspi-accessible.c
@@@ -7,28 -7,82 +7,82 @@@
   * Copyright 2010, 2011 Novell, Inc.
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #include "atspi-private.h"
  #include "atspi-accessible-private.h"
  #include <string.h>
  
+ enum {
+   REGION_CHANGED,
+   LAST_SIGNAL
+ };
  static gboolean enable_caching = FALSE;
  static guint quark_locale;
  
+ static guint atspi_accessible_signals[LAST_SIGNAL] = { 0, };
+ static gboolean
+ screen_reader_signal_watcher (GSignalInvocationHint *signal_hint,
+                               guint                  n_param_values,
+                               const GValue          *param_values,
+                               gpointer               data)
+ {
+   GObject *object;
+   AtspiAccessible *accessible;
+   GSignalQuery signal_query;
+   const char *name;
+   DBusMessage *signal;
+   DBusMessageIter iter, iter_struct, iter_variant, iter_array;
+   dbus_int32_t detail1, detail2;
+   const char *detail = "";
+   object = g_value_get_object (param_values + 0);
+   g_return_val_if_fail (ATSPI_IS_ACCESSIBLE(object), FALSE);
+   g_signal_query (signal_hint->signal_id, &signal_query);
+   name = signal_query.signal_name;
+   detail1 = g_value_get_int (param_values + 1);
+   detail2 = g_value_get_int (param_values + 2);
+   accessible = ATSPI_ACCESSIBLE (object);
+   signal = dbus_message_new_signal (ATSPI_DBUS_PATH_SCREEN_READER,
+                                     ATSPI_DBUS_INTERFACE_EVENT_SCREEN_READER,
+                                     "RegionChanged");
+   dbus_message_iter_init_append (signal, &iter);
+   dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &detail);
+   dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &detail1);
+   dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &detail2);
+   dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "(so)",
+                                     &iter_variant);
+   dbus_message_iter_open_container (&iter_variant, DBUS_TYPE_STRUCT, NULL,
+                                     &iter_struct);
+   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &accessible->parent.app->bus_name);
+   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &accessible->parent.path);
+   dbus_message_iter_close_container (&iter_variant, &iter_struct);
+   dbus_message_iter_close_container (&iter, &iter_variant);
+   dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}",
+                                     &iter_array);
+   dbus_message_iter_close_container (&iter, &iter_array);
+   dbus_connection_send (_atspi_bus (), signal, NULL);
+   dbus_message_unref (signal);
+   return TRUE; 
+ }
  static void
  atspi_action_interface_init (AtspiAction *action)
  {
@@@ -109,6 -163,13 +163,13 @@@ static gint accessible_count = 0
  #endif
  
  static void
+ atspi_accessible_unref (GObject *accessible)
+ {
+   if (accessible != NULL)
+     g_object_unref(accessible);
+ }
+ static void
  atspi_accessible_init (AtspiAccessible *accessible)
  {
  #ifdef DEBUG_REF_COUNTS
  
    accessible->priv = atspi_accessible_get_instance_private (accessible);
  
-   accessible->children = g_ptr_array_new_with_free_func (g_object_unref);
+   accessible->children = g_ptr_array_new_with_free_func (atspi_accessible_unref);
  }
  
  static void
@@@ -189,6 -250,8 +250,8 @@@ atspi_accessible_finalize (GObject *obj
  #endif
  
    G_OBJECT_CLASS (atspi_accessible_parent_class)->finalize (object);
+   /* TODO: remove emission hook */
  }
  
  static void
@@@ -200,6 -263,33 +263,33 @@@ atspi_accessible_class_init (AtspiAcces
    object_class->finalize = atspi_accessible_finalize;
  
    quark_locale = g_quark_from_string ("accessible-locale");
+   /**
+    * AtspiAccessible::region-changed:
+    * @atspiaccessible: the object which received the signal
+    * @arg1: an integer specifying the current offset of the text being read,
+    *        if the object is textual.
+    * @arg2: an integer specifying the ending offset of the text being read,
+    *        if the object is textual.
+    *
+    * The signal "region-changed" is emitted by a screen reader to indicate
+    * that it is now reading or tracking a new object, or, a new piece of
+    * text within an object. This allows a magnifier to gain the information
+    * needed to highlight the object that the screen reader is reading.
+    */
+   atspi_accessible_signals[REGION_CHANGED] =
+     g_signal_new ("region_changed",
+                 G_TYPE_FROM_CLASS (klass),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (AtspiAccessibleClass, region_changed), 
+                 NULL, NULL,
+                 atspi_marshal_VOID__INT_INT,
+                 G_TYPE_NONE,
+                 2, G_TYPE_INT, G_TYPE_INT);
+   g_signal_add_emission_hook (atspi_accessible_signals[REGION_CHANGED], 0,
+                               screen_reader_signal_watcher, NULL,
+                               (GDestroyNotify) NULL);
  }
  
  /**
@@@ -225,522 -315,6 +315,522 @@@ atspi_accessible_get_name (AtspiAccessi
    return g_strdup (obj->name);
  }
  
 +
 +/**
 + * atspi_accessible_get_unique_id:
 + * @obj: a pointer to the #AtspiAccessible object on which to operate.
 + *
 + * Gets the identificator, uniquely identifying object, or NULL if an error occured.
 + *
 + * Returns: a UTF-8 string describing the #AtspiAccessible object
 + * or NULL on exception or NULL object passed.
 + **/
 +gchar *
 +atspi_accessible_get_unique_id(AtspiAccessible *obj, GError **error)
 +{
 +  if (!obj) {
 +    g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "argument is null");
 +    return NULL;
 +  }
 +
 +  gchar *id = NULL;
 +  gchar *bus_name = atspi_accessible_get_bus_name(obj, error);
 +  if (bus_name && bus_name[0]) {
 +    gchar *path = atspi_accessible_get_path(obj, error);
 +    if (path && path[0])
 +      id = g_strdup_printf("%s:%s", bus_name, path);
 +        else
 +      g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get path");
 +    g_free(path);
 +  }
 +  else
 +    g_set_error(error, ATSPI_ERROR, ATSPI_ERROR_IPC, "failed to get bus name");
 +  g_free(bus_name);
 +  return id;
 +}
 +
 +/**
 + * atspi_accessible_get_bus_name:
 + * @obj: a pointer to the #AtspiAccessible object on which to operate.
 + *
 + * Gets the bus name, where object belongs.
 + *
 + * Returns: a UTF-8 string describing the #AtspiAccessible object's
 + * bus name or empty string on exception or NULL object passed.
 + **/
 +gchar *
 +atspi_accessible_get_bus_name(AtspiAccessible *obj, GError **error)
 +{
 +  if (!obj || !obj->parent.app)
 +    return g_strdup("");
 +  return g_strdup (obj->parent.app->bus_name);
 +}
 +
 +/**
 + * atspi_accessible_get_path:
 + * @obj: a pointer to the #AtspiAccessible object on which to operate.
 + *
 + * Gets the path, uniquely identifying object over its bus name.
 + *
 + * Returns: a UTF-8 string describing the #AtspiAccessible object
 + * or empty string on exception or NULL object passed.
 + **/
 +gchar *
 +atspi_accessible_get_path(AtspiAccessible *obj, GError **error)
 +{
 +  static const char *prefix = "/org/a11y/atspi/accessible/";
 +  static int prefix_len = 27;
 +
 +  if (!obj)
 +    return g_strdup("");
 +  AtspiObject *o = ATSPI_OBJECT (obj);
 +  if (!o)
 +    return g_strdup("");
 +  if (strncmp(o->path, prefix, prefix_len) == 0)
 +    return g_strdup(o->path + prefix_len);
 +  return g_strdup (o->path);
 +}
 +
 +/**
 + * atspi_accessible_get_navigable_at_point:
 + * @root: a pointer to the #AtspiAccessible to start search from.
 + * @x: a #gint specifying the x coordinate of the point in question.
 + * @y: a #gint specifying the y coordinate of the point in question.
 + * @ctype: the coordinate system of the point (@x, @y)
 + *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
 + *
 + * Finds the accessible element closest to user (highest in z-order), at a given coordinate within an #AtspiAccessible.
 + * This should be the element, that should be picked, when doing mouse click or finger tap at given coordinates.
 + *
 + * Returns: (nullable) (transfer full): a pointer to an
 + *          #AtspiAccessible descendant (of any depth) of the specified component which
 + *          contains the point (@x, @y), or NULL if no descendant contains
 + *          the point.
 + **/
 +AtspiAccessible *
 +atspi_accessible_get_navigable_at_point (AtspiAccessible *root,
 +                                          gint x,
 +                                          gint y,
 +                                          AtspiCoordType ctype, GError **error)
 +{
 +  dbus_int32_t d_x = x, d_y = y;
 +  dbus_uint32_t d_ctype = ctype;
 +  DBusMessage *reply;
 +  AtspiAccessible *return_value = NULL;
 +  unsigned char recurse = 0;
 +  DBusMessageIter iter;
 +  AtspiAccessible *deputy = NULL;
 +
 +  g_return_val_if_fail (root != NULL, NULL);
 +  do {
 +    reply = _atspi_dbus_call_partial (root, atspi_interface_accessible, "GetNavigableAtPoint", error, "iiu", d_x, d_y, d_ctype);
 +    // call failed, error is set, so we bail out
 +    if (!reply) {
 +      if (deputy) g_object_unref(deputy);
 +      if (return_value) g_object_unref(return_value);
 +      return NULL;
 +    }
 +    _ATSPI_DBUS_CHECK_SIG (reply, "(so)y(so)", NULL, NULL);
 +
 +    dbus_message_iter_init (reply, &iter);
 +    AtspiAccessible *tmp = _atspi_dbus_return_accessible_from_iter (&iter);
 +
 +    unsigned char value = 0;
 +    dbus_message_iter_get_basic (&iter, &value);
 +    dbus_message_iter_next (&iter);
 +    recurse = (value != 0);
 +
 +    /* keep deputy if tmp has deputy */
 +    if (!deputy)
 +      deputy = _atspi_dbus_return_accessible_from_iter (&iter);
 +
 +    dbus_message_unref(reply);
 +
 +    if (!tmp) {
 +      if (deputy) {
 +        /* TODO: need to check deputy works for return value */
 +        if (return_value)
 +          g_object_unref(return_value);
 +        return deputy;
 +      }
 +      break;
 +    }
 +
 +    if (return_value)
 +      g_object_unref(return_value);
 +    return_value = root = tmp;
 +  } while(recurse);
 +  return return_value;
 +}
 +
 +/**
 + * atspi_accessible_get_reading_material:
 + * @obj: a pointer to the #AtspiAccessible object on which to operate.
 + *
 + * Gets reading material
 + *
 + * Returns: reading material to be used screen-reader side. This is not stable.
 + * You have to handle all alocated memory as below on screen-reader side.
 + *
 + * AtspiAccessibleReadingMaterial *rm
 + * g_object_unref(rm->parent);
 + * g_object_unref(rm->described_by_accessible);
 + * g_hash_table_unref(rm->attributes);
 + * free(rm->name);
 + * free(rm->labeled_by_name);
 + * free(rm->text_interface_name);
 + * free(rm->localized_role_name);
 + * free(rm->description);
 + * free(rm);
 + **/
 +AtspiAccessibleReadingMaterial *
 +atspi_accessible_get_reading_material (AtspiAccessible *obj, GError **error)
 +{
 +  AtspiAccessible *parent;
 +  AtspiAccessibleReadingMaterial *reading_material = NULL;
 +  const char *name;
 +  double current_value;
 +  gint count;
 +  guint64 val;
 +  DBusMessage *reply;
 +  DBusMessageIter iter;
 +  DBusMessageIter iter_array;
 +  dbus_uint32_t role;
 +  dbus_uint32_t *states;
 +  dbus_int32_t index_in_parent;
 +  dbus_int32_t child_count;
 +  dbus_bool_t is_selected;
 +
 +  g_return_val_if_fail (obj != NULL, NULL);
 +
 +  reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetReadingMaterial", error, "");
 +
 +  _ATSPI_DBUS_CHECK_SIG (reply, "a{ss}sssuausiddddsibbii(so)auiui(so)", NULL, NULL);
 +
 +  reading_material = calloc(1, sizeof(AtspiAccessibleReadingMaterial));
 +  if (!reading_material)
 +  {
 +    return reading_material;
 +  }
 +
 +  dbus_message_iter_init (reply, &iter);
 +
 +  /* get attributes */
 +  reading_material->attributes =  _atspi_dbus_hash_from_iter (&iter);
 +  dbus_message_iter_next (&iter);
 +
 +  /* get name */
 +  dbus_message_iter_get_basic (&iter, &name);
 +  reading_material->name = g_strdup (name);
 +  dbus_message_iter_next (&iter);
 +
 +  /* get name of relation LABELED_BY */
 +  dbus_message_iter_get_basic (&iter, &name);
 +  reading_material->labeled_by_name = g_strdup (name);
 +  dbus_message_iter_next (&iter);
 +
 +  /* get name of text interface */
 +  dbus_message_iter_get_basic (&iter, &name);
 +  reading_material->text_interface_name = g_strdup (name);
 +  dbus_message_iter_next (&iter);
 +
 +  /* get role */
 +  dbus_message_iter_get_basic (&iter, &role);
 +  reading_material->role = role;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get state set */
 +  dbus_message_iter_recurse (&iter, &iter_array);
 +  dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
 +  val = ((guint64)states [1]) << 32;
 +  val += states [0];
 +  reading_material->states = val;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get localized role name */
 +  dbus_message_iter_get_basic (&iter, &name);
 +  reading_material->localized_role_name = g_strdup (name);
 +  dbus_message_iter_next (&iter);
 +
 +  /* get child count */
 +  dbus_message_iter_get_basic (&iter, &child_count);
 +  reading_material->child_count = child_count;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get current value */
 +  dbus_message_iter_get_basic (&iter, &current_value);
 +  reading_material->value = current_value;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get minimum increment */
 +  dbus_message_iter_get_basic (&iter, &current_value);
 +  reading_material->increment = current_value;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get maximum value */
 +  dbus_message_iter_get_basic (&iter, &current_value);
 +  reading_material->upper = current_value;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get minimum value */
 +  dbus_message_iter_get_basic (&iter, &current_value);
 +  reading_material->lower = current_value;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get description */
 +  dbus_message_iter_get_basic (&iter, &name);
 +  reading_material->description = g_strdup (name);
 +  dbus_message_iter_next (&iter);
 +
 +  /* get index in parent */
 +  dbus_message_iter_get_basic (&iter, &index_in_parent);
 +  reading_material->index_in_parent = index_in_parent;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get selected in parent */
 +  dbus_message_iter_get_basic (&iter, &is_selected);
 +  reading_material->is_selected_in_parent = is_selected;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get has checkbox child */
 +  dbus_message_iter_get_basic (&iter, &is_selected);
 +  reading_material->has_checkbox_child = is_selected;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get list children count */
 +  dbus_message_iter_get_basic (&iter, &child_count);
 +  reading_material->list_children_count = child_count;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get first selected child index */
 +  dbus_message_iter_get_basic (&iter, &index_in_parent);
 +  reading_material->first_selected_child_index = index_in_parent;
 +  dbus_message_iter_next (&iter);
 +
 +  ////////////////
 +  /* get parent */
 +  parent =  _atspi_dbus_return_accessible_from_iter (&iter);
 +  reading_material->parent = parent;
 +
 +  /* parent states */
 +  dbus_message_iter_recurse (&iter, &iter_array);
 +  dbus_message_iter_get_fixed_array (&iter_array, &states, &count);
 +  val = ((guint64)states [1]) << 32;
 +  val += states [0];
 +  reading_material->parent_states = val;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get parent child count */
 +  dbus_message_iter_get_basic (&iter, &child_count);
 +  reading_material->parent_child_count = child_count;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get parent role */
 +  dbus_message_iter_get_basic (&iter, &role);
 +  reading_material->parent_role = role;
 +  dbus_message_iter_next (&iter);
 +
 +  /* get parent selected child count */
 +  dbus_message_iter_get_basic (&iter, &child_count);
 +  reading_material->parent_selected_child_count = child_count;
 +  dbus_message_iter_next (&iter);
 +
 +  ////////////////////////////////////////
 +  /* get relation object - DESCRIBED_BY */
 +  parent =  _atspi_dbus_return_accessible_from_iter (&iter);
 +  reading_material->described_by_accessible = parent;
 +
 +  return reading_material;
 +}
 +
 +/**
 + * atspi_accessible_get_default_label_info:
 + * @obj: a pointer to the #AtspiAccessible object would be window.
 + *
 + * Gets default label information
 + *
 + * Returns: default label information to be used screen-reader side.
 + * This is not stable. And this depends on toolkit side UI definition.
 + * The candidate of default label object could be changed by UI definition.
 + * You have to handle all alocated memory as below on screen-reader side.
 + *
 + * AtspiAccessibleDefaultLabelInfo *dli
 + * g_hash_table_unref(dli->attributes);
 +
 + * g_object_unref(dli->obj);
 + * free(dli);
 + **/
 +AtspiAccessibleDefaultLabelInfo *
 +atspi_accessible_get_default_label_info (AtspiAccessible *obj, GError **error)
 +{
 +  AtspiAccessibleDefaultLabelInfo *default_label_info = NULL;
 +  AtspiAccessible *default_label_object;
 +  dbus_uint32_t role;
 +  DBusMessage *reply;
 +  DBusMessageIter iter;
 +
 +  g_return_val_if_fail (obj != NULL, NULL);
 +
 +  reply = _atspi_dbus_call_partial (obj, atspi_interface_accessible, "GetDefaultLabelInfo", error, "");
 +
 +  _ATSPI_DBUS_CHECK_SIG (reply, "(so)ua{ss}", NULL, NULL);
 +
 +  default_label_info = calloc(1, sizeof(AtspiAccessibleDefaultLabelInfo));
 +  if (!default_label_info)
 +  {
 +    return default_label_info;
 +  }
 +
 +  dbus_message_iter_init (reply, &iter);
 +
 +  default_label_object =  _atspi_dbus_return_accessible_from_iter (&iter);
 +  default_label_info->obj = default_label_object;
 +
 +  dbus_message_iter_get_basic (&iter, &role);
 +  default_label_info->role = role;
 +  dbus_message_iter_next (&iter);
 +
 +  default_label_info->attributes =  _atspi_dbus_hash_from_iter (&iter);
 +  dbus_message_iter_next (&iter);
 +
 +  return default_label_info;
 +}
 +
 +static unsigned char are_objects_on_the_same_bus(AtspiAccessible *obj1, AtspiAccessible *obj2)
 +{
 +  const char *bus_name_1 = obj1->parent.app->bus_name;
 +  const char *bus_name_2 = obj2->parent.app->bus_name;
 +  return strcmp(bus_name_1, bus_name_2) == 0;
 +}
 +
 +static unsigned char object_is_valid(AtspiAccessible *obj)
 +{
 +  if (!obj)
 +    return 0;
 +  AtspiStateSet *ss = atspi_accessible_get_state_set(obj);
 +  if (!ss)
 +    return 0;
 +  unsigned char valid = atspi_state_set_contains(ss, ATSPI_STATE_DEFUNCT) == 0;
 +  g_object_unref(ss);
 +  return valid;
 +}
 +
 +typedef enum {
 +  NEIGHBOR_SEARCH_MODE_NORMAL = 0,
 +  NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT = 1,
 +  NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING = 2,
 +  NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE = 3,
 +} GetNeighborSearchMode;
 +/**
 + * atspi_accessible_get_neighbor:
 + * @root: a pointer to a #AtspiAccessible, which represents current root of subtree to search
 + * @start: a pointer to the #AtspiAccessible to start search from (can be null, which means start from root)
 + * @direction: direction, in which search (forward or backward)
 + *
 + * Calculates next (or previous) accessible element in logical order or null if none found.
 + *
 + * Returns: (nullable) (transfer full): a pointer to an
 + *          #AtspiAccessible element, which is next (previous) in logical order or null if none found.
 + **/
 +AtspiAccessible *
 +atspi_accessible_get_neighbor (AtspiAccessible *root,
 +                                          AtspiAccessible *start,
 +                                          AtspiNeighborSearchDirection direction,
 +                                          GError **error)
 +{
 +  g_return_val_if_fail (object_is_valid(root), NULL);
 +  if (!object_is_valid(start))
 +    start = root;
 +  const char *root_path = ATSPI_OBJECT(root)->path;
 +  AtspiAccessible *return_value = NULL;
 +  g_object_ref(start);
 +  unsigned char recurse;
 +  GetNeighborSearchMode search_mode = NEIGHBOR_SEARCH_MODE_NORMAL;
 +  GQueue *children_root_stack = g_queue_new();
 +  DBusMessageIter iter;
 +
 +  while(1) {
 +    const char *path = are_objects_on_the_same_bus(root, start) ? root_path : "";
 +    DBusMessage *reply = _atspi_dbus_call_partial (start, atspi_interface_accessible, "GetNeighbor", error, "sii", path, (int)direction, (int)search_mode);
 +    // call failed, error is set, so we bail out
 +    if (!reply) break;
 +
 +    _ATSPI_DBUS_CHECK_SIG (reply, "(so)y", error, NULL);
 +    dbus_message_iter_init (reply, &iter);
 +    AtspiAccessible *ret = _atspi_dbus_return_accessible_from_iter (&iter);
 +
 +    unsigned char value = 0;
 +    dbus_message_iter_get_basic (&iter, &value);
 +    dbus_message_iter_next (&iter);
 +    recurse = (value != 0);
 +
 +    dbus_message_unref(reply);
 +
 +    // got return value and request for recursive search, it means ret is on another bridge, than start
 +    // thus we're recursing. should the recurse failed to find anything it will end with
 +    if (ret && recurse) {
 +      g_object_unref(G_OBJECT(start));
 +      start = ret;
 +      g_object_ref(start);
 +      if (are_objects_on_the_same_bus(root, ret))
 +        {
 +          search_mode = NEIGHBOR_SEARCH_MODE_RECURSE_TO_OUTSIDE;
 +        }
 +      else
 +        {
 +          g_queue_push_tail(children_root_stack, ret);
 +          search_mode = NEIGHBOR_SEARCH_MODE_RECURSE_FROM_ROOT;
 +        }
 +      continue;
 +    }
 +    // found the one we've been looking for
 +    if (ret) {
 +      g_object_unref(G_OBJECT(start));
 +      return_value = ret;
 +      break;
 +    }
 +
 +    // we've stepped into different bridges previously and now we're going back to the last one
 +    // and continuing search where we left
 +    if (!g_queue_is_empty(children_root_stack)) {
 +      g_object_unref(G_OBJECT(start));
 +      start = g_queue_pop_tail(children_root_stack);
 +
 +      search_mode = NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING;
 +      continue;
 +    }
 +    // there's no more bridges to check, but we might have started from one
 +    // in that case there might be bridges "below" start, which we yet have to visit
 +    if (!are_objects_on_the_same_bus(root, start)) {
 +      unsigned char continue_loop = 1;
 +      while(continue_loop) {
 +        AtspiAccessible *parent = atspi_accessible_get_parent(start, NULL);
 +        continue_loop = parent ? are_objects_on_the_same_bus(start, parent) : 0;
 +        g_object_unref(G_OBJECT(start));
 +        start = parent;
 +      }
 +
 +      // going up thru parents put us in weird place (we didnt meet root on the way)
 +      // so we bail out
 +      if (!start)
 +        break;
 +
 +      // start object now points to different bridge and must be treated as "resume after recursing"
 +      search_mode = NEIGHBOR_SEARCH_MODE_CONTINUE_AFTER_FAILED_RECURSING;
 +      continue;
 +    }
 +
 +    // nothing found
 +    g_object_unref(start);
 +    break;
 +  }
 +  while(!g_queue_is_empty(children_root_stack))
 +    g_object_unref(g_queue_pop_tail(children_root_stack));
 +  g_queue_free(children_root_stack);
 +
 +  return return_value;
 +}
 +
  /**
   * atspi_accessible_get_description:
   * @obj: a pointer to the #AtspiAccessible object on which to operate.
@@@ -1039,12 -613,12 +1129,12 @@@ atspi_accessible_get_role_name (AtspiAc
   * atspi_accessible_get_localized_role_name:
   * @obj: a pointer to the #AtspiAccessible object on which to operate.
   *
 - * Gets a UTF-8 string corresponding to the name of the role played by an 
 + * Gets a UTF-8 string corresponding to the name of the role played by an
   * object, translated to the current locale.
   * This method will return useful values for roles that fall outside the
   * enumeration used in atspi_accessible_getRole ().
   *
 - * Returns: a localized, UTF-8 string specifying the type of UI role played 
 + * Returns: a localized, UTF-8 string specifying the type of UI role played
   * by an #AtspiAccessible object.
   *
   **/
@@@ -1099,6 -673,7 +1189,6 @@@ atspi_accessible_get_state_set (AtspiAc
      dbus_message_unref (reply);
      _atspi_accessible_add_cache (obj, ATSPI_CACHE_STATES);
    }
 -
    return g_object_ref (obj->states);
  }
  
   * atspi_accessible_get_attributes:
   * @obj: The #AtspiAccessible being queried.
   *
 - * Gets the #AttributeSet representing any assigned 
 + * Gets the #AttributeSet representing any assigned
   * name-value pair attributes or annotations for this object.
   * For typographic, textual, or textually-semantic attributes, see
   * atspi_text_get_attributes instead.
@@@ -1153,7 -728,7 +1243,7 @@@ add_to_attribute_array (gpointer key, g
   * atspi_accessible_get_attributes_as_array:
   * @obj: The #AtspiAccessible being queried.
   *
 - * Gets a #GArray representing any assigned 
 + * Gets a #GArray representing any assigned
   * name-value pair attributes or annotations for this object.
   * For typographic, textual, or textually-semantic attributes, see
   * atspi_text_get_attributes_as_array instead.
@@@ -1311,7 -886,7 +1401,7 @@@ atspi_accessible_get_atspi_version (Ats
   * Gets the application id for a #AtspiAccessible object.
   * Only works on application root objects.
   *
 - * Returns: a positive #gint indicating the id for the #AtspiAccessible object 
 + * Returns: a positive #gint indicating the id for the #AtspiAccessible object
   * or -1 on exception.
   **/
  gint
@@@ -1362,7 -937,7 +1452,7 @@@ _atspi_accessible_is_a (AtspiAccessibl
   * atspi_accessible_is_action:
   * @obj: a pointer to the #AtspiAccessible instance to query.
   *
 - * Query whether the specified #AtspiAccessible implements the 
 + * Query whether the specified #AtspiAccessible implements the
   * #AtspiAction interface.
   *
   * Returns: #TRUE if @obj implements the #AtspiAction interface,
@@@ -1392,7 -967,7 +1482,7 @@@ atspi_accessible_is_application (AtspiA
                              atspi_interface_application);
  }
  
 -/**                      
 +/**
   * atspi_accessible_is_collection:
   * @obj: a pointer to the #AtspiAccessible instance to query.
   *
@@@ -1458,7 -1033,7 +1548,7 @@@ atspi_accessible_is_editable_text (Atsp
    return _atspi_accessible_is_a (obj,
                              atspi_interface_editable_text);
  }
 -                                                                                                                                                                        
 +
  /**
   * atspi_accessible_is_hypertext:
   * @obj: a pointer to the #AtspiAccessible instance to query.
@@@ -1480,7 -1055,7 +1570,7 @@@ atspi_accessible_is_hypertext (AtspiAcc
   * atspi_accessible_is_hyperlink:
   * @obj: a pointer to the #AtspiAccessible instance to query.
   *
 - * Query whether the specified #AtspiAccessible implements the 
 + * Query whether the specified #AtspiAccessible implements the
   * #AtspiHyperlink interface.
   *
   * Returns: #TRUE if @obj implements the #AtspiHypertext interface,
@@@ -1587,7 -1162,7 +1677,7 @@@ atspi_accessible_is_streamable_content 
   * atspi_accessible_is_text:
   * @obj: a pointer to the #AtspiAccessible instance to query.
   *
 - * Query whether the specified #AtspiAccessible implements the 
 + * Query whether the specified #AtspiAccessible implements the
   * #AtspiText interface.
   *
   * Returns: #TRUE if @obj implements the #AtspiText interface,
@@@ -1632,7 -1207,7 +1722,7 @@@ AtspiAction 
  atspi_accessible_get_action (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_action) ?
 -          g_object_ref (ATSPI_ACTION (accessible)) : NULL);  
 +          g_object_ref (ATSPI_ACTION (accessible)) : NULL);
  }
  
  /**
@@@ -1648,7 -1223,7 +1738,7 @@@ AtspiAction 
  atspi_accessible_get_action_iface (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_action) ?
 -          g_object_ref (ATSPI_ACTION (accessible)) : NULL);  
 +          g_object_ref (ATSPI_ACTION (accessible)) : NULL);
  }
  
  /**
@@@ -1666,7 -1241,7 +1756,7 @@@ AtspiCollection 
  atspi_accessible_get_collection (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ?
 -          g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);  
 +          g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);
  }
  
  /**
@@@ -1682,7 -1257,7 +1772,7 @@@ AtspiCollection 
  atspi_accessible_get_collection_iface (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_collection) ?
 -          g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);  
 +          g_object_ref (ATSPI_COLLECTION (accessible)) : NULL);
  }
  
  /**
@@@ -1734,7 -1309,7 +1824,7 @@@ AtspiDocument 
  atspi_accessible_get_document (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_document) ?
 -          g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);  
 +          g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);
  }
  
  /**
@@@ -1750,7 -1325,7 +1840,7 @@@ AtspiDocument 
  atspi_accessible_get_document_iface (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_document) ?
 -          g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);  
 +          g_object_ref (ATSPI_DOCUMENT (accessible)) : NULL);
  }
  
  /**
@@@ -1768,7 -1343,7 +1858,7 @@@ AtspiEditableText 
  atspi_accessible_get_editable_text (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ?
 -          g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);  
 +          g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);
  }
  
  /**
@@@ -1784,7 -1359,7 +1874,7 @@@ AtspiEditableText 
  atspi_accessible_get_editable_text_iface (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_editable_text) ?
 -          g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);  
 +          g_object_ref (ATSPI_EDITABLE_TEXT (accessible)) : NULL);
  }
  
  /**
@@@ -1818,7 -1393,7 +1908,7 @@@ AtspiHypertext 
  atspi_accessible_get_hypertext (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ?
 -          g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);  
 +          g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);
  }
  
  /**
@@@ -1834,7 -1409,7 +1924,7 @@@ AtspiHypertext 
  atspi_accessible_get_hypertext_iface (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_hypertext) ?
 -          g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);  
 +          g_object_ref (ATSPI_HYPERTEXT (accessible)) : NULL);
  }
  
  /**
@@@ -1852,7 -1427,7 +1942,7 @@@ AtspiImage 
  atspi_accessible_get_image (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_image) ?
 -          g_object_ref (ATSPI_IMAGE (accessible)) : NULL);  
 +          g_object_ref (ATSPI_IMAGE (accessible)) : NULL);
  }
  
  /**
@@@ -1868,7 -1443,7 +1958,7 @@@ AtspiImage 
  atspi_accessible_get_image_iface (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_image) ?
 -          g_object_ref (ATSPI_IMAGE (accessible)) : NULL);  
 +          g_object_ref (ATSPI_IMAGE (accessible)) : NULL);
  }
  
  /**
@@@ -1886,7 -1461,7 +1976,7 @@@ AtspiSelection 
  atspi_accessible_get_selection (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ?
 -          g_object_ref (ATSPI_SELECTION (accessible)) : NULL);  
 +          g_object_ref (ATSPI_SELECTION (accessible)) : NULL);
  }
  
  /**
@@@ -1902,7 -1477,7 +1992,7 @@@ AtspiSelection 
  atspi_accessible_get_selection_iface (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_selection) ?
 -          g_object_ref (ATSPI_SELECTION (accessible)) : NULL);  
 +          g_object_ref (ATSPI_SELECTION (accessible)) : NULL);
  }
  
  #if 0
@@@ -1919,7 -1494,7 +2009,7 @@@ AtspiStreamableContent 
  atspi_accessible_get_streamable_content (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_streamable_content) ?
 -          accessible : NULL);  
 +          accessible : NULL);
  }
  #endif
  
@@@ -1938,7 -1513,7 +2028,7 @@@ AtspiTable 
  atspi_accessible_get_table (AtspiAccessible *obj)
  {
    return (_atspi_accessible_is_a (obj, atspi_interface_table) ?
 -          g_object_ref (ATSPI_TABLE (obj)) : NULL);  
 +          g_object_ref (ATSPI_TABLE (obj)) : NULL);
  }
  
  /**
@@@ -1954,7 -1529,7 +2044,7 @@@ AtspiTable 
  atspi_accessible_get_table_iface (AtspiAccessible *obj)
  {
    return (_atspi_accessible_is_a (obj, atspi_interface_table) ?
 -          g_object_ref (ATSPI_TABLE (obj)) : NULL);  
 +          g_object_ref (ATSPI_TABLE (obj)) : NULL);
  }
  
  /**
@@@ -1970,7 -1545,7 +2060,7 @@@ AtspiTableCell 
  atspi_accessible_get_table_cell (AtspiAccessible *obj)
  {
    return (_atspi_accessible_is_a (obj, atspi_interface_table_cell) ?
 -          g_object_ref (ATSPI_TABLE_CELL (obj)) : NULL);  
 +          g_object_ref (ATSPI_TABLE_CELL (obj)) : NULL);
  }
  
  /**
@@@ -2022,7 -1597,7 +2112,7 @@@ AtspiValue 
  atspi_accessible_get_value (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_value) ?
 -          g_object_ref (ATSPI_VALUE (accessible)) : NULL);  
 +          g_object_ref (ATSPI_VALUE (accessible)) : NULL);
  }
  
  /**
@@@ -2038,7 -1613,7 +2128,7 @@@ AtspiValue 
  atspi_accessible_get_value_iface (AtspiAccessible *accessible)
  {
    return (_atspi_accessible_is_a (accessible, atspi_interface_value) ?
 -          g_object_ref (ATSPI_VALUE (accessible)) : NULL);  
 +          g_object_ref (ATSPI_VALUE (accessible)) : NULL);
  }
  
  static void
@@@ -2063,12 -1638,10 +2153,12 @@@ append_const_val (GArray *array, const 
  GArray *
  atspi_accessible_get_interfaces (AtspiAccessible *obj)
  {
 -  GArray *ret = g_array_new (TRUE, TRUE, sizeof (gchar *));
 +  GArray *ret;
  
    g_return_val_if_fail (obj != NULL, NULL);
  
 +  ret  = g_array_new (TRUE, TRUE, sizeof (gchar *));
 +
    append_const_val (ret, "Accessible");
    if (atspi_accessible_is_action (obj))
      append_const_val (ret, "Action");
    return ret;
  }
  
 -AtspiAccessible * 
 +AtspiAccessible *
  _atspi_accessible_new (AtspiApplication *app, const gchar *path)
  {
    AtspiAccessible *accessible;
 -  
 +
    accessible = g_object_new (ATSPI_TYPE_ACCESSIBLE, NULL);
    g_return_val_if_fail (accessible != NULL, NULL);
  
@@@ -2284,6 -1857,33 +2374,33 @@@ atspi_accessible_get_object_locale (Ats
    return locale;
  }
  
+ /**
+  * atspi_accessible_get_accessible_id:
+  * @obj: an #AtspiAccessible
+  *
+  * Gets the accessible id of the accessible.  This is not meant to be presented
+  * to the user, but to be an id which is stable over application development.
+  * Typically, this is the gtkbuilder id.
+  *
+  * Since: 2.34
+  *
+  * Returns: a character string representing the accessible id of the
+  * #AtspiAccessible object or NULL on exception.
+  **/
+ gchar*
+ atspi_accessible_get_accessible_id (AtspiAccessible *obj, GError **error)
+ {
+   gchar *accessible_id;
+   g_return_val_if_fail (obj != NULL, NULL);
+   if (!_atspi_dbus_get_property (obj, atspi_interface_accessible,
+                                "AccessibleId", error, "s", &accessible_id))
+     return NULL;
+   return accessible_id;
+ }
  void
  free_value (gpointer data)
  {
diff --combined atspi/atspi-accessible.h
@@@ -5,22 -5,22 +5,22 @@@
   * Copyright 2002 Ximian, Inc.
   *           2002 Sun Microsystems Inc.
   * Copyright 2010, 2011 Novell, Inc.
 - *           
 + *
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #ifndef _ATSPI_ACCESSIBLE_H_
@@@ -45,41 -45,6 +45,41 @@@ G_BEGIN_DECL
  
  typedef struct _AtspiAccessiblePrivate AtspiAccessiblePrivate;
  
 +struct _AtspiAccessibleDefaultLabelInfo
 +{
 +  AtspiAccessible *obj;
 +  AtspiRole role;
 +  GHashTable *attributes;
 +};
 +
 +struct _AtspiAccessibleReadingMaterial
 +{
 +  AtspiAccessible *parent;
 +  AtspiAccessible *described_by_accessible;
 +  GHashTable *attributes;
 +  AtspiRole role;
 +  AtspiRole parent_role;
 +  char *name;
 +  char *labeled_by_name;
 +  char *text_interface_name;
 +  char *localized_role_name;
 +  char *description;
 +  gdouble value;
 +  gdouble increment;
 +  gdouble lower;
 +  gdouble upper;
 +  gint64 states;
 +  gint64 parent_states;
 +  gint child_count;
 +  gint index_in_parent;
 +  gint list_children_count;
 +  gint first_selected_child_index;
 +  gint parent_child_count;
 +  gint parent_selected_child_count;
 +  gboolean is_selected_in_parent;
 +  gboolean has_checkbox_child;
 +};
 +
  struct _AtspiAccessible
  {
    AtspiObject parent;
@@@ -99,9 -64,11 +99,11 @@@ typedef struct _AtspiAccessibleClass At
  struct _AtspiAccessibleClass
  {
    AtspiObjectClass parent_class;
+   void (*region_changed) (AtspiAccessible *accessible, gint current_offset, gint last_offset);
  };
  
 -GType atspi_accessible_get_type (void); 
 +GType atspi_accessible_get_type (void);
  
  AtspiAccessible *
  _atspi_accessible_new (AtspiApplication *app, const gchar *path);
@@@ -110,20 -77,6 +112,20 @@@ gchar * atspi_accessible_get_name (Atsp
  
  gchar * atspi_accessible_get_description (AtspiAccessible *obj, GError **error);
  
 +gchar * atspi_accessible_get_path (AtspiAccessible *obj, GError **error);
 +
 +gchar * atspi_accessible_get_bus_name (AtspiAccessible *obj, GError **error);
 +
 +gchar * atspi_accessible_get_unique_id (AtspiAccessible *obj, GError **error);
 +
 +AtspiAccessible *atspi_accessible_get_navigable_at_point (AtspiAccessible *root, gint x, gint y, AtspiCoordType ctype, GError **error);
 +
 +AtspiAccessible *atspi_accessible_get_neighbor (AtspiAccessible *root, AtspiAccessible *start, AtspiNeighborSearchDirection direction, GError **error);
 +
 +AtspiAccessibleReadingMaterial *atspi_accessible_get_reading_material (AtspiAccessible *obj, GError **error);
 +
 +AtspiAccessibleDefaultLabelInfo *atspi_accessible_get_default_label_info (AtspiAccessible *obj, GError **error);
 +
  AtspiAccessible * atspi_accessible_get_parent (AtspiAccessible *obj, GError **error);
  
  gint atspi_accessible_get_child_count (AtspiAccessible *obj, GError **error);
@@@ -216,6 -169,8 +218,8 @@@ void atspi_accessible_clear_cache (Atsp
  
  guint atspi_accessible_get_process_id (AtspiAccessible *accessible, GError **error);
  
+ gchar * atspi_accessible_get_accessible_id (AtspiAccessible *obj, GError **error);
  /* private */
  void _atspi_accessible_add_cache (AtspiAccessible *accessible, AtspiCache flag);
  AtspiCache _atspi_accessible_get_cache_mask (AtspiAccessible *accessible);
diff --combined atspi/atspi-action.c
@@@ -6,19 -6,19 +6,19 @@@
   * 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
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #include "atspi-private.h"
@@@ -214,28 -214,6 +214,28 @@@ atspi_action_do_action (AtspiAction *ob
    return retval;
  }
  
 +/**
 + * atspi_action_do_action_name:
 + * @obj: a pointer to the #AtspiAction to query.
 + * @name: a action name specifying which action to invoke.
 + *
 + * Invoke the action indicated by name.
 + *
 + * Returns: #TRUE if the action is successfully invoked, otherwise #FALSE.
 + **/
 +gboolean
 +atspi_action_do_action_name (AtspiAction *obj, const gchar *name, GError **error)
 +{
 +  const char *action_name = name;
 +  dbus_bool_t retval = FALSE;
 +
 +  g_return_val_if_fail (obj != NULL, FALSE);
 +
 +  _atspi_dbus_call (obj, atspi_interface_action, "DoActionName", error, "s=>b", action_name, &retval);
 +
 +  return retval;
 +}
 +
  static void
  atspi_action_base_init (AtspiAction *klass)
  {
diff --combined atspi/atspi-action.h
@@@ -7,19 -7,19 +7,19 @@@
   *           
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #ifndef _ATSPI_ACTION_H_
@@@ -57,7 -57,6 +57,7 @@@ gchar * atspi_action_get_key_binding (A
  gchar * atspi_action_get_localized_name (AtspiAction *obj, gint i, GError **error);
  
  gboolean atspi_action_do_action (AtspiAction *obj, gint i, GError **error);
 +gboolean atspi_action_do_action_name (AtspiAction *obj, const gchar *name, GError **error);
  
  #ifndef ATSPI_DISABLE_DEPRECATED
  gchar * atspi_action_get_description (AtspiAction *obj, gint i, GError **error);
diff --combined atspi/atspi-collection.c
@@@ -6,19 -6,19 +6,19 @@@
   * Copyright 2010, 2011 Novell, Inc.
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #include "atspi-private.h"
@@@ -81,12 -81,10 +81,12 @@@ static GArray 
  return_accessibles (DBusMessage *message)
  {
    DBusMessageIter iter, iter_array;
 -  GArray *ret = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *));
 +  GArray *ret;
  
    _ATSPI_DBUS_CHECK_SIG (message, "a(so)", NULL, NULL);
  
 +  ret = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *));
 +
    dbus_message_iter_init (message, &iter);
    dbus_message_iter_recurse (&iter, &iter_array);
  
diff --combined atspi/atspi-component.c
@@@ -6,19 -6,19 +6,19 @@@
   * 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
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  /*
@@@ -122,7 -122,6 +122,7 @@@ atspi_component_get_accessible_at_poin
    return _atspi_dbus_return_accessible_from_message (reply);
  }
  
 +
  /**
   * atspi_component_get_extents:
   * @obj: a pointer to the #AtspiComponent to query.
   *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
   *
   * Gets the bounding box of the specified #AtspiComponent.
+  * The returned values are meaningful only if the Component has both
+  * STATE_VISIBLE and STATE_SHOWING.
   *
   * Returns: An #AtspiRect giving the accessible's extents.
   **/
@@@ -165,6 -166,8 +167,8 @@@ atspi_component_get_extents (AtspiCompo
   *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
   *
   * Gets the minimum x and y coordinates of the specified #AtspiComponent.
+  * The returned values are meaningful only if the Component has both
+  * STATE_VISIBLE and STATE_SHOWING.
   *
   * returns: An #AtspiPoint giving the @obj's position.
   **/
@@@ -193,6 -196,8 +197,8 @@@ atspi_component_get_position (AtspiComp
   * @obj: a pointer to the #AtspiComponent to query.
   *
   * Gets the size of the specified #AtspiComponent.
+  * The returned values are meaningful only if the Component has both
+  * STATE_VISIBLE and STATE_SHOWING.
   *
   * returns: An #AtspiPoint giving the @obj's size.
   **/
@@@ -216,7 -221,7 +222,7 @@@ atspi_component_get_size (AtspiComponen
   * atspi_component_get_layer:
   * @obj: a pointer to the #AtspiComponent to query.
   *
 - * Queries which layer the component is painted into, to help determine its 
 + * Queries which layer the component is painted into, to help determine its
   *      visibility in terms of stacking order.
   *
   * Returns: the #AtspiComponentLayer into which this component is painted.
@@@ -238,7 -243,7 +244,7 @@@ atspi_component_get_layer (AtspiCompone
   * Queries 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 #gshort indicating the stacking order of the component 
 + * Returns: a #gshort indicating the stacking order of the component
   *       in the MDI layer, or -1 if the component is not in the MDI layer.
   **/
  gshort
@@@ -272,54 -277,14 +278,54 @@@ atspi_component_grab_focus (AtspiCompon
  }
  
  /**
 + * atspi_component_grab_highlight:
 + * @obj: a pointer to the #AtspiComponent on which to operate.
 + *
 + * Attempts to set highlight to the specified
 + *         #AtspiComponent.
 + *
 + * Returns: #TRUE if successful, #FALSE otherwise.
 + *
 + **/
 +gboolean
 +atspi_component_grab_highlight (AtspiComponent *obj, GError **error)
 +{
 +  dbus_bool_t retval = FALSE;
 +
 +  _atspi_dbus_call (obj, atspi_interface_component, "GrabHighlight", error, "=>b", &retval);
 +
 +  return retval;
 +}
 +
 +/**
 + * atspi_component_clear_highlight:
 + * @obj: a pointer to the #AtspiComponent on which to operate.
 + *
 + * Attempts to clear highlight on the specified
 + *         #AtspiComponent.
 + *
 + * Returns: #TRUE if successful, #FALSE otherwise.
 + *
 + **/
 +gboolean
 +atspi_component_clear_highlight (AtspiComponent *obj, GError **error)
 +{
 +  dbus_bool_t retval = FALSE;
 +
 +  _atspi_dbus_call (obj, atspi_interface_component, "ClearHighlight", error, "=>b", &retval);
 +
 +  return retval;
 +}
 +
 +/**
   * atspi_component_get_alpha:
   * @obj: The #AtspiComponent to be queried.
   *
   * Gets the opacity/alpha value of a component, if alpha blending is in use.
   *
 - * Returns: the opacity value of a component, as a #gdouble between 0.0 and 1.0. 
 + * Returns: the opacity value of a component, as a #gdouble between 0.0 and 1.0.
   **/
 -gdouble      
 +gdouble
  atspi_component_get_alpha    (AtspiComponent *obj, GError **error)
  {
    double retval = 1;
@@@ -454,7 -419,6 +460,7 @@@ atspi_component_set_size (AtspiComponen
  }
  
  /**
 +<<<<<<< HEAD
   * atspi_component_scroll_to:
   * @obj: a pointer to the #AtspiComponent object on which to operate.
   * @type: a #AtspiScrollType indicating where the object should be placed on the
@@@ -511,23 -475,6 +517,23 @@@ atspi_component_scroll_to_point (AtspiC
    return retval;
  }
  
 +/**
 + * atspi_component_get_highlight_index
 + * @obj: a pointer to the #AtspiComponent to query.
 + *
 + * Returns: highlight index of object if (>0), 0 if highlight index is not set
 + *          or -1 if an error occured.
 + **/
 +int
 +atspi_component_get_highlight_index (AtspiComponent *obj, GError **error)
 +{
 +   gint ret = -1;
 +   g_return_val_if_fail (obj != NULL, -1);
 +   _atspi_dbus_get_property (obj, atspi_interface_component,
 +                             "HighlightIndex", error, "i", &ret);
 +   return ret;
 +}
 +
  static void
  atspi_component_base_init (AtspiComponent *klass)
  {
diff --combined atspi/atspi-component.h
@@@ -4,22 -4,22 +4,22 @@@
   *
   * 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
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #ifndef _ATSPI_COMPONENT_H_
@@@ -44,7 -44,7 +44,7 @@@ struct _AtspiRec
  
  /**
   * ATSPI_TYPE_RECT:
 - * 
 + *
   * The #GType for a boxed type holding a #AtspiRect.
   */
  #define       ATSPI_TYPE_RECT (atspi_rect_get_type ())
@@@ -62,7 -62,7 +62,7 @@@ struct _AtspiPoin
  
  /**
   * ATSPI_TYPE_POINT:
 - * 
 + *
   * The #GType for a boxed type holding a #AtspiPoint.
   */
  #define       ATSPI_TYPE_POINT (atspi_point_get_type ())
@@@ -111,12 -111,6 +111,12 @@@ gboolean atspi_component_scroll_to (Ats
  
  gboolean atspi_component_scroll_to_point (AtspiComponent *obj, AtspiCoordType coords, gint x, gint y, GError **error);
  
 +gboolean atspi_component_grab_highlight (AtspiComponent *obj, GError **error);
 +
 +gboolean atspi_component_clear_highlight (AtspiComponent *obj, GError **error);
 +
 +int atspi_component_get_highlight_index(AtspiComponent *obj, GError **error);
 +
  G_END_DECLS
  
  #endif        /* _ATSPI_COMPONENT_H_ */
diff --combined atspi/atspi-constants.h
@@@ -6,19 -6,19 +6,19 @@@
   * Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  /* TODO: Auto-generate this file again
@@@ -93,13 -93,13 +93,13 @@@ extern "C" 
  /**
   * AtspiLocaleType:
   * @ATSPI_LOCALE_TYPE_MESSAGES: For localizable natural-language messages.
 - * @ATSPI_LOCALE_TYPE_COLLATE: For regular expression matching and string 
 - * collation. 
 - * @ATSPI_LOCALE_TYPE_CTYPE: For regular expression matching, character 
 - * classification, conversion, case-sensitive comparison, and wide character 
 - * functions. 
 + * @ATSPI_LOCALE_TYPE_COLLATE: For regular expression matching and string
 + * collation.
 + * @ATSPI_LOCALE_TYPE_CTYPE: For regular expression matching, character
 + * classification, conversion, case-sensitive comparison, and wide character
 + * functions.
   * @ATSPI_LOCALE_TYPE_MONETARY: For monetary formatting.
 - * @ATSPI_LOCALE_TYPE_NUMERIC: For number formatting (such as the decimal 
 + * @ATSPI_LOCALE_TYPE_NUMERIC: For number formatting (such as the decimal
   * point and the thousands separator).
   * @ATSPI_LOCALE_TYPE_TIME: For time and date formatting.
   *
@@@ -141,11 -141,6 +141,11 @@@ typedef enum 
      ATSPI_COORD_TYPE_PARENT,
  } AtspiCoordType;
  
 +typedef enum {
 +      ATSPI_NEIGHBOR_SEARCH_FORWARD = 1,
 +      ATSPI_NEIGHBOR_SEARCH_BACKWARD = 2,
 +} AtspiNeighborSearchDirection;
 +
  /**
   * ATSPI_COORD_TYPE_COUNT:
   *
@@@ -257,9 -252,9 +257,9 @@@ typedef enum 
   * UI #AtspiComponent containers.
   * @ATSPI_LAYER_WIDGET: The layer in which the majority of ordinary
   * 'foreground' widgets reside.
 - * @ATSPI_LAYER_MDI: A special layer between @ATSPI_LAYER_CANVAS and 
 - * @ATSPI_LAYER_WIDGET, in which the 'pseudo windows' (e.g. the MDI frames) 
 - * reside. See #atspi_component_get_mdi_z_order. 
 + * @ATSPI_LAYER_MDI: A special layer between @ATSPI_LAYER_CANVAS and
 + * @ATSPI_LAYER_WIDGET, in which the 'pseudo windows' (e.g. the MDI frames)
 + * reside. See #atspi_component_get_mdi_z_order.
   * @ATSPI_LAYER_POPUP: A layer for popup window content, above
   * @ATSPI_LAYER_WIDGET.
   * @ATSPI_LAYER_OVERLAY: The topmost layer.
   * @ATSPI_LAYER_LAST_DEFINED: Used only to determine the end of the
   * enumeration.
   *
 - * The #AtspiComponentLayer of an #AtspiComponent instance indicates its 
 - * relative stacking order with respect to the onscreen visual representation 
 - * of the UI. #AtspiComponentLayer, in combination with #AtspiComponent bounds 
 - * information, can be used to compute the visibility of all or part of a 
 - * component.  This is important in programmatic determination of 
 - * region-of-interest for magnification, and in 
 + * The #AtspiComponentLayer of an #AtspiComponent instance indicates its
 + * relative stacking order with respect to the onscreen visual representation
 + * of the UI. #AtspiComponentLayer, in combination with #AtspiComponent bounds
 + * information, can be used to compute the visibility of all or part of a
 + * component.  This is important in programmatic determination of
 + * region-of-interest for magnification, and in
   * flat screen review models of the screen, as well as
 - * for other uses. Objects residing in two of the #AtspiComponentLayer 
 - * categories support further z-ordering information, with respect to their 
 - * peers in the same layer: namely, @ATSPI_LAYER_WINDOW and 
 - * @ATSPI_LAYER_MDI.  Relative stacking order for other objects within the 
 - * same layer is not available; the recommended heuristic is 
 - * first child paints first. In other words, assume that the 
 - * first siblings in the child list are subject to being overpainted by later 
 + * for other uses. Objects residing in two of the #AtspiComponentLayer
 + * categories support further z-ordering information, with respect to their
 + * peers in the same layer: namely, @ATSPI_LAYER_WINDOW and
 + * @ATSPI_LAYER_MDI.  Relative stacking order for other objects within the
 + * same layer is not available; the recommended heuristic is
 + * first child paints first. In other words, assume that the
 + * first siblings in the child list are subject to being overpainted by later
   * siblings if their bounds intersect. The order of layers, from bottom to top,
   *  is: @ATSPI_LAYER_BACKGROUND, @ATSPI_LAYER_WINDOW, @ATSPI_LAYER_MDI,
 - * @ATSPI_LAYER_CANVAS, @ATSPI_LAYER_WIDGET, @ATSPI_LAYER_POPUP, and     
 + * @ATSPI_LAYER_CANVAS, @ATSPI_LAYER_WIDGET, @ATSPI_LAYER_POPUP, and
   * @ATSPI_LAYER_OVERLAY.
   *
   */
@@@ -309,15 -304,15 +309,15 @@@ typedef enum 
  
  /**
   * AtspiTextBoundaryType:
 - * @ATSPI_TEXT_BOUNDARY_CHAR: An #AtspiText instance is bounded by this 
 - * character only. Start and end offsets differ by one, by definition, 
 + * @ATSPI_TEXT_BOUNDARY_CHAR: An #AtspiText instance is bounded by this
 + * character only. Start and end offsets differ by one, by definition,
   * for this value.
   * @ATSPI_TEXT_BOUNDARY_WORD_START: Boundary condition is start of a word; i.e.
   * range is from start of one word to the start of another word.
   * @ATSPI_TEXT_BOUNDARY_WORD_END: Boundary condition is the end of a word; i.e.
   * range is from the end of one word to the end of another. Some locales
   * may not distinguish between words and characters or glyphs. In particular,
 - * those locales which use wholly or partially ideographic character sets. 
 + * those locales which use wholly or partially ideographic character sets.
   * In these cases, characters may be returned in lieu of multi-character
   * substrings.
   * @ATSPI_TEXT_BOUNDARY_SENTENCE_START: Boundary condition is start of a
   * generally means that an end-of-line character will appear at the end of
   * the range.
   * @ATSPI_TEXT_BOUNDARY_LINE_END: Boundary condition is the end of a line; i.e.
 - * range is from start of one line to the start of another.  This generally 
 + * range is from start of one line to the start of another.  This generally
   * means that an end-of-line character will be the first character of the
   * range.
   *
@@@ -422,7 -417,7 +422,7 @@@ typedef enum 
  
  /**
   * AtspiStateType:
 - * @ATSPI_STATE_INVALID: Indicates an invalid state - probably an error 
 + * @ATSPI_STATE_INVALID: Indicates an invalid state - probably an error
   * condition.
   * @ATSPI_STATE_ACTIVE: Indicates a window is currently the active window, or
   * an object is the active subelement within a container or table.
   * @ATSPI_STATE_ENABLED: Indicates that this object is enabled, i.e. that it
   * currently reflects some application state. Objects that are "greyed out"
   * may lack this state, and may lack the @ATSPI_STATE_SENSITIVE if direct
 - * user interaction cannot cause them to acquire @ATSPI_STATE_ENABLED. 
 + * user interaction cannot cause them to acquire @ATSPI_STATE_ENABLED.
   * See @ATSPI_STATE_SENSITIVE.
   * @ATSPI_STATE_EXPANDABLE: Indicates this object allows progressive
   * disclosure of its children.
   * children that has been selected.
   * @ATSPI_STATE_SENSITIVE: Indicates this object is sensitive, e.g. to user
   * interaction. @ATSPI_STATE_SENSITIVE usually accompanies.
 - * @ATSPI_STATE_ENABLED for user-actionable controls, but may be found in the 
 - * absence of @ATSPI_STATE_ENABLED if the current visible state of the control 
 + * @ATSPI_STATE_ENABLED for user-actionable controls, but may be found in the
 + * absence of @ATSPI_STATE_ENABLED if the current visible state of the control
   * is "disconnected" from the application state.  In such cases, direct user
 - * interaction can often result in the object gaining @ATSPI_STATE_SENSITIVE, 
 + * interaction can often result in the object gaining @ATSPI_STATE_SENSITIVE,
   * for instance if a user makes an explicit selection using an object whose
   * current state is ambiguous or undefined. See @ATSPI_STATE_ENABLED,
   * @ATSPI_STATE_INDETERMINATE.
   * single line of text.
   * @ATSPI_STATE_STALE: Indicates that the information returned for this object
   * may no longer be synchronized with the application state.  This can occur
 - * if the object has @ATSPI_STATE_TRANSIENT, and can also occur towards the 
 + * if the object has @ATSPI_STATE_TRANSIENT, and can also occur towards the
   * end of the object peer's lifecycle.
   * @ATSPI_STATE_TRANSIENT: Indicates this object is transient.
   * @ATSPI_STATE_VERTICAL: Indicates the orientation of this object is vertical;
   * for example this state may appear on such objects as scrollbars, text
   * objects (with vertical text flow), separators, etc.
   * @ATSPI_STATE_VISIBLE: Indicates this object is visible, e.g. has been
 - * explicitly marked for exposure to the user. @ATSPI_STATE_VISIBLE is no 
 - * guarantee that the object is actually unobscured on the screen, only that 
 - * it is 'potentially' visible, barring obstruction, being scrolled or clipped 
 - * out of the field of view, or having an ancestor container that has not yet 
 - * made visible. A widget is potentially onscreen if it has both 
 - * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING. The absence of 
 + * explicitly marked for exposure to the user. @ATSPI_STATE_VISIBLE is no
 + * guarantee that the object is actually unobscured on the screen, only that
 + * it is 'potentially' visible, barring obstruction, being scrolled or clipped
 + * out of the field of view, or having an ancestor container that has not yet
 + * made visible. A widget is potentially onscreen if it has both
 + * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING. The absence of
   * @ATSPI_STATE_VISIBLE and @ATSPI_STATE_SHOWING is
   * semantically equivalent to saying that an object is 'hidden'.
   * @ATSPI_STATE_MANAGES_DESCENDANTS: Indicates that "active-descendant-changed"
   * in very large containers, like tables. The presence of
   * @ATSPI_STATE_MANAGES_DESCENDANTS is an indication to the client that the
   * children should not, and need not, be enumerated by the client.
 - * Objects implementing this state are expected to provide relevant state      
 - * notifications to listening clients, for instance notifications of 
 - * visibility changes and activation of their contained child objects, without 
 + * Objects implementing this state are expected to provide relevant state
 + * notifications to listening clients, for instance notifications of
 + * visibility changes and activation of their contained child objects, without
   * the client having previously requested references to those children.
   * @ATSPI_STATE_INDETERMINATE: Indicates that a check box or other boolean
   * indicator is in a state other than checked or not checked.  This
   * usually means that the boolean value reflected or controlled by the
 - * object does not apply consistently to the entire current context.      
 + * object does not apply consistently to the entire current context.
   * For example, a checkbox for the "Bold" attribute of text may have
   * @ATSPI_STATE_INDETERMINATE if the currently selected text contains a mixture
   * of weight attributes. In many cases interacting with a
   * representation becomes static. Some applications, notably content viewers,
   * may not be able to detect all kinds of animated content.  Therefore the
   * absence of this state should not be taken as
 - * definitive evidence that the object's visual representation is      
 + * definitive evidence that the object's visual representation is
   * static; this state is advisory.
   * @ATSPI_STATE_INVALID_ENTRY: This object has indicated an error condition
   * due to failure of input validation.  For instance, a form control may
   * acquire this state in response to invalid or malformed user input.
   * @ATSPI_STATE_SUPPORTS_AUTOCOMPLETION: This state indicates that the object
 - * in question implements some form of typeahead or       
 + * in question implements some form of typeahead or
   * pre-selection behavior whereby entering the first character of one or more
   * sub-elements causes those elements to scroll into view or become
   * selected. Subsequent character input may narrow the selection further as
   * question supports text selection. It should only be exposed on objects
   * which implement the #AtspiText interface, in order to distinguish this state
   * from @ATSPI_STATE_SELECTABLE, which infers that the object in question is a
 - * selectable child of an object which implements #AtspiSelection. While 
 + * selectable child of an object which implements #AtspiSelection. While
   * similar, text selection and subelement selection are distinct operations.
   * @ATSPI_STATE_IS_DEFAULT: This state indicates that the object in question is
   * the 'default' interaction object in a dialog, i.e. the one that gets
   * @ATSPI_STATE_READ_ONLY: Indicates that an object which is ENABLED and
   * SENSITIVE has a value which can be read, but not modified, by the
   * user. @Since: 2.16
 + * @ATSPI_STATE_HIGHLIGHTED: Indicates that an object which is HIGHLIGHTABLE
 + * has been graphically marked to assits visally impared users. Only one
 + * object per window can have ATSPI_STATE_HIGHLIGHTED  state.
 + * @ATSPI_STATE_HIGHLIGHTABLE: Indicates that an object can be graphically
 + * marked to assist visially impaired users.
 + * user. @Since: 2.16
   * @ATSPI_STATE_LAST_DEFINED: This value of the enumeration should not be used
   * as a parameter, it indicates the number of items in the #AtspiStateType
   * enumeration.
   *
 - * 
 - * Enumeration used by various interfaces indicating every possible state 
 + *
 + * Enumeration used by various interfaces indicating every possible state
   * an #AtspiAccesible object can assume.
   *
   **/
@@@ -643,8 -632,6 +643,8 @@@ typedef enum 
      ATSPI_STATE_CHECKABLE,
      ATSPI_STATE_HAS_POPUP,
      ATSPI_STATE_READ_ONLY,
 +    ATSPI_STATE_HIGHLIGHTED,
 +    ATSPI_STATE_HIGHLIGHTABLE,
      ATSPI_STATE_LAST_DEFINED,
  } AtspiStateType;
  
@@@ -677,18 -664,18 +677,18 @@@ typedef enum 
  
  /**
   * AtspiEventType:
 - * @ATSPI_KEY_PRESSED_EVENT: Indicates that a key on a keyboard device was 
 + * @ATSPI_KEY_PRESSED_EVENT: Indicates that a key on a keyboard device was
   * pressed.
 - * @ATSPI_KEY_RELEASED_EVENT: Indicates that a key on a keyboard device was 
 + * @ATSPI_KEY_RELEASED_EVENT: Indicates that a key on a keyboard device was
   * released.
 - * @ATSPI_BUTTON_PRESSED_EVENT: Indicates that a button on a non-keyboard 
 + * @ATSPI_BUTTON_PRESSED_EVENT: Indicates that a button on a non-keyboard
   * human interface device (HID) was pressed.
   * @ATSPI_BUTTON_RELEASED_EVENT: Indicates that a button on a non-keyboard
   * human interface device (HID) was released.
   *
 - * Enumeration used to specify the event types of interest to an 
 - * #AtspiEventListener, or 
 - * to identify the type of an event for which notification has been sent.  
 + * Enumeration used to specify the event types of interest to an
 + * #AtspiEventListener, or
 + * to identify the type of an event for which notification has been sent.
   *
   **/
  typedef enum {
   * of a hardware keyboard key.
   * @ATSPI_KEY_SYM: A symbolic key event is generated, without specifying a
   * hardware key. Note: if the keysym is not present in the current keyboard
 - * map, the #AtspiDeviceEventController instance has a limited ability to 
 - * generate such keysyms on-the-fly. Reliability of GenerateKeyboardEvent 
 - * calls using out-of-keymap keysyms will vary from system to system, and on 
 + * map, the #AtspiDeviceEventController instance has a limited ability to
 + * generate such keysyms on-the-fly. Reliability of GenerateKeyboardEvent
 + * calls using out-of-keymap keysyms will vary from system to system, and on
   * the number of different out-of-keymap keysyms being generated in quick
 - * succession. 
 - * In practice this is rarely significant, since the keysyms of interest to 
 - * AT clients and keyboard emulators are usually part of the current keymap, 
 - * i.e., present on the system keyboard for the current locale (even if a 
 + * succession.
 + * In practice this is rarely significant, since the keysyms of interest to
 + * AT clients and keyboard emulators are usually part of the current keymap,
 + * i.e., present on the system keyboard for the current locale (even if a
   * physical hardware keyboard is not connected).
   * @ATSPI_KEY_STRING: A string is converted to its equivalent keyboard events
   * and emitted. If the string consists of complex characters or composed
@@@ -801,7 -788,7 +801,7 @@@ typedef enum 
   * modifies the state, onscreen location, or other attributes of one or more
   * target objects.
   * @ATSPI_RELATION_CONTROLLED_BY: Object state, position, etc. is
 - * modified/controlled by user interaction with one or more other objects. 
 + * modified/controlled by user interaction with one or more other objects.
   * For instance a viewport or scroll pane may be @ATSPI_RELATION_CONTROLLED_BY
   * scrollbars.
   * @ATSPI_RELATION_MEMBER_OF: Object has a grouping relationship (e.g. 'same
   * object which is not the 'next sibling' in the accessibility hierarchy.
   * @ATSPI_RELATION_FLOWS_FROM: Reciprocal of @ATSPI_RELATION_FLOWS_TO.
   * @ATSPI_RELATION_SUBWINDOW_OF: Object is visually and semantically considered
 - * a subwindow of another object, even though it is not the object's child. 
 + * a subwindow of another object, even though it is not the object's child.
   * Useful when dealing with embedded applications and other cases where the
   * widget hierarchy does not map cleanly to the onscreen presentation.
 - * @ATSPI_RELATION_EMBEDS: Similar to @ATSPI_RELATION_SUBWINDOW_OF, but 
 + * @ATSPI_RELATION_EMBEDS: Similar to @ATSPI_RELATION_SUBWINDOW_OF, but
   * specifically used for cross-process embedding.
   * @ATSPI_RELATION_EMBEDDED_BY: Reciprocal of @ATSPI_RELATION_EMBEDS. Used to
   * denote content rendered by embedded renderers that live in a separate process
   * @ATSPI_RELATION_POPUP_FOR: Denotes that the object is a transient window or
   * frame associated with another onscreen object. Similar to @ATSPI_TOOLTIP_FOR,
   * but more general. Useful for windows which are technically toplevels
 - * but which, for one or more reasons, do not explicitly cause their 
 + * but which, for one or more reasons, do not explicitly cause their
   * associated window to lose 'window focus'. Creation of an @ATSPI_ROLE_WINDOW
 - * object with the @ATSPI_RELATION_POPUP_FOR relation usually requires 
 + * object with the @ATSPI_RELATION_POPUP_FOR relation usually requires
   * some presentation action on the part
   * of assistive technology clients, even though the previous toplevel
   * @ATSPI_ROLE_FRAME object may still be the active window.
   * Indicates that this object contains an error message describing an invalid
   * condition in the target object(s). @Since: 2.26.
   * @ATSPI_RELATION_LAST_DEFINED: Do not use as a parameter value, used to
 - * determine the size of the enumeration. 
 + * determine the size of the enumeration.
   *
 - * #AtspiRelationType specifies a relationship between objects 
 + * #AtspiRelationType specifies a relationship between objects
   * (possibly one-to-many
   * or many-to-one) outside of the normal parent/child hierarchical
   * relationship. It allows better semantic       identification of how objects
 - * are associated with one another.       For instance the 
 + * are associated with one another.       For instance the
   * @ATSPI_RELATION_LABELLED_BY
   * relationship may be used to identify labelling information       that should
   * accompany the accessible name property when presenting an object's content or
 - * identity       to the end user.  Similarly, 
 + * identity       to the end user.  Similarly,
   * @ATSPI_RELATION_CONTROLLER_FOR can be used
   * to further specify the context in which a valuator is useful, and/or the
   * other UI components which are directly effected by user interactions with
@@@ -971,7 -958,7 +971,7 @@@ typedef enum 
   * etc.
   * @ATSPI_ROLE_GLASS_PANE: A pane that is guaranteed to be painted on top of
   * all panes beneath it.
 - * @ATSPI_ROLE_HTML_CONTAINER: A document container for HTML, whose children   
 + * @ATSPI_ROLE_HTML_CONTAINER: A document container for HTML, whose children
   * represent the document content.
   * @ATSPI_ROLE_ICON: A small fixed size picture, typically used to decorate
   * components.
   * @ATSPI_ROLE_SCROLL_PANE: An object that allows a user to incrementally view
   * a large amount of information. @ATSPI_ROLE_SCROLL_PANE objects are usually
   * accompanied by @ATSPI_ROLE_SCROLL_BAR controllers, on which the
 - * @ATSPI_RELATION_CONTROLLER_FOR and @ATSPI_RELATION_CONTROLLED_BY 
 + * @ATSPI_RELATION_CONTROLLER_FOR and @ATSPI_RELATION_CONTROLLED_BY
   * reciprocal relations are set. See  #atspi_get_relation_set.
   * @ATSPI_ROLE_SEPARATOR: An object usually contained in a menu to provide a
   * visible and logical separation of the contents in a menu.
   * range.
   * @ATSPI_ROLE_SPIN_BUTTON: An object which allows one of a set of choices to
   * be selected, and which displays the current choice.  Unlike
 - * @ATSPI_ROLE_SCROLL_BAR, @ATSPI_ROLE_SLIDER objects need not control 
 + * @ATSPI_ROLE_SCROLL_BAR, @ATSPI_ROLE_SLIDER objects need not control
   * 'viewport'-like objects.
   * @ATSPI_ROLE_SPLIT_PANE: A specialized panel that presents two other panels
   * at the same time.
   * @ATSPI_ROLE_TABLE: An object used to repesent information in terms of rows
   * and columns.
   * @ATSPI_ROLE_TABLE_CELL: A 'cell' or discrete child within a Table. Note:
 - * Table cells need not have @ATSPI_ROLE_TABLE_CELL, other 
 + * Table cells need not have @ATSPI_ROLE_TABLE_CELL, other
   * #AtspiRoleType values are valid as well.
   * @ATSPI_ROLE_TABLE_COLUMN_HEADER: An object which labels a particular column
   * in an #AtspiTable.
   * user.
   * @ATSPI_ROLE_TREE_TABLE: An object that presents both tabular and
   * hierarchical info to the user.
 - * @ATSPI_ROLE_UNKNOWN: The object contains some #AtspiAccessible information, 
 + * @ATSPI_ROLE_UNKNOWN: The object contains some #AtspiAccessible information,
   * but its role is not known.
   * @ATSPI_ROLE_VIEWPORT: An object usually used in a scroll pane, or to
   * otherwise clip a larger object or content renderer to a specific
   * @ATSPI_ROLE_FOOTER: An object that serves as a document footer.
   * @ATSPI_ROLE_PARAGRAPH: An object which is contains a single paragraph of
   * text content. See also @ATSPI_ROLE_TEXT.
 - * @ATSPI_ROLE_RULER: An object which describes margins and tab stops, etc.    
 - *    for text objects which it controls (should have 
 + * @ATSPI_ROLE_RULER: An object which describes margins and tab stops, etc.
 + *    for text objects which it controls (should have
   * @ATSPI_RELATION_CONTROLLER_FOR relation to such).
   * @ATSPI_ROLE_APPLICATION: An object corresponding to the toplevel accessible
 - * of an application, which may contain @ATSPI_ROLE_FRAME objects or other      
 + * of an application, which may contain @ATSPI_ROLE_FRAME objects or other
   * accessible objects. Children of #AccessibleDesktop objects  are generally
   * @ATSPI_ROLE_APPLICATION objects.
   * @ATSPI_ROLE_AUTOCOMPLETE: The object is a dialog or list containing items
   * and for embedding of out-of-process component, "panel applets", etc.
   * @ATSPI_ROLE_ENTRY: The object is a component whose textual content may be
   * entered or modified by the user, provided @ATSPI_STATE_EDITABLE is present.
 - * A readonly @ATSPI_ROLE_ENTRY object (i.e. where @ATSPI_STATE_EDITABLE is 
 - * not present) implies a read-only 'text field' in a form, as opposed to a 
 + * A readonly @ATSPI_ROLE_ENTRY object (i.e. where @ATSPI_STATE_EDITABLE is
 + * not present) implies a read-only 'text field' in a form, as opposed to a
   * title, label, or caption.
   * @ATSPI_ROLE_CHART: The object is a graphical depiction of quantitative data.
   * It may contain multiple subelements whose attributes and/or description
   * may be queried to obtain both the  quantitative data and information about
 - * how the data is being presented. The @ATSPI_LABELLED_BY relation is 
 + * how the data is being presented. The @ATSPI_LABELLED_BY relation is
   * particularly important in interpreting objects of this type, as is the
   * accessible description property. See @ATSPI_ROLE_CAPTION.
   * @ATSPI_ROLE_CAPTION: The object contains descriptive information, usually
   * contains a view of document content. #AtspiDocument frames may occur within
   * another #AtspiDocument instance, in which case the second  document may be
   * said to be embedded in the containing instance.  HTML frames are often
 - * ATSPI_ROLE_DOCUMENT_FRAME:  Either this object, or a singleton descendant, 
 + * ATSPI_ROLE_DOCUMENT_FRAME:  Either this object, or a singleton descendant,
   * should implement the #AtspiDocument interface.
   * @ATSPI_ROLE_HEADING: The object serves as a heading for content which
   * follows it in a document. The 'heading level' of the heading, if
   * this role should be ignored by clients, if they are encountered at all.
   * @ATSPI_ROLE_FORM: The object is a containing instance of document content
   * which has within it components with which the user can interact in order
 - * to input information; i.e. the object is a container for pushbuttons,    
 + * to input information; i.e. the object is a container for pushbuttons,
   * comboboxes, text input fields, and other 'GUI' components. @ATSPI_ROLE_FORM
   * should not, in general, be used for toplevel GUI containers or dialogs,
   * but should be reserved for 'GUI' containers which occur within document
   * content, for instance within Web documents, presentations, or text
 - * documents.  Unlike other GUI containers and dialogs which occur inside      
 + * documents.  Unlike other GUI containers and dialogs which occur inside
   * application instances, @ATSPI_ROLE_FORM containers' components are
 - * associated with the current document, rather than the current foreground 
 + * associated with the current document, rather than the current foreground
   * application or viewer instance.
 - * @ATSPI_ROLE_LINK: The object is a hypertext anchor, i.e. a "link" in a      
 + * @ATSPI_ROLE_LINK: The object is a hypertext anchor, i.e. a "link" in a
   * hypertext document.  Such objects are distinct from 'inline'       content
   * which may also use the #AtspiHypertext/#AtspiHyperlink interfacesto indicate
   * the range/location within a text object where an inline or embedded object
   * lies.
   * @ATSPI_ROLE_INPUT_METHOD_WINDOW: The object is a window or similar viewport
 - * which is used to allow composition or input of a 'complex character',    
 + * which is used to allow composition or input of a 'complex character',
   * in other words it is an "input method window".
   * @ATSPI_ROLE_TABLE_ROW: A row in a table.
   * @ATSPI_ROLE_TREE_ITEM: An object that represents an element of a tree.
   * @ATSPI_ROLE_DESCRIPTION_VALUE: An object that represents the description,
   *  definition, or value of a term. @Since: 2.26.
   * @ATSPI_ROLE_FOOTNOTE: An object that contains the text of a footnote. @Since: 2.26.
+  * @ATSPI_ROLE_CONTENT_DELETION: Content previously deleted or proposed to be
+  * deleted, e.g. in revision history or a content view providing suggestions
+  * from reviewers. @Since: 2.34.
+  * @ATSPI_ROLE_CONTENT_INSERTION: Content previously inserted or proposed to be
+  * inserted, e.g. in revision history or a content view providing suggestions
+  * from reviewers. @Since: 2.34.
   *  @ATSPI_ROLE_LAST_DEFINED: Not a valid role, used for finding end of
   *  enumeration.
   *
@@@ -1380,6 -1373,8 +1386,8 @@@ typedef enum 
      ATSPI_ROLE_DESCRIPTION_TERM,
      ATSPI_ROLE_DESCRIPTION_VALUE,
      ATSPI_ROLE_FOOTNOTE,
+     ATSPI_ROLE_CONTENT_DELETION,
+     ATSPI_ROLE_CONTENT_INSERTION,
      ATSPI_ROLE_LAST_DEFINED,
  } AtspiRole;
  
   *
   * One higher than the highest valid value of #AtspiRole.
   */
- #define ATSPI_ROLE_COUNT (125+1)
+ #define ATSPI_ROLE_COUNT (127+1)
  
 +/**
 + * AtspiMoveOutedType: The type of signal that occurs when an object outted the screen.
 + * @ATSPI_MOVE_OUTED_TOP_LEFT: Object has outted top or left of the screen.
 + * @ATSPI_MOVE_OUTED_BOTTOM_RIGHT: Object has outted bottom or right of the screen.
 + **/
 +
 +typedef enum {
 +    ATSPI_MOVE_OUTED_NULL,
 +    ATSPI_MOVE_OUTED_TOP_LEFT,
 +    ATSPI_MOVE_OUTED_BOTTOM_RIGHT,
 +    ATSPI_MOVE_OUTED_LAST_DEFINDED
 +} AtspiMoveOutedType;
 +
 +/**
 + * ATSPI_MOVE_OUTED_COUNT:
 + *
 + * One higher than the highest valid value of #AtspiScreenOuttedType.
 + **/
 +#define ATSPI_MOVE_OUTED_COUNT (3+1)
 +
  typedef enum
  {
       ATSPI_CACHE_NONE     = 0,
@@@ -1495,6 -1470,9 +1503,9 @@@ typedef enum 
  #define ATSPI_DBUS_INTERFACE_VALUE "org.a11y.atspi.Value"
  #define ATSPI_DBUS_INTERFACE_SOCKET "org.a11y.atspi.Socket"
  
+ #define ATSPI_DBUS_PATH_SCREEN_READER "/org/a11y/atspi/screenreader"
+ #define ATSPI_DBUS_INTERFACE_EVENT_SCREEN_READER "org.a11y.atspi.Event.ScreenReader"
  #ifdef __cplusplus
  }
  #endif
@@@ -7,24 -7,25 +7,25 @@@
   * Copyright 2010, 2011 Novell, Inc.
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #include "atspi-private.h"
  #include "atspi-accessible-private.h"
  #include <string.h>
+ #include <strings.h>
  #include <ctype.h>
  
  typedef struct
@@@ -169,12 -170,15 +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)
    {
@@@ -378,14 -382,14 +382,14 @@@ convert_event_type_to_dbus (const char 
    if (matchrule_array)
    {
      gchar *matchrule;
+     (*matchrule_array) = g_ptr_array_new ();
      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;
+              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])
      {
        gchar *new_str = g_strconcat (matchrule, ",arg0='", detail, "'", NULL);
@@@ -467,6 -471,9 +471,9 @@@ listener_entry_free (EventListenerEntr
   *            object:model-changed
   *            object:active-descendant-changed
   *
+  *  (screen reader events)
+ *             screen-reader:region-changed
+  *
   *  (window events)
   *
   *            window:minimize
   *            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.
   **/
@@@ -786,16 -796,15 +796,16 @@@ atspi_event_listener_deregister_from_ca
    GPtrArray *matchrule_array;
    gint i;
    GList *l;
 +  gboolean result = TRUE;
  
 +  if (!callback)
 +  {
 +    return FALSE;
 +  }
    if (!convert_event_type_to_dbus (event_type, &category, &name, &detail, &matchrule_array))
    {
      return FALSE;
    }
 -  if (!callback)
 -    {
 -      return FALSE;
 -    }
  
    for (l = event_listeners; l;)
    {
            atspi_path_registry,
            atspi_interface_registry,
            "DeregisterEvent");
 -      if (!message)
 -      return FALSE;
 +      if (!message) {
 +        result = FALSE;
 +        break;
 +      }
        dbus_message_append_args (message, DBUS_TYPE_STRING, &event_type, DBUS_TYPE_INVALID);
        reply = _atspi_dbus_send_with_reply_and_block (message, error);
        if (reply)
    for (i = 0; i < matchrule_array->len; i++)
      g_free (g_ptr_array_index (matchrule_array, i));
    g_ptr_array_free (matchrule_array, TRUE);
 -  return TRUE;
 +  return result;
  }
  
  /**
@@@ -875,6 -882,7 +885,7 @@@ atspi_event_copy (AtspiEvent *src
    dst->detail2 = src->detail2;
    g_value_init (&dst->any_data, G_VALUE_TYPE (&src->any_data));
    g_value_copy (&src->any_data, &dst->any_data);
+   dst->sender = g_object_ref (src->sender);
    return dst;
  }
  
@@@ -884,6 -892,7 +895,7 @@@ atspi_event_free (AtspiEvent *event
    g_object_unref (event->source);
    g_free (event->type);
    g_value_unset (&event->any_data);
+   g_object_unref (event->sender);
    g_free (event);
  }
  
@@@ -894,7 -903,7 +906,7 @@@ detail_matches_listener (const char *ev
      return TRUE;
  
    if (!event_detail)
 -    return (listener_detail ? FALSE : TRUE);
 +    return FALSE;
  
    return !(listener_detail [strcspn (listener_detail, ":")] == '\0'
                 ? strncmp (listener_detail, event_detail,
@@@ -954,6 -963,7 +966,7 @@@ _atspi_dbus_handle_event (DBusConnectio
  {
    char *detail = NULL;
    const char *category = dbus_message_get_interface (message);
+   const char *sender = dbus_message_get_sender (message);
    const char *member = dbus_message_get_member (message);
    const char *signature = dbus_message_get_signature (message);
    gchar *name;
    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;
    }
  
    memset (&e, 0, sizeof (e));
  
 -  if (category)
 +  if (!category)
    {
 -    category = g_utf8_strrchr (category, -1, '.');
 -    if (category == NULL)
 -    {
 -      // TODO: Error
 -      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 -    }
 -    category++;
 +    // TODO: Error
 +    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }
 +
 +  category = g_utf8_strrchr (category, -1, '.');
 +  if (category == NULL)
 +  {
 +    // TODO: Error
 +    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 +  }
 +  category++;
 +
    dbus_message_iter_get_basic (&iter, &detail);
    dbus_message_iter_next (&iter);
    dbus_message_iter_get_basic (&iter, &detail1);
      converted_type = p;
    }
    e.type = converted_type;
-   e.source = _atspi_ref_accessible (dbus_message_get_sender(message), dbus_message_get_path(message));
-   if (e.source == NULL)
+   if (strcmp (category, "ScreenReader") != 0)
    {
-     g_warning ("Got no valid source accessible for signal for signal %s from interface %s\n", member, category);
-     g_free (converted_type);
-     g_free (name);
-     g_free (detail);
-     return DBUS_HANDLER_RESULT_HANDLED;
+     e.source = _atspi_ref_accessible (sender, dbus_message_get_path (message));
+     if (e.source == NULL)
+     {
+       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);
        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);
+         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 */
+       accessible = _atspi_dbus_return_accessible_from_iter (&iter_variant);
+         if (!strcmp (category, "ScreenReader"))
+         {
+           e.source = accessible;
+         }
+         else
+         {
+           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;
      }
      cache = _atspi_dbus_update_cache_from_dict (e.source, &iter);
    }
  
+   e.sender = _atspi_ref_accessible (sender, ATSPI_DBUS_PATH_ROOT);
    if (!strncmp (e.type, "object:children-changed", 23))
    {
      cache_process_children_changed (&e);
@@@ -5,22 -5,22 +5,22 @@@
   * Copyright 2002 Ximian, Inc.
   *           2002 Sun Microsystems Inc.
   * Copyright 2010, 2011 Novell, Inc.
 - *           
 + *
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #ifndef _ATSPI_MISC_PRIVATE_H_
@@@ -166,6 -166,8 +166,8 @@@ gboolean _atspi_get_allow_sync ()
  gboolean _atspi_set_allow_sync (gboolean val);
  
  void _atspi_set_error_no_sync (GError **error);
+ gboolean _atspi_prepare_screen_reader_interface ();
  G_END_DECLS
  
  #endif        /* _ATSPI_MISC_PRIVATE_H_ */
diff --combined atspi/atspi-misc.c
@@@ -7,19 -7,19 +7,19 @@@
   * Copyright 2010, 2011 Novell, Inc.
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  /*
@@@ -110,7 -110,7 +110,7 @@@ _atspi_get_iface_num (const char *iface
  GHashTable *
  _atspi_get_live_refs (void)
  {
 -  if (!live_refs) 
 +  if (!live_refs)
      {
        live_refs = g_hash_table_new (g_direct_hash, g_direct_equal);
      }
@@@ -159,7 -159,8 +159,8 @@@ cleanup (
    for (i = desktop->children->len - 1; i >= 0; i--)
    {
      AtspiAccessible *child = g_ptr_array_index (desktop->children, i);
-     g_object_run_dispose (G_OBJECT (child->parent.app));
+     if (child->parent.app)
+       g_object_run_dispose (G_OBJECT (child->parent.app));
      g_object_run_dispose (G_OBJECT (child));
    }
  
@@@ -180,7 -181,6 +181,7 @@@ handle_get_bus_address (DBusPendingCal
    DBusMessage *message;
    const char *address;
    DBusPendingCall *new_pending;
 +  dbus_bool_t result;
  
    if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
    {
                                            "/org/a11y/atspi/cache",
                                            atspi_interface_cache, "GetItems");
  
 -  dbus_connection_send_with_reply (app->bus, message, &new_pending, 2000);
 +  result = dbus_connection_send_with_reply (app->bus, message, &new_pending, 2000);
    dbus_message_unref (message);
 -  if (!new_pending)
 +  if (!result || !new_pending)
      return;
    dbus_pending_call_set_notify (new_pending, handle_get_items, app, NULL);
  }
@@@ -233,7 -233,6 +234,7 @@@ get_application (const char *bus_name
    char *bus_name_dup;
    DBusMessage *message;
    DBusPendingCall *pending = NULL;
 +  dbus_bool_t result;
  
    if (!app_hash)
    {
    message = dbus_message_new_method_call (bus_name, atspi_path_root,
                                            atspi_interface_application, "GetApplicationBusAddress");
  
 -  dbus_connection_send_with_reply (app->bus, message, &pending, 2000);
 +  result = dbus_connection_send_with_reply (app->bus, message, &pending, 2000);
    dbus_message_unref (message);
 -  if (!pending)
 +  if (!result || !pending)
    {
      g_hash_table_remove (app_hash, bus_name_dup);
      return NULL;
    return app;
  }
  
 -static AtspiAccessible *
 +AtspiAccessible *
  ref_accessible (const char *app_name, const char *path)
  {
    AtspiApplication *app;
@@@ -392,7 -391,7 +393,7 @@@ handle_name_owner_changed (DBusConnecti
    else if (app_hash)
    {
      AtspiApplication *app = g_hash_table_lookup (app_hash, old);
 -    if (app && !strcmp (app->bus_name, old))
 +    if (app && app->bus_name && !strcmp(app->bus_name, name))
        g_object_run_dispose (G_OBJECT (app));
    }
    return DBUS_HANDLER_RESULT_HANDLED;
@@@ -533,8 -532,9 +534,9 @@@ handle_get_items (DBusPendingCall *pend
    {
      const char *sender = dbus_message_get_sender (reply);
      const char *error = NULL;
-     if (!strcmp (dbus_message_get_error_name (reply),
-                  DBUS_ERROR_SERVICE_UNKNOWN))
+     const char *error_name = dbus_message_get_error_name (reply);
+     if (!strcmp (error_name, DBUS_ERROR_SERVICE_UNKNOWN)
+      || !strcmp (error_name, DBUS_ERROR_NO_REPLY))
      {
      }
      else
@@@ -674,7 -674,7 +676,7 @@@ _atspi_dbus_return_hyperlink_from_messa
    DBusMessageIter iter;
    AtspiHyperlink *retval = NULL;
    const char *signature;
 -   
 +
    if (!message)
      return NULL;
  
@@@ -889,7 -889,7 +891,7 @@@ spi_display_name (void
   *
   * Connects to the accessibility registry and initializes the SPI.
   *
 - * Returns: 0 on success, 1 if already initialized, or an integer error code.  
 + * Returns: 0 on success, 1 if already initialized, or an integer error code.
   **/
  int
  atspi_init (void)
    bus = atspi_get_a11y_bus ();
    if (!bus)
      return 2;
 -  dbus_bus_register (bus, NULL);
 +  if (!dbus_bus_register (bus, NULL))
 +    return 2;
    atspi_dbus_connection_setup_with_g_main(bus, g_main_context_default());
    dbus_connection_add_filter (bus, atspi_dbus_filter, NULL, NULL);
    match = g_strdup_printf ("type='signal',interface='%s',member='AddAccessible'", atspi_interface_cache);
@@@ -987,7 -986,7 +989,7 @@@ atspi_event_quit (void
  /**
   * atspi_exit:
   *
 - * Disconnects from #AtspiRegistry instances and releases 
 + * Disconnects from #AtspiRegistry instances and releases
   * any floating resources. Call only once at exit.
   *
   * Returns: 0 if there were no leaks, otherwise other integer values.
@@@ -1038,7 -1037,6 +1040,7 @@@ check_for_hang (DBusMessage *message, D
      DBusMessage *message;
      gchar *bus_name_dup;
      DBusPendingCall *pending = NULL;
 +    dbus_bool_t result;
      for (l = hung_processes; l; l = l->next)
        if (!strcmp (l->data, bus_name))
          return;
                                              "Ping");
      if (!message)
        return;
 -    dbus_connection_send_with_reply (bus, message, &pending, -1);
 +    result = dbus_connection_send_with_reply (bus, message, &pending, -1);
      dbus_message_unref (message);
 -    if (!pending)
 +    if (!result || !pending)
        return;
      bus_name_dup = g_strdup (bus_name);
      hung_processes = g_slist_append (hung_processes, bus_name_dup);
@@@ -1146,11 -1144,9 +1148,11 @@@ _atspi_dbus_call_partial (gpointer obj
                            const char *type, ...)
  {
    va_list args;
 -
 +  DBusMessage * result;
    va_start (args, type);
 -  return _atspi_dbus_call_partial_va (obj, interface, method, error, type, args);
 +  result =  _atspi_dbus_call_partial_va (obj, interface, method, error, type, args);
 +  va_end (args);
 +  return result;
  }
  
  
@@@ -1164,9 -1160,9 +1166,9 @@@ _atspi_dbus_call_partial_va (gpointer o
  {
    AtspiObject *aobj = ATSPI_OBJECT (obj);
    DBusError err;
 -    DBusMessage *msg = NULL, *reply = NULL;
 -    DBusMessageIter iter;
 -    const char *p;
 +  DBusMessage *msg = NULL, *reply = NULL;
 +  DBusMessageIter iter;
 +  const char *p;
  
    dbus_error_init (&err);
  
    process_deferred_messages ();
    if (dbus_error_is_set (&err))
    {
 -    /* TODO: Set gerror */
 +    g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, err.message);
      dbus_error_free (&err);
 +    if (reply)
 +      dbus_message_unref(reply);
 +    return NULL;
    }
 -
 -  if (reply && dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
 +  else if (reply && dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
    {
      const char *err_str = NULL;
      dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_str, DBUS_TYPE_INVALID);
      dbus_message_unref (reply);
      return NULL;
    }
 -
    return reply;
  }
  
@@@ -1494,7 -1489,7 +1496,7 @@@ get_accessibility_bus_address_x11 (void
        g_warning ("Could not open X display");
        return NULL;
      }
 -      
 +
    AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False);
    XGetWindowProperty (bridge_display,
                      XDefaultRootWindow (bridge_display),
@@@ -1542,7 -1537,7 +1544,7 @@@ get_accessibility_bus_address_dbus (voi
      dbus_error_free (&error);
      goto out;
    }
 -  
 +
    {
      const char *tmp_address;
      if (!dbus_message_get_args (reply,
@@@ -1597,7 -1592,8 +1599,8 @@@ atspi_get_a11y_bus (void
    if (address_env != NULL && *address_env != 0)
      address = g_strdup (address_env);
  #ifdef HAVE_X11
-   if (!address)
+   if (!address && g_getenv ("DISPLAY") != NULL &&
+       g_getenv ("WAYLAND_DISPLAY") == NULL)
      address = get_accessibility_bus_address_x11 ();
  #endif
    if (!address)
          return NULL;
        }
      }
 -  
 +
    /* Simulate a weak ref on the bus */
    dbus_connection_set_data (a11y_bus, a11y_dbus_slot, a11y_bus, a11y_bus_free);
  
@@@ -1828,7 -1824,7 +1831,7 @@@ _atspi_dbus_update_cache_from_dict (Ats
        g_value_set_boxed (val, &extents);
      }
      if (val)
 -      g_hash_table_insert (cache, g_strdup (key), val); 
 +      g_hash_table_insert (cache, g_strdup (key), val);
      dbus_message_iter_next (&iter_dict);
    }
  
@@@ -1856,3 -1852,50 +1859,50 @@@ _atspi_set_error_no_sync (GError **erro
    g_set_error_literal (error, ATSPI_ERROR, ATSPI_ERROR_SYNC_NOT_ALLOWED,
                          _("Attempted synchronous call where prohibited"));
  }
+ static const char *sr_introspection = "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
+ "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
+ "<node name=\"/org/a11y/atspi/screenreader\">\n"
+ "  <interface name=\"org.a11y.Atspi.ScreenReader\">\n"
+ "    <signal name=\"ReadingPosition\">\n"
+ "      <arg type=\"i\"/>\n"
+ "      <arg type=\"i\"/>\n"
+ "    </signal>\n"
+ "  </interface>\n"
+ "</node>";
+ static DBusHandlerResult
+ screen_reader_filter (DBusConnection *bus, DBusMessage *message, void *user_data)
+ {
+   if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE,
+       "Introspect"))
+   {
+     DBusMessage *reply = dbus_message_new_method_return (message);
+     dbus_message_append_args (reply, DBUS_TYPE_STRING, &sr_introspection,
+                               DBUS_TYPE_INVALID);
+     dbus_connection_send (bus, reply, NULL);
+     dbus_message_unref (reply);
+     return DBUS_HANDLER_RESULT_HANDLED;
+   }
+   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ gboolean
+ _atspi_prepare_screen_reader_interface ()
+ {
+   static gint initialized = 0;
+   DBusConnection *a11y_bus = _atspi_bus ();
+   if (initialized)
+     return (initialized > 0);
+   if (dbus_bus_request_name (a11y_bus, "org.a11y.Atspi.ScreenReader", 0, NULL) < 0)
+   {
+     initialized = -1;
+     return FALSE;
+   }
+   initialized = 1;
+   dbus_connection_add_filter (a11y_bus, screen_reader_filter, NULL, NULL);
+   return TRUE;
+ }
diff --combined atspi/atspi-misc.h
@@@ -8,19 -8,19 +8,19 @@@
   *           
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #ifndef _ATSPI_MISC_H_
@@@ -47,9 -47,6 +47,9 @@@ voi
  atspi_set_main_context (GMainContext *cnx);
  
  gchar * atspi_role_get_name (AtspiRole role);
 +
 +AtspiAccessible *ref_accessible(const char *app_name, const char *path);
 +
  G_END_DECLS
  
  #endif        /* _ATSPI_MISC_H_ */
diff --combined atspi/atspi-registry.c
@@@ -7,19 -7,19 +7,19 @@@
   * 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
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  /* atspi_registry.c: Global functions wrapping the registry */
@@@ -270,7 -270,7 +270,7 @@@ atspi_deregister_keystroke_listener (At
                                       GError             **error)
  {
    GArray *d_key_set;
 -  gchar *path = _atspi_device_listener_get_path (listener);
 +  gchar *path;
    gint i;
    dbus_uint32_t d_modmask = modmask;
    dbus_uint32_t d_event_types = event_types;
      {
        return FALSE;
      }
 +  path = _atspi_device_listener_get_path (listener);
  
    /* copy the keyval filter values from the C api into the DBind KeySet */
    if (key_set)
@@@ -364,7 -363,7 +364,7 @@@ atspi_register_device_event_listener (A
  {
    gboolean                          retval = FALSE;
    dbus_uint32_t d_event_types = event_types;
 -  gchar *path = _atspi_device_listener_get_path (listener);
 +  gchar *path;
    DBusError d_error;
  
    dbus_error_init (&d_error);
      {
        return retval;
      }
 +  path = _atspi_device_listener_get_path (listener);
  
      dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "RegisterDeviceEventListener", &d_error, "ou=>b", path, d_event_types, &retval);
      if (dbus_error_is_set (&d_error))
@@@ -402,7 -400,7 +402,7 @@@ atspi_deregister_device_event_listener 
                                   void                     *filter, GError **error)
  {
    dbus_uint32_t event_types = 0;
 -  gchar *path = _atspi_device_listener_get_path (listener);
 +  gchar *path;
    DBusError d_error;
  
    dbus_error_init (&d_error);
      {
        return FALSE;
      }
 +  path = _atspi_device_listener_get_path (listener);
  
    event_types |= (1 << ATSPI_BUTTON_PRESSED_EVENT);
    event_types |= (1 << ATSPI_BUTTON_RELEASED_EVENT);
    return TRUE;
  }
  
+ static gboolean
+ using_mutter ()
+ {
+   return (g_getenv ("WAYLAND_DISPLAY") != NULL);
+ }
  /**
   * atspi_generate_keyboard_event:
   * @keyval: a #gint indicating the keycode or keysym or modifier mask of the
@@@ -459,6 -462,12 +465,12 @@@ atspi_generate_keyboard_event (glong ke
    dbus_int32_t d_keyval = keyval;
    DBusError d_error;
  
+   if (using_mutter ())
+   {
+     if (_atspi_mutter_generate_keyboard_event (keyval, keystring, synth_type, error))
+       return TRUE;
+   }
    dbus_error_init (&d_error);
    if (!keystring)
      keystring = "";
@@@ -495,6 -504,14 +507,14 @@@ atspi_generate_mouse_event (glong x, gl
    dbus_int32_t d_x = x, d_y = y;
    DBusError d_error;
  
+   g_return_val_if_fail (name != NULL, FALSE);
+   if (using_mutter ())
+   {
+     if (_atspi_mutter_generate_mouse_event (x, y, name, error))
+       return TRUE;
+   }
    dbus_error_init (&d_error);
    dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry,
                                 atspi_path_dec, atspi_interface_dec,
    return TRUE;
  }
  
+ /**
+  * atspi_set_reference_window:
+  *
+  * @accessible: the #AtspiAccessible corresponding to the window to select.
+  *              should be a top-level window with a role of
+  *              ATSPI_ROLE_APPLICATION.
+  *
+  * Sets the reference window that will be used when atspi_generate_mouse_event
+  * is called. Coordinates will be assumed to be relative to this window. This
+  * is needed because, due to Wayland's security model, it is not currently
+  * possible to retrieve global coordinates.
+  * If NULL is passed, then AT-SPI will use the window that has focus at the
+  * time that atspi_generate_mouse_event is called.
+  */
+ void
+ atspi_set_reference_window (AtspiAccessible *accessible)
+ {
+   if (using_mutter ())
+     _atspi_mutter_set_reference_window (accessible);
+ }
  AtspiKeyDefinition *
  atspi_key_definition_copy (AtspiKeyDefinition *src)
  {
diff --combined atspi/atspi-stateset.c
@@@ -7,19 -7,19 +7,19 @@@
   * Copyright 2010, 2011 Novell, Inc.
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #include "atspi-private.h"
@@@ -101,7 -101,6 +101,7 @@@ atspi_state_set_set_by_name (AtspiState
    if (!value)
    {
      g_warning ("AT-SPI: Attempt to set unknown state '%s'", name);
 +    return;
    }
    else
      if (enabled)
diff --combined atspi/atspi-types.h
@@@ -7,19 -7,19 +7,19 @@@
   *           
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #ifndef _ATSPI_TYPES_H_
@@@ -43,8 -43,6 +43,8 @@@ typedef struct _AtspiTable AtspiTable
  typedef struct _AtspiTableCell AtspiTableCell;
  typedef struct _AtspiText AtspiText;
  typedef struct _AtspiValue AtspiValue;
 +typedef struct _AtspiAccessibleReadingMaterial AtspiAccessibleReadingMaterial;
 +typedef struct _AtspiAccessibleDefaultLabelInfo AtspiAccessibleDefaultLabelInfo;
  
  typedef guint AtspiControllerEventMask;
  
@@@ -91,6 -89,7 +91,7 @@@ struct _AtspiEven
    gint         detail1;
    gint         detail2;
    GValue any_data;
+   AtspiAccessible *sender;
  };
  
  /**
@@@ -1,23 -1,23 +1,23 @@@
  /* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 - * 
 - * at-spi-bus-launcher: Manage the a11y bus as a child process 
 + *
 + * at-spi-bus-launcher: Manage the a11y bus as a child process
   *
   * Copyright 2011-2018 Red Hat, Inc.
   *
   * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #include "config.h"
  #include <X11/Xatom.h>
  #endif
  
 +//TODO: move to vconf/vconf-internal-setting-keys.h?
 +#define VCONFKEY_SETAPPL_ACCESSIBILITY_UNIVERSAL_SWITCH_CONFIGURATION_SERVICE "db/setting/accessibility/universal-switch/configuration-service"
 +#define VCONFKEY_SETAPPL_ACCESSIBILITY_UNIVERSAL_SWITCH_INTERACTION_SERVICE "db/setting/accessibility/universal-switch/interaction-service"
 +
 +#define MAX_NUMBER_OF_KEYS_PER_CLIENT 2
 +
 +#define APP_CONTROL_OPERATION_SCREEN_READ "http://tizen.org/appcontrol/operation/read_screen"
 +#define APP_CONTROL_OPERATION_UNIVERSAL_SWITCH "http://tizen.org/appcontrol/operation/universal_switch"
 +#include <appsvc.h>
 +#include <vconf.h>
 +
 +//uncomment if you want debug
 +//#ifndef TIZEN_ENGINEER_MODE
 +//#define TIZEN_ENGINEER_MODE
 +//#endif
 +#ifdef LOG_TAG
 +#undef LOG_TAG
 +#endif
 +
 +#define LOG_TAG "ATSPI_BUS_LAUNCHER"
 +
 +#include <dlog.h>
 +#include <aul.h>
 +
 +//uncomment this if you want log suring startup
 +//seems like dlog is not working at startup time
 +#define ATSPI_BUS_LAUNCHER_LOG_TO_FILE
 +
 +#ifdef ATSPI_BUS_LAUNCHER_LOG_TO_FILE
 +FILE *log_file;
 +#ifdef LOGD
 +#undef LOGD
 +#endif
 +#define LOGD(arg...) do {if (log_file) {fprintf(log_file, ##arg);fprintf(log_file, "\n"); fflush(log_file);}} while(0)
 +#endif
 +
 +static gboolean _launch_process_repeat_until_success(gpointer user_data);
 +
  typedef enum {
    A11Y_BUS_STATE_IDLE = 0,
    A11Y_BUS_STATE_READING_ADDRESS,
  } A11yBusState;
  
  typedef struct {
 +  const char * name;
 +  const char * app_control_operation;
 +  const char * vconf_key[MAX_NUMBER_OF_KEYS_PER_CLIENT];
 +  int number_of_keys;
 +  int launch_repeats;
 +  int pid;
 +} A11yBusClient;
 +
 +typedef struct {
    GMainLoop *loop;
    gboolean launch_immediately;
    gboolean a11y_enabled;
    gboolean screen_reader_enabled;
 +  GHashTable *client_watcher_id;
    GDBusConnection *session_bus;
    GSettings *a11y_schema;
    GSettings *interface_schema;
    int name_owner_id;
  
 +  A11yBusClient screen_reader;
 +  A11yBusClient universal_switch;
 +
    GDBusProxy *client_proxy;
  
    A11yBusState state;
 +
    /* -1 == error, 0 == pending, > 0 == running */
    int a11y_bus_pid;
    char *a11y_bus_address;
+ #ifdef HAVE_X11
+   gboolean x11_prop_set;
+ #endif
    int pipefd[2];
    int listenfd;
    char *a11y_launch_error_message;
@@@ -303,7 -254,7 +306,7 @@@ on_bus_exited (GPid     pid
                 gpointer data)
  {
    A11yBusLauncher *app = data;
 -  
 +
    app->a11y_bus_pid = -1;
    app->state = A11Y_BUS_STATE_ERROR;
    if (app->a11y_launch_error_message == NULL)
          app->a11y_launch_error_message = g_strdup_printf ("Bus stopped by signal %d", WSTOPSIG (status));
      }
    g_main_loop_quit (app->loop);
 -} 
 +}
  
  #ifdef DBUS_DAEMON
  static void
@@@ -343,17 -294,8 +346,17 @@@ ensure_a11y_bus_daemon (A11yBusLaunche
    char addr_buf[2048];
    GError *error = NULL;
  
 +  if (app->a11y_bus_pid != 0)
 +    return FALSE;
 +
 +  argv[1] = (char*)config_path;
 +
    if (pipe (app->pipefd) < 0)
 -    g_error ("Failed to create pipe: %s", strerror (errno));
 +    {
 +      char buf[4096] = { 0 };
 +      strerror_r (errno, buf, sizeof(buf));
 +      g_error ("Failed to create pipe: %s", buf);
 +    }
  
    g_clear_pointer (&app->a11y_launch_error_message, g_free);
  
  
    app->state = A11Y_BUS_STATE_READING_ADDRESS;
    app->a11y_bus_pid = pid;
 -  g_debug ("Launched a11y bus, child is %ld", (long) pid);
 +  LOGD("Launched a11y bus, child is %ld", (long) pid);
    if (!unix_read_all_fd_to_string (app->pipefd[0], addr_buf, sizeof (addr_buf)))
      {
 -      app->a11y_launch_error_message = g_strdup_printf ("Failed to read address: %s", strerror (errno));
 +      char buf[4096] = { 0 };
 +      strerror_r (errno, buf, sizeof(buf));
 +      app->a11y_launch_error_message = g_strdup_printf ("Failed to read address: %s", buf);
        kill (app->a11y_bus_pid, SIGTERM);
+       app->a11y_bus_pid = -1;
        goto error;
      }
    close (app->pipefd[0]);
    app->state = A11Y_BUS_STATE_RUNNING;
  
    /* Trim the trailing newline */
 +  if (app->a11y_bus_address) g_free(app->a11y_bus_address);
    app->a11y_bus_address = g_strchomp (g_strdup (addr_buf));
 -  g_debug ("a11y bus address: %s", app->a11y_bus_address);
 +  LOGD("a11y bus address: %s", app->a11y_bus_address);
  
    return TRUE;
  
  error:
 -  close (app->pipefd[0]);
 -  close (app->pipefd[1]);
 +  if (app->pipefd[0] > 0) close (app->pipefd[0]);
 +  if (app->pipefd[1] > 0) close (app->pipefd[1]);
    app->state = A11Y_BUS_STATE_ERROR;
  
    return FALSE;
@@@ -444,32 -384,16 +448,32 @@@ ensure_a11y_bus_broker (A11yBusLaunche
    GError *error = NULL;
  
    if ((app->listenfd = socket (PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0)
 -    g_error ("Failed to create listening socket: %s", strerror (errno));
 +    {
 +      char buf[4096] = { 0 };
 +      strerror_r (errno, buf, sizeof(buf));
 +      g_error ("Failed to create listening socket: %s", buf);
 +    }
  
    if (bind (app->listenfd, (struct sockaddr *)&addr, sizeof(sa_family_t)) < 0)
 -    g_error ("Failed to bind listening socket: %s", strerror (errno));
 +    {
 +      char buf[4096] = { 0 };
 +      strerror_r (errno, buf, sizeof(buf));
 +      g_error ("Failed to bind listening socket: %s", buf);
 +    }
  
    if (getsockname (app->listenfd, (struct sockaddr *)&addr, &addr_len) < 0)
 -    g_error ("Failed to get socket name for listening socket: %s", strerror(errno));
 +    {
 +      char buf[4096] = { 0 };
 +      strerror_r (errno, buf, sizeof(buf));
 +      g_error ("Failed to get socket name for listening socket: %s", buf);
 +    }
  
    if (listen (app->listenfd, 1024) < 0)
 -    g_error ("Failed to listen on socket: %s", strerror(errno));
 +    {
 +      char buf[4096] = { 0 };
 +      strerror_r (errno, buf, sizeof(buf));
 +      g_error ("Failed to listen on socket: %s", buf);
 +    }
  
    g_clear_pointer (&app->a11y_launch_error_message, g_free);
  
@@@ -546,20 -470,22 +550,22 @@@ ensure_a11y_bus (A11yBusLauncher *app
  #endif
  
  #ifdef HAVE_X11
-   {
-     Display *display = XOpenDisplay (NULL);
-     if (display)
-       {
-         Atom bus_address_atom = XInternAtom (display, "AT_SPI_BUS", False);
-         XChangeProperty (display,
-                          XDefaultRootWindow (display),
-                          bus_address_atom,
-                          XA_STRING, 8, PropModeReplace,
-                          (guchar *) app->a11y_bus_address, strlen (app->a11y_bus_address));
-         XFlush (display);
-         XCloseDisplay (display);
-       }
-   }
+   if (g_getenv ("DISPLAY") != NULL && g_getenv ("WAYLAND_DISPLAY") == NULL)
+     {
+       Display *display = XOpenDisplay (NULL);
+       if (display)
+         {
+           Atom bus_address_atom = XInternAtom (display, "AT_SPI_BUS", False);
+           XChangeProperty (display,
+                            XDefaultRootWindow (display),
+                            bus_address_atom,
+                            XA_STRING, 8, PropModeReplace,
+                            (guchar *) app->a11y_bus_address, strlen (app->a11y_bus_address));
+           XFlush (display);
+           XCloseDisplay (display);
+           app->x11_prop_set = TRUE;
+         }
+     }
  #endif
  
    return TRUE;
@@@ -655,6 -581,11 +661,6 @@@ handle_screen_reader_enabled_change (A1
    if (enabled == app->screen_reader_enabled)
      return;
  
 -  /* If the screen reader is being enabled, we should enable accessibility
 -   * if it isn't enabled already */
 -  if (enabled)
 -    handle_a11y_enabled_change (app, enabled, notify_gsettings);
 -
    app->screen_reader_enabled = enabled;
  
    if (notify_gsettings && app->a11y_schema)
                                                  &builder,
                                                  &invalidated_builder),
                                   NULL);
 -
    g_variant_builder_clear (&builder);
    g_variant_builder_clear (&invalidated_builder);
  }
  
  static gboolean
 +is_client_connected(A11yBusLauncher *app)
 +{
 +  guint watchers = g_hash_table_size(app->client_watcher_id);
 +  LOGD("clients connected: %d", watchers);
 +  return watchers > 0;
 +}
 +
 +static void
 +remove_client_watch(A11yBusLauncher *app,
 +                                  const gchar     *sender)
 +{
 +  LOGD("Remove client watcher for %s", sender);
 +  guint watcher_id = GPOINTER_TO_UINT(g_hash_table_lookup(app->client_watcher_id, sender));
 +  if (watcher_id)
 +    g_bus_unwatch_name(watcher_id);
 +
 +  g_hash_table_remove(app->client_watcher_id, sender);
 +  if (!is_client_connected(app))
 +    handle_a11y_enabled_change (app, FALSE, TRUE);
 +}
 +
 +static void
 +on_client_name_vanished (GDBusConnection *connection,
 +                                       const gchar     *name,
 +                                       gpointer         user_data)
 +{
 +  A11yBusLauncher *app = user_data;
 +  remove_client_watch(app, name);
 +}
 +
 +static void
 +add_client_watch(A11yBusLauncher *app,
 +                               const gchar     *sender)
 +{
 +  LOGD("Add client watcher for %s", sender);
 +
 +  if (g_hash_table_contains(app->client_watcher_id, sender))
 +    {
 +      LOGI("Watcher for %s already registered", sender);
 +      return;
 +    }
 +
 +  guint watcher_id = g_bus_watch_name(G_BUS_TYPE_SESSION,
 +                     sender,
 +                     G_BUS_NAME_WATCHER_FLAGS_NONE,
 +                     NULL,
 +                     on_client_name_vanished,
 +                     app,
 +                     NULL);
 +
 +  g_hash_table_insert(app->client_watcher_id, g_strdup(sender), GUINT_TO_POINTER(watcher_id));
 +  handle_a11y_enabled_change (app, TRUE, TRUE);
 +}
 +
 +static gboolean
  handle_set_property  (GDBusConnection       *connection,
                        const gchar           *sender,
                        const gchar           *object_path,
    A11yBusLauncher *app = user_data;
    const gchar *type = g_variant_get_type_string (value);
    gboolean enabled;
 -  
 +
    if (g_strcmp0 (type, "b") != 0)
      {
        g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
  
    if (g_strcmp0 (property_name, "IsEnabled") == 0)
      {
 -      handle_a11y_enabled_change (app, enabled, TRUE);
 +      if (enabled)
 +        add_client_watch(app, sender);
 +      else
 +        remove_client_watch(app, sender);
        return TRUE;
      }
    else if (g_strcmp0 (property_name, "ScreenReaderEnabled") == 0)
@@@ -801,7 -675,7 +807,7 @@@ on_bus_acquired (GDBusConnection *conne
    A11yBusLauncher *app = user_data;
    GError *error;
    guint registration_id;
 -  
 +
    if (connection == NULL)
      {
        g_main_loop_quit (app->loop);
      }
    app->session_bus = connection;
  
-   if (app->launch_immediately)
-     {
-       ensure_a11y_bus (app);
-       if (app->state == A11Y_BUS_STATE_ERROR)
-         {
-           g_main_loop_quit (app->loop);
-           return;
-         }
-     }
    error = NULL;
    registration_id = g_dbus_connection_register_object (connection,
                                                         "/org/a11y/bus",
@@@ -860,6 -724,18 +856,18 @@@ on_name_acquired (GDBusConnection *conn
                    const gchar     *name,
                    gpointer         user_data)
  {
+   A11yBusLauncher *app = user_data;
+   if (app->launch_immediately)
+     {
+       ensure_a11y_bus (app);
+       if (app->state == A11Y_BUS_STATE_ERROR)
+         {
+           g_main_loop_quit (app->loop);
+           return;
+         }
+     }
    g_bus_watch_name (G_BUS_TYPE_SESSION,
                      "org.gnome.SessionManager",
                      G_BUS_NAME_WATCHER_FLAGS_NONE,
@@@ -881,7 -757,7 +889,7 @@@ on_sigterm_pipe (GIOChannel  *channel
                   gpointer     data)
  {
    A11yBusLauncher *app = data;
 -  
 +
    g_main_loop_quit (app->loop);
  
    return FALSE;
@@@ -893,11 -769,7 +901,11 @@@ init_sigterm_handling (A11yBusLauncher 
    GIOChannel *sigterm_channel;
  
    if (pipe (sigterm_pipefd) < 0)
 -    g_error ("Failed to create pipe: %s", strerror (errno));
 +    {
 +      char buf[4096] = { 0 };
 +      strerror_r (errno, buf, sizeof(buf));
 +      g_error ("Failed to create pipe: %s", buf);
 +    }
    signal (SIGTERM, sigterm_handler);
  
    sigterm_channel = g_io_channel_unix_new (sigterm_pipefd[0]);
                    app);
  }
  
- static gboolean
- already_running ()
- {
- #ifdef HAVE_X11
-   Atom AT_SPI_BUS;
-   Atom actual_type;
-   Display *bridge_display;
-   int actual_format;
-   unsigned char *data = NULL;
-   unsigned long nitems;
-   unsigned long leftover;
-   gboolean result = FALSE;
-   bridge_display = XOpenDisplay (NULL);
-   if (!bridge_display)
-             return FALSE;
-   AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False);
-   XGetWindowProperty (bridge_display,
-                     XDefaultRootWindow (bridge_display),
-                     AT_SPI_BUS, 0L,
-                     (long) BUFSIZ, False,
-                     (Atom) 31, &actual_type, &actual_format,
-                     &nitems, &leftover, &data);
-   if (data)
-   {
-     GDBusConnection *bus;
-     bus = g_dbus_connection_new_for_address_sync ((const gchar *)data, 0,
-                                                   NULL, NULL, NULL);
-     if (bus != NULL)
-       {
-         result = TRUE;
-         g_object_unref (bus);
-       }
-   }
-   XCloseDisplay (bridge_display);
-   return result;
- #else
-   return FALSE;
- #endif
- }
  static GSettings *
  get_schema (const gchar *name)
  {
  #if GLIB_CHECK_VERSION (2, 32, 0)
    GSettingsSchemaSource *source = g_settings_schema_source_get_default ();
 +  if (!source) return NULL;
 +
    GSettingsSchema *schema = g_settings_schema_source_lookup (source, name, FALSE);
  
    if (schema == NULL)
@@@ -990,263 -816,16 +954,257 @@@ gsettings_key_changed (GSettings *gsett
      handle_screen_reader_enabled_change (_global_app, new_val, FALSE);
  }
  
 +static int
 +_process_dead_tracker (int pid, void *data)
 +{
 +  A11yBusLauncher *app = data;
 +
 +  if (app->screen_reader.pid > 0 && pid == app->screen_reader.pid)
 +    {
 +      LOGE("screen reader is dead, pid: %d, restarting", pid);
 +      app->screen_reader.pid = 0;
 +      g_timeout_add_seconds (2, _launch_process_repeat_until_success, &app->screen_reader);
 +    }
 +
 +  if (app->universal_switch.pid > 0 && pid == app->universal_switch.pid)
 +    {
 +      LOGE("universal switch is dead, pid: %d, restarting", pid);
 +      app->universal_switch.pid = 0;
 +      g_timeout_add_seconds (2, _launch_process_repeat_until_success, &app->universal_switch);
 +    }
 +  return 0;
 +}
 +
 +static void
 +_register_process_dead_tracker ()
 +{
 +      if(_global_app->screen_reader.pid > 0 || _global_app->universal_switch.pid > 0) {
 +              LOGD("registering process dead tracker");
 +              aul_listen_app_dead_signal(_process_dead_tracker, _global_app);
 +      } else {
 +              LOGD("unregistering process dead tracker");
 +              aul_listen_app_dead_signal(NULL, NULL);
 +      }
 +}
 +
 +
 +static gboolean
 +_launch_client(A11yBusClient *client, gboolean by_vconf_change)
 +{
 +   LOGD("Launching %s", client->name);
 +
 +   bundle *kb = NULL;
 +   gboolean ret = FALSE;
 +
 +   kb = bundle_create();
 +
 +   if (kb == NULL)
 +     {
 +        LOGD("Can't create bundle");
 +        return FALSE;
 +     }
 +
 +   if (by_vconf_change)
 +     {
 +        if (bundle_add_str(kb, "by_vconf_change", "yes") != BUNDLE_ERROR_NONE)
 +          {
 +             LOGD("Can't add information to bundle");
 +          }
 +     }
 +
 +   int operation_error = appsvc_set_operation(kb, client->app_control_operation);
 +   LOGD("appsvc_set_operation: %i", operation_error);
 +
 +   client->pid = appsvc_run_service(kb, 0, NULL, NULL);
 +
 +   if (client->pid > 0)
 +     {
 +        LOGD("Process launched with pid: %i", client->pid);
 +        _register_process_dead_tracker();
 +        ret = TRUE;
 +     }
 +   else
 +     {
 +        LOGD("Can't start %s - error code: %i", client->name, client->pid);
 +     }
 +
 +   bundle_free(kb);
 +   return ret;
 +}
 +
 +static gboolean
 +_launch_process_repeat_until_success(gpointer user_data) {
 +    A11yBusClient *client = user_data;
 +
 +    if (client->launch_repeats > 100 || client->pid > 0)
 +      {
 +         //do not try anymore
 +         return FALSE;
 +      }
 +
 +    gboolean ret = _launch_client(client, FALSE);
 +
 +    if (ret)
 +      {
 +         //we managed to
 +         client->launch_repeats = 0;
 +         return FALSE;
 +      }
 +    client->launch_repeats++;
 +    //try again
 +    return TRUE;
 +}
 +
 +static gboolean
 +_terminate_process(int pid)
 +{
 +   int ret;
 +   int ret_aul;
 +   if (pid <= 0)
 +     return FALSE;
 +
 +   int status = aul_app_get_status_bypid(pid);
 +
 +   if (status < 0)
 +     {
 +       LOGD("App with pid %d already terminated", pid);
 +       return TRUE;
 +     }
 +
 +   LOGD("terminate process with pid %d", pid);
 +   ret_aul = aul_terminate_pid(pid);
 +   if (ret_aul >= 0)
 +     {
 +        LOGD("Terminating with aul_terminate_pid: return is %d", ret_aul);
 +        return TRUE;
 +     }
 +   else
 +     LOGD("aul_terminate_pid failed: return is %d", ret_aul);
 +
 +   LOGD("Unable to terminate process using aul api. Sending SIGTERM signal");
 +   ret = kill(pid, SIGTERM);
 +   if (!ret)
 +     {
 +        return TRUE;
 +     }
 +
 +   LOGD("Unable to terminate process: %d with api or signal.", pid);
 +   return FALSE;
 +}
 +
 +static gboolean
 +_terminate_client(A11yBusClient *client)
 +{
 +   LOGD("Terminating %s", client->name);
 +   int pid = client->pid;
 +   client->pid = 0;
 +   _register_process_dead_tracker();
 +   gboolean ret = _terminate_process(pid);
 +   return ret;
 +}
 +
 +void vconf_client_cb(keynode_t *node, void *user_data)
 +{
 +   A11yBusClient *client = user_data;
 +
 +   gboolean client_needed = FALSE;
 +   int i;
 +   for (i = 0; i < client->number_of_keys; i++) {
 +      int status = 0;
 +      int ret =vconf_get_bool(client->vconf_key[i], &status);
 +      if (ret != 0)
 +      {
 +        LOGD("Could not read %s key value.\n", client->vconf_key[i]);
 +        return;
 +      }
 +      LOGD("vconf_keynode_get_bool(node): %i", status);
 +      if (status < 0)
 +        return;
 +
 +      if (status == 1) {
 +        client_needed = TRUE;
 +        break;
 +      }
 +   }
 +
 +   //check if process really exists (e.g didn't crash)
 +   if (client->pid > 0)
 +     {
 +        int err = kill(client->pid,0);
 +        //process doesn't exist
 +        if (err == ESRCH)
 +          client->pid = 0;
 +     }
 +
 +   LOGD("client_needed: %i, client->pid: %i", client_needed, client->pid);
 +   if (!client_needed && (client->pid > 0))
 +         _terminate_client(client);
 +   else if (client_needed && (client->pid <= 0))
 +     _launch_client(client, TRUE);
 +}
 +
 +
 +static gboolean register_executable(A11yBusClient *client)
 +{
 +  gboolean client_needed = FALSE;
 +
 +  int i;
 +  for (i = 0; i < client->number_of_keys; i++) {
 +    if (!client->vconf_key[i]) {
 +      LOGE("Vconf_key missing for client: %d \n", i);
 +      return FALSE;
 +    }
 +
 +    int status = 0;
 +    int ret = vconf_get_bool(client->vconf_key[i], &status);
 +    if (ret != 0)
 +    {
 +      LOGD("Could not read %s key value.\n", client->vconf_key[i]);
 +      return FALSE;
 +    }
 +    ret = vconf_notify_key_changed(client->vconf_key[i], vconf_client_cb, client);
 +    if (ret != 0)
 +    {
 +      LOGD("Could not add information level callback\n");
 +      return FALSE;
 +    }
 +    if (status)
 +      client_needed = TRUE;
 +  }
 +
 +  if (client_needed)
 +  g_timeout_add_seconds(2,_launch_process_repeat_until_success, client);
 +  return TRUE;
 +}
 +
  int
  main (int    argc,
        char **argv)
  {
 +#ifdef ATSPI_BUS_LAUNCHER_LOG_TO_FILE
 +  log_file = fopen("/tmp/at-spi-bus-launcher.log", "a");
 +#endif
 +
 +  LOGD("Starting atspi bus launcher");
 +
    gboolean a11y_set = FALSE;
    gboolean screen_reader_set = FALSE;
    gint i;
  
-   if (already_running ())
-     {
-        LOGD("atspi bus launcher is already running");
-        return 0;
-     }
    _global_app = g_slice_new0 (A11yBusLauncher);
    _global_app->loop = g_main_loop_new (NULL, FALSE);
 +  _global_app->client_watcher_id = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
 +
 +  _global_app->screen_reader.name = "screen-reader";
 +  _global_app->screen_reader.app_control_operation = APP_CONTROL_OPERATION_SCREEN_READ;
 +  _global_app->screen_reader.vconf_key[0] = VCONFKEY_SETAPPL_ACCESSIBILITY_TTS;
 +  _global_app->screen_reader.number_of_keys = 1;
 +
 +  _global_app->universal_switch.name = "universal-switch";
 +  _global_app->universal_switch.app_control_operation = APP_CONTROL_OPERATION_UNIVERSAL_SWITCH;
 +  _global_app->universal_switch.vconf_key[0] = VCONFKEY_SETAPPL_ACCESSIBILITY_UNIVERSAL_SWITCH_CONFIGURATION_SERVICE;
 +  _global_app->universal_switch.vconf_key[1] = VCONFKEY_SETAPPL_ACCESSIBILITY_UNIVERSAL_SWITCH_INTERACTION_SERVICE;
 +  _global_app->universal_switch.number_of_keys = 2;
  
    for (i = 1; i < argc; i++)
      {
    introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
    g_assert (introspection_data != NULL);
  
 -  _global_app->name_owner_id =
 -    g_bus_own_name (G_BUS_TYPE_SESSION,
 -                    "org.a11y.Bus",
 -                    G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
 -                    on_bus_acquired,
 -                    on_name_acquired,
 -                    on_name_lost,
 -                    _global_app,
 -                    NULL);
 +  g_bus_own_name (G_BUS_TYPE_SESSION,
 +                                  "org.a11y.Bus",
 +                                  G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT,
 +                                  on_bus_acquired,
 +                                  on_name_acquired,
 +                                  on_name_lost,
 +                                  _global_app,
 +                                  NULL);
 +
 +  register_executable (&_global_app->screen_reader);
 +  register_executable (&_global_app->universal_switch);
  
    g_main_loop_run (_global_app->loop);
  
    if (_global_app->a11y_bus_pid > 0)
      kill (_global_app->a11y_bus_pid, SIGTERM);
  
 -  /* Clear the X property if our bus is gone; in the case where e.g. 
 +  /* Clear the X property if our bus is gone; in the case where e.g.
     * GDM is launching a login on an X server it was using before,
     * we don't want early login processes to pick up the stale address.
     */
  #ifdef HAVE_X11
-   {
-     Display *display = XOpenDisplay (NULL);
-     if (display)
-       {
-         Atom bus_address_atom = XInternAtom (display, "AT_SPI_BUS", False);
-         XDeleteProperty (display,
-                          XDefaultRootWindow (display),
-                          bus_address_atom);
+   if (_global_app->x11_prop_set)
+     {
+       Display *display = XOpenDisplay (NULL);
+       if (display)
+         {
+           Atom bus_address_atom = XInternAtom (display, "AT_SPI_BUS", False);
+           XDeleteProperty (display,
+                            XDefaultRootWindow (display),
+                            bus_address_atom);
  
-         XFlush (display);
-         XCloseDisplay (display);
-       }
-   }
+           XFlush (display);
+           XCloseDisplay (display);
+         }
+     }
  #endif
  
    if (_global_app->a11y_launch_error_message)
diff --combined bus/meson.build
@@@ -34,7 -34,6 +34,7 @@@ configure_file(input: 'at-spi-dbus-bus.
  launcher_args = [
               '-DSYSCONFDIR="@0@"'.format(atspi_sysconfdir),
               '-DDATADIR="@0@"'.format(atspi_datadir),
 +             '-fPIE'
             ]
  
  if get_option('dbus_daemon') != 'default'
@@@ -45,6 -44,7 +45,7 @@@ els
                               '/usr/sbin/dbus-daemon',
                               '/libexec/dbus-daemon',
                               '/usr/libexec/dbus-daemon',
+                              '/usr/lib/dbus-daemon',
                               '/usr/pkg/bin/dbus-daemon',
                               required: false)
    if dbus_daemon.found()
@@@ -68,8 -68,7 +69,8 @@@ endi
  
  executable('at-spi-bus-launcher', 'at-spi-bus-launcher.c',
             include_directories: [ root_inc, include_directories('.') ],
 -           dependencies: [ gio_dep, x11_deps ],
 +           dependencies: [ gio_dep, x11_deps, app_svc_dep ],
             c_args: launcher_args,
 +           link_args: '-pie',
             install: true,
             install_dir: atspi_libexecdir)
diff --combined meson.build
@@@ -1,12 -1,12 +1,12 @@@
  project('at-spi2-core', 'c',
-         version: '2.31.1',
+         version: '2.34.0',
          license: 'LGPLv2.1+',
          default_options: [
            'buildtype=debugoptimized',
            'warning_level=1',
            'c_std=c99',
          ],
-         meson_version: '>= 0.40.1')
+         meson_version: '>= 0.50.0')
  
  add_project_arguments([ '-D_POSIX_C_SOURCE=200809L', '-D_DEFAULT_SOURCE' ], language: 'c')
  
@@@ -28,7 -28,6 +28,7 @@@ atspi_datadir = join_paths(atspi_prefix
  atspi_libexecdir = join_paths(atspi_prefix, get_option('libexecdir'))
  atspi_sysconfdir = join_paths(atspi_prefix, get_option('sysconfdir'))
  atspi_libdir = join_paths(atspi_prefix, get_option('libdir'))
 +atspi_bindir = join_paths(atspi_prefix, get_option('bindir'))
  atspi_includedir = join_paths(atspi_prefix, get_option('includedir'))
  
  if get_option('dbus_services_dir') != 'default'
@@@ -48,17 -47,21 +48,23 @@@ libdbus_req_version = '>= 1.5
  glib_req_version = '>= 2.32.0'
  gobject_req_version = '>= 2.0.0'
  gio_req_version = '>= 2.28.0'
 +app_svc_req_version = '>= 0.0.0'
  
  libdbus_dep = dependency('dbus-1', version: libdbus_req_version)
  glib_dep = dependency('glib-2.0', version: glib_req_version)
  gobject_dep = dependency('gobject-2.0', version: gobject_req_version)
  gio_dep = dependency('gio-2.0', version: gio_req_version)
- dl_dep = cc.find_library('dl', required: false)
 +app_svc_dep = dependency('appsvc', version: app_svc_req_version)
+ if cc.has_function('dlopen')
+   dl_dep = []
+ elif cc.has_function('dlopen', args: '-ldl')
+   dl_dep = cc.find_library('dl')
+ else
+   error('Could not find a library with the dlopen function')
+ endif
  
  x11_deps = []
- x11_option = get_option('enable-x11')
+ x11_option = get_option('x11')
  if x11_option != 'no'
    x11_dep = dependency('x11', required: false)
  
@@@ -99,7 -102,7 +105,7 @@@ at_spi_conf.set('ALIGNOF_DBIND_STRUCT'
  # introspection support
  have_gir = false
  
- introspection_option = get_option('enable-introspection')
+ introspection_option = get_option('introspection')
  if introspection_option != 'no'
    gir_dep = dependency('gobject-introspection-1.0', version: '>= 0.6.7', required: false)
  
@@@ -120,7 -123,7 +126,7 @@@ subdir('bus'
  subdir('registryd')
  subdir('test')
  
- if get_option('enable_docs')
+ if get_option('docs')
    subdir('doc/libatspi')
  endif
  
index c2db81e,0000000..6316fb2
mode 100644,000000..100644
--- /dev/null
@@@ -1,129 -1,0 +1,129 @@@
- Version: 2.31.1
 +%bcond_with x
 +
 +Name: at-spi2-core
++Version: 2.34.0
 +Release: 0
 +Summary: Assistive Technology Service Provider Interface - D-Bus based implementation
 +License: LGPL-2.0+
 +Group: System/Libraries
 +Url: http://www.gnome.org/
 +Source: http://ftp.gnome.org/pub/GNOME/sources/at-spi2-core/2.31/%{name}-%{version}.tar.xz
 +Source1001:    %{name}.manifest
 +Requires:      dbus
 +BuildRequires: python-devel
 +BuildRequires: python-xml
 +BuildRequires: intltool
 +BuildRequires: dbus-devel
 +BuildRequires: glib2-devel
 +BuildRequires: gettext
 +BuildRequires: gtk-doc
 +%if %{with x}
 +BuildRequires: libX11-devel
 +BuildRequires: libXtst-devel
 +BuildRequires: libXi-devel
 +%endif
 +BuildRequires: pkgconfig(vconf)
 +BuildRequires: pkgconfig(appsvc)
 +BuildRequires: pkgconfig(dlog)
 +BuildRequires: pkgconfig(aul)
 +BuildRequires: gobject-introspection
 +BuildRequires: meson
 +BuildRequires: app-svc-devel
 +
 +%description
 +AT-SPI is a general interface for applications to make use of the
 +accessibility toolkit. This version is based on dbus.
 +
 +This package contains the AT-SPI registry daemon. It provides a
 +mechanism for all assistive technologies to discover and interact
 +with applications running on the desktop.
 +
 +%package -n libatspi0
 +Summary: An Accessibility ToolKit -- Library
 +Group: System/Libraries
 +
 +%description -n libatspi0
 +AT-SPI is a general interface for applications to make use of the
 +accessibility toolkit. This version is based on dbus.
 +
 +%package -n typelib-1_0-Atspi-2_0
 +Summary: An Accessibility ToolKit -- Introspection bindings
 +Group: System/Libraries
 +
 +%description -n typelib-1_0-Atspi-2_0
 +AT-SPI is a general interface for applications to make use of the
 +accessibility toolkit. This version is based on dbus.
 +
 +This package provides the GObject Introspection bindings for the
 +libatspi library.
 +
 +%package devel
 +Summary: Include Files and Libraries mandatory for Development
 +Group: Development/Libraries
 +Requires: %{name} = %{version}
 +Requires: libatspi0 = %{version}
 +Requires: typelib-1_0-Atspi-2_0 = %{version}
 +
 +%description devel
 +This package contains all necessary include files and libraries needed
 +to develop applications that require these.
 +
 +%prep
 +%setup -q
 +cp %{SOURCE1001} .
 +
 +%build
 +meson --prefix /usr --libdir %{_libdir} build -Dwith-dbus-daemondir=%{_bindir} -Ddbus_daemon=/usr/bin/dbus-daemon \
 +%if !%{with x}
 +        -Denable-x11=no \
 +%else
 +        -Denable-x11=yes \
 +%endif
 +        -Denable-static=no
 +
 +ninja -C build all
 +
 +%install
 +find %{buildroot} -name '*.la' -or -name '*.a' | xargs rm -f
 +
 +export DESTDIR=%{buildroot}
 +ninja -C build install
 +
 +%find_lang %{name}
 +
 +%clean
 +rm -fr %{buildroot}
 +
 +%post -n libatspi0 -p /sbin/ldconfig
 +
 +%postun -n libatspi0 -p /sbin/ldconfig
 +
 +%files -f %{name}.lang
 +%manifest %{name}.manifest
 +%defattr(-,root,root)
 +%{_bindir}/at_spi2_tool
 +
 +%doc AUTHORS README
 +%license COPYING
 +%{_libexecdir}/at-spi-bus-launcher
 +%{_libexecdir}/at-spi2-registryd
 +%{_datadir}/defaults/at-spi2/accessibility.conf
 +%{_sysconfdir}/xdg/autostart/at-spi-dbus-bus.desktop
 +%{_datadir}/dbus-1/accessibility-services/org.a11y.atspi.Registry.service
 +%{_datadir}/dbus-1/services/org.a11y.Bus.service
 +%{_prefix}/lib/systemd/user/at-spi-dbus-bus.service
 +%files -n libatspi0
 +%manifest %{name}.manifest
 +%defattr(-, root, root)
 +%{_libdir}/libatspi.so.0*
 +
 +%files -n typelib-1_0-Atspi-2_0
 +%manifest %{name}.manifest
 +%defattr(-, root, root)
 +
 +%files devel
 +%manifest %{name}.manifest
 +%defattr(-, root, root)
 +%{_includedir}/at-spi-2.0
 +%{_libdir}/libatspi.so
 +%{_libdir}/pkgconfig/atspi-2.pc
@@@ -6,19 -6,19 +6,19 @@@
   * 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
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  /* deviceeventcontroller.c: implement the DeviceEventController interface */
@@@ -927,7 -927,6 +927,7 @@@ send_and_allow_reentry (DBusConnection 
        {
          const char *dest = dbus_message_get_destination (message);
          GSList *l;
 +        dbus_bool_t result;
          gchar *bus_name_dup;
          dbus_message_ref (message);
          dbus_pending_call_set_notify (pending, reset_hung_process, message,
                                                  "Ping");
          if (!message)
            return NULL;
 -        dbus_connection_send_with_reply (bus, message, &pending, -1);
 +        result = dbus_connection_send_with_reply (bus, message, &pending, -1);
          dbus_message_unref (message);
 -        if (!pending)
 +        if (!result || !pending)
            return NULL;
          bus_name_dup = g_strdup (dest);
          dbus_pending_call_set_notify (pending, reset_hung_process_from_ping,
@@@ -1366,7 -1365,6 +1366,7 @@@ impl_register_keystroke_listener (DBusC
      Accessibility_KeyDefinition *kd = (Accessibility_KeyDefinition *)g_malloc(sizeof(Accessibility_KeyDefinition));
      if (!spi_dbus_message_iter_get_struct(&iter_array, DBUS_TYPE_INT32, &kd->keycode, DBUS_TYPE_INT32, &kd->keysym, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_INVALID))
      {
 +      g_free (kd);
        break;
      }
      kd->keystring = g_strdup (keystring);
@@@ -1577,7 -1575,6 +1577,7 @@@ impl_deregister_keystroke_listener (DBu
  
      if (!spi_dbus_message_iter_get_struct(&iter_array, DBUS_TYPE_INT32, &kd->keycode, DBUS_TYPE_INT32, &kd->keysym, DBUS_TYPE_STRING, &keystring, DBUS_TYPE_INVALID))
      {
 +      g_free(kd);
        break;
      }
      kd->keystring = g_strdup (keystring);
@@@ -1859,7 -1856,7 +1859,7 @@@ spi_device_event_controller_class_init 
    object_class->finalize = spi_device_event_controller_object_finalize;
  
  #ifdef HAVE_X11
-   if (g_getenv ("DISPLAY"))
+   if (g_getenv ("DISPLAY") != NULL && g_getenv ("WAYLAND_DISPLAY") == NULL)
      spi_dec_setup_x11 (klass);
    else
  #endif
diff --combined registryd/meson.build
@@@ -16,7 -16,7 +16,7 @@@ registryd_deps = 
    dl_dep,
  ]
  
- x11_option = get_option('enable-x11')
+ x11_option = get_option('x11')
  if x11_option != 'no'
    if x11_dep.found()
      registryd_sources += [
@@@ -32,8 -32,6 +32,8 @@@ endi
  
  executable('at-spi2-registryd', registryd_sources,
             dependencies: registryd_deps,
 +           c_args: '-fPIE',
 +           link_args: '-pie',
             install: true,
             install_dir: atspi_libexecdir)
  
diff --combined registryd/registry.c
@@@ -7,19 -7,19 +7,19 @@@
   * 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
+  * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
-  * version 2 of the License, or (at your option) any later version.
+  * version 2.1 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.
+  * Lesser General Public License for more details.
   *
-  * You should have received a copy of the GNU Library General Public
+  * You should have received a copy of the GNU Lesser 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.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
  
  #include <config.h>
@@@ -542,30 -542,6 +542,30 @@@ impl_GrabFocus (DBusConnection * bus, D
  }
  
  static DBusMessage *
 +impl_ClearHighlight (DBusConnection * bus, DBusMessage * message, void *user_data)
 +{
 +  DBusMessage *reply;
 +  dbus_bool_t retval = FALSE;
 +
 +  reply = dbus_message_new_method_return (message);
 +  dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &retval,
 +                            DBUS_TYPE_INVALID);
 +  return reply;
 +}
 +
 +static DBusMessage *
 +impl_GrabHighlight (DBusConnection * bus, DBusMessage * message, void *user_data)
 +{
 +  DBusMessage *reply;
 +  dbus_bool_t retval = FALSE;
 +
 +  reply = dbus_message_new_method_return (message);
 +  dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &retval,
 +                            DBUS_TYPE_INVALID);
 +  return reply;
 +}
 +
 +static DBusMessage *
  impl_GetAlpha (DBusConnection * bus, DBusMessage * message, void *user_data)
  {
    double rv = 1.0;
@@@ -1272,10 -1248,6 +1272,10 @@@ handle_method_root (DBusConnection *bus
            reply = impl_GetMDIZOrder (bus, message, user_data);
        else if (!strcmp (member, "GrabFocus"))
            reply = impl_GrabFocus (bus, message, user_data);
 +      else if (!strcmp (member, "GrabHighlight"))
 +          reply = impl_GrabHighlight (bus, message, user_data);
 +      else if (!strcmp (member, "ClearHighlight"))
 +          reply = impl_ClearHighlight (bus, message, user_data);
        else if (!strcmp (member, "GetAlpha"))
            reply = impl_GetAlpha (bus, message, user_data);
        else