accessibility: Added mechanism for handling the reading stopped/cancelled events... 88/72988/8
authorLukasz Oleksak <l.oleksak@samsung.com>
Fri, 3 Jun 2016 10:51:45 +0000 (12:51 +0200)
committerTomasz Iwanek <t.iwanek@samsung.com>
Thu, 4 Aug 2016 11:19:22 +0000 (13:19 +0200)
* fixes from review
* support for smart callbacks added for backward compatibility

Change-Id: I30cee98112079b3d557439e8e44281be647a4662

src/lib/elm_atspi_bridge.c
src/lib/elm_atspi_bridge.h
src/lib/elm_interface_atspi_widget_action.c
src/lib/elm_interface_atspi_widget_action.eo
src/lib/elm_object_item.h
src/lib/elm_widget.c
src/lib/elm_widget.eo
src/lib/elm_widget_item.eo

index b4141c4..0d301e8 100644 (file)
 #define ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE ELM_ACCESS_OBJECT_PATH_PREFIX "%llu"
 
 #define ELM_ATSPI_DBUS_INTERFACE_PROXY "elm.atspi.bridge.proxy.Socket"
-
+//TIZEN_ONLY(20160527) - Add direct reading feature
+#define ELM_ATSPI_DIRECT_READ_BUS "org.tizen.ScreenReader"
+#define ELM_ATSPI_DIRECT_READ_PATH "/org/tizen/DirectReading"
+#define ELM_ATSPI_DIRECT_READ_INTERFACE "org.tizen.DirectReading"
+struct _Elm_Atspi_Say_Info
+{
+   void                    *data;
+   Elm_Atspi_Say_Signal_Cb  func; //this function will be called when state of related reading is changed
+};
+typedef struct _Elm_Atspi_Say_Info Elm_Atspi_Say_Info;
+static Eina_Hash *read_command_id = NULL;
+//
 #define SIZE(x) sizeof(x)/sizeof(x[0])
 #define ELM_ATSPI_BRIDGE_CLASS_NAME "__Elm_Atspi_Bridge"
 
@@ -74,6 +85,9 @@ typedef struct _Elm_Atspi_Bridge_Data
    Eldbus_Service_Interface *cache_interface;
    Eldbus_Signal_Handler *register_hdl;
    Eldbus_Signal_Handler *unregister_hdl;
+//TIZEN_ONLY(20160614):apply callbacks on direct reading stop/cancel/skipp
+   Eldbus_Signal_Handler *reading_state_changed_hdl;
+//
    unsigned long object_broadcast_mask;
    unsigned long object_property_broadcast_mask;
    unsigned long object_children_broadcast_mask;
@@ -4304,6 +4318,30 @@ _text_selection_changed_send(void *data, Eo *obj, const Eo_Event_Description *de
    return EINA_TRUE;
 }
 
+//TIZEN_ONLY(20160527) - Add direct reading feature
+static void
+_on_reading_state_changed(void *data EINA_UNUSED, const Eldbus_Message *msg)
+{
+   const int32_t i;
+   const char *say_signal_name = "";
+   Elm_Atspi_Say_Info *say_info;
+
+   if (eldbus_message_arguments_get(msg, "is", &i, &say_signal_name))
+     {  if (read_command_id)
+          {
+             say_info = eina_hash_find(read_command_id, &i);
+             if (say_info)
+               {
+                  if (say_info->func && say_signal_name)
+                     say_info->func(say_info->data, say_signal_name);
+                  eina_hash_del(read_command_id, &i, NULL);
+                  free(say_info);
+               }
+          }
+     }
+}
+//
+
 static void
 _event_handlers_register(Eo *bridge)
 {
@@ -4314,7 +4352,9 @@ _event_handlers_register(Eo *bridge)
    // register signal handlers in order to update list of registered listeners of ATSPI-Clients
    pd->register_hdl = eldbus_signal_handler_add(pd->a11y_bus, ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "EventListenerRegistered", _handle_listener_change, bridge);
    pd->unregister_hdl = eldbus_signal_handler_add(pd->a11y_bus, ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "EventListenerDeregistered", _handle_listener_change, bridge);
-
+   //TIZEN_ONLY(20160527) - Add direct reading feature
+   pd->reading_state_changed_hdl = eldbus_signal_handler_add(pd->a11y_bus, ELM_ATSPI_DIRECT_READ_BUS, ELM_ATSPI_DIRECT_READ_PATH, ELM_ATSPI_DIRECT_READ_INTERFACE, "ReadingStateChanged", _on_reading_state_changed, bridge);
+   //
    pd->key_flr = ecore_event_filter_add(NULL, _elm_atspi_bridge_key_filter, NULL, bridge);
 }
 
