diff --git a/legacy/elementary/src/lib/Makefile.am b/legacy/elementary/src/lib/Makefile.am index ed2fd90faf..16c576ed9a 100644 --- a/legacy/elementary/src/lib/Makefile.am +++ b/legacy/elementary/src/lib/Makefile.am @@ -447,8 +447,10 @@ elm_icon.c \ elm_image.c \ elm_index.c \ elm_interface_atspi_accessible.c \ +elm_interface_atspi_action.c \ elm_interface_atspi_component.c \ elm_interface_atspi_widget.c \ +elm_interface_atspi_widget_action.c \ elm_interface_atspi_window.c \ elm_interface_fileselector.c \ elm_interface_scrollable.c \ @@ -616,10 +618,14 @@ BUILT_SOURCES = \ elm_index.eo.h \ elm_interface_atspi_accessible.eo.c \ elm_interface_atspi_accessible.eo.h \ + elm_interface_atspi_action.eo.c \ + elm_interface_atspi_action.eo.h \ elm_interface_atspi_component.eo.c \ elm_interface_atspi_component.eo.h \ elm_interface_atspi_widget.eo.c \ elm_interface_atspi_widget.eo.h \ + elm_interface_atspi_widget_action.eo.c \ + elm_interface_atspi_widget_action.eo.h \ elm_interface_atspi_window.eo.c \ elm_interface_atspi_window.eo.h \ elm_interface_fileselector.eo.c \ @@ -711,8 +717,10 @@ EXTRA_DIST += \ elm_app_server_view.eo \ elm_atspi_app_object.eo \ elm_interface_atspi_accessible.eo \ + elm_interface_atspi_action.eo \ elm_interface_atspi_component.eo \ elm_interface_atspi_widget.eo \ + elm_interface_atspi_widget_action.eo \ elm_interface_atspi_window.eo \ elm_bg.eo \ elm_box.eo \ @@ -797,8 +805,10 @@ nodist_includesunstable_HEADERS = \ elm_app_server_view.eo.h \ elm_atspi_app_object.eo.h \ elm_interface_atspi_accessible.eo.h \ + elm_interface_atspi_action.eo.h \ elm_interface_atspi_component.eo.h \ elm_interface_atspi_widget.eo.h \ + elm_interface_atspi_widget_action.eo.h \ elm_interface_atspi_window.eo.h \ elm_box.eo.h \ elm_bg.eo.h \ diff --git a/legacy/elementary/src/lib/elm_atspi_bridge.c b/legacy/elementary/src/lib/elm_atspi_bridge.c index e1b1b220ff..fe99411050 100644 --- a/legacy/elementary/src/lib/elm_atspi_bridge.c +++ b/legacy/elementary/src/lib/elm_atspi_bridge.c @@ -4,6 +4,7 @@ #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED +#define ELM_INTERFACE_ATSPI_ACTION_PROTECTED #include "atspi/atspi-constants.h" #include @@ -15,6 +16,7 @@ #include "elm_interface_atspi_accessible.eo.h" #include "elm_interface_atspi_component.eo.h" #include "elm_interface_atspi_window.eo.h" +#include "elm_interface_atspi_action.eo.h" /* * Accessibility Bus info not defined in atspi-constants.h @@ -550,6 +552,158 @@ static const Eldbus_Method accessible_methods[] = { { NULL, NULL, NULL, NULL, 0 } }; +static Eldbus_Message * +_action_description_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *description, *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int idx; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "i", &idx)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, description = elm_interface_atspi_action_description_get(idx)); + description = description ? description : ""; + eldbus_message_arguments_append(ret, "s", description); + + return ret; +} + +static Eldbus_Message * +_action_name_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *name, *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int idx; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "i", &idx)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, name = elm_interface_atspi_action_name_get(idx)); + name = name ? name : ""; + eldbus_message_arguments_append(ret, "s", name); + + return ret; +} + +static Eldbus_Message * +_action_localized_name_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *name, *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int idx; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "i", &idx)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, name = elm_interface_atspi_action_localized_name_get(idx)); + name = name ? name : ""; + eldbus_message_arguments_append(ret, "s", name); + + return ret; +} + +static Eldbus_Message * +_action_key_binding_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *key, *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int idx; + Eldbus_Message *ret; + + if (!eldbus_message_arguments_get(msg, "i", &idx)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, key = elm_interface_atspi_action_keybinding_get(idx)); + key = key ? key : ""; + eldbus_message_arguments_append(ret, "s", key); + + return ret; +} + +static Eldbus_Message * +_action_actions_get(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *action, *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + Eina_List *actions; + Eldbus_Message *ret; + Eldbus_Message_Iter *iter, *iter_array; + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + iter = eldbus_message_iter_get(ret); + EINA_SAFETY_ON_NULL_RETURN_VAL(iter, NULL); + + iter_array = eldbus_message_iter_container_new(iter, 'a', "sss"); + EINA_SAFETY_ON_NULL_RETURN_VAL(iter_array, NULL); + + eo_do(obj, actions = elm_interface_atspi_action_actions_get()); + + int id = 0; + EINA_LIST_FREE(actions, action) + { + const char *key, *descr; + eo_do(obj, key = elm_interface_atspi_action_keybinding_get(id)); + key = key ? key : ""; + eo_do(obj, descr = elm_interface_atspi_action_description_get(id)); + descr = descr ? descr : ""; + eldbus_message_iter_arguments_append(iter_array, "sss", action, descr, key); + id++; + } + + eldbus_message_iter_container_close(iter, iter_array); + + return ret; +} + +static Eldbus_Message * +_action_action_do(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg) +{ + const char *obj_path = eldbus_service_object_path_get(iface); + Eo *obj = _access_object_from_path(obj_path); + int idx; + Eldbus_Message *ret; + Eina_Bool result; + + if (!eldbus_message_arguments_get(msg, "i", &idx)) + return eldbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidArgs", "Invalid index type."); + + ret = eldbus_message_method_return_new(msg); + EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL); + + eo_do(obj, result = elm_interface_atspi_action_action_do(idx)); + eldbus_message_arguments_append(ret, "b", result); + + return ret; +} + +static const Eldbus_Method action_methods[] = { + { "GetDescription", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "description"}), _action_description_get, 0 }, + { "GetName", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "name"}), _action_name_get, 0 }, + { "GetLocalizedName", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "name"}), _action_localized_name_get, 0 }, + { "GetKeyBinding", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"s", "key"}), _action_key_binding_get, 0 }, + { "GetActions", NULL, ELDBUS_ARGS({"a(sss)", "actions"}), _action_actions_get, 0 }, + { "DoAction", ELDBUS_ARGS({"i", "index"}), ELDBUS_ARGS({"b", "result"}), _action_action_do, 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; + static Eo * _access_object_from_path(const char *path) { @@ -633,6 +787,27 @@ _accessible_property_get(const Eldbus_Service_Interface *interface, const char * return EINA_FALSE; } +static Eina_Bool +_action_property_get(const Eldbus_Service_Interface *interface, const char *property, + Eldbus_Message_Iter *iter, const Eldbus_Message *request_msg EINA_UNUSED, + Eldbus_Message **error EINA_UNUSED) +{ + Eina_List *actions; + const char *obj_path = eldbus_service_object_path_get(interface); + Eo *obj = _access_object_from_path(obj_path); + + EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE); + + if (!strcmp(property, "NActions")) + { + eo_do(obj, actions = elm_interface_atspi_action_actions_get()); + eldbus_message_iter_basic_append(iter, 'i', eina_list_count(actions)); + eina_list_free(actions); + return EINA_TRUE; + } + return EINA_FALSE; +} + static const Eldbus_Property accessible_properties[] = { { "Name", "s", _accessible_property_get, NULL, 0 }, { "Description", "s", _accessible_property_get, NULL, 0 }, @@ -641,6 +816,11 @@ static const Eldbus_Property accessible_properties[] = { { NULL, NULL, NULL, NULL, 0 } }; +static const Eldbus_Property action_properties[] = { + { "NActions", "i", _action_property_get, NULL, 0 }, + { NULL, NULL, NULL, NULL, 0 } +}; + static const Eldbus_Service_Interface_Desc accessible_iface_desc = { ATSPI_DBUS_INTERFACE_ACCESSIBLE, accessible_methods, NULL, accessible_properties, _accessible_property_get, NULL }; @@ -653,6 +833,10 @@ static const Eldbus_Service_Interface_Desc window_iface_desc = { ATSPI_DBUS_INTERFACE_EVENT_WINDOW, NULL, _window_obj_signals, NULL, NULL, NULL }; +static const Eldbus_Service_Interface_Desc action_iface_desc = { + ATSPI_DBUS_INTERFACE_ACTION, action_methods, NULL, action_properties, NULL, NULL +}; + static void _object_append_reference(Eldbus_Message_Iter *iter, Eo *obj) { @@ -727,6 +911,8 @@ _append_item_fn(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_ACCESSIBLE); if (eo_isa(data, ELM_INTERFACE_ATSPI_COMPONENT_CLASS)) eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_COMPONENT); + if (eo_isa(data, ELM_INTERFACE_ATSPI_ACTION_CLASS)) + eldbus_message_iter_basic_append(iter_sub_array, 's', ATSPI_DBUS_INTERFACE_ACTION); eldbus_message_iter_container_close(iter_struct, iter_sub_array); @@ -1616,6 +1802,10 @@ static void _object_register(Eo *obj, char *path) eo_do(obj, eo_event_callback_array_add(_window_cb(), infc)); } + if (eo_isa(obj, ELM_INTERFACE_ATSPI_ACTION_CLASS)) + { + infc = eldbus_service_interface_register(_a11y_bus, path, &action_iface_desc); + } } } diff --git a/legacy/elementary/src/lib/elm_button.c b/legacy/elementary/src/lib/elm_button.c index 8960c695b8..5bb8a87a6e 100644 --- a/legacy/elementary/src/lib/elm_button.c +++ b/legacy/elementary/src/lib/elm_button.c @@ -9,6 +9,10 @@ #define MY_CLASS ELM_OBJ_BUTTON_CLASS +// ATSPI Accessibility +#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED +#include "elm_interface_atspi_widget_action.eo.h" + #define MY_CLASS_NAME "Elm_Button" #define MY_CLASS_NAME_LEGACY "elm_button" @@ -418,6 +422,12 @@ _elm_button_elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Butto return EINA_FALSE; } +EOLIAN const Elm_Action * +_elm_button_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Button_Data *pd EINA_UNUSED) +{ + return &key_actions[0]; +} + static void _elm_button_class_constructor(Eo_Class *klass) { diff --git a/legacy/elementary/src/lib/elm_button.eo b/legacy/elementary/src/lib/elm_button.eo index 27df63d8d7..1325196d39 100644 --- a/legacy/elementary/src/lib/elm_button.eo +++ b/legacy/elementary/src/lib/elm_button.eo @@ -1,4 +1,5 @@ -class Elm_Button (Elm_Layout, Evas_Clickable_Interface) +class Elm_Button (Elm_Layout, Evas_Clickable_Interface, + Elm_Interface_Atspi_Widget_Action) { eo_prefix: elm_obj_button; properties { @@ -108,5 +109,6 @@ class Elm_Button (Elm_Layout, Evas_Clickable_Interface) Elm_Layout::text_aliases::get; Elm_Layout::content_aliases::get; Elm_Layout::sizing_eval; + Elm_Interface_Atspi_Widget_Action::elm_actions::get; } } diff --git a/legacy/elementary/src/lib/elm_interface_atspi_action.c b/legacy/elementary/src/lib/elm_interface_atspi_action.c new file mode 100644 index 0000000000..ef3d9d07ef --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_action.c @@ -0,0 +1,25 @@ +#ifdef HAVE_CONFIG_H + #include "elementary_config.h" +#endif + +#include +#include "elm_widget.h" +#include "elm_priv.h" + +#define ELM_INTERFACE_ATSPI_ACTION_PROTECTED + +#include "elm_interface_atspi_action.eo.h" + +EOLIAN const char * +_elm_interface_atspi_action_localized_name_get(Eo *obj, void *pd EINA_UNUSED, int id) +{ + const char *ret = NULL; + + eo_do(obj, ret = elm_interface_atspi_action_name_get(id)); +#ifdef ENABLE_NLS + ret = gettext(ret); +#endif + return ret; +} + +#include "elm_interface_atspi_action.eo.c" diff --git a/legacy/elementary/src/lib/elm_interface_atspi_action.eo b/legacy/elementary/src/lib/elm_interface_atspi_action.eo new file mode 100644 index 0000000000..5ccc7ef59b --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_action.eo @@ -0,0 +1,78 @@ +mixin Elm_Interface_Atspi_Action () +{ + legacy_prefix: null; + eo_prefix: elm_interface_atspi_action; + data: null; + properties { + protected name { + get { + /*@ Gets action name for given id */ + } + values { + const char *name; + } + keys { + int id; + } + } + protected localized_name { + get { + /*@ Gets localized action name for given id */ + } + values { + const char *; + } + keys { + int id; + } + } + protected description { + get { + /*@ Gets action description for given id */ + } + set { + /*@ Sets action description for given id */ + return Eina_Bool; + } + values { + const char *description; + } + keys { + int id; + } + } + protected actions { + get { + /*@ Get list of available widget actions */ + } + values { + Eina_List *actions; /*@ contains statically allocated strings */ + } + } + } + methods { + protected action_do { + /*@ Performs action on given widget. */ + params { + @in int id; + } + return Eina_Bool; + } + protected keybinding_get { + /*@ Gets configured keybinding for specific action and widget. */ + params { + @in int id; + } + return const char *; + } + } + implements { + virtual::action_do; + virtual::keybinding_get; + virtual::name::get; + virtual::name::set; + virtual::description::get; + virtual::description::set; + virtual::actions::get; + } +} diff --git a/legacy/elementary/src/lib/elm_interface_atspi_widget_action.c b/legacy/elementary/src/lib/elm_interface_atspi_widget_action.c new file mode 100644 index 0000000000..15caf02525 --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_widget_action.c @@ -0,0 +1,131 @@ +#ifdef HAVE_CONFIG_H + #include "elementary_config.h" +#endif + +#include +#include "elm_widget.h" +#include "elm_priv.h" + +#define ELM_INTERFACE_ATSPI_ACTION_PROTECTED +#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED + +#include "elm_interface_atspi_action.eo.h" +#include "elm_interface_atspi_widget_action.eo.h" + +extern Eina_Hash *_elm_key_bindings; + +EOLIAN static Eina_Bool +_elm_interface_atspi_widget_action_elm_interface_atspi_action_action_do(Eo *obj, void *pd EINA_UNUSED, int id) +{ + const Elm_Action *actions = NULL; + Eina_Bool (*func)(Eo *eo, const char *params) = NULL; + int tmp = 0; + + 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; + break; + } + tmp++; + } + + if (!func) + return EINA_FALSE; + + return func(obj, NULL); +} + +EOLIAN static const char * +_elm_interface_atspi_widget_action_elm_interface_atspi_action_keybinding_get(Eo *obj, void *pd EINA_UNUSED, int id) +{ + const Elm_Action *actions = NULL; + Eina_List *l, *binding_list; + const char *action = NULL; + Elm_Config_Binding_Key *binding; + int tmp = 0; + + if (!eo_isa(obj, ELM_OBJ_WIDGET_CLASS)) + return NULL; + + eo_do(obj, actions = elm_interface_atspi_widget_action_elm_actions_get()); + if (!actions) return NULL; + + while (actions[tmp].name) + { + if (tmp == id) + { + action = actions->name; + break; + } + tmp++; + } + if (!action) return NULL; + + binding_list = eina_hash_find(_elm_key_bindings, elm_widget_type_get(obj)); + + if (binding_list) + { + EINA_LIST_FOREACH(binding_list, l, binding) + { + if (!strcmp(binding->action, action)) + return binding->key; + } + } + + return NULL; +} + +EOLIAN static const char * +_elm_interface_atspi_widget_action_elm_interface_atspi_action_name_get(Eo *obj, void *pd EINA_UNUSED, int id) +{ + const Elm_Action *actions = NULL; + int tmp = 0; + + eo_do(obj, actions = elm_interface_atspi_widget_action_elm_actions_get()); + if (!actions) return EINA_FALSE; + + while (actions[tmp].name) + { + if (tmp == id) return actions->name; + tmp++; + } + return NULL; +} + +EOLIAN static Eina_Bool +_elm_interface_atspi_widget_action_elm_interface_atspi_action_description_set(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, int id EINA_UNUSED, const char *description EINA_UNUSED) +{ + return EINA_FALSE; +} + +EOLIAN static const char * +_elm_interface_atspi_widget_action_elm_interface_atspi_action_description_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, int id EINA_UNUSED) +{ + return NULL; +} + +EOLIAN static Eina_List* +_elm_interface_atspi_widget_action_elm_interface_atspi_action_actions_get(Eo *obj, void *pd EINA_UNUSED) +{ + const Elm_Action *actions = NULL; + Eina_List *ret = NULL; + int tmp = 0; + + eo_do(obj, actions = elm_interface_atspi_widget_action_elm_actions_get()); + if (!actions) return NULL; + + while (actions[tmp].name) + { + ret = eina_list_append(ret, actions[tmp].name); + tmp++; + } + + return ret; +} + +#include "elm_interface_atspi_widget_action.eo.c" diff --git a/legacy/elementary/src/lib/elm_interface_atspi_widget_action.eo b/legacy/elementary/src/lib/elm_interface_atspi_widget_action.eo new file mode 100644 index 0000000000..a14c19bf51 --- /dev/null +++ b/legacy/elementary/src/lib/elm_interface_atspi_widget_action.eo @@ -0,0 +1,25 @@ +mixin Elm_Interface_Atspi_Widget_Action (Elm_Interface_Atspi_Action) +{ + legacy_prefix: null; + eo_prefix: elm_interface_atspi_widget_action; + data: null; + properties { + protected elm_actions { + get { + } + values { + const Elm_Action *actions; /*@ NULL-terminated array of Elm_Actions + */ + } + } + } + implements { + Elm_Interface_Atspi_Action::action_do; + Elm_Interface_Atspi_Action::keybinding_get; + Elm_Interface_Atspi_Action::name::get; + Elm_Interface_Atspi_Action::description::set; + Elm_Interface_Atspi_Action::description::get; + Elm_Interface_Atspi_Action::actions::get; + virtual::elm_actions::get; + } +}