forked from enlightenment/efl
edbus: Add edbus_service_object_manager_attach/detach
Patch by: José Roberto de Souza <zehortigoza@profusion.mobi> SVN revision: 79382
This commit is contained in:
parent
d26d9a48b1
commit
2c9e6e4760
|
@ -46,6 +46,7 @@ extern "C" {
|
||||||
#define EDBUS_FDO_PATH "/org/freedesktop/DBus"
|
#define EDBUS_FDO_PATH "/org/freedesktop/DBus"
|
||||||
#define EDBUS_FDO_INTERFACE EDBUS_FDO_BUS
|
#define EDBUS_FDO_INTERFACE EDBUS_FDO_BUS
|
||||||
#define EDBUS_FDO_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
|
#define EDBUS_FDO_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
|
||||||
|
#define EDBUS_FDO_INTERFACE_OBJECT_MANAGER "org.freedesktop.DBus.ObjectManager"
|
||||||
|
|
||||||
typedef struct _EDBus_Version
|
typedef struct _EDBus_Version
|
||||||
{
|
{
|
||||||
|
|
|
@ -145,6 +145,11 @@ struct _EDBus_Service_Object
|
||||||
Eina_Inlist *data;
|
Eina_Inlist *data;
|
||||||
EDBus_Service_Object *parent;
|
EDBus_Service_Object *parent;
|
||||||
Eina_Inlist *children;
|
Eina_Inlist *children;
|
||||||
|
//ObjectManager data
|
||||||
|
Eina_Bool has_objectmanager:1;
|
||||||
|
Eina_List *iface_added;
|
||||||
|
Eina_List *iface_removed;
|
||||||
|
Ecore_Idler *idler_iface_changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _EDBus_Service_Interface
|
struct _EDBus_Service_Interface
|
||||||
|
|
|
@ -64,6 +64,7 @@ static DBusObjectPathVTable vtable = {
|
||||||
|
|
||||||
EDBus_Service_Interface *introspectable;
|
EDBus_Service_Interface *introspectable;
|
||||||
EDBus_Service_Interface *properties_iface;
|
EDBus_Service_Interface *properties_iface;
|
||||||
|
EDBus_Service_Interface *objmanager;
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_introspect_arguments_append(Eina_Strbuf *buf, const EDBus_Arg_Info *args,
|
_introspect_arguments_append(Eina_Strbuf *buf, const EDBus_Arg_Info *args,
|
||||||
|
@ -232,35 +233,10 @@ not_found:
|
||||||
"Property not found.");
|
"Property not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDBus_Message *
|
static Eina_Bool
|
||||||
_cb_property_getall(const EDBus_Service_Interface *piface, const EDBus_Message *msg)
|
_props_getall(EDBus_Service_Interface *iface, Eina_Iterator *iterator, EDBus_Message_Iter *dict, const EDBus_Message *input_msg, EDBus_Message **error_reply)
|
||||||
{
|
{
|
||||||
const char *iface_name;
|
|
||||||
EDBus_Service_Object *obj = piface->obj;
|
|
||||||
EDBus_Service_Interface *iface;
|
|
||||||
Eina_Iterator *iterator;
|
|
||||||
Property *prop;
|
Property *prop;
|
||||||
EDBus_Message *reply, *error_reply;
|
|
||||||
EDBus_Message_Iter *main_iter, *dict;
|
|
||||||
|
|
||||||
if (!edbus_message_arguments_get(msg, "s", &iface_name))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
iface = eina_hash_find(obj->interfaces, iface_name);
|
|
||||||
if (!iface)
|
|
||||||
return edbus_message_error_new(msg, DBUS_ERROR_UNKNOWN_INTERFACE,
|
|
||||||
"Interface not found.");
|
|
||||||
|
|
||||||
reply = edbus_message_method_return_new(msg);
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
|
|
||||||
main_iter = edbus_message_iter_get(reply);
|
|
||||||
if (!edbus_message_iter_arguments_set(main_iter, "a{sv}", &dict))
|
|
||||||
{
|
|
||||||
edbus_message_unref(reply);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator = eina_hash_iterator_data_new(iface->properties);
|
|
||||||
EINA_ITERATOR_FOREACH(iterator, prop)
|
EINA_ITERATOR_FOREACH(iterator, prop)
|
||||||
{
|
{
|
||||||
EDBus_Message_Iter *entry, *var;
|
EDBus_Message_Iter *entry, *var;
|
||||||
|
@ -282,21 +258,52 @@ _cb_property_getall(const EDBus_Service_Interface *piface, const EDBus_Message *
|
||||||
var = edbus_message_iter_container_new(entry, 'v',
|
var = edbus_message_iter_container_new(entry, 'v',
|
||||||
prop->property->type);
|
prop->property->type);
|
||||||
|
|
||||||
ret = getter(iface, prop->property->name, var, msg, &error_reply);
|
ret = getter(iface, prop->property->name, var, input_msg, error_reply);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
return EINA_FALSE;
|
||||||
edbus_message_unref(reply);
|
|
||||||
reply = error_reply;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
edbus_message_iter_container_close(entry, var);
|
edbus_message_iter_container_close(entry, var);
|
||||||
edbus_message_iter_container_close(dict, entry);
|
edbus_message_iter_container_close(dict, entry);
|
||||||
}
|
}
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EDBus_Message *
|
||||||
|
_cb_property_getall(const EDBus_Service_Interface *piface, const EDBus_Message *msg)
|
||||||
|
{
|
||||||
|
const char *iface_name;
|
||||||
|
EDBus_Service_Object *obj = piface->obj;
|
||||||
|
EDBus_Service_Interface *iface;
|
||||||
|
Eina_Iterator *iterator;
|
||||||
|
EDBus_Message *reply, *error_reply;
|
||||||
|
EDBus_Message_Iter *main_iter, *dict;
|
||||||
|
|
||||||
|
if (!edbus_message_arguments_get(msg, "s", &iface_name))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
iface = eina_hash_find(obj->interfaces, iface_name);
|
||||||
|
if (!iface)
|
||||||
|
return edbus_message_error_new(msg, DBUS_ERROR_UNKNOWN_INTERFACE,
|
||||||
|
"Interface not found.");
|
||||||
|
|
||||||
|
reply = edbus_message_method_return_new(msg);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
|
||||||
|
main_iter = edbus_message_iter_get(reply);
|
||||||
|
if (!edbus_message_iter_arguments_set(main_iter, "a{sv}", &dict))
|
||||||
|
{
|
||||||
|
edbus_message_unref(reply);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator = eina_hash_iterator_data_new(iface->properties);
|
||||||
|
if (!_props_getall(iface, iterator, dict, msg, &error_reply))
|
||||||
|
{
|
||||||
|
edbus_message_unref(reply);
|
||||||
|
eina_iterator_free(iterator);
|
||||||
|
return error_reply;
|
||||||
|
}
|
||||||
edbus_message_iter_container_close(main_iter, dict);
|
edbus_message_iter_container_close(main_iter, dict);
|
||||||
|
|
||||||
end:
|
|
||||||
eina_iterator_free(iterator);
|
eina_iterator_free(iterator);
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
@ -420,6 +427,11 @@ _default_interfaces_free(void)
|
||||||
eina_hash_free(properties_iface->properties);
|
eina_hash_free(properties_iface->properties);
|
||||||
eina_array_free(properties_iface->sign_of_signals);
|
eina_array_free(properties_iface->sign_of_signals);
|
||||||
free(properties_iface);
|
free(properties_iface);
|
||||||
|
|
||||||
|
eina_hash_free(objmanager->methods);
|
||||||
|
eina_hash_free(objmanager->properties);
|
||||||
|
eina_array_free(objmanager->sign_of_signals);
|
||||||
|
free(objmanager);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const EDBus_Method _property_methods[] = {
|
static const EDBus_Method _property_methods[] = {
|
||||||
|
@ -467,6 +479,125 @@ _properties_create(void)
|
||||||
eina_array_push(properties_iface->sign_of_signals, "sa{sv}as");
|
eina_array_push(properties_iface->sign_of_signals, "sa{sv}as");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_propmgr_iface_props_append(EDBus_Service_Interface *iface, EDBus_Message_Iter *array)
|
||||||
|
{
|
||||||
|
EDBus_Message_Iter *iface_entry, *props_array;
|
||||||
|
Eina_Iterator *iterator;
|
||||||
|
EDBus_Message *error_msg;
|
||||||
|
|
||||||
|
edbus_message_iter_arguments_set(array, "{sa{sv}}", &iface_entry);
|
||||||
|
|
||||||
|
edbus_message_iter_arguments_set(iface_entry, "sa{sv}", iface->name, &props_array);
|
||||||
|
iterator = eina_hash_iterator_data_new(iface->properties);
|
||||||
|
if (!_props_getall(iface, iterator, props_array, NULL, &error_msg))
|
||||||
|
{
|
||||||
|
ERR("Error reply was set without pass any input message.");
|
||||||
|
edbus_message_unref(error_msg);
|
||||||
|
eina_iterator_free(iterator);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
eina_iterator_free(iterator);
|
||||||
|
edbus_message_iter_container_close(iface_entry, props_array);
|
||||||
|
edbus_message_iter_container_close(array, iface_entry);
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_managed_obj_append(EDBus_Service_Object *obj, EDBus_Message_Iter *array, Eina_Bool first)
|
||||||
|
{
|
||||||
|
EDBus_Message_Iter *obj_entry, *array_interface;
|
||||||
|
Eina_Iterator *iface_iter;
|
||||||
|
EDBus_Service_Interface *children_iface;
|
||||||
|
EDBus_Service_Object *children;
|
||||||
|
|
||||||
|
if (first) goto foreach;
|
||||||
|
if (obj->has_objectmanager) return EINA_TRUE;
|
||||||
|
|
||||||
|
edbus_message_iter_arguments_set(array, "{oa{sa{sv}}}", &obj_entry);
|
||||||
|
edbus_message_iter_arguments_set(obj_entry, "oa{sa{sv}}", obj->path,
|
||||||
|
&array_interface);
|
||||||
|
iface_iter = eina_hash_iterator_data_new(obj->interfaces);
|
||||||
|
EINA_ITERATOR_FOREACH(iface_iter, children_iface)
|
||||||
|
{
|
||||||
|
Eina_Bool ret;
|
||||||
|
ret = _propmgr_iface_props_append(children_iface, array_interface);
|
||||||
|
if (ret) continue;
|
||||||
|
|
||||||
|
eina_iterator_free(iface_iter);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
eina_iterator_free(iface_iter);
|
||||||
|
edbus_message_iter_container_close(obj_entry, array_interface);
|
||||||
|
edbus_message_iter_container_close(array, obj_entry);
|
||||||
|
|
||||||
|
foreach:
|
||||||
|
EINA_INLIST_FOREACH(obj->children, children)
|
||||||
|
{
|
||||||
|
Eina_Bool ret;
|
||||||
|
ret = _managed_obj_append(children, array, EINA_FALSE);
|
||||||
|
if (!ret) return EINA_FALSE;
|
||||||
|
}
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EDBus_Message *
|
||||||
|
_cb_managed_objects(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||||
|
{
|
||||||
|
EDBus_Message *reply = edbus_message_method_return_new(msg);
|
||||||
|
EDBus_Message_Iter *array_path, *main_iter;
|
||||||
|
Eina_Bool ret;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
|
||||||
|
main_iter = edbus_message_iter_get(reply);
|
||||||
|
edbus_message_iter_arguments_set(main_iter, "a{oa{sa{sv}}}", &array_path);
|
||||||
|
|
||||||
|
ret = _managed_obj_append(iface->obj, array_path, EINA_TRUE);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
edbus_message_unref(reply);
|
||||||
|
return edbus_message_error_new(msg, "org.freedesktop.DBus.Error",
|
||||||
|
"Irrecoverable error happen");
|
||||||
|
}
|
||||||
|
|
||||||
|
edbus_message_iter_container_close(main_iter, array_path);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EDBus_Method get_managed_objects = {
|
||||||
|
"GetManagedObjects", NULL, EDBUS_ARGS({"a{oa{sa{sv}}}", "objects"}),
|
||||||
|
_cb_managed_objects
|
||||||
|
};
|
||||||
|
|
||||||
|
static const EDBus_Signal _object_manager_signals[] = {
|
||||||
|
{
|
||||||
|
"InterfacesAdded", EDBUS_ARGS({"o", "object"}, {"a{sa{sv}}", "interfaces"})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"InterfacesRemoved", EDBUS_ARGS({"o", "object"}, {"as", "interfaces"})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_object_manager_create(void)
|
||||||
|
{
|
||||||
|
objmanager = calloc(1, sizeof(EDBus_Service_Interface));
|
||||||
|
if (!objmanager) return;
|
||||||
|
|
||||||
|
EINA_MAGIC_SET(objmanager, EDBUS_SERVICE_INTERFACE_MAGIC);
|
||||||
|
objmanager->sign_of_signals = eina_array_new(1);
|
||||||
|
objmanager->properties = eina_hash_string_small_new(NULL);
|
||||||
|
objmanager->name = EDBUS_FDO_INTERFACE_OBJECT_MANAGER;
|
||||||
|
objmanager->methods = eina_hash_string_small_new(NULL);
|
||||||
|
|
||||||
|
eina_hash_add(objmanager->methods, get_managed_objects.member,
|
||||||
|
&get_managed_objects);
|
||||||
|
|
||||||
|
objmanager->signals = _object_manager_signals;
|
||||||
|
eina_array_push(objmanager->sign_of_signals, "oa{sa{sv}}");
|
||||||
|
eina_array_push(objmanager->sign_of_signals, "oas");
|
||||||
|
}
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
edbus_service_init(void)
|
edbus_service_init(void)
|
||||||
{
|
{
|
||||||
|
@ -474,6 +605,8 @@ edbus_service_init(void)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(introspectable, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(introspectable, EINA_FALSE);
|
||||||
_properties_create();
|
_properties_create();
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(properties_iface, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(properties_iface, EINA_FALSE);
|
||||||
|
_object_manager_create();
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(objmanager, EINA_FALSE);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -538,7 +671,7 @@ _edbus_service_object_add(EDBus_Connection *conn, const char *path)
|
||||||
if (obj->parent)
|
if (obj->parent)
|
||||||
{
|
{
|
||||||
obj->parent->children = eina_inlist_append(obj->parent->children,
|
obj->parent->children = eina_inlist_append(obj->parent->children,
|
||||||
EINA_INLIST_GET(obj));
|
EINA_INLIST_GET(obj));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,10 +706,118 @@ _props_free(void *data)
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct iface_remove_data {
|
||||||
|
const char *obj_path;
|
||||||
|
const char *iface;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_iface_changed_send(void *data)
|
||||||
|
{
|
||||||
|
EDBus_Service_Object *parent = data;
|
||||||
|
|
||||||
|
while (parent->iface_added)
|
||||||
|
{
|
||||||
|
EDBus_Service_Interface *iface, *next_iface;
|
||||||
|
EDBus_Message *msg;
|
||||||
|
EDBus_Message_Iter *array_iface, *main_iter;
|
||||||
|
Eina_List *l, *l2;
|
||||||
|
|
||||||
|
iface = eina_list_data_get(parent->iface_added);
|
||||||
|
parent->iface_added = eina_list_remove_list(parent->iface_added,
|
||||||
|
parent->iface_added);
|
||||||
|
|
||||||
|
msg = edbus_message_signal_new(parent->path,
|
||||||
|
EDBUS_FDO_INTERFACE_OBJECT_MANAGER,
|
||||||
|
"InterfacesAdded");
|
||||||
|
if (!msg)
|
||||||
|
{
|
||||||
|
ERR("msg == NULL");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
main_iter = edbus_message_iter_get(msg);
|
||||||
|
edbus_message_iter_arguments_set(main_iter, "oa{sa{sv}}",
|
||||||
|
iface->obj->path, &array_iface);
|
||||||
|
if (!_propmgr_iface_props_append(iface, array_iface))
|
||||||
|
goto error;
|
||||||
|
EINA_LIST_FOREACH_SAFE(parent->iface_added, l, l2, next_iface)
|
||||||
|
{
|
||||||
|
if (iface->obj->path != next_iface->obj->path)
|
||||||
|
continue;
|
||||||
|
parent->iface_added = eina_list_remove(parent->iface_added,
|
||||||
|
next_iface);
|
||||||
|
if (!_propmgr_iface_props_append(next_iface, array_iface))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
edbus_message_iter_container_close(main_iter, array_iface);
|
||||||
|
edbus_connection_send(parent->conn, msg, NULL, NULL, -1);
|
||||||
|
continue;
|
||||||
|
error:
|
||||||
|
ERR("Error appending InterfacesAdded to msg.");
|
||||||
|
edbus_message_unref(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (parent->iface_removed)
|
||||||
|
{
|
||||||
|
EDBus_Message *msg;
|
||||||
|
EDBus_Message_Iter *array_iface, *main_iter;
|
||||||
|
struct iface_remove_data *iface_data, *iface_data_next;
|
||||||
|
Eina_List *l, *l2;
|
||||||
|
|
||||||
|
iface_data = eina_list_data_get(parent->iface_removed);
|
||||||
|
parent->iface_removed = eina_list_remove_list(parent->iface_removed,
|
||||||
|
parent->iface_removed);
|
||||||
|
|
||||||
|
msg = edbus_message_signal_new(parent->path,
|
||||||
|
EDBUS_FDO_INTERFACE_OBJECT_MANAGER,
|
||||||
|
"InterfacesRemoved");
|
||||||
|
EINA_SAFETY_ON_NULL_GOTO(msg, error2);
|
||||||
|
main_iter = edbus_message_iter_get(msg);
|
||||||
|
|
||||||
|
edbus_message_iter_arguments_set(main_iter, "oas", iface_data->obj_path,
|
||||||
|
&array_iface);
|
||||||
|
edbus_message_iter_basic_append(array_iface, 's', iface_data->iface);
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH_SAFE(parent->iface_removed, l, l2, iface_data_next)
|
||||||
|
{
|
||||||
|
if (iface_data->obj_path != iface_data_next->obj_path)
|
||||||
|
continue;
|
||||||
|
parent->iface_removed = eina_list_remove(parent->iface_removed,
|
||||||
|
iface_data_next);
|
||||||
|
edbus_message_iter_basic_append(array_iface, 's',
|
||||||
|
iface_data_next->iface);
|
||||||
|
eina_stringshare_del(iface_data_next->iface);
|
||||||
|
eina_stringshare_del(iface_data_next->obj_path);
|
||||||
|
free(iface_data_next);
|
||||||
|
}
|
||||||
|
edbus_message_iter_container_close(main_iter, array_iface);
|
||||||
|
edbus_connection_send(parent->conn, msg, NULL, NULL, -1);
|
||||||
|
error2:
|
||||||
|
eina_stringshare_del(iface_data->iface);
|
||||||
|
eina_stringshare_del(iface_data->obj_path);
|
||||||
|
free(iface_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent->idler_iface_changed = NULL;
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EDBus_Service_Object *
|
||||||
|
_find_object_manager_parent(EDBus_Service_Object *obj)
|
||||||
|
{
|
||||||
|
if (!obj->parent)
|
||||||
|
return NULL;
|
||||||
|
if (obj->parent->has_objectmanager)
|
||||||
|
return obj->parent;
|
||||||
|
return _find_object_manager_parent(obj->parent);
|
||||||
|
}
|
||||||
|
|
||||||
static EDBus_Service_Interface *
|
static EDBus_Service_Interface *
|
||||||
_edbus_service_interface_add(EDBus_Service_Object *obj, const char *interface)
|
_edbus_service_interface_add(EDBus_Service_Object *obj, const char *interface)
|
||||||
{
|
{
|
||||||
EDBus_Service_Interface *iface;
|
EDBus_Service_Interface *iface;
|
||||||
|
EDBus_Service_Object *parent;
|
||||||
|
|
||||||
iface = eina_hash_find(obj->interfaces, interface);
|
iface = eina_hash_find(obj->interfaces, interface);
|
||||||
if (iface) return iface;
|
if (iface) return iface;
|
||||||
|
@ -590,6 +831,15 @@ _edbus_service_interface_add(EDBus_Service_Object *obj, const char *interface)
|
||||||
iface->properties = eina_hash_string_superfast_new(_props_free);
|
iface->properties = eina_hash_string_superfast_new(_props_free);
|
||||||
iface->obj = obj;
|
iface->obj = obj;
|
||||||
eina_hash_add(obj->interfaces, iface->name, iface);
|
eina_hash_add(obj->interfaces, iface->name, iface);
|
||||||
|
|
||||||
|
parent = _find_object_manager_parent(obj);
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
if (!parent->idler_iface_changed)
|
||||||
|
parent->idler_iface_changed = ecore_idler_add(_iface_changed_send,
|
||||||
|
parent);
|
||||||
|
parent->iface_added = eina_list_append(parent->iface_added, iface);
|
||||||
|
}
|
||||||
return iface;
|
return iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,10 +997,12 @@ static void
|
||||||
_interface_free(EDBus_Service_Interface *interface)
|
_interface_free(EDBus_Service_Interface *interface)
|
||||||
{
|
{
|
||||||
unsigned size, i;
|
unsigned size, i;
|
||||||
if (interface == introspectable || interface == properties_iface) return;
|
EDBus_Service_Object *parent;
|
||||||
|
if (interface == introspectable || interface == properties_iface ||
|
||||||
|
interface == objmanager)
|
||||||
|
return;
|
||||||
|
|
||||||
eina_hash_free(interface->methods);
|
eina_hash_free(interface->methods);
|
||||||
eina_stringshare_del(interface->name);
|
|
||||||
size = eina_array_count(interface->sign_of_signals);
|
size = eina_array_count(interface->sign_of_signals);
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
eina_stringshare_del(eina_array_data_get(interface->sign_of_signals, i));
|
eina_stringshare_del(eina_array_data_get(interface->sign_of_signals, i));
|
||||||
|
@ -762,6 +1014,25 @@ _interface_free(EDBus_Service_Interface *interface)
|
||||||
ecore_idler_del(interface->idler_propschanged);
|
ecore_idler_del(interface->idler_propschanged);
|
||||||
if (interface->prop_invalidated)
|
if (interface->prop_invalidated)
|
||||||
eina_array_free(interface->prop_invalidated);
|
eina_array_free(interface->prop_invalidated);
|
||||||
|
|
||||||
|
parent = _find_object_manager_parent(interface->obj);
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
struct iface_remove_data *data;
|
||||||
|
|
||||||
|
data = malloc(sizeof(struct iface_remove_data));
|
||||||
|
EINA_SAFETY_ON_NULL_GOTO(data, end);
|
||||||
|
data->obj_path = eina_stringshare_add(interface->obj->path);
|
||||||
|
data->iface = eina_stringshare_add(interface->name);
|
||||||
|
|
||||||
|
if (!parent->idler_iface_changed)
|
||||||
|
parent->idler_iface_changed = ecore_idler_add(_iface_changed_send,
|
||||||
|
parent);
|
||||||
|
parent->iface_removed = eina_list_append(parent->iface_removed, data);
|
||||||
|
parent->iface_added = eina_list_remove(parent->iface_added, interface);
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
eina_stringshare_del(interface->name);
|
||||||
free(interface);
|
free(interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,6 +1041,7 @@ _object_free(EDBus_Service_Object *obj)
|
||||||
{
|
{
|
||||||
Eina_Iterator *iterator;
|
Eina_Iterator *iterator;
|
||||||
EDBus_Service_Interface *iface;
|
EDBus_Service_Interface *iface;
|
||||||
|
struct iface_remove_data *data;
|
||||||
|
|
||||||
iterator = eina_hash_iterator_data_new(obj->interfaces);
|
iterator = eina_hash_iterator_data_new(obj->interfaces);
|
||||||
EINA_ITERATOR_FOREACH(iterator, iface)
|
EINA_ITERATOR_FOREACH(iterator, iface)
|
||||||
|
@ -783,7 +1055,7 @@ _object_free(EDBus_Service_Object *obj)
|
||||||
if (obj->parent)
|
if (obj->parent)
|
||||||
{
|
{
|
||||||
obj->parent->children = eina_inlist_append(obj->parent->children,
|
obj->parent->children = eina_inlist_append(obj->parent->children,
|
||||||
EINA_INLIST_GET(child));
|
EINA_INLIST_GET(child));
|
||||||
child->parent = obj->parent;
|
child->parent = obj->parent;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -795,13 +1067,22 @@ _object_free(EDBus_Service_Object *obj)
|
||||||
}
|
}
|
||||||
if (obj->parent)
|
if (obj->parent)
|
||||||
obj->parent->children = eina_inlist_remove(obj->parent->children,
|
obj->parent->children = eina_inlist_remove(obj->parent->children,
|
||||||
EINA_INLIST_GET(obj));
|
EINA_INLIST_GET(obj));
|
||||||
else
|
else
|
||||||
obj->conn->root_objs = eina_inlist_remove(obj->conn->root_objs,
|
obj->conn->root_objs = eina_inlist_remove(obj->conn->root_objs,
|
||||||
EINA_INLIST_GET(obj));
|
EINA_INLIST_GET(obj));
|
||||||
|
|
||||||
edbus_data_del_all(&obj->data);
|
edbus_data_del_all(&obj->data);
|
||||||
|
|
||||||
|
EINA_LIST_FREE(obj->iface_removed, data)
|
||||||
|
{
|
||||||
|
eina_stringshare_del(data->iface);
|
||||||
|
eina_stringshare_del(data->obj_path);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
eina_list_free(obj->iface_added);
|
||||||
|
if (obj->idler_iface_changed)
|
||||||
|
ecore_idler_del(obj->idler_iface_changed);
|
||||||
eina_hash_free(obj->interfaces);
|
eina_hash_free(obj->interfaces);
|
||||||
eina_iterator_free(iterator);
|
eina_iterator_free(iterator);
|
||||||
if (obj->introspection_data)
|
if (obj->introspection_data)
|
||||||
|
@ -1150,3 +1431,33 @@ edbus_service_property_invalidate_set(EDBus_Service_Interface *iface, const char
|
||||||
iface->prop_invalidated = eina_array_new(1);
|
iface->prop_invalidated = eina_array_new(1);
|
||||||
return eina_array_push(iface->prop_invalidated, prop);
|
return eina_array_push(iface->prop_invalidated, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
edbus_service_object_manager_attach(EDBus_Service_Interface *iface)
|
||||||
|
{
|
||||||
|
EDBus_Service_Object *obj;
|
||||||
|
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, EINA_FALSE);
|
||||||
|
|
||||||
|
obj = iface->obj;
|
||||||
|
if (!eina_hash_find(obj->interfaces, objmanager->name))
|
||||||
|
if (!eina_hash_add(obj->interfaces, objmanager->name, objmanager))
|
||||||
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
obj->has_objectmanager = EINA_TRUE;
|
||||||
|
obj->introspection_dirty = EINA_TRUE;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
edbus_service_object_manager_detach(EDBus_Service_Interface *iface)
|
||||||
|
{
|
||||||
|
EDBus_Service_Object *obj;
|
||||||
|
Eina_Bool ret;
|
||||||
|
|
||||||
|
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, EINA_FALSE);
|
||||||
|
obj = iface->obj;
|
||||||
|
ret = eina_hash_del(obj->interfaces, objmanager->name, NULL);
|
||||||
|
obj->has_objectmanager = EINA_FALSE;
|
||||||
|
obj->introspection_dirty = EINA_TRUE;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -182,6 +182,22 @@ EAPI void *edbus_service_object_data_del(EDBus_Service_Interface *iface, const c
|
||||||
EAPI Eina_Bool edbus_service_property_changed(EDBus_Service_Interface *iface, const char *name);
|
EAPI Eina_Bool edbus_service_property_changed(EDBus_Service_Interface *iface, const char *name);
|
||||||
|
|
||||||
EAPI Eina_Bool edbus_service_property_invalidate_set(EDBus_Service_Interface *iface, const char *name, Eina_Bool is_invalidate);
|
EAPI Eina_Bool edbus_service_property_invalidate_set(EDBus_Service_Interface *iface, const char *name, Eina_Bool is_invalidate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach ObjectManager interface.
|
||||||
|
*
|
||||||
|
* @param iface ObjectManager will be attach in object path of this interface.
|
||||||
|
* @return EINA_TRUE if success
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool edbus_service_object_manager_attach(EDBus_Service_Interface *iface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach ObjectManager interface.
|
||||||
|
*
|
||||||
|
* @param iface ObjectManager of object path of this interface will be detach.
|
||||||
|
* @return EINA_TRUE if success
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool edbus_service_object_manager_detach(EDBus_Service_Interface *iface);
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue