summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <lukasz.stanislawski@gmail.com>2017-05-14 23:05:12 +0200
committerLukasz Stanislawski <l.stanislaws@samsung.com>2017-05-31 16:21:50 +0200
commit6c22f0ea1fcccc5f1a428061f9b34e7075481178 (patch)
treedc362aec8040eb67aa47043d7ead2d27048b1715
parent8e03d7af3bbc511d181b965f8cdcf0281a274fa6 (diff)
downloadefl-6c22f0ea1fcccc5f1a428061f9b34e7075481178.tar.gz
elementary: add atspi plug & socket classes
Change-Id: Ie2f9d8f92b16f10039c14c2de8070d2e4c7a3f51
-rw-r--r--src/Makefile_Elementary.am8
-rw-r--r--src/bin/elementary/test_win_plug.c23
-rw-r--r--src/bin/elementary/test_win_socket.c26
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/plug/Makefile30
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/plug/efl-socket.c95
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-accessible.c168
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-accessible.h55
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-vbox.c76
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-vbox.h57
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug.c94
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/socket/Makefile20
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-accessible.c59
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-accessible.h55
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-label.c62
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-label.h55
-rw-r--r--src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket.c99
-rw-r--r--src/lib/elementary/Elementary.h4
-rw-r--r--src/lib/elementary/efl_ui_win.c5
-rw-r--r--src/lib/elementary/elm_atspi_app_object.c43
-rw-r--r--src/lib/elementary/elm_atspi_app_object.eo7
-rw-r--r--src/lib/elementary/elm_atspi_bridge.c486
-rw-r--r--src/lib/elementary/elm_atspi_bridge.eo12
-rw-r--r--src/lib/elementary/elm_atspi_plug.c46
-rw-r--r--src/lib/elementary/elm_atspi_plug.eo13
-rw-r--r--src/lib/elementary/elm_atspi_plug.h8
-rw-r--r--src/lib/elementary/elm_atspi_proxy.c23
-rw-r--r--src/lib/elementary/elm_atspi_proxy.eo28
-rw-r--r--src/lib/elementary/elm_atspi_socket.c25
-rw-r--r--src/lib/elementary/elm_atspi_socket.eo10
-rw-r--r--src/lib/elementary/elm_atspi_socket.h9
-rw-r--r--src/lib/elementary/elm_interface_atspi_accessible.c35
-rw-r--r--src/lib/elementary/elm_interface_atspi_accessible.eo5
-rw-r--r--src/lib/elementary/elm_interface_atspi_socket.c69
-rw-r--r--src/lib/elementary/elm_interface_atspi_socket.eo69
-rw-r--r--src/lib/elementary/elm_interfaces.h2
35 files changed, 1719 insertions, 162 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index b6c0c6e100..4a28d376db 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -4,7 +4,9 @@
elm_public_eolian_files = \
lib/elementary/elm_atspi_bridge.eo \
lib/elementary/elm_atspi_app_object.eo \
+ lib/elementary/elm_atspi_plug.eo \
lib/elementary/elm_atspi_proxy.eo \
+ lib/elementary/elm_atspi_socket.eo \
lib/elementary/elm_bg.eo \
lib/elementary/efl_ui_button.eo \
lib/elementary/elm_calendar.eo \
@@ -35,6 +37,7 @@ elm_public_eolian_files = \
lib/elementary/elm_interface_atspi_text_editable.eo \
lib/elementary/elm_interface_atspi_image.eo \
lib/elementary/elm_interface_atspi_selection.eo \
+ lib/elementary/elm_interface_atspi_socket.eo \
lib/elementary/elm_interface_atspi_text.eo \
lib/elementary/elm_interface_atspi_value.eo \
lib/elementary/elm_interface_atspi_widget_action.eo \
@@ -205,7 +208,9 @@ includesdir = $(includedir)/elementary-@VMAJ@
includesunstable_HEADERS = \
lib/elementary/elm_gen_common.h \
lib/elementary/elm_atspi_bridge.h \
+ lib/elementary/elm_atspi_plug.h \
lib/elementary/elm_atspi_proxy.h \
+ lib/elementary/elm_atspi_socket.h \
lib/elementary/elm_interface_atspi_accessible.h \
lib/elementary/elm_interface_atspi_text.h \
lib/elementary/elm_interface_atspi_widget_action.h \
@@ -553,7 +558,9 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/elm_actionslider.c \
lib/elementary/elm_atspi_app_object.c \
lib/elementary/elm_atspi_bridge.c \
+ lib/elementary/elm_atspi_plug.c \
lib/elementary/elm_atspi_proxy.c \
+ lib/elementary/elm_atspi_socket.c \
lib/elementary/elm_bg.c \
lib/elementary/elm_box.c \
lib/elementary/elm_bubble.c \
@@ -606,6 +613,7 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/elm_interface_atspi_text_editable.c \
lib/elementary/elm_interface_atspi_image.c \
lib/elementary/elm_interface_atspi_selection.c \
+ lib/elementary/elm_interface_atspi_socket.c \
lib/elementary/elm_interface_atspi_text.c \
lib/elementary/elm_interface_atspi_value.c \
lib/elementary/elm_interface_atspi_widget_action.c \
diff --git a/src/bin/elementary/test_win_plug.c b/src/bin/elementary/test_win_plug.c
index ad94dde91d..8c53f9bbdb 100644
--- a/src/bin/elementary/test_win_plug.c
+++ b/src/bin/elementary/test_win_plug.c
@@ -5,6 +5,7 @@
#define MAX_TRY 40
+extern char *plugid;
static int try_num = 0;
static void
@@ -171,6 +172,23 @@ _notify_error(Evas_Object *parent, const char *msg)
evas_object_show(notif);
}
+static void
+a11y_init(Evas_Object *plug)
+{
+ // assume bridge is initialized
+ Elm_Atspi_Socket *socket = efl_add(ELM_ATSPI_SOCKET_CLASS, plug);
+ Elm_Atspi_Proxy *proxy;
+
+ proxy = efl_add(ELM_ATSPI_PROXY_CLASS, socket, elm_atspi_proxy_id_constructor(efl_added, plugid));
+
+ // FIXME order seems important!
+ elm_interface_atspi_accessible_parent_set(socket, plug);
+ elm_interface_atspi_accessible_parent_set(proxy, socket);
+
+ // FIXME asume bridge is connected
+ elm_interface_atspi_socket_embed(socket, proxy);
+}
+
void
test_win_plug(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@@ -197,6 +215,9 @@ test_win_plug(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UN
return;
}
+ //FIXME oreder seems important
+ //a11y_init(plug);
+
evas_object_smart_callback_add(plug, "image,deleted", cb_plug_disconnected, NULL);
evas_object_smart_callback_add(plug, "image,resized", cb_plug_resized, NULL);
@@ -208,4 +229,6 @@ test_win_plug(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UN
evas_object_resize(win, 400, 600);
evas_object_show(win);
+
+ a11y_init(plug);
}
diff --git a/src/bin/elementary/test_win_socket.c b/src/bin/elementary/test_win_socket.c
index 664f097bde..ef488b46a2 100644
--- a/src/bin/elementary/test_win_socket.c
+++ b/src/bin/elementary/test_win_socket.c
@@ -3,6 +3,8 @@
#endif
#include <Elementary.h>
+char *plugid;
+
static void
_win_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@@ -140,6 +142,29 @@ fill(Evas_Object *win, Eina_Bool do_bg)
evas_object_show(sc);
}
+static void
+_on_plug_id_changed(void *data, const Efl_Event *event)
+{
+ Elm_Atspi_Plug *plug = event->object;
+ plugid = elm_interface_atspi_socket_id_get(plug);
+ // send id using elementary IPC mechanism
+}
+
+static void
+a11y_init(Evas_Object *socket_window)
+{
+ // create a11y plug to get dbus reference to object
+ Elm_Atspi_Plug *plug = efl_add(ELM_ATSPI_PLUG_CLASS, socket_window);
+
+ // make plug parent of socket_window
+ elm_interface_atspi_accessible_parent_set(socket_window, plug);
+
+ // get address when bridge gets connected
+ efl_event_callback_add(plug, ELM_INTERFACE_ATSPI_SOCKET_EVENT_ID_CHANGED, _on_plug_id_changed, NULL);
+
+ plugid = elm_interface_atspi_socket_id_get(plug);
+}
+
void
test_win_socket(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@@ -193,6 +218,7 @@ test_win_socket(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *even
elm_win_autodel_set(win_socket, EINA_TRUE);
fill(win_socket, EINA_TRUE);
+ a11y_init(win_socket);
evas_object_resize(win_socket, 400, 600);
evas_object_show(win_socket);
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/plug/Makefile b/src/examples/elementary/a11y/efl-gtk-integration/plug/Makefile
new file mode 100644
index 0000000000..712d7732d0
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/plug/Makefile
@@ -0,0 +1,30 @@
+CC=gcc
+TARGET_GTK=gtk-plug
+SOURCES_GTK=ta-plug.c \
+ ta-plug-vbox.h \
+ ta-plug-vbox.c \
+ ta-plug-accessible.h \
+ ta-plug-accessible.c
+
+LIBS_GTK=atk gtk+-3.0
+CFLAGS_GTK=`pkg-config --cflags $(LIBS_GTK)`
+LDFLAGS_GTK=`pkg-config --libs $(LIBS_GTK)`
+
+TARGET_EFL=efl-socket
+SOURCES_EFL=efl-socket.c
+LIBS_EFL=elementary
+CFLAGS_EFL=`pkg-config --cflags $(LIBS_EFL)`
+LDFLAGS_EFL=`pkg-config --libs $(LIBS_EFL)`
+
+all: compile_gtk compile_efl
+
+compile_gtk:
+ $(CC) -o $(TARGET_GTK) $(SOURCES_GTK) $(CFLAGS_GTK) $(LDFLAGS_GTK)
+
+compile_efl:
+ $(CC) -o $(TARGET_EFL) $(SOURCES_EFL) $(CFLAGS_EFL) $(LDFLAGS_EFL)
+
+clean:
+ rm -rf $(TARGET_GTK)
+ rm -rf $(TARGET_EFL)
+ rm -rf *~
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/plug/efl-socket.c b/src/examples/elementary/a11y/efl-gtk-integration/plug/efl-socket.c
new file mode 100644
index 0000000000..5cb521ec39
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/plug/efl-socket.c
@@ -0,0 +1,95 @@
+#define EFL_BETA_API_SUPPORT
+#define EFL_EO_API_SUPPORT
+#include <Elementary.h>
+
+static struct app_state {
+ Evas_Object *entry;
+ Elm_Atspi_Socket *socket;
+ Elm_Atspi_Socket *proxy;
+ Evas_Object *container;
+} state;
+
+static void a11y_init(void)
+{
+ if (state.socket)
+ efl_del(state.socket)
+
+ if (!elm_entry_is_empty(state.entry))
+ {
+ printf("Embedded plug: %s\n", elm_object_text_get(state.entry));
+ state.socket = efl_add(ELM_ATSPI_SOCKET_CLASS, NULL);
+ // Weird constructor
+ state.proxy = efl_add(ELM_ATSPI_PROXY_CLASS, NULL, elm_atspi_proxy_id_constructor(efl_added, elm_object_text_get(state.entry)));
+
+ // fires accessible parent should be set to eo_parent (???)
+ elm_interface_atspi_accessible_parent_set(state.socket, state.container);
+ // following line shuold be not necessary:
+ elm_interface_atspi_accessible_parent_set(state.proxy, state.socket);
+
+ // FIXME order matters = should be fixed!!!
+ // if state.socket is not attached to tree, embed will have empty
+ // implemnetation
+ elm_interface_atspi_socket_embed(state.socket, state.proxy);
+ }
+}
+
+static void
+_connect_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ if (elm_config_atspi_mode_get())
+ a11y_init();
+ else
+ printf("Atspi mode is not enabled. Adjust elementary configuration using elementary_config app\n");
+}
+
+static void
+_create_layout(Evas_Object *win)
+{
+ Evas_Object *box = elm_box_add(win);
+ evas_object_size_hint_expand_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(win, box);
+
+ Evas_Object *label = elm_label_add(box);
+ evas_object_size_hint_align_set(label, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_object_text_set(label, "Past Plug Id here:");
+ elm_box_pack_end(box, label);
+ evas_object_show(label);
+
+ Evas_Object *entry = elm_entry_add(box);
+ elm_entry_single_line_set(entry, EINA_TRUE);
+ elm_entry_scrollable_set(entry, EINA_TRUE);
+ evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_box_pack_end(box, entry);
+ evas_object_show(entry);
+ state.entry = entry;
+
+ Evas_Object *button = elm_button_add(box);
+ elm_object_text_set(button, "Connect");
+ elm_box_pack_end(box, button);
+ evas_object_smart_callback_add(button, "clicked", _connect_clicked_cb, NULL);
+ evas_object_show(button);
+
+ state.container = elm_label_add(box);
+ evas_object_size_hint_align_set(state.container, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_object_text_set(state.container, "Embedded content goes here:");
+ elm_box_pack_end(box, state.container);
+ evas_object_show(state.container);
+
+ evas_object_show(box);
+}
+
+int elm_main(int argc, char **argv)
+{
+ Evas_Object *win = elm_win_util_standard_add("Efl socket", "Efl socket");
+ elm_win_autodel_set(win, EINA_TRUE);
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+ evas_object_resize(win, 300, 200);
+
+ _create_layout(win);
+
+ evas_object_show(win);
+ elm_run();
+ return 0;
+}
+
+ELM_MAIN();
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-accessible.c b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-accessible.c
new file mode 100644
index 0000000000..46d99f7337
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-accessible.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include "ta-plug-accessible.h"
+
+#include <atk/atk.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+struct _TaPlugAccessiblePrivate {
+ GtkWidget *widget;
+};
+
+#define TA_PLUG_ACCESSIBLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), TA_TYPE_PLUG_ACCESSIBLE, TaPlugAccessiblePrivate))
+
+G_DEFINE_TYPE (TaPlugAccessible, ta_plug_accessible, ATK_TYPE_PLUG);
+
+static void ta_plug_accessible_initialize (AtkObject *object, gpointer data)
+{
+ g_return_if_fail (TA_IS_PLUG_ACCESSIBLE (object));
+
+ TaPlugAccessible *plug = NULL;
+ TaPlugAccessiblePrivate *priv = NULL;
+
+ ATK_OBJECT_CLASS(ta_plug_accessible_parent_class)->initialize(object, data);
+
+ plug = TA_PLUG_ACCESSIBLE (object);
+ priv = TA_PLUG_ACCESSIBLE_GET_PRIVATE(plug);
+ priv->widget = NULL;
+ if (GTK_IS_WIDGET (data))
+ priv->widget = GTK_WIDGET (data);
+}
+
+static const gchar *ta_plug_accessible_get_name (AtkObject *object)
+{
+ g_return_val_if_fail(ATK_IS_OBJECT (object), NULL);
+ return "The Plug";
+}
+
+static AtkRole ta_plug_accessible_get_role (AtkObject *object)
+{
+ g_return_val_if_fail(ATK_IS_OBJECT (object), ATK_ROLE_UNKNOWN);
+ return ATK_ROLE_PANEL;
+}
+
+static gint ta_plug_accessible_get_n_children (AtkObject *object)
+{
+ g_return_val_if_fail (TA_IS_PLUG_ACCESSIBLE (object), 0);
+
+ TaPlugAccessible *plug = NULL;
+ TaPlugAccessiblePrivate *priv = NULL;
+ GList *children = NULL;
+ GList *item = NULL;
+ gint n_children = 0;
+
+ plug = TA_PLUG_ACCESSIBLE (object);
+ priv = TA_PLUG_ACCESSIBLE_GET_PRIVATE(plug);
+
+ if (!priv->widget)
+ return 0;
+
+ if (!GTK_IS_CONTAINER (priv->widget))
+ return 0;
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->widget));
+ n_children = g_list_length (children);
+ g_list_free (children);
+
+ return n_children;
+}
+
+static AtkObject *ta_plug_accessible_ref_child (AtkObject *object, gint i)
+{
+ g_return_val_if_fail (TA_IS_PLUG_ACCESSIBLE (object), NULL);
+
+ TaPlugAccessible *plug = NULL;
+ TaPlugAccessiblePrivate *priv = NULL;
+ GList *children = NULL;
+ GList *item = NULL;
+ gint n_children = 0;
+ GtkWidget *child = NULL;
+ AtkObject *axChild = NULL;
+
+ plug = TA_PLUG_ACCESSIBLE (object);
+ priv = TA_PLUG_ACCESSIBLE_GET_PRIVATE(plug);
+
+ if (!priv->widget)
+ return NULL;
+
+ if (!GTK_IS_CONTAINER (priv->widget))
+ return NULL;
+
+ children = gtk_container_get_children (GTK_CONTAINER (priv->widget));
+ if (i < 0 || i >= g_list_length (children))
+ return NULL;
+
+ child = GTK_WIDGET (g_list_nth_data (children, i));
+ if (!child)
+ return NULL;
+
+ g_list_free (children);
+
+ axChild = gtk_widget_get_accessible (child);
+ return g_object_ref (axChild);
+}
+
+static void ta_plug_accessible_dispose (GObject *object)
+{
+ TaPlugAccessible *plug = NULL;
+ TaPlugAccessiblePrivate *priv = NULL;
+
+ plug = TA_PLUG_ACCESSIBLE (object);
+ priv = TA_PLUG_ACCESSIBLE_GET_PRIVATE(plug);
+
+ if (priv->widget)
+ {
+ g_object_unref (priv->widget);
+ priv->widget = NULL;
+ }
+
+ G_OBJECT_CLASS(ta_plug_accessible_parent_class)->dispose(object);
+}
+
+static void ta_plug_accessible_class_init (TaPlugAccessibleClass *klass)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
+ AtkObjectClass *atk_object_class = NULL;
+
+ g_object_class->dispose = ta_plug_accessible_dispose;
+
+ atk_object_class = ATK_OBJECT_CLASS (klass);
+ atk_object_class->initialize = ta_plug_accessible_initialize;
+ atk_object_class->get_name = ta_plug_accessible_get_name;
+ atk_object_class->get_role = ta_plug_accessible_get_role;
+ atk_object_class->get_n_children = ta_plug_accessible_get_n_children;
+ atk_object_class->get_index_in_parent = NULL;
+ atk_object_class->ref_child = ta_plug_accessible_ref_child;
+
+ g_type_class_add_private(g_object_class, sizeof(TaPlugAccessiblePrivate));
+}
+
+static void ta_plug_accessible_init(TaPlugAccessible *plug)
+{
+}
+
+AtkObject *ta_plug_accessible_new ()
+{
+ return ATK_OBJECT (g_object_new(TA_TYPE_PLUG_ACCESSIBLE, 0));
+}
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-accessible.h b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-accessible.h
new file mode 100644
index 0000000000..c862db179c
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-accessible.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#ifndef TaPlugAccessible_h
+#define TaPlugAccessible_h
+
+#include <atk/atk.h>
+
+G_BEGIN_DECLS
+
+#define TA_TYPE_PLUG_ACCESSIBLE (ta_plug_accessible_get_type ())
+#define TA_PLUG_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TA_TYPE_PLUG_ACCESSIBLE, TaPlugAccessible))
+#define TA_PLUG_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TA_TYPE_PLUG_ACCESSIBLE, TaPlugAccessibleClass))
+#define TA_IS_PLUG_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TA_TYPE_PLUG_ACCESSIBLE))
+#define TA_IS_PLUG_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TA_TYPE_PLUG_ACCESSIBLE))
+#define TA_PLUG_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TA_TYPE_PLUG_ACCESSIBLE, TaPlugAccessibleClass))
+
+typedef struct _TaPlugAccessible TaPlugAccessible;
+typedef struct _TaPlugAccessibleClass TaPlugAccessibleClass;
+typedef struct _TaPlugAccessiblePrivate TaPlugAccessiblePrivate;
+
+struct _TaPlugAccessible {
+ AtkPlug parent;
+};
+
+struct _TaPlugAccessibleClass {
+ AtkPlugClass parentClass;
+};
+
+GType ta_plug_accessible_get_type(void) G_GNUC_CONST;
+
+AtkObject *ta_plug_accessible_new (void);
+
+G_END_DECLS
+
+#endif // TaPlugAccessible_h
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-vbox.c b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-vbox.c
new file mode 100644
index 0000000000..7ec8533054
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-vbox.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include "ta-plug-vbox.h"
+
+#include "ta-plug-accessible.h"
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_DEFINE_TYPE (TaPlugVBox, ta_plug_vbox, GTK_TYPE_VBOX);
+
+static AtkObject *_get_accessible (GtkWidget *widget)
+{
+ static AtkObject *new = NULL;
+
+ if (!new)
+ {
+ new = ta_plug_accessible_new ();
+ atk_object_initialize (new, G_OBJECT (widget));
+ }
+
+ return new;
+}
+
+static void ta_plug_vbox_class_init (TaPlugVBoxClass *klass)
+{
+ GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+
+ widget_class->get_accessible = _get_accessible;
+}
+
+static void ta_plug_vbox_init(TaPlugVBox *plug)
+{
+}
+
+GtkWidget *ta_plug_vbox_new (gboolean homogeneous, gint spacing)
+{
+ return GTK_WIDGET (g_object_new(TA_TYPE_PLUG_VBOX,
+ "homogeneous", homogeneous,
+ "spacing", spacing,
+ 0));
+}
+
+gchar *ta_plug_vbox_get_id (TaPlugVBox *plug)
+{
+ AtkObject *plugAxObject = NULL;
+ gchar *text_id = NULL;
+
+ plugAxObject = gtk_widget_get_accessible (GTK_WIDGET (plug));
+ if (ATK_IS_PLUG (plugAxObject))
+ text_id = atk_plug_get_id (ATK_PLUG (plugAxObject));
+ else
+ g_print ("Not an instance of AtkPlug\n");
+
+ return text_id;
+}
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-vbox.h b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-vbox.h
new file mode 100644
index 0000000000..d2e1fac898
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug-vbox.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#ifndef TaPlugVBox_h
+#define TaPlugVBox_h
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define TA_TYPE_PLUG_VBOX (ta_plug_vbox_get_type ())
+#define TA_PLUG_VBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TA_TYPE_PLUG_VBOX, TaPlugVBox))
+#define TA_PLUG_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TA_TYPE_PLUG_VBOX, TaPlugVBoxClass))
+#define TA_IS_PLUG_VBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TA_TYPE_PLUG_VBOX))
+#define TA_IS_PLUG_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TA_TYPE_PLUG_VBOX))
+#define TA_PLUG_VBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TA_TYPE_PLUG_VBOX, TaPlugVBoxClass))
+
+typedef struct _TaPlugVBox TaPlugVBox;
+typedef struct _TaPlugVBoxClass TaPlugVBoxClass;
+typedef struct _TaPlugVBoxPrivate TaPlugVBoxPrivate;
+
+struct _TaPlugVBox {
+ GtkVBox parent;
+};
+
+struct _TaPlugVBoxClass {
+ GtkVBoxClass parentClass;
+};
+
+GType ta_plug_vbox_get_type(void) G_GNUC_CONST;
+
+GtkWidget *ta_plug_vbox_new (gboolean homogeneous, gint spacing);
+
+gchar *ta_plug_vbox_get_id (TaPlugVBox *plug);
+
+G_END_DECLS
+
+#endif // TaPlugVBox_h
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug.c b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug.c
new file mode 100644
index 0000000000..ac534825a6
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/plug/ta-plug.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include "ta-plug-vbox.h"
+
+#include <gtk/gtk.h>
+
+#define WINDOW_WIDTH 350
+#define WINDOW_HEIGHT -1
+
+static void
+_button_clicked_cb (GtkButton *button, gpointer data)
+{
+ GtkWindow *window = GTK_WINDOW (data);
+
+ GtkWidget *dialog =
+ gtk_message_dialog_new (window,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ "I told you so:\nthe button does ALMOST nothing",
+ NULL);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+int
+main (int argc, char**argv)
+{
+ GtkWidget *window = NULL;
+ GtkWidget *hbox = NULL;
+ GtkWidget *plug = NULL;
+ GtkWidget *widget = NULL;
+ gchar *plug_id = NULL;
+ gchar *entry_txt = NULL;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+ plug = ta_plug_vbox_new (FALSE, 0);
+ plug_id = ta_plug_vbox_get_id (TA_PLUG_VBOX (plug));
+ if (plug_id)
+ g_print ("[PLUG] Id is %s\n", plug_id);
+ else
+ g_print ("Not a valid ID found\n");
+
+
+ hbox = gtk_hbox_new (FALSE, 0);
+
+ widget = gtk_label_new ("Plug ID: ");
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 6);
+
+ widget = gtk_entry_new ();
+ entry_txt = g_strdup_printf ("%s", plug_id);
+ gtk_entry_set_text (GTK_ENTRY (widget), entry_txt);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 6);
+
+ gtk_box_pack_start (GTK_BOX (plug), hbox, TRUE, TRUE, 6);
+
+ widget = gtk_button_new_with_label ("A button which does almost nothing");
+ g_signal_connect (widget, "clicked", G_CALLBACK (_button_clicked_cb), window);
+ gtk_box_pack_start (GTK_BOX (plug), widget, FALSE, FALSE, 6);
+
+ g_free (entry_txt);
+ g_free (plug_id);
+
+ gtk_container_add (GTK_CONTAINER (window), plug);
+
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ WINDOW_WIDTH, WINDOW_HEIGHT);
+ gtk_widget_show_all (window);
+ gtk_main ();
+}
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/socket/Makefile b/src/examples/elementary/a11y/efl-gtk-integration/socket/Makefile
new file mode 100644
index 0000000000..1266623c9b
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/socket/Makefile
@@ -0,0 +1,20 @@
+CC=gcc
+TARGET=ta-socket
+SOURCES=ta-socket.c \
+ ta-socket-label.h \
+ ta-socket-label.c \
+ ta-socket-accessible.h \
+ ta-socket-accessible.c
+
+LIBS=atk gtk+-3.0
+CFLAGS=`pkg-config --cflags $(LIBS)`
+LDFLAGS=`pkg-config --libs $(LIBS)`
+
+all: compile
+
+compile:
+ $(CC) -o $(TARGET) $(SOURCES) $(CFLAGS) $(LDFLAGS)
+
+clean:
+ rm -rf $(TARGET)
+ rm -rf *~
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-accessible.c b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-accessible.c
new file mode 100644
index 0000000000..01db3ad2a6
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-accessible.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include "ta-socket-accessible.h"
+
+#include <atk/atk.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_DEFINE_TYPE (TaSocketAccessible, ta_socket_accessible, ATK_TYPE_SOCKET);
+
+static const gchar *ta_socket_accessible_get_name (AtkObject *object)
+{
+ g_return_val_if_fail(ATK_IS_OBJECT (object), NULL);
+ return "The Socket";
+}
+
+static AtkRole ta_socket_accessible_get_role (AtkObject *object)
+{
+ g_return_val_if_fail(ATK_IS_OBJECT (object), ATK_ROLE_UNKNOWN);
+ return ATK_ROLE_PANEL;
+}
+
+static void ta_socket_accessible_class_init (TaSocketAccessibleClass *klass)
+{
+ AtkObjectClass *atk_object_class = NULL;
+
+ atk_object_class = ATK_OBJECT_CLASS (klass);
+ atk_object_class->get_name = ta_socket_accessible_get_name;
+ atk_object_class->get_role = ta_socket_accessible_get_role;
+}
+
+static void ta_socket_accessible_init(TaSocketAccessible *socket)
+{
+}
+
+AtkObject *ta_socket_accessible_new (void)
+{
+ return ATK_OBJECT (g_object_new(TA_TYPE_SOCKET_ACCESSIBLE, 0));
+}
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-accessible.h b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-accessible.h
new file mode 100644
index 0000000000..55c35f80cd
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-accessible.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#ifndef TaSocketAccessible_h
+#define TaSocketAccessible_h
+
+#include <atk/atk.h>
+
+G_BEGIN_DECLS
+
+#define TA_TYPE_SOCKET_ACCESSIBLE (ta_socket_accessible_get_type ())
+#define TA_SOCKET_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TA_TYPE_SOCKET_ACCESSIBLE, TaSocketAccessible))
+#define TA_SOCKET_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TA_TYPE_SOCKET_ACCESSIBLE, TaSocketAccessibleClass))
+#define TA_IS_SOCKET_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TA_TYPE_SOCKET_ACCESSIBLE))
+#define TA_IS_SOCKET_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TA_TYPE_SOCKET_ACCESSIBLE))
+#define TA_SOCKET_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TA_TYPE_SOCKET_ACCESSIBLE, TaSocketAccessibleClass))
+
+typedef struct _TaSocketAccessible TaSocketAccessible;
+typedef struct _TaSocketAccessibleClass TaSocketAccessibleClass;
+typedef struct _TaSocketAccessiblePrivate TaSocketAccessiblePrivate;
+
+struct _TaSocketAccessible {
+ AtkSocket parent;
+};
+
+struct _TaSocketAccessibleClass {
+ AtkSocketClass parentClass;
+};
+
+GType ta_socket_accessible_get_type(void) G_GNUC_CONST;
+
+AtkObject *ta_socket_accessible_new (void);
+
+G_END_DECLS
+
+#endif // TaSocketAccessible_h
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-label.c b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-label.c
new file mode 100644
index 0000000000..4141205c0c
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-label.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include "ta-socket-label.h"
+
+#include "ta-socket-accessible.h"
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_DEFINE_TYPE (TaSocketLabel, ta_socket_label, GTK_TYPE_LABEL);
+
+
+static AtkObject *_get_accessible (GtkWidget *widget)
+{
+ static AtkObject *new = NULL;
+
+ if (!new)
+ {
+ new = ta_socket_accessible_new ();
+ atk_object_initialize (new, G_OBJECT (widget));
+ }
+
+ return new;
+}
+
+static void ta_socket_label_class_init (TaSocketLabelClass *klass)
+{
+ GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+
+ widget_class->get_accessible = _get_accessible;
+}
+
+static void ta_socket_label_init(TaSocketLabel *socket)
+{
+}
+
+GtkWidget *ta_socket_label_new (const gchar *text)
+{
+ return GTK_WIDGET (g_object_new(TA_TYPE_SOCKET_LABEL,
+ "label", text,
+ 0));
+}
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-label.h b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-label.h
new file mode 100644
index 0000000000..a2b60ced6b
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket-label.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#ifndef TaSocketLabel_h
+#define TaSocketLabel_h
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define TA_TYPE_SOCKET_LABEL (ta_socket_label_get_type ())
+#define TA_SOCKET_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TA_TYPE_SOCKET_LABEL, TaSocketLabel))
+#define TA_SOCKET_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TA_TYPE_SOCKET_LABEL, TaSocketLabelClass))
+#define TA_IS_SOCKET_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TA_TYPE_SOCKET_LABEL))
+#define TA_IS_SOCKET_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TA_TYPE_SOCKET_LABEL))
+#define TA_SOCKET_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TA_TYPE_SOCKET_LABEL, TaSocketLabelClass))
+
+typedef struct _TaSocketLabel TaSocketLabel;
+typedef struct _TaSocketLabelClass TaSocketLabelClass;
+typedef struct _TaSocketLabelPrivate TaSocketLabelPrivate;
+
+struct _TaSocketLabel {
+ GtkLabel parent;
+};
+
+struct _TaSocketLabelClass {
+ GtkLabelClass parentClass;
+};
+
+GType ta_socket_label_get_type(void) G_GNUC_CONST;
+
+GtkWidget *ta_socket_label_new (const gchar *text);
+
+G_END_DECLS
+
+#endif // TaSocketLabel_h
diff --git a/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket.c b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket.c
new file mode 100644
index 0000000000..700021b924
--- /dev/null
+++ b/src/examples/elementary/a11y/efl-gtk-integration/socket/ta-socket.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Authors: Mario Sanchez Prada <msanchez@igalia.com>
+ *
+ * Based on a C# example written in C# by Mike Gorse:
+ * http://mgorse.freeshell.org/plug-socket-test.tar.gz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+#include "ta-socket-label.h"
+
+#include <gtk/gtk.h>
+
+#define WINDOW_WIDTH 300
+#define WINDOW_HEIGHT -1
+
+static GtkWidget *entry = NULL;
+static GtkWidget *button = NULL;
+static GtkWidget *socket = NULL;
+
+static void
+_button_clicked_cb (GtkButton *button, gpointer data)
+{
+ AtkObject *socketAxObject = NULL;
+ gchar *text_id = NULL;
+
+ text_id = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+
+ if (text_id && text_id[0] != '\0')
+ {
+ socketAxObject = gtk_widget_get_accessible (socket);
+
+ if (ATK_IS_SOCKET (socketAxObject))
+ {
+ g_print ("[SOCKET] Embedding object with ID %s\n", text_id);
+ atk_socket_embed (ATK_SOCKET (socketAxObject), text_id);
+ g_print ("[SOCKET] Done\n");
+ }
+ else
+ g_print ("Not embedding anything: Not an instance of AtkSocket\n");
+ }
+ else
+ g_print ("Not embedding: you need to provide an ID\n");
+
+ g_free (text_id);
+}
+
+static void
+_create_widgets (GtkWidget *window)
+{
+ GtkWidget *vbox = NULL;
+
+ vbox = gtk_vbox_new (FALSE, 0);
+
+ /* Label + entry */
+ entry = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 6);
+
+ button = gtk_button_new_with_label ("Connect to plug");
+ g_signal_connect (button, "clicked", G_CALLBACK (_button_clicked_cb), NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 6);
+
+ /* Our socket accessible */
+ socket = ta_socket_label_new ("Socket accessible goes here");
+ gtk_box_pack_start (GTK_BOX (vbox), socket, FALSE, FALSE, 6);
+
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+}
+
+int
+main (int argc, char**argv)
+{
+ GtkWidget *window = NULL;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+ _create_widgets (window);
+
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ WINDOW_WIDTH, WINDOW_HEIGHT);
+ gtk_widget_show_all (window);
+ gtk_main ();
+}
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index e05cd690f1..8690719593 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -172,6 +172,7 @@ EAPI extern Elm_Version *elm_version;
#include <elm_scroller.h>
#include <elm_entry.h>
#include <elm_list.h>
+#include <elm_atspi_proxy.h>
/* Interfaces */
#include <elm_interfaces.h>
@@ -190,7 +191,8 @@ EAPI extern Elm_Version *elm_version;
#include <elm_actionslider.h>
#include <elm_app.h>
#include <elm_atspi_app_object.h>
-#include <elm_atspi_proxy.h>
+#include <elm_atspi_plug.h>
+#include <elm_atspi_socket.h>
#include <elm_atspi_bridge.h>
#include <elm_bg.h>
#include <elm_box.h>
diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c
index b7cf93a44f..fa6317fa27 100644
--- a/src/lib/elementary/efl_ui_win.c
+++ b/src/lib/elementary/efl_ui_win.c
@@ -2273,7 +2273,7 @@ _efl_ui_win_show(Eo *obj, Efl_Ui_Win_Data *sd)
TRAP(sd, show);
- if (_elm_config->atspi_mode)
+ if (sd->type != ELM_WIN_SOCKET_IMAGE)
{
Eo *root = elm_interface_atspi_accessible_root_get(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN);
elm_interface_atspi_accessible_parent_set(obj, root);
@@ -6470,7 +6470,6 @@ _on_atspi_bus_connected(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUS
Evas_Object *win;
Eina_List *l;
- Eo *root = elm_interface_atspi_accessible_root_get(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN);
EINA_LIST_FOREACH(_elm_win_list, l, win)
{
/**
@@ -6479,7 +6478,7 @@ _on_atspi_bus_connected(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUS
* receive all org.a11y.window events and could keep track of active
* windows whithin system.
*/
- elm_interface_atspi_accessible_parent_set(win, root);
+ ERR("Reemit created");
elm_interface_atspi_window_created_signal_emit(win);
if (elm_win_focus_get(win))
{
diff --git a/src/lib/elementary/elm_atspi_app_object.c b/src/lib/elementary/elm_atspi_app_object.c
index 00ec5dfb29..a64ac43d81 100644
--- a/src/lib/elementary/elm_atspi_app_object.c
+++ b/src/lib/elementary/elm_atspi_app_object.c
@@ -8,10 +8,15 @@
#include "elm_widget.h"
#include "elm_priv.h"
+#include "atspi/atspi-constants.h"
+
+#define ATSPI_REGISTRYD_ROOT_ID ATSPI_DBUS_NAME_REGISTRY ":" ATSPI_DBUS_PATH_ROOT
+
typedef struct _Elm_Atspi_App_Object_Data Elm_Atspi_App_Object_Data;
struct _Elm_Atspi_App_Object_Data
{
+ Elm_Atspi_Proxy *desktop_proxy;
const char *descr;
};
@@ -19,10 +24,20 @@ EOLIAN static void
_elm_atspi_app_object_efl_object_destructor(Eo *obj EINA_UNUSED, Elm_Atspi_App_Object_Data *_pd)
{
if (_pd->descr) eina_stringshare_del(_pd->descr);
-
efl_destructor(efl_super(obj, ELM_ATSPI_APP_OBJECT_CLASS));
}
+EOLIAN static Eo*
+_elm_atspi_app_object_efl_object_constructor(Eo *obj, Elm_Atspi_App_Object_Data *_pd)
+{
+ efl_constructor(efl_super(obj, ELM_ATSPI_APP_OBJECT_CLASS));
+ _pd->desktop_proxy = efl_add(ELM_ATSPI_PROXY_CLASS, obj, elm_atspi_proxy_id_constructor(efl_added, ATSPI_REGISTRYD_ROOT_ID));
+
+ elm_interface_atspi_accessible_parent_set(obj, _pd->desktop_proxy);
+
+ return obj;
+}
+
EOLIAN static const char*
_elm_atspi_app_object_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Atspi_App_Object_Data *_pd EINA_UNUSED)
{
@@ -49,4 +64,30 @@ _elm_atspi_app_object_elm_interface_atspi_accessible_role_get(Eo *obj EINA_UNUSE
return ELM_ATSPI_ROLE_APPLICATION;
}
+EOLIAN static void
+_elm_atspi_app_object_elm_interface_atspi_socket_on_connected(Eo *obj, Elm_Atspi_App_Object_Data *_pd)
+{
+ ERR("On Connected: %s", elm_interface_atspi_socket_id_get(obj));
+ elm_interface_atspi_socket_embed_by(obj, _pd->desktop_proxy);
+}
+
+EOLIAN static void
+_elm_atspi_app_object_elm_interface_atspi_socket_on_disconnected(Eo *obj EINA_UNUSED, Elm_Atspi_App_Object_Data *_pd EINA_UNUSED)
+{
+ ERR("On Disconnected: %s", elm_interface_atspi_socket_id_get(obj));
+ elm_interface_atspi_socket_unembed_by(obj, _pd->desktop_proxy);
+}
+
+EOLIAN static void
+_elm_atspi_app_object_elm_interface_atspi_socket_on_embedded(Eo *obj EINA_UNUSED, Elm_Atspi_App_Object_Data *_pd EINA_UNUSED, Elm_Atspi_Proxy *proxy EINA_UNUSED)
+{
+ ERR("Application successfully registered as desktop child");
+}
+
+EOLIAN static int
+_elm_atspi_app_object_elm_interface_atspi_accessible_index_in_parent_get(Eo *obj EINA_UNUSED, Elm_Atspi_App_Object_Data *_pd EINA_UNUSED)
+{
+ return -1;
+}
+
#include "elm_atspi_app_object.eo.c"
diff --git a/src/lib/elementary/elm_atspi_app_object.eo b/src/lib/elementary/elm_atspi_app_object.eo
index dbcaacd8c9..a48697dae3 100644
--- a/src/lib/elementary/elm_atspi_app_object.eo
+++ b/src/lib/elementary/elm_atspi_app_object.eo
@@ -1,12 +1,17 @@
-class Elm.Atspi.App.Object (Efl.Object, Elm.Interface.Atspi_Accessible)
+class Elm.Atspi.App.Object (Elm.Atspi.Plug, Elm.Interface.Atspi_Accessible)
{
[[AT-SPI application object class]]
legacy_prefix: elm_atspi_app_object;
data: Elm_Atspi_App_Object_Data;
implements {
+ Efl.Object.constructor;
Efl.Object.destructor;
Elm.Interface.Atspi_Accessible.name { get; }
Elm.Interface.Atspi_Accessible.description { get; set; }
Elm.Interface.Atspi_Accessible.role { get; }
+ Elm.Interface.Atspi_Accessible.index_in_parent { get; }
+ Elm.Interface.Atspi.Socket.on_embedded;
+ Elm.Interface.Atspi.Socket.on_connected;
+ Elm.Interface.Atspi.Socket.on_disconnected;
}
}
diff --git a/src/lib/elementary/elm_atspi_bridge.c b/src/lib/elementary/elm_atspi_bridge.c
index 1f418d47f5..ff89370761 100644
--- a/src/lib/elementary/elm_atspi_bridge.c
+++ b/src/lib/elementary/elm_atspi_bridge.c
@@ -8,6 +8,7 @@
#define ELM_INTERFACE_ATSPI_VALUE_PROTECTED
#define ELM_INTERFACE_ATSPI_IMAGE_PROTECTED
#define ELM_INTERFACE_ATSPI_SELECTION_PROTECTED
+#define ELM_INTERFACE_ATSPI_SOCKET_PROTECTED
#define ELM_INTERFACE_ATSPI_TEXT_PROTECTED
#define ELM_INTERFACE_ATSPI_TEXT_EDITABLE_PROTECTED
@@ -16,6 +17,7 @@
#include <stdint.h>
#include <Elementary.h>
#include "elm_priv.h"
+#include <assert.h>
/*
* Accessibility Bus info not defined in atspi-constants.h
@@ -92,13 +94,14 @@ typedef struct _Elm_Atspi_Bridge_Data
Eldbus_Service_Interface *selection;
Eldbus_Service_Interface *text;
Eldbus_Service_Interface *value;
+ Eldbus_Service_Interface *socket;
} interfaces;
Eo *root;
+ Eina_List *plugs;
Eldbus_Pending *connect_request;
Eldbus_Pending *stack_status_request;
Eldbus_Proxy *status_proxy;
Eina_Bool connected : 1;
- Eina_Bool registered: 1;
} Elm_Atspi_Bridge_Data;
@@ -115,8 +118,12 @@ struct collection_match_rule {
Eina_Bool auto_register : 1;
};
-static Eo *_instance;
-static int _init_count = 0;
+struct dbus_address {
+ char bus[256];
+ char path[256];
+};
+
+static Elm_Atspi_Bridge *_instance;
// Object Event handlers
static void _state_changed_signal_send(void *data, const Efl_Event *event);
@@ -135,7 +142,7 @@ static void _text_selection_changed_send(void *data, const Efl_Event *event);
// bridge private methods
static void _bridge_object_register(Eo *bridge, Eo *obj);
static void _bridge_object_unregister(Eo *bridge, Eo *obj);
-static void _elm_atspi_bridge_address_from_object(Eo *bridge, const Eo *eo, const char **bus, const char **path);
+static struct dbus_address _elm_atspi_bridge_address_from_object(Eo *bridge, const Eo *eo);
static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *ifc, const Eldbus_Signal *signal, const char *minor, unsigned int det1, unsigned int det2, const char *variant_sig, ...);
static Eo * _bridge_object_from_path(Eo *bridge, const char *path);
static void _bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj);
@@ -144,16 +151,20 @@ static void _elm_atspi_bridge_disconnect(Elm_Atspi_Bridge *bridge);
static void _elm_atspi_bridge_on_disconnected(Elm_Atspi_Bridge *bridge);
static void _elm_atspi_bridge_connect(Elm_Atspi_Bridge *bridge);
static void _elm_atspi_bridge_on_connected(Elm_Atspi_Bridge *bridge);
-static void _elm_atspi_bridge_pending_add(Elm_Atspi_Bridge *obj, Eldbus_Pending *pending);
+static void _elm_atspi_bridge_pending_add(Elm_Atspi_Bridge *obj, Eldbus_Pending *pending, Eldbus_Free_Cb cb, const void *data);
static void _elm_atspi_bridge_pending_del(Elm_Atspi_Bridge *obj, Eldbus_Pending *pending);
static void _elm_atspi_bridge_pending_cancel_all(Elm_Atspi_Bridge *obj);
+static void _elm_atspi_bridge_socket_hooks_uninstall(Elm_Interface_Atspi_Socket *socket);
+static void _elm_atspi_bridge_socket_hooks_install(Elm_Interface_Atspi_Socket *socket);
+
// utility functions
static void _iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj);
static Eina_Bool _elm_atspi_bridge_key_filter(void *data, void *loop, int type, void *event);
-static void _object_desktop_reference_append(Eldbus_Message_Iter *iter);
static void _bridge_object_added_signal_send(Elm_Atspi_Bridge *bridge, Eo *object);
static void _bridge_object_removed_signal_send(Elm_Atspi_Bridge *bridge, Eo *object);
+static Eina_Bool _elm_atspi_bridge_id_parse(const char *id, struct dbus_address *addr);
+static char *_elm_atspi_bridge_id_make(const struct dbus_address *addr);
EFL_CALLBACKS_ARRAY_DEFINE(event_handlers,
{ ELM_INTERFACE_ATSPI_ACCESSIBLE_EVENT_CHILDREN_CHANGED, _children_changed_signal_send},
@@ -1023,6 +1034,26 @@ static const Eldbus_Method selection_methods[] = {
};
static Eldbus_Message *
+_socket_embedded(const Eldbus_Service_Interface *iface, const Eldbus_Message *msg)
+{
+ const char *obj_path = eldbus_message_path_get(msg);
+ Eo *bridge = eldbus_service_object_data_get(iface, ELM_ATSPI_BRIDGE_CLASS_NAME);
+ Eo *obj = _bridge_object_from_path(bridge, obj_path);
+
+ ERR("Recieved embedded request");
+ ELM_ATSPI_OBJ_CHECK_OR_RETURN_DBUS_ERROR(obj, ELM_INTERFACE_ATSPI_SOCKET_MIXIN, msg);
+
+ elm_interface_atspi_socket_on_embedded(obj, NULL);
+
+ return eldbus_message_method_return_new(msg);
+}
+
+static const Eldbus_Method socket_methods[] = {
+ { "Embedded", ELDBUS_ARGS({"(so)", "parentObject"}), NULL, _socket_embedded, 0 },
+ { 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_message_path_get(msg);
@@ -2034,35 +2065,39 @@ _bridge_object_from_path(Eo *bridge, const char *path)
return ret;
}
-static void
-_elm_atspi_bridge_address_from_object(Eo *bridge, const Eo *eo, const char **bus, const char **path)
+static struct dbus_address
+_elm_atspi_bridge_address_from_object(Eo *bridge, const Eo *eo)
{
- static char buf[64];
+ struct dbus_address ret = {{0,}};
- ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN_VAL(bridge, pd, ret);
if (!eo)
{
- if (bus) *bus = eldbus_connection_unique_name_get(pd->a11y_bus);
- if (path) *path = ATSPI_DBUS_PATH_NULL;
+ snprintf(ret.bus, sizeof(ret.bus), "%s", eldbus_connection_unique_name_get(pd->a11y_bus));
+ snprintf(ret.path, sizeof(ret.path), "%s", ATSPI_DBUS_PATH_NULL);
}
else if (eo == pd->root)
{
- snprintf(buf, sizeof(buf), "%s%s", ELM_ACCESS_OBJECT_PATH_PREFIX, ELM_ACCESS_OBJECT_PATH_ROOT);
- if (bus) *bus = eldbus_connection_unique_name_get(pd->a11y_bus);
- if (path) *path = buf;
+ snprintf(ret.bus, sizeof(ret.bus), "%s", eldbus_connection_unique_name_get(pd->a11y_bus));
+ snprintf(ret.path, sizeof(ret.path), "%s%s", ELM_ACCESS_OBJECT_PATH_PREFIX, ELM_ACCESS_OBJECT_PATH_ROOT);
}
else if (efl_isa(eo, ELM_ATSPI_PROXY_CLASS))
{
- if (bus) *bus = elm_atspi_proxy_bus_name_get(eo);
- if (path) *path = elm_atspi_proxy_path_get(eo);
+ if (!_elm_atspi_bridge_id_parse(elm_atspi_proxy_id_get(eo), &ret))
+ {
+ ERR("Unable to parse id: %s", elm_atspi_proxy_id_get(eo));
+ snprintf(ret.bus, sizeof(ret.bus), "%s", eldbus_connection_unique_name_get(pd->a11y_bus));
+ snprintf(ret.path, sizeof(ret.path), "%s", ATSPI_DBUS_PATH_NULL);
+ }
}
else
{
- snprintf(buf, sizeof(buf), ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE, (unsigned long long)(uintptr_t)eo);
- if (bus) *bus = eldbus_connection_unique_name_get(pd->a11y_bus);
- if (path) *path = buf;
+ snprintf(ret.bus, sizeof(ret.bus), "%s", eldbus_connection_unique_name_get(pd->a11y_bus));
+ snprintf(ret.path, sizeof(ret.path), ELM_ACCESS_OBJECT_REFERENCE_TEMPLATE, (unsigned long long)(uintptr_t)eo);
}
+
+ return ret;
}
static Eina_Bool
@@ -2095,12 +2130,7 @@ _accessible_property_get(const Eldbus_Service_Interface *interface, const char *
else if (!strcmp(property, "Parent"))
{
ret_obj = elm_interface_atspi_accessible_parent_get(obj);
- Elm_Atspi_Role role = ELM_ATSPI_ROLE_INVALID;
- role = elm_interface_atspi_accessible_role_get(obj);
- if ((!ret_obj) && (ELM_ATSPI_ROLE_APPLICATION == role))
- _object_desktop_reference_append(iter);
- else
- _bridge_iter_object_reference_append(bridge, iter, ret_obj);
+ _bridge_iter_object_reference_append(bridge, iter, ret_obj);
return EINA_TRUE;
}
else if (!strcmp(property, "ChildCount"))
@@ -2404,6 +2434,10 @@ static const Eldbus_Service_Interface_Desc selection_iface_desc = {
ATSPI_DBUS_INTERFACE_SELECTION, selection_methods, NULL, selection_properties, NULL, NULL
};
+static const Eldbus_Service_Interface_Desc socket_iface_desc = {
+ ATSPI_DBUS_INTERFACE_SOCKET, socket_methods, NULL, NULL, NULL, NULL
+};
+
static const Eldbus_Service_Interface_Desc text_iface_desc = {
ATSPI_DBUS_INTERFACE_TEXT, text_methods, NULL, text_properties, _text_properties_get, NULL
};
@@ -3090,30 +3124,19 @@ static const Eldbus_Service_Interface_Desc collection_iface_desc = {
static void
_bridge_iter_object_reference_append(Eo *bridge, Eldbus_Message_Iter *iter, const Eo *obj)
{
- const char *path, *bus;
+ struct dbus_address addr;
ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
EINA_SAFETY_ON_NULL_RETURN(iter);
- _elm_atspi_bridge_address_from_object(bridge, obj, &bus, &path);
+ addr = _elm_atspi_bridge_address_from_object(bridge, obj);
- eldbus_message_iter_basic_append(iter_struct, 's', bus);
- eldbus_message_iter_basic_append(iter_struct, 'o', path);
+ eldbus_message_iter_basic_append(iter_struct, 's', addr.bus);
+ eldbus_message_iter_basic_append(iter_struct, 'o', addr.path);
eldbus_message_iter_container_close(iter, iter_struct);
}
static void
-_object_desktop_reference_append(Eldbus_Message_Iter *iter)
-{
- Eldbus_Message_Iter *iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
- EINA_SAFETY_ON_NULL_RETURN(iter);
-
- eldbus_message_iter_basic_append(iter_struct, 's', ATSPI_DBUS_NAME_REGISTRY);
- eldbus_message_iter_basic_append(iter_struct, 'o', ATSPI_DBUS_PATH_ROOT);
- eldbus_message_iter_container_close(iter, iter_struct);
-}
-
-static void
_iter_interfaces_append(Eldbus_Message_Iter *iter, const Eo *obj)
{
Eldbus_Message_Iter *iter_array;
@@ -3167,13 +3190,9 @@ _cache_item_reference_append_cb(Eo *bridge, Eo *data, Eldbus_Message_Iter *iter_
/* Marshall application */
_bridge_iter_object_reference_append(bridge, iter_struct, pd->root);
- Eo *parent = NULL;
- parent = elm_interface_atspi_accessible_parent_get(data);
/* Marshall parent */
- if ((!parent) && (ELM_ATSPI_ROLE_APPLICATION == role))
- _object_desktop_reference_append(iter_struct);
- else
- _bridge_iter_object_reference_append(bridge, iter_struct, parent);
+ Eo *parent = parent = elm_interface_atspi_accessible_parent_get(data);
+ _bridge_iter_object_reference_append(bridge, iter_struct, parent);
/* Marshall children */
Eina_List *children_list = NULL, *l;
@@ -3258,6 +3277,9 @@ _cache_get_items(const Eldbus_Service_Interface *iface, const Eldbus_Message *ms
{
Eo *obj = eina_list_data_get(to_process);
to_process = eina_list_remove_list(to_process, to_process);
+
+ // FIXME do not return references to non-local objects in cache
+ if (efl_isa(obj, ELM_ATSPI_PROXY_CLASS)) continue;
_cache_item_reference_append_cb(bridge, obj, iter_array);
Eina_List *children;
@@ -3609,78 +3631,54 @@ static const Eldbus_Service_Interface_Desc component_iface_desc = {
};
static void
-_on_elm_atspi_bridge_root_register(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
+_on_elm_atspi_bridge_plug_register(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
{
const char *errname, *errmsg;
Elm_Atspi_Bridge *bridge = data;
ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ _elm_atspi_bridge_pending_del(bridge, pending);
+
if (eldbus_message_error_get(msg, &errname, &errmsg))
{
ERR("%s %s", errname, errmsg);
return;
}
- pd->registered = EINA_TRUE;
- _elm_atspi_bridge_pending_del(bridge, pending);
- DBG("Application successfuly registered at ATSPI2 bus.");
+ Eo *obj = eldbus_pending_data_get(pending, "__obj");
+ Eo *proxy = eldbus_pending_data_get(pending, "__proxy");
+
+ // check if object is still in cache, since it may be unregistered
+ // before dbus request complete
+ if (eina_hash_find(pd->cache, &obj))
+ elm_interface_atspi_socket_on_embedded(obj, proxy);
}
EAPI void
-_elm_atspi_bridge_root_register(Eo *bridge)
+_elm_atspi_bridge_plugs_register(Eo *bridge)
{
ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
- if (!pd->root) return;
-
- Eldbus_Pending *register_req;
- Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
- ATSPI_DBUS_PATH_ROOT,
- ATSPI_DBUS_INTERFACE_SOCKET,
- "Embed");
- if (!message) return;
- Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
- if (!iter)
- {
- ERR("eldbus_message_iter_get failed");
- eldbus_message_unref(message);
- return;
- }
+ assert (pd->connected);
+ Eina_List *l;
+ Elm_Atspi_Plug *plug;
- _bridge_iter_object_reference_append(bridge, iter, pd->root);
- register_req = eldbus_connection_send(pd->a11y_bus, message, _on_elm_atspi_bridge_root_register, bridge, -1);
- if (!register_req)
+ EINA_LIST_FOREACH(pd->plugs, l, plug)
{
- ERR("eldbus_connection_send failed");
- eldbus_message_unref(message);
- return;
+ _bridge_object_register(bridge, plug);
}
-
- _bridge_object_register(bridge, pd->root);
- _elm_atspi_bridge_pending_add(bridge, register_req);
}
EAPI void
-_elm_atspi_bridge_root_unregister(Elm_Atspi_Bridge *bridge)
+_elm_atspi_bridge_plugs_unregister(Elm_Atspi_Bridge *bridge)
{
ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ assert (!pd->connected);
+ Eina_List *l;
+ Elm_Atspi_Plug *plug;
- if (!pd->registered) return;
-
- Eldbus_Message *message = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY,
- ATSPI_DBUS_PATH_ROOT,
- ATSPI_DBUS_INTERFACE_SOCKET,
- "Unembed");
- if (!message) return;
- Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
- if (!iter)
+ EINA_LIST_FOREACH(pd->plugs, l, plug)
{
- ERR("eldbus_message_iter_get failed");
- eldbus_message_unref(message);
- return;
+ _bridge_object_unregister(bridge, plug);
}
-
- _bridge_iter_object_reference_append(bridge, iter, pd->root);
- _bridge_object_unregister(bridge, pd->root);
- eldbus_connection_send(pd->a11y_bus, message, NULL, NULL, -1);
}
static void
@@ -3819,7 +3817,7 @@ _registered_events_list_update(Eo *bridge)
msg = eldbus_message_method_call_new(ATSPI_DBUS_NAME_REGISTRY, ATSPI_DBUS_PATH_REGISTRY, ATSPI_DBUS_INTERFACE_REGISTRY, "GetRegisteredEvents");
p = eldbus_connection_send(pd->a11y_bus, msg, _registered_listeners_get, bridge, -1);
- _elm_atspi_bridge_pending_add(bridge, p);
+ _elm_atspi_bridge_pending_add(bridge, p, NULL, NULL);
}
static void
@@ -4053,7 +4051,7 @@ static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *infc, const Eld
Eldbus_Message_Iter *iter , *iter_stack[64], *iter_struct;
va_list va;
Eo *atspi_obj;
- const char *path, *bus;
+ struct dbus_address addr;
int top = 0;
EINA_SAFETY_ON_NULL_RETURN(infc);
@@ -4062,9 +4060,9 @@ static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *infc, const Eld
EINA_SAFETY_ON_NULL_RETURN(obj);
ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
- _elm_atspi_bridge_address_from_object(bridge, obj, NULL, &path);
+ addr = _elm_atspi_bridge_address_from_object(bridge, obj);
- msg = eldbus_message_signal_new(path, infc, signal->name);
+ msg = eldbus_message_signal_new(addr.path, infc, signal->name);
if (!msg) return;
va_start(va, variant_sig);
@@ -4093,8 +4091,8 @@ static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *infc, const Eld
break;
case 'o':
atspi_obj = va_arg(va, Eo*);
- _elm_atspi_bridge_address_from_object(bridge, atspi_obj, NULL, &path);
- eldbus_message_iter_basic_append(iter_stack[top], 'o', path);
+ addr = _elm_atspi_bridge_address_from_object(bridge, atspi_obj);
+ eldbus_message_iter_basic_append(iter_stack[top], 'o', addr.path);
break;
case ')':
eldbus_message_iter_container_close(iter_stack[top - 1], iter_stack[top]);
@@ -4120,9 +4118,9 @@ static void _bridge_signal_send(Eo *bridge, Eo *obj, const char *infc, const Eld
eldbus_message_iter_container_close(iter, iter_stack[0]);
iter_struct = eldbus_message_iter_container_new(iter, 'r', NULL);
- _elm_atspi_bridge_address_from_object(bridge, pd->root, &bus, &path);
- eldbus_message_iter_basic_append(iter_struct, 's', bus);
- eldbus_message_iter_basic_append(iter_struct, 'o', path);
+ addr = _elm_atspi_bridge_address_from_object(bridge, pd->root);
+ eldbus_message_iter_basic_append(iter_struct, 's', addr.bus);
+ eldbus_message_iter_basic_append(iter_struct, 'o', addr.path);
eldbus_message_iter_container_close(iter, iter_struct);
eldbus_connection_send(pd->a11y_bus, msg, NULL, NULL, -1);
@@ -4209,6 +4207,41 @@ _elm_atspi_bridge_event_handlers_unregister(Eo *bridge)
}
static void
+_elm_atspi_bridge_on_object_unregistered(Elm_Atspi_Bridge *bridge, Eo *obj)
+{
+ efl_event_callback_array_del(obj, event_handlers(), bridge);
+ _bridge_object_removed_signal_send(bridge, obj);
+
+ if (efl_isa(obj, ELM_INTERFACE_ATSPI_SOCKET_MIXIN))
+ {
+ elm_interface_atspi_socket_on_disconnected(obj);
+ elm_interface_atspi_socket_id_set(obj, NULL);
+ _elm_atspi_bridge_socket_hooks_uninstall(obj);
+ }
+}
+
+static void
+_elm_atspi_bridge_on_object_registered(Elm_Atspi_Bridge *bridge, Eo *obj)
+{
+ struct dbus_address addr;
+ if (!efl_isa(obj, ELM_ATSPI_PROXY_CLASS))
+ {
+ _bridge_object_added_signal_send(bridge, obj);
+ efl_event_callback_array_add(obj, event_handlers(), bridge);
+ }
+
+ if (efl_isa(obj, ELM_INTERFACE_ATSPI_SOCKET_MIXIN))
+ {
+ _elm_atspi_bridge_socket_hooks_install(obj);
+ addr = _elm_atspi_bridge_address_from_object(bridge, obj);
+ char *id = _elm_atspi_bridge_id_make(&addr);
+ elm_interface_atspi_socket_id_set(obj, id);
+ elm_interface_atspi_socket_on_connected(obj);
+ free(id);
+ }
+}
+
+static void
_bridge_object_unregister(Eo *bridge, Eo *obj)
{
ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
@@ -4224,8 +4257,8 @@ _bridge_object_unregister(Eo *bridge, Eo *obj)
continue;
eina_hash_del(pd->cache, &o, o);
- efl_event_callback_array_del(o, event_handlers(), bridge);
- _bridge_object_removed_signal_send(bridge, o);
+
+ _elm_atspi_bridge_on_object_unregistered(bridge, o);
Eina_List *children;
children = elm_interface_atspi_accessible_children_get(o);
@@ -4240,6 +4273,7 @@ _bridge_object_added_signal_send(Elm_Atspi_Bridge *bridge, Eo *object)
Eldbus_Message_Iter *iter;
ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ if (!pd->connected) return;
sig = eldbus_service_signal_new(pd->cache_interface, ATSPI_OBJECT_CHILD_ADDED);
iter = eldbus_message_iter_get(sig);
@@ -4332,6 +4366,9 @@ _elm_atspi_bridge_interfaces_register(Eo *bridge)
pd->interfaces.value =
eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &value_iface_desc);
eldbus_service_object_data_set(pd->interfaces.value, ELM_ATSPI_BRIDGE_CLASS_NAME, bridge);
+
+ pd->interfaces.socket =
+ eldbus_service_interface_fallback_register(pd->a11y_bus, ELM_ACCESS_OBJECT_PATH_PREFIX2, &socket_iface_desc);
}
static void
@@ -4433,8 +4470,8 @@ static void _bridge_object_register(Eo *bridge, Eo *obj)
continue;
eina_hash_add(pd->cache, &o, o);
- _bridge_object_added_signal_send(bridge, o);
- efl_event_callback_array_add(o, event_handlers(), bridge);
+
+ _elm_atspi_bridge_on_object_registered(bridge, o);
Eina_List *children;
children = elm_interface_atspi_accessible_children_get(o);
@@ -4445,12 +4482,13 @@ static void _bridge_object_register(Eo *bridge, Eo *obj)
void
_elm_atspi_bridge_init(void)
{
- if (!_init_count)
+ if (!_instance)
{
_instance = efl_add(ELM_ATSPI_BRIDGE_CLASS, NULL);
Efl_Object *root = elm_interface_atspi_accessible_root_get(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN);
+ elm_atspi_bridge_plug_register(_instance, root);
elm_atspi_bridge_root_set(_instance, root);
- _init_count = 1;
+ elm_interface_atspi_accessible_observer_install(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN);
}
}
@@ -4463,10 +4501,11 @@ _elm_atspi_bridge_get(void)
void
_elm_atspi_bridge_shutdown(void)
{
- if (_init_count)
+ if (_instance)
{
+ elm_interface_atspi_accessible_observer_uninstall(ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN);
efl_del(_instance);
- _init_count = 0;
+ _instance = NULL;
}
}
@@ -4700,6 +4739,132 @@ _elm_atspi_bridge_platform_a11y_status_monitor_shutdown(Elm_Atspi_Bridge *bridge
if (pd->bus_obj) eldbus_object_unref(pd->bus_obj);
}
+static Eldbus_Message*
+_elm_atspi_bridge_method_call_to_proxy_new(Elm_Atspi_Proxy *proxy, const char *interface, const char *method)
+{
+ struct dbus_address addr = {{0, }};
+
+ if (!_elm_atspi_bridge_id_parse(elm_atspi_proxy_id_get(proxy), &addr))
+ {
+ ERR("Unable to parset elm_atspi_proxy id: (%s)", elm_atspi_proxy_id_get(proxy));
+ return NULL;
+ }
+
+ return eldbus_message_method_call_new(addr.bus, addr.path, interface, method);
+}
+
+static void
+_elm_atspi_bridge_elm_interface_atspi_socket_embed(Eo *obj, void *data, Elm_Atspi_Proxy *proxy)
+{
+ Elm_Atspi_Bridge *bridge = _elm_atspi_bridge_get();
+
+ assert (bridge != NULL);
+ ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ if (!pd->connected) return;
+
+ Eldbus_Message *message =
+ _elm_atspi_bridge_method_call_to_proxy_new(proxy, ATSPI_DBUS_INTERFACE_SOCKET, "Embedded");
+ if (!message) return;
+ Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
+ if (!iter)
+ {
+ ERR("eldbus_message_iter_get failed");
+ eldbus_message_unref(message);
+ return;
+ }
+
+ eldbus_connection_send(pd->a11y_bus, message, NULL, NULL, -1);
+ ERR("Embed on elm_atspi_bridge");
+}
+
+static void
+_elm_atspi_bridge_elm_interface_atspi_socket_unembed(Eo *obj EINA_UNUSED, void *data EINA_UNUSED, Elm_Atspi_Proxy *proxy EINA_UNUSED)
+{
+ // Currently "Unembedded" is not supported by at-spi protocol.
+}
+
+static void
+_elm_atspi_bridge_ref_release(void *data, const void *deadptr EINA_UNUSED)
+{
+ efl_unref((Eo*)data);
+}
+
+static void
+_elm_atspi_bridge_elm_interface_atspi_socket_embed_by(Eo *obj, void *data, Elm_Atspi_Proxy *proxy)
+{
+ Elm_Atspi_Bridge *bridge = _elm_atspi_bridge_get();
+
+ assert (bridge != NULL);
+ ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ if (!pd->connected) return;
+
+ Eldbus_Message *message =
+ _elm_atspi_bridge_method_call_to_proxy_new(proxy, ATSPI_DBUS_INTERFACE_SOCKET, "Embed");
+
+ if (!message) return;
+ Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
+ if (!iter)
+ {
+ ERR("eldbus_message_iter_get failed");
+ eldbus_message_unref(message);
+ return;
+ }
+ _bridge_iter_object_reference_append(bridge, iter, obj);
+
+ Eldbus_Pending *req = eldbus_connection_send(pd->a11y_bus, message, _on_elm_atspi_bridge_plug_register, bridge, 100);
+ eldbus_pending_data_set(req, "__obj", obj);
+ eldbus_pending_data_set(req, "__proxy", proxy);
+ if (!req)
+ ERR("eldbus_connection_send failed");
+ else
+ _elm_atspi_bridge_pending_add(bridge, req, _elm_atspi_bridge_ref_release, efl_ref(proxy));
+}
+
+static void
+_elm_atspi_bridge_elm_interface_atspi_socket_unembed_by(Eo *obj, void *data, Elm_Atspi_Proxy *proxy)
+{
+ Elm_Atspi_Bridge *bridge = _elm_atspi_bridge_get();
+
+ ERR("UnEmbed_by on elm_atspi_bridge");
+
+ assert (bridge != NULL);
+ ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ if (!pd->connected) return;
+
+ Eldbus_Message *message =
+ _elm_atspi_bridge_method_call_to_proxy_new(proxy, ATSPI_DBUS_INTERFACE_SOCKET, "Unembed");
+
+ if (!message) return;
+ Eldbus_Message_Iter *iter = eldbus_message_iter_get(message);
+ if (!iter)
+ {
+ ERR("eldbus_message_iter_get failed");
+ eldbus_message_unref(message);
+ return;
+ }
+
+ eldbus_connection_send(pd->a11y_bus, message, NULL, NULL, -1);
+}
+
+static void
+_elm_atspi_bridge_socket_hooks_uninstall(Elm_Interface_Atspi_Socket *socket)
+{
+ efl_object_override(socket, NULL);
+}
+
+static void
+_elm_atspi_bridge_socket_hooks_install(Elm_Interface_Atspi_Socket *socket)
+{
+ ERR("Install hooks for %s", efl_class_name_get(socket));
+ EFL_OPS_DEFINE(_elm_atspi_bridge_hooks,
+ EFL_OBJECT_OP_FUNC(elm_interface_atspi_socket_embed, _elm_atspi_bridge_elm_interface_atspi_socket_embed),
+ EFL_OBJECT_OP_FUNC(elm_interface_atspi_socket_unembed, _elm_atspi_bridge_elm_interface_atspi_socket_unembed),
+ EFL_OBJECT_OP_FUNC(elm_interface_atspi_socket_embed_by, _elm_atspi_bridge_elm_interface_atspi_socket_embed_by),
+ EFL_OBJECT_OP_FUNC(elm_interface_atspi_socket_unembed_by, _elm_atspi_bridge_elm_interface_atspi_socket_unembed_by));
+
+ efl_object_override(socket, &_elm_atspi_bridge_hooks);
+}
+
EOLIAN Efl_Object*
_elm_atspi_bridge_efl_object_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
{
@@ -4715,7 +4880,7 @@ _elm_atspi_bridge_efl_object_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
if (!_elm_atspi_bridge_platform_a11y_status_monitor_init(obj))
{
- ERR("Unable to get platform's a11y status.");
+ WRN("Unable to get platform's a11y status. Is a11y stack running?");
eldbus_connection_unref(pd->session_bus);
return NULL;
}
@@ -4723,11 +4888,20 @@ _elm_atspi_bridge_efl_object_constructor(Eo *obj, Elm_Atspi_Bridge_Data *pd)
return obj;
}
+static void
+_elm_atspi_bridge_plugs_clean_up(Eo *bridge)
+{
+ ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ eina_list_free(pd->plugs);
+ pd->plugs = NULL;
+}
+
EOLIAN void
_elm_atspi_bridge_efl_object_destructor(Eo *obj, Elm_Atspi_Bridge_Data *pd EINA_UNUSED)
{
_elm_atspi_bridge_disconnect(obj);
elm_atspi_bridge_root_set(obj, NULL);
+ _elm_atspi_bridge_plugs_clean_up(obj);
_elm_atspi_bridge_platform_a11y_status_monitor_shutdown(obj);
eldbus_connection_unref(pd->session_bus);
@@ -4741,14 +4915,14 @@ _elm_atspi_bridge_root_get(Eo *obj EINA_UNUSED, Elm_Atspi_Bridge_Data *pd)
}
static void
-_elm_atspi_bridge_root_del(void *data, const Efl_Event *event EINA_UNUSED)
+_elm_atspi_bridge_plug_del(void *data, const Efl_Event *event)
{
Elm_Atspi_Bridge *bridge = data;
- elm_atspi_bridge_root_set(bridge, NULL);
+ elm_atspi_bridge_plug_unregister(bridge, event->object);
}
/**
- * triggers re-registration of accassible application
+ * @brief triggers re-registration of accessible application
*/
EOLIAN void
_elm_atspi_bridge_root_set(Eo *obj, Elm_Atspi_Bridge_Data *pd, Efl_Object *new_root)
@@ -4761,9 +4935,7 @@ _elm_atspi_bridge_root_set(Eo *obj, Elm_Atspi_Bridge_Data *pd, Efl_Object *new_r
if (pd->connected)
_elm_atspi_bridge_disconnect(obj);
- if (pd->root) efl_event_callback_del(pd->root, EFL_EVENT_CALLBACK_DEL, _elm_atspi_bridge_root_del, obj);
pd->root = new_root;
- if (pd->root) efl_event_callback_add(pd->root, EFL_EVENT_CALLBACK_DEL, _elm_atspi_bridge_root_del, obj);
if (was_connected)
_elm_atspi_bridge_connect(obj);
@@ -4815,9 +4987,10 @@ _elm_atspi_bridge_disconnect(Elm_Atspi_Bridge *bridge)
}
static void
-_elm_atspi_bridge_pending_add(Elm_Atspi_Bridge *bridge, Eldbus_Pending *pending)
+_elm_atspi_bridge_pending_add(Elm_Atspi_Bridge *bridge, Eldbus_Pending *pending, Eldbus_Free_Cb cb, const void *data)
{
ELM_ATSPI_BRIDGE_DATA_GET_OR_RETURN(bridge, pd);
+ if (cb) eldbus_pending_free_cb_add(pending, cb, data);
pd->pending_requests = eina_list_append(pd->pending_requests, pending);
}
@@ -4851,7 +5024,7 @@ _elm_atspi_bridge_on_disconnected(Elm_Atspi_Bridge *bridge)
_elm_atspi_bridge_pending_cancel_all(bridge);
- _elm_atspi_bridge_root_unregister(bridge);
+ _elm_atspi_bridge_plugs_unregister(bridge);
_elm_atspi_bridge_event_handlers_unregister(bridge);
_elm_atspi_bridge_interfaces_unregister(bridge);
@@ -4873,7 +5046,7 @@ _elm_atspi_bridge_on_connected(Elm_Atspi_Bridge *bridge)
_elm_atspi_bridge_interfaces_register(bridge);
_elm_atspi_bridge_event_handlers_register(bridge);
- _elm_atspi_bridge_root_register(bridge);
+ _elm_atspi_bridge_plugs_register(bridge);
}
static void
@@ -4885,4 +5058,79 @@ _elm_atspi_bridge_enabled_set(Elm_Atspi_Bridge *bridge, Eina_Bool value)
_elm_atspi_bridge_disconnect(bridge);
}
+EOLIAN void
+_elm_atspi_bridge_plug_register(Eo *obj, Elm_Atspi_Bridge_Data *pd, Elm_Atspi_Plug *plug)
+{
+ EINA_SAFETY_ON_NULL_RETURN(plug);
+
+ if (!eina_list_data_find(pd->plugs, plug))
+ {
+ if (pd->connected)
+ _bridge_object_register(obj, plug);
+ efl_event_callback_add(plug, EFL_EVENT_DEL, _elm_atspi_bridge_plug_del, obj);
+ pd->plugs = eina_list_append(pd->plugs, plug);
+ }
+}
+
+EOLIAN void
+_elm_atspi_bridge_plug_unregister(Eo *obj, Elm_Atspi_Bridge_Data *pd, Elm_Atspi_Plug *plug)
+{
+ EINA_SAFETY_ON_NULL_RETURN(plug);
+ Eina_List *node;
+
+ if ((node = eina_list_data_find_list(pd->plugs, plug)))
+ {
+ if (pd->connected)
+ _bridge_object_unregister(obj, plug);
+ efl_event_callback_del(plug, EFL_EVENT_DEL, _elm_atspi_bridge_plug_del, obj);
+ pd->plugs = eina_list_remove_list(pd->plugs, node);
+ }
+}
+
+static Eina_Bool
+_elm_atspi_bridge_id_parse(const char *id, struct dbus_address *addr)
+{
+ int written;
+ Eina_Bool ret = EINA_FALSE;
+
+ if (!addr || !id)
+ return EINA_FALSE;
+
+ char *copy = strdup(id);
+ if (!copy)
+ return EINA_FALSE;
+
+ char *split = strrchr(copy, ':');
+ if (!split)
+ goto exit;
+
+ *split = '\0';
+
+ written = snprintf(addr->bus, sizeof(addr->bus), "%s", copy);
+ if ((written < 0) || (written >= (int)sizeof(addr->bus)))
+ goto exit;
+
+ written = snprintf(addr->path, sizeof(addr->path), "%s", split + 1);
+ if ((written < 0) || (written >= (int)sizeof(addr->path)))
+ goto exit;
+
+ ret = EINA_TRUE;
+
+exit:
+ free(copy);
+ return ret;
+}
+
+static char*
+_elm_atspi_bridge_id_make(const struct dbus_address *address)
+{
+ char buf[256];
+
+ int written = snprintf(buf, sizeof(buf), "%s:%s", address->bus, address->path);
+ if ((written < 0) || (written >= (int)sizeof(buf)))
+ return NULL;
+
+ return strdup(buf);
+}
+
#include "elm_atspi_bridge.eo.c"
diff --git a/src/lib/elementary/elm_atspi_bridge.eo b/src/lib/elementary/elm_atspi_bridge.eo
index 3e8ef5dce5..a1fb6a1bfa 100644
--- a/src/lib/elementary/elm_atspi_bridge.eo
+++ b/src/lib/elementary/elm_atspi_bridge.eo
@@ -20,7 +20,17 @@ class Elm.Atspi.Bridge (Efl.Object)
set {
}
values {
- ret: Efl.Object; [[Root accessible object, or null if not set ]]
+ ret: Elm.Atspi.Plug; [[Root accessible object, or null if not set ]]
+ }
+ }
+ plug_register {
+ params {
+ @in plug: Elm.Atspi.Plug;
+ }
+ }
+ plug_unregister {
+ params {
+ @in plug: Elm.Atspi.Plug;
}
}
}
diff --git a/src/lib/elementary/elm_atspi_plug.c b/src/lib/elementary/elm_atspi_plug.c
new file mode 100644
index 0000000000..dbcd83339f
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_plug.c
@@ -0,0 +1,46 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include <elm_priv.h>
+#include <assert.h>
+
+
+typedef struct _Elm_Atspi_Plug_Data {
+ Elm_Atspi_Proxy *proxy_parent; // technical object for keep bridge coherent
+} Elm_Atspi_Plug_Data;
+
+EOLIAN Eo*
+_elm_atspi_plug_efl_object_constructor(Eo *obj, Elm_Atspi_Plug_Data *pd)
+{
+ efl_constructor(efl_super(obj, ELM_ATSPI_PLUG_CLASS));
+
+ Elm_Atspi_Bridge *bridge = _elm_atspi_bridge_get();
+ if (bridge)
+ elm_atspi_bridge_plug_register(bridge, obj);
+
+ elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_FRAME);
+ return obj;
+}
+
+EOLIAN void
+_elm_atspi_plug_efl_object_destructor(Eo *obj EINA_UNUSED, Elm_Atspi_Plug_Data *pd)
+{
+ efl_destructor(efl_super(obj, ELM_ATSPI_PLUG_CLASS));
+}
+
+EOLIAN void
+_elm_atspi_plug_elm_interface_atspi_socket_on_embedded(Eo *obj EINA_UNUSED, Elm_Atspi_Plug_Data *pd, Elm_Atspi_Proxy *proxy)
+{
+ ERR("On embedded");
+}
+
+EOLIAN void
+_elm_atspi_plug_elm_interface_atspi_socket_on_unembedded(Eo *obj EINA_UNUSED, Elm_Atspi_Plug_Data *pd, Elm_Atspi_Proxy *proxy)
+{
+ ERR("On unembedded");
+}
+
+#include "elm_atspi_plug.eo.c"
+
diff --git a/src/lib/elementary/elm_atspi_plug.eo b/src/lib/elementary/elm_atspi_plug.eo
new file mode 100644
index 0000000000..e7c133f847
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_plug.eo
@@ -0,0 +1,13 @@
+class Elm.Atspi.Plug (Efl.Object, Elm.Interface.Atspi_Accessible,
+ Elm.Interface.Atspi.Socket)
+{
+ [[AT-SPI Plug class.]]
+ legacy_prefix: elm_atspi_plug;
+ eo_prefix: elm_obj_atspi_plug;
+ implements {
+ Efl.Object.destructor;
+ Efl.Object.constructor;
+ Elm.Interface.Atspi.Socket.on_embedded;
+ Elm.Interface.Atspi.Socket.on_unembedded;
+ }
+}
diff --git a/src/lib/elementary/elm_atspi_plug.h b/src/lib/elementary/elm_atspi_plug.h
new file mode 100644
index 0000000000..2b716f0106
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_plug.h
@@ -0,0 +1,8 @@
+#ifdef EFL_BETA_API_SUPPORT
+#ifdef EFL_EO_API_SUPPORT
+#include "elm_atspi_plug.eo.h"
+#endif
+#ifndef EFL_NOLEGACY_API_SUPPORT
+#include "elm_atspi_plug.eo.legacy.h"
+#endif
+#endif
diff --git a/src/lib/elementary/elm_atspi_proxy.c b/src/lib/elementary/elm_atspi_proxy.c
index 102bcf03d6..0fef9cb21c 100644
--- a/src/lib/elementary/elm_atspi_proxy.c
+++ b/src/lib/elementary/elm_atspi_proxy.c
@@ -7,35 +7,26 @@
#include <assert.h>
typedef struct _Elm_Atspi_Proxy_Data {
- const char *bus;
- const char *path;
+ const char *id;
} Elm_Atspi_Proxy_Data;
EOLIAN void
_elm_atspi_proxy_efl_object_destructor(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *pd)
{
- eina_stringshare_del(pd->bus);
- eina_stringshare_del(pd->path);
+ if (pd->id) eina_stringshare_del(pd->id);
+ efl_destructor(efl_super(obj, ELM_ATSPI_PROXY_CLASS));
}
EOLIAN const char*
-_elm_atspi_proxy_path_get(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *pd)
+_elm_atspi_proxy_id_get(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *pd)
{
- return pd->path;
-}
-
-EOLIAN const char*
-_elm_atspi_proxy_bus_name_get(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *pd)
-{
- return pd->bus;
+ return pd->id;
}
EOLIAN void
-_elm_atspi_proxy_constructor(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *pd, const char *bus, const char *path)
+_elm_atspi_proxy_id_constructor(Eo *obj EINA_UNUSED, Elm_Atspi_Proxy_Data *pd, const char *id)
{
- pd->bus = eina_stringshare_add(bus);
- pd->path = eina_stringshare_add(path);
+ pd->id = eina_stringshare_add(id);
}
-
#include "elm_atspi_proxy.eo.c"
diff --git a/src/lib/elementary/elm_atspi_proxy.eo b/src/lib/elementary/elm_atspi_proxy.eo
index 43ee235622..ecb8352acb 100644
--- a/src/lib/elementary/elm_atspi_proxy.eo
+++ b/src/lib/elementary/elm_atspi_proxy.eo
@@ -1,34 +1,28 @@
+import elm_general;
+
class Elm.Atspi.Proxy (Efl.Object, Elm.Interface.Atspi_Accessible)
{
- [[AT-SPI Proxy class. Represents out-of-process accessibility object]]
+ [[AT-SPI Proxy class. Represents accessibility object from external process.]]
legacy_prefix: elm_atspi_proxy;
eo_prefix: elm_obj_atspi_proxy;
methods {
- @property path {
+ @property id {
get {
- values {
- ret: string;
- }
}
- }
- @property bus_name {
- get {
- values {
- ret: string;
- }
+ values {
+ ret: string;
}
}
- constructor {
- params {
- @in bus: string;
- @in path: string;
- }
+ id_constructor {
+ params {
+ @in id: string;
+ }
}
}
implements {
Efl.Object.destructor;
}
constructors {
- .constructor;
+ .id_constructor;
}
}
diff --git a/src/lib/elementary/elm_atspi_socket.c b/src/lib/elementary/elm_atspi_socket.c
new file mode 100644
index 0000000000..c925d1d6cb
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_socket.c
@@ -0,0 +1,25 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include <elm_priv.h>
+
+typedef struct _Elm_Atspi_Socket_Data {
+} Elm_Atspi_Socket_Data;
+
+EOLIAN void
+_elm_atspi_socket_efl_object_destructor(Eo *obj EINA_UNUSED, Elm_Atspi_Socket_Data *pd)
+{
+ efl_destructor(efl_super(obj, ELM_ATSPI_SOCKET_CLASS));
+}
+
+EOLIAN Eo*
+_elm_atspi_socket_efl_object_constructor(Eo *obj, Elm_Atspi_Socket_Data *pd EINA_UNUSED)
+{
+ efl_constructor(efl_super(obj, ELM_ATSPI_SOCKET_CLASS));
+ elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_EMBEDDED);
+
+ return obj;
+}
+#include "elm_atspi_socket.eo.c"
diff --git a/src/lib/elementary/elm_atspi_socket.eo b/src/lib/elementary/elm_atspi_socket.eo
new file mode 100644
index 0000000000..12ccab0a72
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_socket.eo
@@ -0,0 +1,10 @@
+class Elm.Atspi.Socket (Efl.Object, Elm.Interface.Atspi_Accessible, Elm.Interface.Atspi.Socket)
+{
+ [[AT-SPI Socket class]]
+ legacy_prefix: elm_atspi_socket;
+ eo_prefix: elm_obj_atspi_socket;
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ }
+}
diff --git a/src/lib/elementary/elm_atspi_socket.h b/src/lib/elementary/elm_atspi_socket.h
new file mode 100644
index 0000000000..6da89489b1
--- /dev/null
+++ b/src/lib/elementary/elm_atspi_socket.h
@@ -0,0 +1,9 @@
+#ifdef EFL_BETA_API_SUPPORT
+#ifdef EFL_EO_API_SUPPORT
+#include "elm_atspi_socket.eo.h"
+#endif
+#ifndef EFL_NOLEGACY_API_SUPPORT
+#include "elm_atspi_socket.eo.legacy.h"
+#endif
+#endif
+
diff --git a/src/lib/elementary/elm_interface_atspi_accessible.c b/src/lib/elementary/elm_interface_atspi_accessible.c
index f6dadf0fd1..5537b1e19a 100644
--- a/src/lib/elementary/elm_interface_atspi_accessible.c
+++ b/src/lib/elementary/elm_interface_atspi_accessible.c
@@ -128,10 +128,19 @@ struct _Elm_Interface_Atspi_Accessible_Data
Eina_Inlist *children;
};
+
typedef struct _Elm_Interface_Atspi_Accessible_Data Elm_Interface_Atspi_Accessible_Data;
+struct Accessibility_Plugin
+{
+ void *plugin_private_data;
+};
+
+static void _elm_interface_atspi_accessible_observers_notify(Eo *object);
+
static Eo *root;
+static Eina_List *plugins;
EOLIAN static int
_elm_interface_atspi_accessible_index_in_parent_get(Eo *obj, Elm_Interface_Atspi_Accessible_Data *pd EINA_UNUSED)
@@ -525,7 +534,33 @@ EOLIAN Eo *
_elm_interface_atspi_accessible_efl_object_constructor(Eo *obj, Elm_Interface_Atspi_Accessible_Data *pd)
{
pd->self = obj;
+ _elm_interface_atspi_accessible_observers_notify(obj);
return efl_constructor(efl_super(obj, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN));
}
+static void
+_elm_interface_atspi_accessible_observers_notify(Eo *object)
+{
+ if (observers)
+ {
+ ERR("Query observer");
+ }
+}
+
+EOLIAN void
+_elm_interface_atspi_accessible_observer_install(Eo *socket_class, void *data)
+{
+ ERR("Observer installed");
+ observers = 0x1;
+ if (!observers)
+ observers = eina_array_new(1);
+}
+
+EOLIAN void
+_elm_interface_atspi_accessible_observer_uninstall(Eo *socket_class, void *data)
+{
+ ERR("Observer uninstalled");
+ observers = NULL;
+}
+
#include "elm_interface_atspi_accessible.eo.c"
diff --git a/src/lib/elementary/elm_interface_atspi_accessible.eo b/src/lib/elementary/elm_interface_atspi_accessible.eo
index 037d02182a..1999d59910 100644
--- a/src/lib/elementary/elm_interface_atspi_accessible.eo
+++ b/src/lib/elementary/elm_interface_atspi_accessible.eo
@@ -1,6 +1,3 @@
-/* FIXME: This definitely shouldn't be here. */
-type Efl_Event_Cb: __undefined_type; [[Efl event callback type]]
-
enum Elm.Atspi.Role
{
[[Describes the role of an object visible to AT-SPI Clients.]]
@@ -391,6 +388,8 @@ mixin Elm.Interface.Atspi_Accessible (Efl.Interface, Efl.Object)
ret: Efl.Object; [[Root object]]
}
}
+ set {
+ }
}
}
implements {
diff --git a/src/lib/elementary/elm_interface_atspi_socket.c b/src/lib/elementary/elm_interface_atspi_socket.c
new file mode 100644
index 0000000000..0753306beb
--- /dev/null
+++ b/src/lib/elementary/elm_interface_atspi_socket.c
@@ -0,0 +1,69 @@
+#ifdef HAVE_CONFIG_H
+ #include "elementary_config.h"
+#endif
+
+#include <Elementary.h>
+#include "elm_widget.h"
+#include "elm_priv.h"
+
+typedef struct _Elm_Inteface_Atspi_Socket_Data
+{
+ const char *id;
+ Eina_Bool occupied : 1;
+} Elm_Interface_Atspi_Socket_Data;
+
+EOLIAN const char*
+_elm_interface_atspi_socket_id_get(Eo *socket EINA_UNUSED, Elm_Interface_Atspi_Socket_Data *pd)
+{
+ return pd->id;
+}
+
+EOLIAN void
+_elm_interface_atspi_socket_id_set(Eo *socket, Elm_Interface_Atspi_Socket_Data *pd, const char *new_id)
+{
+ const char *id = eina_stringshare_add(new_id);
+ if (pd->id != id)
+ {
+ eina_stringshare_del(pd->id);
+ pd->id = id;
+ efl_event_callback_call(socket, ELM_INTERFACE_ATSPI_SOCKET_EVENT_ID_CHANGED, NULL);
+ }
+ else
+ eina_stringshare_del(id);
+}
+
+EOLIAN Eina_Bool
+_elm_interface_atspi_socket_occupied_get(Eo *socket EINA_UNUSED, Elm_Interface_Atspi_Socket_Data *pd)
+{
+ return pd->occupied;
+}
+
+EOLIAN void
+_elm_interface_atspi_socket_occupied_set(Eo *socket EINA_UNUSED, Elm_Interface_Atspi_Socket_Data *pd, Eina_Bool val)
+{
+ pd->occupied = val;
+}
+
+EOLIAN void
+_elm_interface_atspi_socket_on_embedded(Eo *socket, Elm_Interface_Atspi_Socket_Data *pd EINA_UNUSED, Elm_Atspi_Proxy *proxy)
+{
+ efl_event_callback_call(socket, ELM_INTERFACE_ATSPI_SOCKET_EVENT_EMBEDDED, proxy);
+}
+
+EOLIAN void
+_elm_interface_atspi_socket_on_unembedded(Eo *socket, Elm_Interface_Atspi_Socket_Data *pd EINA_UNUSED, Elm_Atspi_Proxy *proxy)
+{
+ efl_event_callback_call(socket, ELM_INTERFACE_ATSPI_SOCKET_EVENT_UNEMBEDDED, proxy);
+}
+
+EOLIAN void
+_elm_interface_atspi_socket_on_connected(Eo *socket, Elm_Interface_Atspi_Socket_Data *pd EINA_UNUSED)
+{
+}
+
+EOLIAN void
+_elm_interface_atspi_socket_on_disconnected(Eo *socket, Elm_Interface_Atspi_Socket_Data *pd EINA_UNUSED)
+{
+}
+
+#include "elm_interface_atspi_socket.eo.c"
diff --git a/src/lib/elementary/elm_interface_atspi_socket.eo b/src/lib/elementary/elm_interface_atspi_socket.eo
new file mode 100644
index 0000000000..7efbfa4681
--- /dev/null
+++ b/src/lib/elementary/elm_interface_atspi_socket.eo
@@ -0,0 +1,69 @@
+import elm_general;
+
+mixin Elm.Interface.Atspi.Socket(Efl.Interface, Efl.Object)
+{
+ [[Elementary AT-SPI socket interface]]
+ eo_prefix: elm_interface_atspi_socket;
+ methods {
+ @property id {
+ get {
+ } set {
+ }
+ values {
+ ret: string;
+ }
+ }
+ @property occupied {
+ get {
+ }
+ set {
+ }
+ values {
+ ret: bool;
+ }
+ }
+ embed @pure_virtual {
+ [[ Embed remote accessible object as a child.]]
+ params {
+ @in proxy: Elm.Atspi.Proxy;
+ }
+ }
+ unembed @pure_virtual {
+ // unembed
+ params {
+ @in proxy: Elm.Atspi.Proxy;
+ }
+ }
+ embed_by @pure_virtual {
+ [[ Embed accessible object as a child of remote object.]]
+ params {
+ @in proxy: Elm.Atspi.Proxy;
+ }
+ }
+ unembed_by @pure_virtual {
+ // unembed
+ params {
+ @in proxy: Elm.Atspi.Proxy;
+ }
+ }
+ on_embedded {
+ params {
+ @in proxy: Elm.Atspi.Proxy;
+ }
+ }
+ on_unembedded {
+ params {
+ @in proxy: Elm.Atspi.Proxy;
+ }
+ }
+ on_connected {
+ }
+ on_disconnected {
+ }
+ }
+ events {
+ embedded;
+ unembedded;
+ id,changed;
+ }
+}
diff --git a/src/lib/elementary/elm_interfaces.h b/src/lib/elementary/elm_interfaces.h
index 58ce5c0bae..c0c5a8bfdb 100644
--- a/src/lib/elementary/elm_interfaces.h
+++ b/src/lib/elementary/elm_interfaces.h
@@ -11,6 +11,7 @@
#include "elm_interface_atspi_text_editable.eo.h"
#include "elm_interface_atspi_image.eo.h"
#include "elm_interface_atspi_selection.eo.h"
+#include "elm_interface_atspi_socket.eo.h"
#include "elm_interface_atspi_value.eo.h"
#endif
#endif
@@ -21,6 +22,7 @@
#include "elm_interface_atspi_text_editable.eo.legacy.h"
#include "elm_interface_atspi_image.eo.legacy.h"
#include "elm_interface_atspi_selection.eo.legacy.h"
+#include "elm_interface_atspi_socket.eo.legacy.h"
#include "elm_interface_atspi_value.eo.legacy.h"
#endif
#endif