@@ -4440,6 +4480,11 @@ _a11y_connection_shutdown(Eo *bridge)
    if (pd->unregister_hdl) eldbus_signal_handler_del(pd->unregister_hdl);
    pd->unregister_hdl = NULL;
 
+   //TIZEN_ONLY(20160527) - Add direct reading feature
+   if (pd->reading_state_changed_hdl) eldbus_signal_handler_del(pd->reading_state_changed_hdl);
+   pd->reading_state_changed_hdl = NULL;
+   //
+
    EINA_LIST_FREE(pd->pending_requests, pending)
       eldbus_pending_cancel(pending);
    pd->pending_requests = NULL;
@@ -5251,4 +5296,75 @@ EAPI void elm_atspi_bridge_utils_proxy_listen(Eo *proxy)
      }
    _socket_ifc_create(pd->a11y_bus, proxy);
 }
+
+//TIZEN_ONLY(20160527) - Add direct reading feature
+static void
+_on_read_command_call(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EINA_UNUSED)
+{
+   const char *errname, *errmsg;
+   const char *s;
+   const Eina_Bool b;
+   const int32_t i;
+   Elm_Atspi_Say_Info *say_info = data;
+
+   if (eldbus_message_error_get(msg, &errname, &errmsg))
+     {
+        ERR("%s %s", errname, errmsg);
+        return;
+     }
+
+   if (say_info)
+     {
+        // get read command id and map it to obj
+        if (eldbus_message_arguments_get(msg, "sbi", &s, &b, &i))
+          {
+             if (!read_command_id)
+               read_command_id = eina_hash_int32_new(NULL);
+
+             if (!read_command_id) {
+               ERR("eina_hash_int32_new() failed to create new map to store callbacks for direct reading commands");
+               return;
+             }
+
+             eina_hash_add(read_command_id, &i, say_info);
+          }
+     }
+}
+
+EAPI void
+elm_atspi_bridge_utils_say(const char* text,
+                           Eina_Bool discardable,
+                           const Elm_Atspi_Say_Signal_Cb func,
+                           const void *data)
+{
+   Eldbus_Message *msg;
+   Eldbus_Message_Iter *iter;
+   Elm_Atspi_Say_Info *say_info = NULL;
+   Eo *bridge = _elm_atspi_bridge_get();
+   if (!bridge)
+     {
+        ERR("AT-SPI: Atspi bridge is not enabled.");
+        return;
+     }
+   ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+   if (!pd->a11y_bus)
+     {
+        ERR("AT-SPI: a11y bus is not set.");
+        return;
+     }
+
+   msg = eldbus_message_method_call_new(ELM_ATSPI_DIRECT_READ_BUS,
+                                        ELM_ATSPI_DIRECT_READ_PATH,
+                                        ELM_ATSPI_DIRECT_READ_INTERFACE,
+                                        "ReadCommand");
+   iter = eldbus_message_iter_get(msg);
+   eldbus_message_iter_arguments_append(iter, "sb", text, discardable);
+   if (func) {
+      say_info = calloc(1, sizeof(Elm_Atspi_Say_Info));
+      say_info->func = func;
+      say_info->data = (void *)data;
+   }
+   eldbus_connection_send(pd->a11y_bus, msg, _on_read_command_call, say_info, -1);
+}
+//
 #include "elm_atspi_bridge.eo.c"
