forked from enlightenment/efl
edbus: Implement DBus.Properties for services
Patch by: José Roberto de Souza <zehortigoza@profusion.mobi> SVN revision: 79035
This commit is contained in:
parent
ec5d3e18f8
commit
ffc6f5cf9f
|
@ -158,7 +158,7 @@ _property_changed(void *data, EDBus_Proxy *proxy, void *event_info)
|
||||||
name = event->name;
|
name = event->name;
|
||||||
value = event->value;
|
value = event->value;
|
||||||
|
|
||||||
if (!strcmp(name, "text"))
|
if (!strcmp(name, "text") || !strcmp(name, "Resp2"))
|
||||||
{
|
{
|
||||||
const char *txt;
|
const char *txt;
|
||||||
eina_value_get(value, &txt);
|
eina_value_get(value, &txt);
|
||||||
|
@ -189,18 +189,27 @@ _read_cache(void *data)
|
||||||
Eina_Value *v;
|
Eina_Value *v;
|
||||||
|
|
||||||
v = edbus_proxy_property_local_get(proxy, "text");
|
v = edbus_proxy_property_local_get(proxy, "text");
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
eina_value_get(v, &txt);
|
eina_value_get(v, &txt);
|
||||||
printf("Read cache: [txt] = %s\n", txt);
|
printf("Read cache: [txt] = %s\n", txt);
|
||||||
|
}
|
||||||
|
|
||||||
v = edbus_proxy_property_local_get(proxy, "int32");
|
v = edbus_proxy_property_local_get(proxy, "int32");
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
eina_value_get(v, &num);
|
eina_value_get(v, &num);
|
||||||
printf("Read cache: [int32] = %d\n", num);
|
printf("Read cache: [int32] = %d\n", num);
|
||||||
|
}
|
||||||
|
|
||||||
v = edbus_proxy_property_local_get(proxy, "st");
|
v = edbus_proxy_property_local_get(proxy, "st");
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
eina_value_struct_get(v, "arg0", &txt);
|
eina_value_struct_get(v, "arg0", &txt);
|
||||||
printf("Read cache: [st] %s | ", txt);
|
printf("Read cache: [st] %s | ", txt);
|
||||||
eina_value_struct_get(v, "arg1", &txt);
|
eina_value_struct_get(v, "arg1", &txt);
|
||||||
printf("%s\n", txt);
|
printf("%s\n", txt);
|
||||||
|
}
|
||||||
|
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -258,6 +267,7 @@ main(void)
|
||||||
EDBUS_PROXY_EVENT_PROPERTY_CHANGED,
|
EDBUS_PROXY_EVENT_PROPERTY_CHANGED,
|
||||||
_property_changed, NULL);
|
_property_changed, NULL);
|
||||||
|
|
||||||
|
edbus_proxy_properties_monitor(proxy, EINA_TRUE);
|
||||||
ecore_timer_add(10, _read_cache, proxy);
|
ecore_timer_add(10, _read_cache, proxy);
|
||||||
|
|
||||||
ecore_main_loop_begin();
|
ecore_main_loop_begin();
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#define IFACE "com.profusion.Test"
|
#define IFACE "com.profusion.Test"
|
||||||
|
|
||||||
static char *resp2;
|
static char *resp2;
|
||||||
|
/* dummy, incremented each time DBus.Properties.Get() is called */
|
||||||
|
static int int32 = 35;
|
||||||
|
static Ecore_Timer *timer;
|
||||||
|
|
||||||
static EDBus_Message *
|
static EDBus_Message *
|
||||||
_receive_array(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
_receive_array(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||||
|
@ -199,47 +202,31 @@ _double_container(const EDBus_Service_Interface *iface, const EDBus_Message *msg
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDBus_Message *
|
static Eina_Bool
|
||||||
_properties_get(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
_properties_get(const EDBus_Service_Interface *iface, const char *propname, EDBus_Message_Iter *iter, EDBus_Message **error)
|
||||||
{
|
{
|
||||||
EDBus_Message *reply;
|
printf("Properties_get - %s\n", propname);
|
||||||
char *interface, *property;
|
if (!strcmp(propname, "Resp2"))
|
||||||
EDBus_Message_Iter *variant, *iter;
|
edbus_message_iter_basic_append(iter, 's', resp2);
|
||||||
|
else if (!strcmp(propname, "text"))
|
||||||
if (!edbus_message_arguments_get(msg, "ss", &interface, &property))
|
edbus_message_iter_basic_append(iter, 's', "lalalala");
|
||||||
|
else if (!strcmp(propname, "int32"))
|
||||||
{
|
{
|
||||||
printf("Error on edbus_message_arguments_get()\n");
|
edbus_message_iter_arguments_set(iter, "i", int32);
|
||||||
return NULL;
|
int32++;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(propname, "st"))
|
||||||
if (strcmp(interface, IFACE))
|
|
||||||
{
|
{
|
||||||
reply = edbus_message_error_new(msg,
|
EDBus_Message_Iter *st;
|
||||||
"org.freedesktop.DBus.Error.UnknownInterface",
|
edbus_message_iter_arguments_set(iter, "(ss)", &st);
|
||||||
"Interface not found.");
|
edbus_message_iter_arguments_set(st, "ss", "string1", "string2");
|
||||||
return reply;
|
edbus_message_iter_container_close(iter, st);
|
||||||
}
|
}
|
||||||
|
return EINA_TRUE;
|
||||||
if (strcmp(property, "Resp2"))
|
|
||||||
{
|
|
||||||
reply = edbus_message_error_new(msg,
|
|
||||||
"org.freedesktop.DBus.Error.UnknownProperty",
|
|
||||||
"Property not found.");
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
reply = edbus_message_method_return_new(msg);
|
|
||||||
iter = edbus_message_iter_get(reply);
|
|
||||||
variant = edbus_message_iter_container_new(iter, 'v', "s");
|
|
||||||
edbus_message_iter_basic_append(variant, 's', resp2);
|
|
||||||
printf("get %s\n", resp2);
|
|
||||||
edbus_message_iter_container_close(iter, variant);
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDBus_Message *
|
static EDBus_Message *
|
||||||
_properties_set(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
_properties_set(const EDBus_Service_Interface *iface, const char *propname, const EDBus_Message *msg)
|
||||||
{
|
{
|
||||||
EDBus_Message *reply;
|
EDBus_Message *reply;
|
||||||
char *interface, *property, *type, *txt;
|
char *interface, *property, *type, *txt;
|
||||||
|
@ -251,24 +238,7 @@ _properties_set(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(interface, IFACE))
|
|
||||||
{
|
|
||||||
reply = edbus_message_error_new(msg,
|
|
||||||
"org.freedesktop.DBus.Error.UnknownInterface",
|
|
||||||
"Interface not found.");
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(property, "Resp2"))
|
|
||||||
{
|
|
||||||
reply = edbus_message_error_new(msg,
|
|
||||||
"org.freedesktop.DBus.Error.UnknownProperty",
|
|
||||||
"Property not found.");
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = edbus_message_iter_signature_get(variant);
|
type = edbus_message_iter_signature_get(variant);
|
||||||
|
|
||||||
if (type[0] != 's')
|
if (type[0] != 's')
|
||||||
{
|
{
|
||||||
reply = edbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidSignature",
|
reply = edbus_message_error_new(msg, "org.freedesktop.DBus.Error.InvalidSignature",
|
||||||
|
@ -279,6 +249,7 @@ _properties_set(const EDBus_Service_Interface *iface, const EDBus_Message *msg)
|
||||||
|
|
||||||
reply = edbus_message_method_return_new(msg);
|
reply = edbus_message_method_return_new(msg);
|
||||||
edbus_message_iter_arguments_get(variant, "s", &txt);
|
edbus_message_iter_arguments_get(variant, "s", &txt);
|
||||||
|
printf("Resp2 was set to: %s, previously was: %s\n", txt, resp2);
|
||||||
free(type);
|
free(type);
|
||||||
free(resp2);
|
free(resp2);
|
||||||
resp2 = strdup(txt);
|
resp2 = strdup(txt);
|
||||||
|
@ -319,38 +290,30 @@ static const EDBus_Method methods[] = {
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const EDBus_Method properties_methods[] = {
|
static const EDBus_Property properties[] = {
|
||||||
{
|
{ "Resp2", "s", NULL, _properties_set },
|
||||||
"Get", EDBUS_ARGS({"s", "interface"}, {"s", "property"}),
|
{ "text", "s", NULL, NULL },
|
||||||
EDBUS_ARGS({"v", "value"}), _properties_get, 0
|
{ "int32", "i", NULL, NULL },
|
||||||
},
|
{ "st", "(ss)", NULL, NULL},
|
||||||
{
|
|
||||||
"Set", EDBUS_ARGS({"s", "interface"}, {"s", "property"}, {"v", "value"}),
|
|
||||||
NULL, _properties_set, 0
|
|
||||||
},
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Temporary way to test the PropertiesChanged signal in FDO Properties
|
|
||||||
* interface. TODO: Remove me when service part is done.
|
|
||||||
*/
|
|
||||||
static const EDBus_Signal properties_signals[] = {
|
|
||||||
{ "PropertiesChanged",
|
|
||||||
EDBUS_ARGS({"s", "interface"}, {"a{sv}", "data"}, {"as", "invalidate"}), 0
|
|
||||||
},
|
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const EDBus_Service_Interface_Desc iface_desc = {
|
static const EDBus_Service_Interface_Desc iface_desc = {
|
||||||
IFACE, methods
|
IFACE, methods, NULL, properties, _properties_get
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Eina_Bool _emit_changed(void *data)
|
||||||
|
{
|
||||||
|
EDBus_Service_Interface *iface = data;
|
||||||
|
edbus_service_property_changed(iface, "int32");
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_name_request(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
on_name_request(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||||
{
|
{
|
||||||
unsigned int flag;
|
unsigned int flag;
|
||||||
|
EDBus_Service_Interface *iface = data;
|
||||||
|
|
||||||
resp2 = malloc(sizeof(char) * 5);
|
resp2 = malloc(sizeof(char) * 5);
|
||||||
strcpy(resp2, "test");
|
strcpy(resp2, "test");
|
||||||
|
@ -372,24 +335,29 @@ on_name_request(void *data, const EDBus_Message *msg, EDBus_Pending *pending)
|
||||||
printf("error name already in use\n");
|
printf("error name already in use\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer = ecore_timer_add(3, _emit_changed, iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
EDBus_Connection *conn;
|
EDBus_Connection *conn;
|
||||||
|
EDBus_Service_Interface *iface;
|
||||||
|
|
||||||
ecore_init();
|
ecore_init();
|
||||||
edbus_init();
|
edbus_init();
|
||||||
|
|
||||||
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
|
conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION);
|
||||||
|
|
||||||
edbus_service_interface_register(conn, PATH, &iface_desc);
|
iface = edbus_service_interface_register(conn, PATH, &iface_desc);
|
||||||
edbus_name_request(conn, BUS, EDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, on_name_request, NULL);
|
edbus_name_request(conn, BUS, EDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE,
|
||||||
|
on_name_request, iface);
|
||||||
|
|
||||||
ecore_main_loop_begin();
|
ecore_main_loop_begin();
|
||||||
|
|
||||||
free(resp2);
|
free(resp2);
|
||||||
|
ecore_timer_del(timer);
|
||||||
edbus_connection_unref(conn);
|
edbus_connection_unref(conn);
|
||||||
|
|
||||||
edbus_shutdown();
|
edbus_shutdown();
|
||||||
|
|
|
@ -150,6 +150,11 @@ struct _EDBus_Service_Interface
|
||||||
const EDBus_Signal *signals;
|
const EDBus_Signal *signals;
|
||||||
Eina_Array *sign_of_signals;
|
Eina_Array *sign_of_signals;
|
||||||
EDBus_Service_Object *obj;
|
EDBus_Service_Object *obj;
|
||||||
|
Eina_Hash *properties;
|
||||||
|
EDBus_Property_Set_Cb set_func;
|
||||||
|
EDBus_Property_Get_Cb get_func;
|
||||||
|
Ecore_Idler *idler_propschanged;
|
||||||
|
Eina_Array *props_changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _Signal_Argument
|
typedef struct _Signal_Argument
|
||||||
|
|
|
@ -51,6 +51,7 @@ static DBusObjectPathVTable vtable = {
|
||||||
};
|
};
|
||||||
|
|
||||||
EDBus_Service_Interface *introspectable;
|
EDBus_Service_Interface *introspectable;
|
||||||
|
EDBus_Service_Interface *properties_iface;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_introspect_append_signal(Eina_Strbuf *buf, const EDBus_Signal *sig)
|
_introspect_append_signal(Eina_Strbuf *buf, const EDBus_Signal *sig)
|
||||||
|
@ -76,6 +77,23 @@ _introspect_append_signal(Eina_Strbuf *buf, const EDBus_Signal *sig)
|
||||||
eina_strbuf_append(buf, "</signal>");
|
eina_strbuf_append(buf, "</signal>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_instrospect_append_property(Eina_Strbuf *buf, const EDBus_Property *prop, const EDBus_Service_Interface *iface)
|
||||||
|
{
|
||||||
|
eina_strbuf_append_printf(buf, "<property name=\"%s\" type=\"%s\" access=\"",
|
||||||
|
prop->name, prop->type);
|
||||||
|
if (iface->get_func || prop->get_func)
|
||||||
|
eina_strbuf_append(buf, "read");
|
||||||
|
if (iface->set_func || prop->set_func)
|
||||||
|
eina_strbuf_append(buf, "write");
|
||||||
|
eina_strbuf_append(buf, "\">");
|
||||||
|
|
||||||
|
if (prop->flags & EDBUS_PROPERTY_FLAG_DEPRECATED)
|
||||||
|
eina_strbuf_append(buf, DBUS_ANNOTATION_DEPRECATED);
|
||||||
|
|
||||||
|
eina_strbuf_append(buf, "</property>");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_introspect_append_method(Eina_Strbuf *buf, const EDBus_Method *method)
|
_introspect_append_method(Eina_Strbuf *buf, const EDBus_Method *method)
|
||||||
{
|
{
|
||||||
|
@ -122,6 +140,7 @@ static void
|
||||||
_introspect_append_interface(Eina_Strbuf *buf, EDBus_Service_Interface *iface)
|
_introspect_append_interface(Eina_Strbuf *buf, EDBus_Service_Interface *iface)
|
||||||
{
|
{
|
||||||
EDBus_Method *method;
|
EDBus_Method *method;
|
||||||
|
EDBus_Property *prop;
|
||||||
Eina_Iterator *iterator;
|
Eina_Iterator *iterator;
|
||||||
unsigned short i;
|
unsigned short i;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
@ -136,9 +155,175 @@ _introspect_append_interface(Eina_Strbuf *buf, EDBus_Service_Interface *iface)
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
_introspect_append_signal(buf, &iface->signals[i]);
|
_introspect_append_signal(buf, &iface->signals[i]);
|
||||||
|
|
||||||
|
iterator = eina_hash_iterator_data_new(iface->properties);
|
||||||
|
EINA_ITERATOR_FOREACH(iterator, prop)
|
||||||
|
_instrospect_append_property(buf, prop, iface);
|
||||||
|
eina_iterator_free(iterator);
|
||||||
|
|
||||||
eina_strbuf_append(buf, "</interface>");
|
eina_strbuf_append(buf, "</interface>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EDBus_Message *
|
||||||
|
_cb_property_get(const EDBus_Service_Interface *piface, const EDBus_Message *msg)
|
||||||
|
{
|
||||||
|
const char *propname, *iface_name;
|
||||||
|
EDBus_Service_Object *obj = piface->obj;
|
||||||
|
EDBus_Service_Interface *iface;
|
||||||
|
EDBus_Property *prop;
|
||||||
|
EDBus_Message *reply, *error_reply = NULL;
|
||||||
|
EDBus_Message_Iter *main_iter, *variant;
|
||||||
|
Eina_Bool ret;
|
||||||
|
EDBus_Property_Get_Cb getter = NULL;
|
||||||
|
|
||||||
|
if (!edbus_message_arguments_get(msg, "ss", &iface_name, &propname))
|
||||||
|
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.");
|
||||||
|
|
||||||
|
prop = eina_hash_find(iface->properties, propname);
|
||||||
|
if (!prop) goto not_found;
|
||||||
|
|
||||||
|
if (prop->get_func)
|
||||||
|
getter = prop->get_func;
|
||||||
|
else if (iface->get_func)
|
||||||
|
getter = iface->get_func;
|
||||||
|
|
||||||
|
if (!getter) goto not_found;
|
||||||
|
|
||||||
|
reply = edbus_message_method_return_new(msg);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(reply, NULL);
|
||||||
|
|
||||||
|
main_iter = edbus_message_iter_get(reply);
|
||||||
|
variant = edbus_message_iter_container_new(main_iter, 'v', prop->type);
|
||||||
|
|
||||||
|
ret = getter(iface, propname, variant, &error_reply);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
edbus_message_iter_container_close(main_iter, variant);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
edbus_message_unref(reply);
|
||||||
|
return error_reply;
|
||||||
|
|
||||||
|
not_found:
|
||||||
|
return edbus_message_error_new(msg, DBUS_ERROR_UNKNOWN_PROPERTY,
|
||||||
|
"Property not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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)
|
||||||
|
{
|
||||||
|
EDBus_Message_Iter *entry, *var;
|
||||||
|
Eina_Bool ret;
|
||||||
|
EDBus_Property_Get_Cb getter = NULL;
|
||||||
|
|
||||||
|
if (prop->get_func)
|
||||||
|
getter = prop->get_func;
|
||||||
|
else if (iface->get_func)
|
||||||
|
getter = iface->get_func;
|
||||||
|
|
||||||
|
if (!getter)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!edbus_message_iter_arguments_set(dict, "{sv}", &entry))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
edbus_message_iter_basic_append(entry, 's', prop->name);
|
||||||
|
var = edbus_message_iter_container_new(entry, 'v', prop->type);
|
||||||
|
|
||||||
|
ret = getter(iface, prop->name, var, &error_reply);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
edbus_message_unref(reply);
|
||||||
|
reply = error_reply;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
edbus_message_iter_container_close(entry, var);
|
||||||
|
edbus_message_iter_container_close(dict, entry);
|
||||||
|
}
|
||||||
|
edbus_message_iter_container_close(main_iter, dict);
|
||||||
|
|
||||||
|
end:
|
||||||
|
eina_iterator_free(iterator);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EDBus_Message *
|
||||||
|
_cb_property_set(const EDBus_Service_Interface *piface, const EDBus_Message *msg)
|
||||||
|
{
|
||||||
|
const char *propname, *iface_name;
|
||||||
|
EDBus_Service_Object *obj = piface->obj;
|
||||||
|
EDBus_Service_Interface *iface;
|
||||||
|
EDBus_Property *prop;
|
||||||
|
EDBus_Message *reply;
|
||||||
|
EDBus_Message_Iter *main_iter;
|
||||||
|
EDBus_Property_Set_Cb setter = NULL;
|
||||||
|
|
||||||
|
main_iter = edbus_message_iter_get(msg);
|
||||||
|
if (!edbus_message_iter_get_and_next(main_iter, 's', &iface_name) ||
|
||||||
|
!edbus_message_iter_get_and_next(main_iter, 's', &propname))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dbus_message_iter_init(msg->dbus_msg,
|
||||||
|
&main_iter->dbus_iterator);
|
||||||
|
|
||||||
|
iface = eina_hash_find(obj->interfaces, iface_name);
|
||||||
|
if (!iface)
|
||||||
|
return edbus_message_error_new(msg, DBUS_ERROR_UNKNOWN_INTERFACE,
|
||||||
|
"Interface not found.");
|
||||||
|
|
||||||
|
prop = eina_hash_find(iface->properties, propname);
|
||||||
|
if (!prop)
|
||||||
|
return edbus_message_error_new(msg, DBUS_ERROR_UNKNOWN_PROPERTY,
|
||||||
|
"Property not found.");
|
||||||
|
|
||||||
|
if (prop->set_func)
|
||||||
|
setter = prop->set_func;
|
||||||
|
else if (iface->set_func)
|
||||||
|
setter = iface->set_func;
|
||||||
|
|
||||||
|
if (!setter)
|
||||||
|
return edbus_message_error_new(msg, DBUS_ERROR_PROPERTY_READ_ONLY,
|
||||||
|
"This property is read only");
|
||||||
|
reply = setter(iface, propname, msg);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
static EDBus_Message *
|
static EDBus_Message *
|
||||||
cb_introspect(const EDBus_Service_Interface *_iface, const EDBus_Message *message)
|
cb_introspect(const EDBus_Service_Interface *_iface, const EDBus_Message *message)
|
||||||
{
|
{
|
||||||
|
@ -184,6 +369,7 @@ _introspectable_create(void)
|
||||||
|
|
||||||
EINA_MAGIC_SET(introspectable, EDBUS_SERVICE_INTERFACE_MAGIC);
|
EINA_MAGIC_SET(introspectable, EDBUS_SERVICE_INTERFACE_MAGIC);
|
||||||
introspectable->sign_of_signals = eina_array_new(1);
|
introspectable->sign_of_signals = eina_array_new(1);
|
||||||
|
introspectable->properties = eina_hash_string_small_new(NULL);
|
||||||
introspectable->name = eina_stringshare_add("org.freedesktop.DBus.Introspectable");
|
introspectable->name = eina_stringshare_add("org.freedesktop.DBus.Introspectable");
|
||||||
introspectable->methods = eina_hash_string_small_new(NULL);
|
introspectable->methods = eina_hash_string_small_new(NULL);
|
||||||
|
|
||||||
|
@ -191,12 +377,63 @@ _introspectable_create(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_introspectable_free(void)
|
_default_interfaces_free(void)
|
||||||
{
|
{
|
||||||
eina_hash_free(introspectable->methods);
|
eina_hash_free(introspectable->methods);
|
||||||
|
eina_hash_free(introspectable->properties);
|
||||||
eina_stringshare_del(introspectable->name);
|
eina_stringshare_del(introspectable->name);
|
||||||
eina_array_free(introspectable->sign_of_signals);
|
eina_array_free(introspectable->sign_of_signals);
|
||||||
free(introspectable);
|
free(introspectable);
|
||||||
|
|
||||||
|
eina_hash_free(properties_iface->methods);
|
||||||
|
eina_hash_free(properties_iface->properties);
|
||||||
|
eina_array_free(properties_iface->sign_of_signals);
|
||||||
|
free(properties_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const EDBus_Method _property_methods[] = {
|
||||||
|
{
|
||||||
|
"Get", EDBUS_ARGS({"s", "interface"}, {"s", "property"}),
|
||||||
|
EDBUS_ARGS({"v", "value"}), _cb_property_get
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Set", EDBUS_ARGS({"s", "interface"}, {"s", "property"}, {"v", "value"}),
|
||||||
|
NULL, _cb_property_set
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GetAll", EDBUS_ARGS({"s", "interface"}), EDBUS_ARGS({"a{sv}", "props"}),
|
||||||
|
_cb_property_getall
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const EDBus_Signal _properties_signals[] = {
|
||||||
|
{
|
||||||
|
"PropertiesChanged",
|
||||||
|
EDBUS_ARGS({"s", "interface"}, {"a{sv}", "changed_properties"}, {"as", "invalidated_properties"})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_properties_create(void)
|
||||||
|
{
|
||||||
|
properties_iface = calloc(1, sizeof(EDBus_Service_Interface));
|
||||||
|
if (!properties_iface) return;
|
||||||
|
|
||||||
|
properties_iface->sign_of_signals = eina_array_new(1);
|
||||||
|
properties_iface->properties = eina_hash_string_small_new(NULL);
|
||||||
|
properties_iface->name = EDBUS_FDO_INTERFACE_PROPERTIES;
|
||||||
|
properties_iface->methods = eina_hash_string_small_new(NULL);
|
||||||
|
EINA_MAGIC_SET(properties_iface, EDBUS_SERVICE_INTERFACE_MAGIC);
|
||||||
|
|
||||||
|
eina_hash_add(properties_iface->methods, _property_methods[0].member,
|
||||||
|
&_property_methods[0]);
|
||||||
|
eina_hash_add(properties_iface->methods, _property_methods[1].member,
|
||||||
|
&_property_methods[1]);
|
||||||
|
eina_hash_add(properties_iface->methods, _property_methods[2].member,
|
||||||
|
&_property_methods[2]);
|
||||||
|
|
||||||
|
properties_iface->signals = _properties_signals;
|
||||||
|
eina_array_push(properties_iface->sign_of_signals, "sa{sv}as");
|
||||||
}
|
}
|
||||||
|
|
||||||
Eina_Bool
|
Eina_Bool
|
||||||
|
@ -204,6 +441,8 @@ edbus_service_init(void)
|
||||||
{
|
{
|
||||||
_introspectable_create();
|
_introspectable_create();
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(introspectable, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(introspectable, EINA_FALSE);
|
||||||
|
_properties_create();
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(properties_iface, EINA_FALSE);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +450,7 @@ edbus_service_init(void)
|
||||||
void
|
void
|
||||||
edbus_service_shutdown(void)
|
edbus_service_shutdown(void)
|
||||||
{
|
{
|
||||||
_introspectable_free();
|
_default_interfaces_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDBus_Service_Object *
|
static EDBus_Service_Object *
|
||||||
|
@ -235,6 +474,7 @@ _edbus_service_object_add(EDBus_Connection *conn, const char *path)
|
||||||
edbus_connection_cb_free_add(conn, _on_connection_free, obj);
|
edbus_connection_cb_free_add(conn, _on_connection_free, obj);
|
||||||
|
|
||||||
eina_hash_add(obj->interfaces, introspectable->name, introspectable);
|
eina_hash_add(obj->interfaces, introspectable->name, introspectable);
|
||||||
|
eina_hash_add(obj->interfaces, properties_iface->name, properties_iface);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -253,6 +493,7 @@ _edbus_service_interface_add(EDBus_Service_Object *obj, const char *interface)
|
||||||
EINA_MAGIC_SET(iface, EDBUS_SERVICE_INTERFACE_MAGIC);
|
EINA_MAGIC_SET(iface, EDBUS_SERVICE_INTERFACE_MAGIC);
|
||||||
iface->name = eina_stringshare_add(interface);
|
iface->name = eina_stringshare_add(interface);
|
||||||
iface->methods = eina_hash_string_superfast_new(NULL);
|
iface->methods = eina_hash_string_superfast_new(NULL);
|
||||||
|
iface->properties = eina_hash_string_superfast_new(NULL);
|
||||||
iface->obj = obj;
|
iface->obj = obj;
|
||||||
eina_hash_add(obj->interfaces, iface->name, iface);
|
eina_hash_add(obj->interfaces, iface->name, iface);
|
||||||
return iface;
|
return iface;
|
||||||
|
@ -292,12 +533,25 @@ _edbus_service_method_add(EDBus_Service_Interface *interface, EDBus_Method *meth
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_edbus_service_property_add(EDBus_Service_Interface *interface, EDBus_Property *property)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(!!eina_hash_find(interface->properties,
|
||||||
|
property->name), EINA_FALSE);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(property->type, EINA_FALSE);
|
||||||
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(
|
||||||
|
dbus_signature_validate_single(property->type, NULL), EINA_FALSE);
|
||||||
|
|
||||||
|
return eina_hash_add(interface->properties, property->name, property);
|
||||||
|
}
|
||||||
|
|
||||||
EAPI EDBus_Service_Interface *
|
EAPI EDBus_Service_Interface *
|
||||||
edbus_service_interface_register(EDBus_Connection *conn, const char *path, const EDBus_Service_Interface_Desc *desc)
|
edbus_service_interface_register(EDBus_Connection *conn, const char *path, const EDBus_Service_Interface_Desc *desc)
|
||||||
{
|
{
|
||||||
EDBus_Service_Object *obj;
|
EDBus_Service_Object *obj;
|
||||||
EDBus_Service_Interface *iface;
|
EDBus_Service_Interface *iface;
|
||||||
EDBus_Method *method;
|
EDBus_Method *method;
|
||||||
|
EDBus_Property *property;
|
||||||
unsigned short i, z;
|
unsigned short i, z;
|
||||||
Eina_Strbuf *buf = NULL;
|
Eina_Strbuf *buf = NULL;
|
||||||
|
|
||||||
|
@ -352,6 +606,13 @@ edbus_service_interface_register(EDBus_Connection *conn, const char *path, const
|
||||||
}
|
}
|
||||||
iface->signals = desc->signals;
|
iface->signals = desc->signals;
|
||||||
|
|
||||||
|
for (property = (EDBus_Property *)desc->properties;
|
||||||
|
property && property->name; property++)
|
||||||
|
_edbus_service_property_add(iface, property);
|
||||||
|
|
||||||
|
iface->get_func = desc->default_get;
|
||||||
|
iface->set_func = desc->default_set;
|
||||||
|
|
||||||
return iface;
|
return iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +620,7 @@ static void
|
||||||
_interface_free(EDBus_Service_Interface *interface)
|
_interface_free(EDBus_Service_Interface *interface)
|
||||||
{
|
{
|
||||||
unsigned size, i;
|
unsigned size, i;
|
||||||
if (interface == introspectable) return;
|
if (interface == introspectable || interface == properties_iface) return;
|
||||||
|
|
||||||
eina_hash_free(interface->methods);
|
eina_hash_free(interface->methods);
|
||||||
eina_stringshare_del(interface->name);
|
eina_stringshare_del(interface->name);
|
||||||
|
@ -367,6 +628,11 @@ _interface_free(EDBus_Service_Interface *interface)
|
||||||
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));
|
||||||
eina_array_free(interface->sign_of_signals);
|
eina_array_free(interface->sign_of_signals);
|
||||||
|
eina_hash_free(interface->properties);
|
||||||
|
if (interface->props_changed)
|
||||||
|
eina_array_free(interface->props_changed);
|
||||||
|
if (interface->idler_propschanged)
|
||||||
|
ecore_idler_del(interface->idler_propschanged);
|
||||||
free(interface);
|
free(interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +668,7 @@ edbus_service_interface_unregister(EDBus_Service_Interface *iface)
|
||||||
{
|
{
|
||||||
EDBUS_SERVICE_INTERFACE_CHECK(iface);
|
EDBUS_SERVICE_INTERFACE_CHECK(iface);
|
||||||
eina_hash_del(iface->obj->interfaces, NULL, iface);
|
eina_hash_del(iface->obj->interfaces, NULL, iface);
|
||||||
if (eina_hash_population(iface->obj->interfaces) < 2)
|
if (eina_hash_population(iface->obj->interfaces) < 3)
|
||||||
edbus_service_object_unregister(iface);
|
edbus_service_object_unregister(iface);
|
||||||
_interface_free(iface);
|
_interface_free(iface);
|
||||||
}
|
}
|
||||||
|
@ -585,3 +851,106 @@ edbus_service_object_data_del(EDBus_Service_Interface *iface, const char *key)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
||||||
return edbus_data_del(&(((EDBus_Service_Object *)iface->obj)->data), key);
|
return edbus_data_del(&(((EDBus_Service_Object *)iface->obj)->data), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_idler_propschanged(void *data)
|
||||||
|
{
|
||||||
|
EDBus_Service_Interface *iface = data;
|
||||||
|
EDBus_Message *msg;
|
||||||
|
EDBus_Message_Iter *main_iter, *dict, *array_invalidate;
|
||||||
|
Eina_Hash *added = NULL;
|
||||||
|
EDBus_Property *prop;
|
||||||
|
|
||||||
|
iface->idler_propschanged = NULL;
|
||||||
|
|
||||||
|
added = eina_hash_string_small_new(NULL);
|
||||||
|
msg = edbus_message_signal_new(iface->obj->path, properties_iface->name,
|
||||||
|
properties_iface->signals[0].name);
|
||||||
|
EINA_SAFETY_ON_NULL_GOTO(msg, error);
|
||||||
|
|
||||||
|
main_iter = edbus_message_iter_get(msg);
|
||||||
|
if (!edbus_message_iter_arguments_set(main_iter, "sa{sv}", iface->name, &dict))
|
||||||
|
{
|
||||||
|
edbus_message_unref(msg);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iface->props_changed)
|
||||||
|
goto invalidate;
|
||||||
|
while ((prop = eina_array_pop(iface->props_changed)))
|
||||||
|
{
|
||||||
|
EDBus_Message_Iter *entry, *var;
|
||||||
|
EDBus_Message *error_reply;
|
||||||
|
Eina_Bool ret;
|
||||||
|
EDBus_Property_Get_Cb getter = NULL;
|
||||||
|
|
||||||
|
if (eina_hash_find(added, prop->name))
|
||||||
|
continue;
|
||||||
|
eina_hash_add(added, prop->name, prop);
|
||||||
|
|
||||||
|
if (prop->get_func)
|
||||||
|
getter = prop->get_func;
|
||||||
|
else if (iface->get_func)
|
||||||
|
getter = iface->get_func;
|
||||||
|
|
||||||
|
if (!getter)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_FALSE_GOTO(
|
||||||
|
edbus_message_iter_arguments_set(dict, "{sv}", &entry), error);
|
||||||
|
|
||||||
|
edbus_message_iter_basic_append(entry, 's', prop->name);
|
||||||
|
var = edbus_message_iter_container_new(entry, 'v', prop->type);
|
||||||
|
|
||||||
|
ret = getter(iface, prop->name, var, &error_reply);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
const char *errorname, *errormsg;
|
||||||
|
if (error_reply &&
|
||||||
|
edbus_message_error_get(error_reply, &errorname, &errormsg))
|
||||||
|
ERR("%s %s", errorname, errormsg);
|
||||||
|
|
||||||
|
edbus_message_unref(msg);
|
||||||
|
if (error_reply) edbus_message_unref(error_reply);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
edbus_message_iter_container_close(entry, var);
|
||||||
|
edbus_message_iter_container_close(dict, entry);
|
||||||
|
}
|
||||||
|
invalidate:
|
||||||
|
edbus_message_iter_container_close(main_iter, dict);
|
||||||
|
|
||||||
|
edbus_message_iter_arguments_set(main_iter, "as", &array_invalidate);
|
||||||
|
edbus_message_iter_container_close(main_iter, array_invalidate);
|
||||||
|
|
||||||
|
edbus_service_signal_send(iface, msg);
|
||||||
|
edbus_message_unref(msg);
|
||||||
|
error:
|
||||||
|
if (added)
|
||||||
|
eina_hash_free(added);
|
||||||
|
if (iface->props_changed)
|
||||||
|
eina_array_flush(iface->props_changed);
|
||||||
|
return ECORE_CALLBACK_CANCEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
edbus_service_property_changed(EDBus_Service_Interface *iface, const char *name)
|
||||||
|
{
|
||||||
|
EDBus_Property *prop;
|
||||||
|
EDBUS_SERVICE_INTERFACE_CHECK_RETVAL(iface, EINA_FALSE);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
|
||||||
|
|
||||||
|
prop = eina_hash_find(iface->properties, name);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE);
|
||||||
|
|
||||||
|
if (!iface->idler_propschanged)
|
||||||
|
{
|
||||||
|
iface->idler_propschanged = ecore_idler_add(_idler_propschanged, iface);
|
||||||
|
if (!iface->props_changed)
|
||||||
|
iface->props_changed = eina_array_new(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return eina_array_push(iface->props_changed, prop);
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#define EDBUS_SIGNAL_FLAG_DEPRECATED 1
|
#define EDBUS_SIGNAL_FLAG_DEPRECATED 1
|
||||||
|
|
||||||
|
#define EDBUS_PROPERTY_FLAG_DEPRECATED 1
|
||||||
|
|
||||||
typedef struct _EDBus_Arg_Info
|
typedef struct _EDBus_Arg_Info
|
||||||
{
|
{
|
||||||
const char *signature;
|
const char *signature;
|
||||||
|
@ -29,8 +31,8 @@ typedef struct _EDBus_Arg_Info
|
||||||
typedef struct _EDBus_Service_Interface EDBus_Service_Interface;
|
typedef struct _EDBus_Service_Interface EDBus_Service_Interface;
|
||||||
typedef EDBus_Message * (*EDBus_Method_Cb)(const EDBus_Service_Interface *iface, const EDBus_Message *message);
|
typedef EDBus_Message * (*EDBus_Method_Cb)(const EDBus_Service_Interface *iface, const EDBus_Message *message);
|
||||||
|
|
||||||
typedef Eina_Bool (*EDBus_Property_Get_Cb)(EDBus_Service_Interface *iface, const char *propname, EDBus_Message_Iter *iter, EDBus_Message **error);
|
typedef Eina_Bool (*EDBus_Property_Get_Cb)(const EDBus_Service_Interface *iface, const char *propname, EDBus_Message_Iter *iter, EDBus_Message **error);
|
||||||
typedef EDBus_Message *(*EDBus_Property_Set_Cb)(EDBus_Service_Interface *iface, const char *propname, EDBus_Message *input_msg);
|
typedef EDBus_Message *(*EDBus_Property_Set_Cb)(const EDBus_Service_Interface *iface, const char *propname, const EDBus_Message *input_msg);
|
||||||
|
|
||||||
typedef struct _EDBus_Method
|
typedef struct _EDBus_Method
|
||||||
{
|
{
|
||||||
|
@ -52,19 +54,19 @@ typedef struct _EDBus_Property
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *type;
|
const char *type;
|
||||||
unsigned int flags;
|
|
||||||
EDBus_Property_Set_Cb set_func;
|
|
||||||
EDBus_Property_Get_Cb get_func;
|
EDBus_Property_Get_Cb get_func;
|
||||||
|
EDBus_Property_Set_Cb set_func;
|
||||||
|
unsigned int flags;
|
||||||
} EDBus_Property;
|
} EDBus_Property;
|
||||||
|
|
||||||
typedef struct _EDBus_Service_Interface_Desc
|
typedef struct _EDBus_Service_Interface_Desc
|
||||||
{
|
{
|
||||||
const char *interface;
|
const char *interface; /**< interface name */
|
||||||
const EDBus_Method *methods;
|
const EDBus_Method *methods; /**< array of the methods that should be registered in this interface, the last item of array should be filled with NULL */
|
||||||
const EDBus_Signal *signals;
|
const EDBus_Signal *signals; /**< array of signal that this interface send, the last item of array should be filled with NULL */
|
||||||
const EDBus_Property *properties;
|
const EDBus_Property *properties; /**< array of property that this interface have, the last item of array should be filled with NULL */
|
||||||
const EDBus_Property_Set_Cb default_set;
|
const EDBus_Property_Get_Cb default_get; /**< default get function, if a property don't have a get function this will be used */
|
||||||
const EDBus_Property_Get_Cb default_get;
|
const EDBus_Property_Set_Cb default_set; /**< default set function, if a property don't have a set function this will be used */
|
||||||
} EDBus_Service_Interface_Desc;
|
} EDBus_Service_Interface_Desc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,13 +74,7 @@ typedef struct _EDBus_Service_Interface_Desc
|
||||||
*
|
*
|
||||||
* @param conn where the interface should listen
|
* @param conn where the interface should listen
|
||||||
* @param path object path
|
* @param path object path
|
||||||
* @param iface interface
|
* @param desc description of interface
|
||||||
* @param methods array of the methods that should be registered in this
|
|
||||||
* interface, the last item of array should be filled with NULL
|
|
||||||
* @param signals array of signal that this interface send, the last item
|
|
||||||
* of array should be filled with NULL
|
|
||||||
*
|
|
||||||
* @note methods and signals must be static variables
|
|
||||||
*
|
*
|
||||||
* @return Interface
|
* @return Interface
|
||||||
*/
|
*/
|
||||||
|
@ -150,6 +146,13 @@ EAPI void *edbus_service_object_data_get(const EDBus_Service_Interface *iface, c
|
||||||
* @return pointer to data if found otherwise NULL
|
* @return pointer to data if found otherwise NULL
|
||||||
*/
|
*/
|
||||||
EAPI void *edbus_service_object_data_del(EDBus_Service_Interface *iface, const char *key);
|
EAPI void *edbus_service_object_data_del(EDBus_Service_Interface *iface, const char *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add property to changed list. *
|
||||||
|
* A PropertiesChanged signal will be send on next idler iteration with all
|
||||||
|
* properties in changed list.
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool edbus_service_property_changed(EDBus_Service_Interface *iface, const char *name);
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue