summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <l.stanislaws@samsung.com>2017-12-01 23:13:02 +0100
committerLukasz Stanislawski <lukasz.stanislawski@gmail.com>2017-12-01 23:13:02 +0100
commit2d4917a48ae7ebeb89acfbf6cdcef1900a808d6c (patch)
tree2c38a696241956312845d3035dbf21206340bdc0
parent76c2520efd6060ad7a1a14a2243c6acef722905e (diff)
downloadefl-2d4917a48ae7ebeb89acfbf6cdcef1900a808d6c.tar.gz
elm: implement elm_bus_watcher class
Summary: Purpose of this class it to create base class for Change-Id: Id28e43ba43caa9c3290d462d807acde710fce7d6 Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D5560
-rw-r--r--src/Makefile_Elementary.am1
-rw-r--r--src/examples/elementary/Makefile.am9
-rw-r--r--src/examples/elementary/bus_watcher.c52
-rw-r--r--src/lib/elementary/Elementary.h1
-rw-r--r--src/lib/elementary/a11y/elm_atspi_bus_watcher.eo8
-rw-r--r--src/lib/elementary/a11y/elm_bus_watcher.c158
-rw-r--r--src/lib/elementary/a11y/elm_bus_watcher.eo47
-rw-r--r--src/lib/elementary/a11y/elm_bus_watcher.h8
-rw-r--r--src/lib/elementary/a11y/elm_bus_watcher_private.x71
9 files changed, 342 insertions, 13 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 7b63a5dfb5..3c637bef70 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -728,6 +728,7 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/efl_ui_focus_parent_provider_gen.c \
lib/elementary/efl_ui_focus_util.c \
lib/elementary/elm_widget_item_static_focus.c \
+ lib/elementary/a11y/elm_bus_watcher.c \
$(NULL)
diff --git a/src/examples/elementary/Makefile.am b/src/examples/elementary/Makefile.am
index c4b5944c71..79f8e42f96 100644
--- a/src/examples/elementary/Makefile.am
+++ b/src/examples/elementary/Makefile.am
@@ -67,7 +67,8 @@ $(top_builddir)/src/lib/embryo/libembryo.la \
$(top_builddir)/src/lib/edje/libedje.la \
$(top_builddir)/src/lib/elementary/libelementary.la \
$(top_builddir)/src/lib/ethumb_client/libethumb_client.la \
-$(top_builddir)/src/lib/elocation/libelocation.la
+$(top_builddir)/src/lib/elocation/libelocation.la \
+$(top_builddir)/src/lib/eldbus/libeldbus.la
SRCS = \
actionslider_example_01.c \
@@ -176,7 +177,8 @@ efl_thread_2.c \
efl_thread_3.c \
efl_thread_4.c \
efl_thread_5.c \
-efl_thread_6.c
+efl_thread_6.c \
+bus_watcher.c
if HAVE_CXX11
SRCS += \
@@ -364,7 +366,8 @@ efl_thread_2 \
efl_thread_3 \
efl_thread_4 \
efl_thread_5 \
-efl_thread_6
+efl_thread_6 \
+bus_watcher
#benchmark3d
#sphere-hunter
diff --git a/src/examples/elementary/bus_watcher.c b/src/examples/elementary/bus_watcher.c
new file mode 100644
index 0000000000..3897b49193
--- /dev/null
+++ b/src/examples/elementary/bus_watcher.c
@@ -0,0 +1,52 @@
+#define EFL_EO_API_SUPPORT
+#define EFL_BETA_API_SUPPORT
+
+#include <Elementary.h>
+#include <stdio.h>
+
+static void _cb(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ Elm_Bus_Watcher_Service_Change_Info *info = event->info;
+ printf("Registered %s by %s\n", info->service_name, info->new_id);
+}
+
+static void _cb2(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
+{
+ Elm_Bus_Watcher_Service_Change_Info *info = event->info;
+ printf("Unregistered %s by %s\n", info->service_name, info->old_id);
+}
+
+static void parse_args(Elm_Bus_Watcher *watcher, int argc, char **argv)
+{
+ int i;
+ if (argc < 2)
+ {
+ fprintf(stderr, "Invalid usage:\n%s <dbus-service-name>\n", argv[0]);
+ exit(1);
+ }
+ for (i = 1; i < argc; ++i)
+ {
+ elm_bus_watcher_service_add(watcher, argv[i]);
+ elm_bus_watcher_service_add(watcher, argv[i]);
+ }
+}
+
+EAPI_MAIN int
+elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
+{
+ Elm_Bus_Watcher *watcher = efl_add(ELM_BUS_WATCHER_CLASS, NULL);
+ Eldbus_Connection *conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SESSION);
+
+ parse_args(watcher, argc, argv);
+
+ elm_bus_watcher_connection_set(watcher, conn);
+ efl_event_callback_add(watcher, ELM_BUS_WATCHER_EVENT_REGISTERED, _cb, watcher);
+ efl_event_callback_add(watcher, ELM_BUS_WATCHER_EVENT_UNREGISTERED, _cb2, watcher);
+ eldbus_connection_unref(conn);
+
+ elm_run();
+ efl_unref(watcher);
+
+ return 0;
+}
+ELM_MAIN()
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 64367cadc8..2bfc98ceb7 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -307,6 +307,7 @@ EAPI extern Elm_Version *elm_version;
# include <efl_ui_spin.eo.h>
# include <efl_ui_spin_button.eo.h>
# include <efl_ui_image_factory.eo.h>
+# include <a11y/elm_bus_watcher.eo.h>
#endif
/* include deprecated calls last of all */
diff --git a/src/lib/elementary/a11y/elm_atspi_bus_watcher.eo b/src/lib/elementary/a11y/elm_atspi_bus_watcher.eo
index c38da26dea..7940be3371 100644
--- a/src/lib/elementary/a11y/elm_atspi_bus_watcher.eo
+++ b/src/lib/elementary/a11y/elm_atspi_bus_watcher.eo
@@ -9,19 +9,19 @@ class Elm.Atspi.Bus.Watcher (Elm.Bus.Watcher)
set {
}
values {
- conn: Eldbus.Connection;
+ conn: ptr(Eldbus.Connection);
}
}
ref_a11y_bus_connection {
- return: Eldbus.Connection;
+ return: ptr(Eldbus.Connection);
}
}
constructors {
.connection;
}
implements {
- Elm.Bus.Watcher.OnRegistered;
- Elm.Bus.Watcher.OnUnregistered;
+ Elm.Bus.Watcher.on_registered;
+ Elm.Bus.Watcher.on_unregistered;
}
events {
enabled;
diff --git a/src/lib/elementary/a11y/elm_bus_watcher.c b/src/lib/elementary/a11y/elm_bus_watcher.c
new file mode 100644
index 0000000000..ae950aacee
--- /dev/null
+++ b/src/lib/elementary/a11y/elm_bus_watcher.c
@@ -0,0 +1,158 @@
+#ifdef HAVE_CONFIG_H
+ #include "elementary_config.h"
+#endif
+
+#define ELM_BUS_WATCHER_PROTECTED
+
+#include <Elementary.h>
+#include "elm_widget.h"
+#include "elm_priv.h"
+
+#include "elm_bus_watcher.eo.h"
+#include "elm_bus_watcher_private.x"
+
+static Eina_Bool _bus_watcher_service_unregister_callback(const void *container, void *data, void *gdata);
+static Eina_Bool _bus_watcher_service_register_callback(const void *container, void *data, void *gdata);
+
+typedef struct _Elm_Bus_Watcher_Data
+{
+ Eina_Array *service_names;
+ Eldbus_Connection *connection;
+} Elm_Bus_Watcher_Data;
+
+EOLIAN static Eo*
+_elm_bus_watcher_efl_object_constructor(Eo *obj, Elm_Bus_Watcher_Data *pd)
+{
+ obj = efl_constructor(efl_super(obj, ELM_BUS_WATCHER_CLASS));
+ pd->service_names = eina_array_new(2); // make step small since in most cases watchers will have 1-2 names.
+ return obj;
+}
+
+EOLIAN static void
+_elm_bus_watcher_efl_object_destructor(Eo *obj, Elm_Bus_Watcher_Data *pd)
+{
+ elm_bus_watcher_connection_set(obj, NULL);
+ _eina_array_strings_clear(pd->service_names);
+ eina_array_free(pd->service_names);
+
+ efl_destructor(efl_super(obj, ELM_BUS_WATCHER_CLASS));
+}
+
+static void
+_elm_atspi_bus_watcher_name_owner_changed_callback(void *data, const char *bus, const char *old_id, const char *new_id)
+{
+ Elm_Bus_Watcher *watcher = data;
+ Elm_Bus_Watcher_Data *pd = efl_data_scope_get(watcher, ELM_BUS_WATCHER_CLASS);
+ Elm_Bus_Watcher_Service_Change_Info info = { .service_name = bus, .old_id = old_id, .new_id = new_id };
+
+ if (!_eina_array_string_contains(pd->service_names, bus)) return;
+
+ /**
+ Dbus deamon in case when service gets unregisted sends NameChanged signal with "newid"
+ parameter set to empty string "".
+ */
+ if (!new_id || !strcmp(new_id, ""))
+ {
+ elm_bus_watcher_on_unregistered(watcher, bus, old_id);
+ efl_event_callback_call(watcher, ELM_BUS_WATCHER_EVENT_UNREGISTERED, &info);
+ }
+ else if (new_id)
+ {
+ elm_bus_watcher_on_registered(watcher, bus, old_id, new_id);
+ efl_event_callback_call(watcher, ELM_BUS_WATCHER_EVENT_REGISTERED, &info);
+ }
+}
+
+static void
+_elm_bus_watcher_dbus_setup(Eo *obj, Eldbus_Connection *conn, const char *service_name)
+{
+ eldbus_name_owner_changed_callback_add(conn, service_name, _elm_atspi_bus_watcher_name_owner_changed_callback, obj, EINA_TRUE);
+}
+
+static void
+_elm_bus_watcher_dbus_teardown(Eo *obj, Eldbus_Connection *conn, const char *service_name)
+{
+ eldbus_name_owner_changed_callback_del(conn, service_name, _elm_atspi_bus_watcher_name_owner_changed_callback, obj);
+}
+
+EOLIAN static void
+_elm_bus_watcher_service_add(Eo *obj, Elm_Bus_Watcher_Data *pd, const char *service)
+{
+ if (!service || _eina_array_string_contains(pd->service_names, service))
+ return;
+
+ _eina_array_string_push(pd->service_names, service);
+ if (pd->connection) _elm_bus_watcher_dbus_setup(obj, pd->connection, service);
+}
+
+EOLIAN static void
+_elm_bus_watcher_service_remove(Eo *obj EINA_UNUSED, Elm_Bus_Watcher_Data *pd, const char *service)
+{
+ if (!_eina_array_string_contains(pd->service_names, service))
+ return;
+
+ _eina_array_string_remove(pd->service_names, service);
+ if (pd->connection) _elm_bus_watcher_dbus_teardown(obj, pd->connection, service);
+}
+
+static Eina_Bool
+_bus_watcher_service_register_callback(const void *container EINA_UNUSED, void *data, void *gdata)
+{
+ Elm_Bus_Watcher *watcher = gdata;
+ Elm_Bus_Watcher_Data *pd = efl_data_scope_get(watcher, ELM_BUS_WATCHER_CLASS);
+ const char *service_name = data;
+
+ _elm_bus_watcher_dbus_setup(watcher, pd->connection, service_name);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_bus_watcher_service_unregister_callback(const void *container EINA_UNUSED, void *data, void *gdata)
+{
+ Elm_Bus_Watcher *watcher = gdata;
+ Elm_Bus_Watcher_Data *pd = efl_data_scope_get(watcher, ELM_BUS_WATCHER_CLASS);
+ const char *service_name = data;
+
+ _elm_bus_watcher_dbus_teardown(watcher, pd->connection, service_name);
+ return EINA_TRUE;
+}
+
+EOLIAN static void
+_elm_bus_watcher_connection_set(Eo *obj, Elm_Bus_Watcher_Data *pd, Eldbus_Connection *conn)
+{
+ if (pd->connection)
+ {
+ eina_array_foreach(pd->service_names, _bus_watcher_service_unregister_callback, obj);
+ eldbus_connection_unref(pd->connection);
+ pd->connection = NULL;
+ }
+ if (conn)
+ {
+ pd->connection = eldbus_connection_ref(conn);
+ eina_array_foreach(pd->service_names, _bus_watcher_service_register_callback, obj);
+ }
+}
+
+EOLIAN static Eldbus_Connection*
+_elm_bus_watcher_connection_get(Eo *obj EINA_UNUSED, Elm_Bus_Watcher_Data *pd)
+{
+ return pd->connection;
+}
+
+EOLIAN static Eina_Iterator*
+_elm_bus_watcher_services_get(Eo *obj EINA_UNUSED, Elm_Bus_Watcher_Data *pd)
+{
+ return eina_array_iterator_new(pd->service_names);
+}
+
+EOLIAN static void
+_elm_bus_watcher_on_registered(Eo *obj EINA_UNUSED, Elm_Bus_Watcher_Data *pd EINA_UNUSED, const char *service EINA_UNUSED, const char *oldid EINA_UNUSED, const char *newid EINA_UNUSED)
+{
+}
+
+EOLIAN static void
+_elm_bus_watcher_on_unregistered(Eo *obj EINA_UNUSED, Elm_Bus_Watcher_Data *pd EINA_UNUSED, const char *service EINA_UNUSED, const char *oldid EINA_UNUSED)
+{
+}
+
+#include "elm_bus_watcher.eo.c" \ No newline at end of file
diff --git a/src/lib/elementary/a11y/elm_bus_watcher.eo b/src/lib/elementary/a11y/elm_bus_watcher.eo
index 0b6fd8728c..1ca104edf4 100644
--- a/src/lib/elementary/a11y/elm_bus_watcher.eo
+++ b/src/lib/elementary/a11y/elm_bus_watcher.eo
@@ -1,27 +1,62 @@
import eldbus_types;
+struct Elm.Bus.Watcher.Service.Change.Info
+{
+ service_name: string;
+ old_id: string;
+ new_id: string;
+}
+
class Elm.Bus.Watcher (Efl.Object)
{
methods {
- @property service {
- values {
- bus: string;
+ service_add {
+ params {
+ @in bus: string;
+ }
+ }
+ service_remove {
+ params {
+ @in bus: string;
}
}
+ @property services {
+ get {
+ }
+ values {
+ services: iterator<string>;
+ }
+ }
@property connection {
get {
}
set {
}
values {
- conn: Eldbus.Connection;
+ conn: ptr(Eldbus.Connection);
}
}
- OnRegistered @protected {
+ on_registered @protected {
+ params {
+ @in bus_name: string;
+ @in old_id: string;
+ @in new_id: string;
+ }
}
- OnUnregistered @protected {
+ on_unregistered @protected {
+ params {
+ @in bus_name: string;
+ @in old_id: string;
+ }
}
}
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ }
+ constructors {
+ .connection;
+ }
events {
registered;
unregistered;
diff --git a/src/lib/elementary/a11y/elm_bus_watcher.h b/src/lib/elementary/a11y/elm_bus_watcher.h
new file mode 100644
index 0000000000..329543cfb2
--- /dev/null
+++ b/src/lib/elementary/a11y/elm_bus_watcher.h
@@ -0,0 +1,8 @@
+#ifndef ELM_BUS_WATCHER_H
+#define ELM_BUS_WATCHER_H
+
+#ifdef EFL_EO_API_SUPPORT
+#include "elm_bus_watcher.eo.h"
+#endif
+
+#endif
diff --git a/src/lib/elementary/a11y/elm_bus_watcher_private.x b/src/lib/elementary/a11y/elm_bus_watcher_private.x
new file mode 100644
index 0000000000..a3f297e805
--- /dev/null
+++ b/src/lib/elementary/a11y/elm_bus_watcher_private.x
@@ -0,0 +1,71 @@
+#include <Eina.h>
+
+/**
+ @brief Helpers for manipulating eina_array of stringshared strings.
+*/
+
+typedef struct _Eina_Array_Foreach_Closure_Data
+{
+ const char *searched_string;
+ Eina_Bool *return_value;
+} Eina_Array_Foreach_Closure_Data;
+
+static void
+_eina_array_string_push(Eina_Array *array, const char *string)
+{
+ EINA_SAFETY_ON_NULL_RETURN(string);
+ eina_array_push(array, eina_stringshare_add(string));
+}
+
+static Eina_Bool
+_eina_stringshare_foreach(const void *container EINA_UNUSED, void *data, void *gdata)
+{
+ Eina_Array_Foreach_Closure_Data *closure = gdata;
+ const char *str = data;
+
+ if (str && closure->searched_string && !strcmp(str, closure->searched_string))
+ *closure->return_value = EINA_TRUE;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_array_string_contains(Eina_Array *array, const char *string)
+{
+ Eina_Bool found = EINA_FALSE;
+ Eina_Array_Foreach_Closure_Data closure = { .searched_string = string, .return_value = &found };
+ return eina_array_foreach(array, _eina_stringshare_foreach, &closure) && found;
+}
+
+static Eina_Bool
+_eina_stringshare_remove(void *data, void *gdata)
+{
+ const char *string = data;
+ const char *string_to_remove = gdata;
+
+ if (string && string_to_remove && !strcmp(string, string_to_remove))
+ return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_array_string_remove(Eina_Array *array, const char *string)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE);
+ return eina_array_remove(array, _eina_stringshare_remove, (void*)string);
+}
+
+static Eina_Bool
+_eina_stringshare_del_stringshare(const void *container EINA_UNUSED, void *data, void *gdata EINA_UNUSED)
+{
+ const char *string = data;
+ eina_stringshare_del(string);
+ return EINA_TRUE;
+}
+
+static void
+_eina_array_strings_clear(Eina_Array *array)
+{
+ eina_array_foreach(array, _eina_stringshare_del_stringshare, NULL);
+} \ No newline at end of file