index 8827096..d04f994 100644 (file)
@@ -1,6 +1,13 @@
 #ifdef EFL_BETA_API_SUPPORT
 #ifdef EFL_EO_API_SUPPORT
 #include "elm_atspi_bridge.eo.h"
+//TIZEN_ONLY(20160527) - Add direct reading feature
+typedef void (*Elm_Atspi_Say_Signal_Cb)(void *data, const char *say_signal);
+EAPI void elm_atspi_bridge_utils_say(const char* text,
+                                     Eina_Bool discardable,
+                                     const Elm_Atspi_Say_Signal_Cb func,
+                                     const void *data);
+//
 #endif
 #ifndef EFL_NOLEGACY_API_SUPPORT
 #include "elm_atspi_bridge.eo.legacy.h"
index 1cc2b58..c0ebdc2 100644 (file)
 
 extern Eina_Hash *_elm_key_bindings;
 
+//TIZEN_ONLY(20160524):apply callbacks on direct reading stop/cancel
+
+EOLIAN static Eina_List*
+_elm_interface_atspi_widget_action_elm_interface_atspi_action_actions_get(Eo *obj, void *pd EINA_UNUSED);
+
+EOLIAN static const char *
+_elm_interface_atspi_widget_action_elm_interface_atspi_action_name_get(Eo *obj, void *pd EINA_UNUSED, int id);
+
+/* support for smart callbacks added for backward compatibility */
+static const char SIG_READ_STOP[] = "access,read,stop";
+static const char SIG_READ_CANCEL[] = "access,read,cancel";
+static const char SIG_READ_SKIP[] = "access,read,skip";
+
+static const char *
+_read_signal_get(const char *action_name)
+{
+   if (!strcmp("ReadingStopped", action_name))
+     {
+        return SIG_READ_STOP;
+     }
+   if (!strcmp("ReadingCancelled", action_name))
+     {
+        return SIG_READ_CANCEL;
+     }
+   if (!strcmp("ReadingSkipped", action_name))
+     {
+        return SIG_READ_SKIP;
+     }
+   return NULL;
+}
+//
+
 EOLIAN static Eina_Bool
 _elm_interface_atspi_widget_action_elm_interface_atspi_action_action_do(Eo *obj, void *pd EINA_UNUSED, int id)
 {
@@ -19,6 +51,8 @@ _elm_interface_atspi_widget_action_elm_interface_atspi_action_action_do(Eo *obj,
    Eina_Bool (*func)(Eo *eo, const char *params) = NULL;
    int tmp = 0;
 
+   //TIZEN_ONLY(20160524):apply callbacks on direct reading stop/cancel
+   /*
    eo_do(obj, actions = elm_interface_atspi_widget_action_elm_actions_get());
    if (!actions) return EINA_FALSE;
 
@@ -32,7 +66,46 @@ _elm_interface_atspi_widget_action_elm_interface_atspi_action_action_do(Eo *obj,
           }
         tmp++;
      }
+   */
+   if (!obj || id < 0)
+      return EINA_FALSE;
+
+   char *action_name = _elm_interface_atspi_widget_action_elm_interface_atspi_action_name_get(obj, NULL, id);
 
+   if (!strcmp("ReadingStopped", action_name) || !strcmp("ReadingCancelled", action_name) || !strcmp("ReadingSkipped", action_name))
+     {
+        Eina_Bool ret;
+        eo_do(obj, ret = eo_event_callback_call(ELM_INTERFACE_ATSPI_WIDGET_ACTION_EVENT_READING_STATE_CHANGED, action_name));
+        /* support for smart callbacks added for backward compatibility */
+        if (eo_isa(obj,EVAS_OBJECT_CLASS))
+          {
+              evas_object_smart_callback_call(obj, _read_signal_get(action_name), NULL);
+          }
+        else if (eo_isa(obj,ELM_WIDGET_ITEM_CLASS))
+          {
+             Evas_Object *parent = elm_object_item_widget_get(obj);
+             evas_object_smart_callback_call(parent, _read_signal_get(action_name), obj);
+          }
+        return ret;
+     }
+   else
+     {
+        eo_do(obj, actions = elm_interface_atspi_widget_action_elm_actions_get());
+
+        if (!actions) return EINA_FALSE;
+
+        while (actions[tmp].name)
+          {
+             if (tmp == id)
+               {
+                  func = actions[tmp].func;
+                  param = actions[tmp].param;
+                  break;
+               }
+             tmp++;
+         }
+     }
+   //
    if (!func)
      return EINA_FALSE;
 
@@ -95,6 +168,8 @@ _elm_interface_atspi_widget_action_elm_interface_atspi_action_keybinding_get(Eo
 EOLIAN static const char *
 _elm_interface_atspi_widget_action_elm_interface_atspi_action_name_get(Eo *obj, void *pd EINA_UNUSED, int id)
 {
+   //TIZEN_ONLY(20160524):apply callbacks on direct reading stop/cancel
+   /*
    const Elm_Atspi_Action *actions = NULL;
    int tmp = 0;
 
@@ -107,6 +182,14 @@ _elm_interface_atspi_widget_action_elm_interface_atspi_action_name_get(Eo *obj,
         tmp++;
      }
    return NULL;
+   */
+
+   if (!obj || id < 0)
+      return NULL;
+
+   Eina_List *action_names = _elm_interface_atspi_widget_action_elm_interface_atspi_action_actions_get(obj, NULL);
+   return eina_list_nth(action_names, id);
+   //
 }
 
 EOLIAN static Eina_Bool
@@ -125,10 +208,16 @@ EOLIAN static Eina_List*
 _elm_interface_atspi_widget_action_elm_interface_atspi_action_actions_get(Eo *obj, void *pd EINA_UNUSED)
 {
    const Elm_Atspi_Action *actions = NULL;
-   Eina_List *ret = NULL;
-   int tmp = 0;
+   Eina_List *action_names = NULL;
+   int index = 0;
+
+   if (!obj)
+     return NULL;
 
    eo_do(obj, actions = elm_interface_atspi_widget_action_elm_actions_get());
+
+   //TIZEN_ONLY(20160524):apply callbacks on direct reading stop/cancel/skipp
+   /*
    if (!actions) return NULL;
 
    while (actions[tmp].name)
@@ -136,8 +225,19 @@ _elm_interface_atspi_widget_action_elm_interface_atspi_action_actions_get(Eo *ob
         ret = eina_list_append(ret, actions[tmp].name);
         tmp++;
      }
+   */
+   while (actions && actions[index].name)
+     {
+        action_names = eina_list_append(action_names, actions[index].name);
+        index++;
+     }
+
+   action_names = eina_list_append(action_names, "ReadingStopped");
+   action_names = eina_list_append(action_names, "ReadingCancelled");
+   action_names = eina_list_append(action_names, "ReadingSkipped");
+   //
 
-   return ret;
+   return action_names;
 }
 
 #include "elm_interface_atspi_widget_action.eo.c"
index 8f2b365..c2f5c7c 100644 (file)
@@ -21,4 +21,9 @@ mixin Elm_Interface_Atspi_Widget_Action (Elm_Interface_Atspi_Action)
       Elm_Interface_Atspi_Action.actions.get;
       @virtual .elm_actions.get;
    }
+   //TIZEN_ONLY(20160614): add callbacks for reading state changed events: cancel/stop/skip
+   events {
+      reading,state,changed;
+   }
+   //
 }
index db19862..45ad485 100644 (file)
@@ -19,7 +19,7 @@ typedef Eo Elm_Object_Item;
  *
  * @ingroup General
  */
-typedef void                  (*Elm_Object_Item_Signal_Cb)(void *data, Elm_Object_Item *it, const char *emission, const char *source);
+typedef void (*Elm_Object_Item_Signal_Cb)(void *data, Elm_Object_Item *it, const char *emission, const char *source);
 
 #include "elm_widget_item.eo.h"
 #include "elm_widget_item.eo.legacy.h"
@@ -76,4 +76,4 @@ EAPI void *elm_object_item_data_get(const Elm_Object_Item *it);
  * @note Every elm_object_item supports this API
  * @ingroup General
  */
-EAPI void elm_object_item_data_set(Elm_Object_Item *it, void *data);
+EAPI void elm_object_item_data_set(Elm_Object_Item *it, void *data);
\ No newline at end of file
index 3a3a15f..f18bbff 100644 (file)
@@ -4,6 +4,7 @@
 
 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
 #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
+#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
 #define ELM_WIDGET_ITEM_PROTECTED
 #include <Elementary.h>
 
@@ -6829,5 +6830,19 @@ _elm_widget_efl_gfx_base_color_part_get(Eo *obj, Elm_Widget_Smart_Data *sd, cons
 }
 //
 
+//TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets and widget_items, add handlers for reading stopped/cancelled
+EOLIAN const Elm_Atspi_Action *
+_elm_widget_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
+{
+   return NULL;
+}
+
+EOLIAN const Elm_Atspi_Action *
+_elm_widget_item_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *pd EINA_UNUSED)
+{
+   return NULL;
+}
+//
+
 #include "elm_widget_item.eo.c"
 #include "elm_widget.eo.c"
index 3c6b897..570d827 100644 (file)
@@ -7,7 +7,13 @@ enum Elm.Theme.Apply
    success = 3
 }
 
+//TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets
+/*
 abstract Elm.Widget (Evas.Object_Smart, Elm_Interface_Atspi_Accessible, Elm_Interface_Atspi_Component)
+*/
+abstract Elm.Widget (Evas.Object_Smart, Elm_Interface_Atspi_Accessible,
+         Elm_Interface_Atspi_Component, Elm_Interface_Atspi_Widget_Action)
+//
 {
    eo_prefix: elm_obj_widget;
    data: Elm_Widget_Smart_Data;
@@ -829,6 +835,9 @@ abstract Elm.Widget (Evas.Object_Smart, Elm_Interface_Atspi_Accessible, Elm_Inte
       //TIZEN_ONLY(20160329): widget: improve accessibile_at_point getter (a8aff0423202b9a55dbb3843205875226678fbd6)
       Elm_Interface_Atspi_Component.accessible_at_point_get;
       //
+      //TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets
+      Elm_Interface_Atspi_Widget_Action.elm_actions.get;
+      //
    }
    events {
       moved;
index db830b2..f100b50 100644 (file)
@@ -1,5 +1,12 @@
+//TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets
+/*
 class Elm.Widget_Item(Eo.Base, Elm_Interface_Atspi_Accessible,
                       Elm_Interface_Atspi_Component)
+*/
+class Elm.Widget_Item (Eo.Base, Elm_Interface_Atspi_Accessible,
+         Elm_Interface_Atspi_Component, Elm_Interface_Atspi_Widget_Action)
+//
+
 {
       eo_prefix: elm_wdg_item;
       legacy_prefix: elm_object_item;
@@ -555,5 +562,8 @@ class Elm.Widget_Item(Eo.Base, Elm_Interface_Atspi_Accessible,
            Elm_Interface_Atspi_Component.focus_grab;
            Elm_Interface_Atspi_Component.highlight_grab;
            Elm_Interface_Atspi_Component.highlight_clear;
+           //TIZEN_ONLY(20160527): widget item: add AtspiAction interface to all widget items
+           Elm_Interface_Atspi_Widget_Action.elm_actions.get;
+           //
       }
 }