2013-03-15 01:32:20 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
#include "eldbus_private.h"
|
|
|
|
#include "eldbus_private_types.h"
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
/* TODO: mempool of Eldbus_Proxy, Eldbus_Proxy_Context_Event_Cb and
|
|
|
|
* Eldbus_Proxy_Context_Event
|
2012-09-17 13:41:05 -07:00
|
|
|
*/
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
typedef struct _Eldbus_Proxy_Context_Event_Cb
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
EINA_INLIST;
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Event_Cb cb;
|
2012-09-17 13:41:05 -07:00
|
|
|
const void *cb_data;
|
|
|
|
Eina_Bool deleted : 1;
|
2013-04-23 07:40:05 -07:00
|
|
|
} Eldbus_Proxy_Context_Event_Cb;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
typedef struct _Eldbus_Proxy_Context_Event
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
Eina_Inlist *list;
|
|
|
|
int walking;
|
|
|
|
Eina_List *to_delete;
|
2013-04-23 07:40:05 -07:00
|
|
|
} Eldbus_Proxy_Context_Event;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
struct _Eldbus_Proxy
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
EINA_MAGIC;
|
|
|
|
int refcount;
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Object *obj;
|
2012-09-17 13:41:05 -07:00
|
|
|
const char *interface;
|
|
|
|
Eina_Inlist *pendings;
|
|
|
|
Eina_List *handlers;
|
|
|
|
Eina_Inlist *cbs_free;
|
2013-01-24 05:09:26 -08:00
|
|
|
Eina_Inlist *data;
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event event_handlers[ELDBUS_PROXY_EVENT_LAST];
|
2012-10-26 11:19:32 -07:00
|
|
|
Eina_Hash *props;
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Signal_Handler *properties_changed;
|
2012-10-26 11:19:32 -07:00
|
|
|
Eina_Bool monitor_enabled:1;
|
2012-09-17 13:41:05 -07:00
|
|
|
};
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
#define ELDBUS_PROXY_CHECK(proxy) \
|
2012-09-17 13:41:05 -07:00
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(proxy); \
|
2013-04-23 07:40:05 -07:00
|
|
|
if (!EINA_MAGIC_CHECK(proxy, ELDBUS_PROXY_MAGIC)) \
|
2012-09-17 13:41:05 -07:00
|
|
|
{ \
|
2013-04-23 07:40:05 -07:00
|
|
|
EINA_MAGIC_FAIL(proxy, ELDBUS_PROXY_MAGIC); \
|
2012-09-17 13:41:05 -07:00
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN(proxy->refcount <= 0); \
|
|
|
|
} \
|
|
|
|
while (0)
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
#define ELDBUS_PROXY_CHECK_RETVAL(proxy, retval) \
|
2012-09-17 13:41:05 -07:00
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, retval); \
|
2013-04-23 07:40:05 -07:00
|
|
|
if (!EINA_MAGIC_CHECK(proxy, ELDBUS_PROXY_MAGIC)) \
|
2012-09-17 13:41:05 -07:00
|
|
|
{ \
|
2013-04-23 07:40:05 -07:00
|
|
|
EINA_MAGIC_FAIL(proxy, ELDBUS_PROXY_MAGIC); \
|
2012-09-17 13:41:05 -07:00
|
|
|
return retval; \
|
|
|
|
} \
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(proxy->refcount <= 0, retval); \
|
|
|
|
} \
|
|
|
|
while (0)
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
#define ELDBUS_PROXY_CHECK_GOTO(proxy, label) \
|
2012-09-17 13:41:05 -07:00
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
EINA_SAFETY_ON_NULL_GOTO(proxy, label); \
|
2013-04-23 07:40:05 -07:00
|
|
|
if (!EINA_MAGIC_CHECK(proxy, ELDBUS_PROXY_MAGIC)) \
|
2012-09-17 13:41:05 -07:00
|
|
|
{ \
|
2013-04-23 07:40:05 -07:00
|
|
|
EINA_MAGIC_FAIL(proxy, ELDBUS_PROXY_MAGIC); \
|
2012-09-17 13:41:05 -07:00
|
|
|
goto label; \
|
|
|
|
} \
|
|
|
|
EINA_SAFETY_ON_TRUE_GOTO(proxy->refcount <= 0, label); \
|
|
|
|
} \
|
|
|
|
while (0)
|
|
|
|
|
|
|
|
Eina_Bool
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_init(void)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_shutdown(void)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
static void _eldbus_proxy_event_callback_call(Eldbus_Proxy *proxy, Eldbus_Proxy_Event_Type type, const void *event_info);
|
|
|
|
static void _eldbus_proxy_context_event_cb_del(Eldbus_Proxy_Context_Event *ce, Eldbus_Proxy_Context_Event_Cb *ctx);
|
2012-10-18 13:11:04 -07:00
|
|
|
static void _on_signal_handler_free(void *data, const void *dead_pointer);
|
2013-11-29 10:39:10 -08:00
|
|
|
|
2012-09-17 13:41:05 -07:00
|
|
|
static void
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_call_del(Eldbus_Proxy *proxy)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event *ce;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_event_callback_call(proxy, ELDBUS_PROXY_EVENT_DEL, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
|
|
|
/* clear all del callbacks so we don't call them twice at
|
2013-04-23 07:40:05 -07:00
|
|
|
* _eldbus_proxy_clear()
|
2012-09-17 13:41:05 -07:00
|
|
|
*/
|
2013-04-23 07:40:05 -07:00
|
|
|
ce = proxy->event_handlers + ELDBUS_PROXY_EVENT_DEL;
|
2012-09-17 13:41:05 -07:00
|
|
|
while (ce->list)
|
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event_Cb *ctx;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
|
|
|
ctx = EINA_INLIST_CONTAINER_GET(ce->list,
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event_Cb);
|
|
|
|
_eldbus_proxy_context_event_cb_del(ce, ctx);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_clear(Eldbus_Proxy *proxy)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Signal_Handler *h;
|
|
|
|
Eldbus_Pending *p;
|
2012-09-17 13:41:05 -07:00
|
|
|
Eina_List *iter, *iter_next;
|
|
|
|
Eina_Inlist *in_l;
|
|
|
|
DBG("proxy=%p, refcount=%d, interface=%s, obj=%p",
|
|
|
|
proxy, proxy->refcount, proxy->interface, proxy->obj);
|
|
|
|
proxy->refcount = 1;
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_object_proxy_del(proxy->obj, proxy, proxy->interface);
|
|
|
|
_eldbus_proxy_call_del(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
|
|
|
EINA_LIST_FOREACH_SAFE(proxy->handlers, iter, iter_next, h)
|
|
|
|
{
|
|
|
|
DBG("proxy=%p delete owned signal handler %p %s",
|
2013-04-23 07:40:05 -07:00
|
|
|
proxy, h, eldbus_signal_handler_match_get(h));
|
|
|
|
eldbus_signal_handler_del(h);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH_SAFE(proxy->pendings, in_l, p)
|
|
|
|
{
|
|
|
|
DBG("proxy=%p delete owned pending call=%p dest=%s path=%s %s.%s()",
|
|
|
|
proxy, p,
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_pending_destination_get(p),
|
|
|
|
eldbus_pending_path_get(p),
|
|
|
|
eldbus_pending_interface_get(p),
|
|
|
|
eldbus_pending_method_get(p));
|
|
|
|
eldbus_pending_cancel(p);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_cbs_free_dispatch(&(proxy->cbs_free), proxy);
|
2012-10-26 11:19:32 -07:00
|
|
|
if (proxy->props)
|
|
|
|
eina_hash_free(proxy->props);
|
2012-09-17 13:41:05 -07:00
|
|
|
proxy->refcount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_free(Eldbus_Proxy *proxy)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
unsigned int i;
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Signal_Handler *h;
|
2012-10-18 13:11:04 -07:00
|
|
|
|
2016-02-13 08:25:48 -08:00
|
|
|
DBG("freeing proxy=%p", proxy);
|
2012-10-19 11:24:30 -07:00
|
|
|
EINA_LIST_FREE(proxy->handlers, h)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2012-10-18 13:11:04 -07:00
|
|
|
if (h->dangling)
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_signal_handler_free_cb_del(h, _on_signal_handler_free, proxy);
|
2012-10-18 13:11:04 -07:00
|
|
|
else
|
|
|
|
ERR("proxy=%p alive handler=%p %s", proxy, h,
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_signal_handler_match_get(h));
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (proxy->pendings)
|
2013-12-25 19:22:05 -08:00
|
|
|
CRI("Proxy %p released with live pending calls!", proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
for (i = 0; i < ELDBUS_PROXY_EVENT_LAST; i++)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event *ce = proxy->event_handlers + i;
|
2012-09-17 13:41:05 -07:00
|
|
|
while (ce->list)
|
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event_Cb *ctx;
|
2012-09-17 13:41:05 -07:00
|
|
|
ctx = EINA_INLIST_CONTAINER_GET(ce->list,
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event_Cb);
|
|
|
|
_eldbus_proxy_context_event_cb_del(ce, ctx);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
eina_list_free(ce->to_delete);
|
|
|
|
}
|
|
|
|
|
|
|
|
eina_stringshare_del(proxy->interface);
|
|
|
|
EINA_MAGIC_SET(proxy, EINA_MAGIC_NONE);
|
|
|
|
free(proxy);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-01-03 06:05:51 -08:00
|
|
|
_on_object_free(void *data, const void *dead_pointer EINA_UNUSED)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy *proxy = data;
|
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
DBG("proxy=%p, refcount=%d, interface=%s, obj=%p",
|
|
|
|
proxy, proxy->refcount, proxy->interface, proxy->obj);
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_data_del_all(&(proxy->data));
|
|
|
|
_eldbus_proxy_clear(proxy);
|
|
|
|
_eldbus_proxy_free(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Proxy *
|
|
|
|
eldbus_proxy_get(Eldbus_Object *obj, const char *interface)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy *proxy;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
proxy = eldbus_object_proxy_get(obj, interface);
|
2012-12-11 11:51:29 -08:00
|
|
|
if (proxy)
|
2013-04-23 07:40:05 -07:00
|
|
|
return eldbus_proxy_ref(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
proxy = calloc(1, sizeof(Eldbus_Proxy));
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, NULL);
|
|
|
|
|
|
|
|
proxy->refcount = 1;
|
|
|
|
proxy->obj = obj;
|
|
|
|
proxy->interface = eina_stringshare_add(interface);
|
2013-04-23 07:40:05 -07:00
|
|
|
EINA_MAGIC_SET(proxy, ELDBUS_PROXY_MAGIC);
|
|
|
|
if (!eldbus_object_proxy_add(obj, proxy))
|
2012-09-17 13:41:05 -07:00
|
|
|
goto cleanup;
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_object_free_cb_add(obj, _on_object_free, proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
|
|
|
return proxy;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
eina_stringshare_del(proxy->interface);
|
|
|
|
free(proxy);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _on_signal_handler_free(void *data, const void *dead_pointer);
|
|
|
|
|
|
|
|
static void
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_unref(Eldbus_Proxy *proxy)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
proxy->refcount--;
|
|
|
|
if (proxy->refcount > 0) return;
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_object_free_cb_del(proxy->obj, _on_object_free, proxy);
|
|
|
|
eldbus_data_del_all(&(proxy->data));
|
|
|
|
_eldbus_proxy_clear(proxy);
|
|
|
|
_eldbus_proxy_free(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Proxy *
|
|
|
|
eldbus_proxy_ref(Eldbus_Proxy *proxy)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
DBG("proxy=%p, pre-refcount=%d, interface=%s, obj=%p",
|
|
|
|
proxy, proxy->refcount, proxy->interface, proxy->obj);
|
|
|
|
proxy->refcount++;
|
|
|
|
return proxy;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_unref(Eldbus_Proxy *proxy)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
DBG("proxy=%p, pre-refcount=%d, interface=%s, obj=%p",
|
|
|
|
proxy, proxy->refcount, proxy->interface, proxy->obj);
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_unref(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_free_cb_add(Eldbus_Proxy *proxy, Eldbus_Free_Cb cb, const void *data)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(cb);
|
2013-04-23 07:40:05 -07:00
|
|
|
proxy->cbs_free = eldbus_cbs_free_add(proxy->cbs_free, cb, data);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_free_cb_del(Eldbus_Proxy *proxy, Eldbus_Free_Cb cb, const void *data)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(cb);
|
2013-04-23 07:40:05 -07:00
|
|
|
proxy->cbs_free = eldbus_cbs_free_del(proxy->cbs_free, cb, data);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2013-01-24 05:09:26 -08:00
|
|
|
EAPI void
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_data_set(Eldbus_Proxy *proxy, const char *key, const void *data)
|
2013-01-24 05:09:26 -08:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2013-01-24 05:09:26 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(key);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(data);
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_data_set(&(proxy->data), key, data);
|
2013-01-24 05:09:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void *
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_data_get(const Eldbus_Proxy *proxy, const char *key)
|
2013-01-24 05:09:26 -08:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2013-01-24 05:09:26 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
2013-04-23 07:40:05 -07:00
|
|
|
return eldbus_data_get(&(((Eldbus_Proxy *)proxy)->data), key);
|
2013-01-24 05:09:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void *
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_data_del(Eldbus_Proxy *proxy, const char *key)
|
2013-01-24 05:09:26 -08:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2013-01-24 05:09:26 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
|
2013-04-23 07:40:05 -07:00
|
|
|
return eldbus_data_del(&(((Eldbus_Proxy *)proxy)->data), key);
|
2013-01-24 05:09:26 -08:00
|
|
|
}
|
|
|
|
|
2015-02-05 06:20:36 -08:00
|
|
|
static Eina_Value *
|
|
|
|
_iter_hash_value_set(Eina_Hash *props, const char *key, Eldbus_Message_Iter *var) EINA_ARG_NONNULL(1, 2, 3)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2015-02-05 06:20:36 -08:00
|
|
|
Eina_Value *st_value = _message_iter_struct_to_eina_value(var);
|
|
|
|
Eina_Value *value;
|
|
|
|
Eina_Value stack_value;
|
2012-10-26 11:19:32 -07:00
|
|
|
|
|
|
|
eina_value_struct_value_get(st_value, "arg0", &stack_value);
|
|
|
|
|
2015-02-05 06:20:36 -08:00
|
|
|
value = eina_hash_find(props, key);
|
2015-02-05 06:15:37 -08:00
|
|
|
if (!value)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2015-02-05 06:15:37 -08:00
|
|
|
value = eina_value_new(eina_value_type_get(&stack_value));
|
2015-02-05 06:20:36 -08:00
|
|
|
eina_hash_add(props, key, value);
|
2012-10-26 11:19:32 -07:00
|
|
|
}
|
|
|
|
|
2015-02-05 06:15:37 -08:00
|
|
|
eina_value_flush(value);
|
|
|
|
eina_value_copy(&stack_value, value);
|
|
|
|
|
2015-02-05 06:20:36 -08:00
|
|
|
eina_value_flush(&stack_value);
|
|
|
|
eina_value_free(st_value);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_property_changed_iter(void *data, const void *key, Eldbus_Message_Iter *var)
|
|
|
|
{
|
|
|
|
Eldbus_Proxy *proxy = data;
|
|
|
|
const char *skey = key;
|
|
|
|
|
|
|
|
Eina_Value *value = _iter_hash_value_set(proxy->props, skey, var);
|
|
|
|
|
|
|
|
Eldbus_Proxy_Event_Property_Changed event = {.name = skey,
|
|
|
|
.value = value,
|
|
|
|
.proxy = proxy};
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_event_callback_call(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
|
2013-08-30 06:15:10 -07:00
|
|
|
&event);
|
2012-10-26 11:19:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-04-23 07:40:05 -07:00
|
|
|
_properties_changed(void *data, const Eldbus_Message *msg)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy *proxy = data;
|
|
|
|
Eldbus_Message_Iter *array, *invalidate;
|
2012-10-26 11:19:32 -07:00
|
|
|
const char *iface;
|
|
|
|
const char *invalidate_prop;
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "sa{sv}as", &iface, &array, &invalidate))
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
|
|
|
ERR("Error getting data from properties changed signal.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (proxy->props)
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_message_iter_dict_iterate(array, "sv", _property_changed_iter,
|
2012-10-26 11:19:32 -07:00
|
|
|
proxy);
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
while (eldbus_message_iter_get_and_next(invalidate, 's', &invalidate_prop))
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Event_Property_Removed event;
|
2012-10-26 11:19:32 -07:00
|
|
|
event.interface = proxy->interface;
|
|
|
|
event.name = invalidate_prop;
|
|
|
|
event.proxy = proxy;
|
|
|
|
if (proxy->props)
|
|
|
|
eina_hash_del(proxy->props, event.name, NULL);
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_event_callback_call(proxy, ELDBUS_PROXY_EVENT_PROPERTY_REMOVED,
|
2012-10-26 11:19:32 -07:00
|
|
|
&event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_props_cache_free(void *data)
|
|
|
|
{
|
|
|
|
Eina_Value *value = data;
|
|
|
|
eina_value_free(value);
|
|
|
|
}
|
|
|
|
|
2012-09-17 13:41:05 -07:00
|
|
|
EAPI void
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_event_callback_add(Eldbus_Proxy *proxy, Eldbus_Proxy_Event_Type type, Eldbus_Proxy_Event_Cb cb, const void *cb_data)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event *ce;
|
|
|
|
Eldbus_Proxy_Context_Event_Cb *ctx;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(cb);
|
2013-04-23 07:40:05 -07:00
|
|
|
EINA_SAFETY_ON_TRUE_RETURN(type >= ELDBUS_PROXY_EVENT_LAST);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
|
|
|
ce = proxy->event_handlers + type;
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
ctx = calloc(1, sizeof(Eldbus_Proxy_Context_Event_Cb));
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(ctx);
|
|
|
|
ctx->cb = cb;
|
|
|
|
ctx->cb_data = cb_data;
|
|
|
|
|
|
|
|
ce->list = eina_inlist_append(ce->list, EINA_INLIST_GET(ctx));
|
2012-10-26 11:19:32 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
if (type == ELDBUS_PROXY_EVENT_PROPERTY_CHANGED)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
|
|
|
if (proxy->properties_changed) return;
|
|
|
|
if (!proxy->props)
|
|
|
|
proxy->props = eina_hash_string_superfast_new(_props_cache_free);
|
2012-10-26 11:19:46 -07:00
|
|
|
proxy->properties_changed =
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_properties_changed_callback_add(proxy,
|
2012-10-26 11:19:46 -07:00
|
|
|
_properties_changed,
|
|
|
|
proxy);
|
2012-10-26 11:19:32 -07:00
|
|
|
}
|
2013-04-23 07:40:05 -07:00
|
|
|
else if (type == ELDBUS_PROXY_EVENT_PROPERTY_REMOVED)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
|
|
|
if (proxy->properties_changed) return;
|
2012-10-26 11:19:46 -07:00
|
|
|
proxy->properties_changed =
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_properties_changed_callback_add(proxy,
|
2012-10-26 11:19:46 -07:00
|
|
|
_properties_changed,
|
|
|
|
proxy);
|
2012-10-26 11:19:32 -07:00
|
|
|
}
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_context_event_cb_del(Eldbus_Proxy_Context_Event *ce, Eldbus_Proxy_Context_Event_Cb *ctx)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
ce->list = eina_inlist_remove(ce->list, EINA_INLIST_GET(ctx));
|
|
|
|
free(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_event_callback_del(Eldbus_Proxy *proxy, Eldbus_Proxy_Event_Type type, Eldbus_Proxy_Event_Cb cb, const void *cb_data)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event *ce;
|
|
|
|
Eldbus_Proxy_Context_Event_Cb *iter, *found = NULL;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(cb);
|
2013-04-23 07:40:05 -07:00
|
|
|
EINA_SAFETY_ON_TRUE_RETURN(type >= ELDBUS_PROXY_EVENT_LAST);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
|
|
|
ce = proxy->event_handlers + type;
|
|
|
|
|
2012-10-19 11:24:30 -07:00
|
|
|
EINA_INLIST_FOREACH(ce->list, iter)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
if (cb != iter->cb) continue;
|
|
|
|
if ((cb_data) && (cb_data != iter->cb_data)) continue;
|
|
|
|
|
|
|
|
found = iter;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(found);
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN(found->deleted);
|
|
|
|
|
|
|
|
if (ce->walking)
|
|
|
|
{
|
|
|
|
found->deleted = EINA_TRUE;
|
|
|
|
ce->to_delete = eina_list_append(ce->to_delete, found);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_context_event_cb_del(ce, found);
|
2012-10-26 11:19:32 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
if (type == ELDBUS_PROXY_EVENT_PROPERTY_CHANGED)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event *ce_prop_remove;
|
2012-10-26 11:19:32 -07:00
|
|
|
ce_prop_remove = proxy->event_handlers +
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_EVENT_PROPERTY_REMOVED;
|
2012-10-26 11:19:32 -07:00
|
|
|
if (!ce->list && !proxy->monitor_enabled)
|
|
|
|
{
|
|
|
|
eina_hash_free(proxy->props);
|
|
|
|
proxy->props = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ce_prop_remove->list && !ce->list && !proxy->monitor_enabled)
|
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_signal_handler_unref(proxy->properties_changed);
|
2012-10-26 11:19:32 -07:00
|
|
|
proxy->properties_changed = NULL;
|
|
|
|
}
|
|
|
|
}
|
2013-04-23 07:40:05 -07:00
|
|
|
else if (type == ELDBUS_PROXY_EVENT_PROPERTY_REMOVED)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event *ce_prop_changed;
|
2012-10-26 11:19:32 -07:00
|
|
|
ce_prop_changed = proxy->event_handlers +
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_EVENT_PROPERTY_CHANGED;
|
2012-10-26 11:19:32 -07:00
|
|
|
|
|
|
|
if (!ce_prop_changed->list && !ce->list && !proxy->monitor_enabled)
|
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_signal_handler_unref(proxy->properties_changed);
|
2012-10-26 11:19:32 -07:00
|
|
|
proxy->properties_changed = NULL;
|
|
|
|
}
|
|
|
|
}
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_event_callback_call(Eldbus_Proxy *proxy, Eldbus_Proxy_Event_Type type, const void *event_info)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event *ce;
|
|
|
|
Eldbus_Proxy_Context_Event_Cb *iter;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
|
|
|
ce = proxy->event_handlers + type;
|
|
|
|
|
|
|
|
ce->walking++;
|
2012-10-19 11:24:30 -07:00
|
|
|
EINA_INLIST_FOREACH(ce->list, iter)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
|
|
|
if (iter->deleted) continue;
|
|
|
|
iter->cb((void *)iter->cb_data, proxy, (void *)event_info);
|
|
|
|
}
|
|
|
|
ce->walking--;
|
|
|
|
if (ce->walking > 0) return;
|
|
|
|
|
2012-10-19 11:24:30 -07:00
|
|
|
EINA_LIST_FREE(ce->to_delete, iter)
|
2013-04-23 07:40:05 -07:00
|
|
|
_eldbus_proxy_context_event_cb_del(ce, iter);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Object *
|
|
|
|
eldbus_proxy_object_get(const Eldbus_Proxy *proxy)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
return proxy->obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_interface_get(const Eldbus_Proxy *proxy)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
return proxy->interface;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-12-17 10:57:03 -08:00
|
|
|
_on_proxy_message_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2014-12-17 10:57:03 -08:00
|
|
|
Eldbus_Message_Cb cb = eldbus_pending_data_del(pending, "__user_cb");
|
|
|
|
Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, "__proxy");
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
proxy->pendings = eina_inlist_remove(proxy->pendings,
|
|
|
|
EINA_INLIST_GET(pending));
|
2014-12-17 10:57:03 -08:00
|
|
|
cb(data, msg, pending);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
static Eldbus_Pending *
|
|
|
|
_eldbus_proxy_send(Eldbus_Proxy *proxy, Eldbus_Message *msg, Eldbus_Message_Cb cb, const void *cb_data, double timeout)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Pending *pending;
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2014-12-17 10:57:03 -08:00
|
|
|
if (!cb)
|
|
|
|
{
|
|
|
|
_eldbus_connection_send(proxy->obj->conn, msg, NULL, NULL, timeout);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
pending = _eldbus_connection_send(proxy->obj->conn, msg,
|
|
|
|
_on_proxy_message_cb, cb_data, timeout);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL);
|
|
|
|
|
2014-12-17 10:57:03 -08:00
|
|
|
eldbus_pending_data_set(pending, "__user_cb", cb);
|
|
|
|
eldbus_pending_data_set(pending, "__proxy", proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
proxy->pendings = eina_inlist_append(proxy->pendings,
|
|
|
|
EINA_INLIST_GET(pending));
|
|
|
|
|
|
|
|
return pending;
|
|
|
|
}
|
|
|
|
|
2014-12-04 06:48:21 -08:00
|
|
|
static Eldbus_Message *
|
2014-12-04 19:04:20 -08:00
|
|
|
_eldbus_proxy_send_and_block(Eldbus_Proxy *proxy, Eldbus_Message *msg, double timeout)
|
2014-12-04 06:48:21 -08:00
|
|
|
{
|
2014-12-04 19:04:20 -08:00
|
|
|
return _eldbus_connection_send_and_block(proxy->obj->conn, msg, timeout);
|
2014-12-04 06:48:21 -08:00
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Pending *
|
|
|
|
eldbus_proxy_send(Eldbus_Proxy *proxy, Eldbus_Message *msg, Eldbus_Message_Cb cb, const void *cb_data, double timeout)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
return _eldbus_proxy_send(proxy, msg, cb, cb_data, timeout);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2014-12-04 06:48:21 -08:00
|
|
|
EAPI Eldbus_Message *
|
2014-12-04 19:04:20 -08:00
|
|
|
eldbus_proxy_send_and_block(Eldbus_Proxy *proxy, Eldbus_Message *msg, double timeout)
|
2014-12-04 06:48:21 -08:00
|
|
|
{
|
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
|
|
|
|
2014-12-04 19:04:20 -08:00
|
|
|
return _eldbus_proxy_send_and_block(proxy, msg, timeout);
|
2014-12-04 06:48:21 -08:00
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Message *
|
|
|
|
eldbus_proxy_method_call_new(Eldbus_Proxy *proxy, const char *member)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Message *msg;
|
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
msg = eldbus_message_method_call_new(
|
|
|
|
eldbus_object_bus_name_get(proxy->obj),
|
|
|
|
eldbus_object_path_get(proxy->obj),
|
2012-09-17 13:41:05 -07:00
|
|
|
proxy->interface, member);
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
static Eldbus_Pending *
|
|
|
|
_eldbus_proxy_vcall(Eldbus_Proxy *proxy, const char *member, Eldbus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, va_list ap)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Message *msg = eldbus_proxy_method_call_new(proxy, member);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
if (!eldbus_message_arguments_vappend(msg, signature, ap))
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_message_unref(msg);
|
2012-09-17 13:41:05 -07:00
|
|
|
ERR("Error setting arguments");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
return _eldbus_proxy_send(proxy, msg, cb, cb_data, timeout);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Pending *
|
|
|
|
eldbus_proxy_call(Eldbus_Proxy *proxy, const char *member, Eldbus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, ...)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Pending *pending;
|
2012-09-17 13:41:05 -07:00
|
|
|
va_list ap;
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(member, NULL);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, NULL);
|
|
|
|
|
|
|
|
va_start(ap, signature);
|
2013-04-23 07:40:05 -07:00
|
|
|
pending = _eldbus_proxy_vcall(proxy, member, cb, cb_data, timeout,
|
2012-09-17 13:41:05 -07:00
|
|
|
signature, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
return pending;
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Pending *
|
|
|
|
eldbus_proxy_vcall(Eldbus_Proxy *proxy, const char *member, Eldbus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, va_list ap)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(member, NULL);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, NULL);
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
return _eldbus_proxy_vcall(proxy, member, cb, cb_data, timeout,
|
2012-09-17 13:41:05 -07:00
|
|
|
signature, ap);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_on_signal_handler_free(void *data, const void *dead_pointer)
|
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy *proxy = data;
|
|
|
|
ELDBUS_PROXY_CHECK(proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
proxy->handlers = eina_list_remove(proxy->handlers, dead_pointer);
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Signal_Handler *
|
|
|
|
eldbus_proxy_signal_handler_add(Eldbus_Proxy *proxy, const char *member, Eldbus_Signal_Cb cb, const void *cb_data)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Signal_Handler *handler;
|
2012-09-17 13:41:05 -07:00
|
|
|
const char *name, *path;
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
name = eldbus_object_bus_name_get(proxy->obj);
|
|
|
|
path = eldbus_object_path_get(proxy->obj);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
handler = _eldbus_signal_handler_add(proxy->obj->conn, name, path,
|
2012-12-11 11:50:01 -08:00
|
|
|
proxy->interface, member, cb, cb_data);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(handler, NULL);
|
2016-02-13 08:25:48 -08:00
|
|
|
DBG("signal handler added: proxy=%p handler=%p cb=%p", proxy, handler, cb);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_signal_handler_free_cb_add(handler, _on_signal_handler_free, proxy);
|
2012-09-17 13:41:05 -07:00
|
|
|
proxy->handlers = eina_list_append(proxy->handlers, handler);
|
|
|
|
|
|
|
|
return handler;
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Pending *
|
|
|
|
eldbus_proxy_property_get(Eldbus_Proxy *proxy, const char *name, Eldbus_Message_Cb cb, const void *data)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
2013-04-23 07:40:05 -07:00
|
|
|
return eldbus_proxy_call(proxy->obj->properties, "Get", cb, data, -1,
|
2012-09-17 13:41:05 -07:00
|
|
|
"ss", proxy->interface, name);
|
|
|
|
}
|
|
|
|
|
2014-08-10 13:55:38 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
_type_is_number(char sig)
|
|
|
|
{
|
|
|
|
switch (sig)
|
|
|
|
{
|
|
|
|
case 'y': case 'b': case 'n': case 'q': case 'i':
|
|
|
|
case 'u': case 'x': case 't': case 'd': case 'h':
|
|
|
|
return EINA_TRUE;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Pending *
|
|
|
|
eldbus_proxy_property_set(Eldbus_Proxy *proxy, const char *name, const char *sig, const void *value, Eldbus_Message_Cb cb, const void *data)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Message *msg;
|
|
|
|
Eldbus_Message_Iter *iter, *variant;
|
2012-12-20 13:48:22 -08:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
2012-12-20 13:48:22 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(sig, NULL);
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate_single(sig, NULL), NULL);
|
2014-08-10 13:55:38 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL((_type_is_number(sig[0]) || value), NULL);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
msg = eldbus_proxy_method_call_new(proxy->obj->properties, "Set");
|
|
|
|
iter = eldbus_message_iter_get(msg);
|
|
|
|
eldbus_message_iter_basic_append(iter, 's', proxy->interface);
|
|
|
|
eldbus_message_iter_basic_append(iter, 's', name);
|
|
|
|
variant = eldbus_message_iter_container_new(iter, 'v', sig);
|
2012-12-20 13:48:22 -08:00
|
|
|
if (dbus_type_is_basic(sig[0]))
|
|
|
|
dbus_message_iter_append_basic(&variant->dbus_iterator, sig[0], &value);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!_message_iter_from_eina_value_struct(sig, variant, value))
|
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_message_unref(msg);
|
2012-12-20 13:48:22 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_message_iter_container_close(iter, variant);
|
2012-09-17 13:41:05 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
return eldbus_proxy_send(proxy->obj->properties, msg, cb, data, -1);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
|
|
|
|
2015-01-09 08:20:14 -08:00
|
|
|
EAPI Eldbus_Pending *
|
|
|
|
eldbus_proxy_property_value_set(Eldbus_Proxy *proxy, const char *name, const char *sig, const Eina_Value *value, Eldbus_Message_Cb cb, const void *data)
|
|
|
|
{
|
|
|
|
Eldbus_Message *msg;
|
|
|
|
Eldbus_Message_Iter *iter, *variant;
|
|
|
|
|
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(sig, NULL);
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate_single(sig, NULL), NULL);
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL((_type_is_number(sig[0]) || value), NULL);
|
|
|
|
|
|
|
|
msg = eldbus_proxy_method_call_new(proxy->obj->properties, "Set");
|
|
|
|
iter = eldbus_message_iter_get(msg);
|
|
|
|
eldbus_message_iter_basic_append(iter, 's', proxy->interface);
|
|
|
|
eldbus_message_iter_basic_append(iter, 's', name);
|
|
|
|
variant = eldbus_message_iter_container_new(iter, 'v', sig);
|
|
|
|
if (dbus_type_is_basic(sig[0]))
|
|
|
|
{
|
|
|
|
if (!_message_iter_from_eina_value(sig, variant, value))
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!_message_iter_from_eina_value_struct(sig, variant, value))
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
eldbus_message_iter_container_close(iter, variant);
|
|
|
|
|
|
|
|
return eldbus_proxy_send(proxy->obj->properties, msg, cb, data, -1);
|
|
|
|
|
|
|
|
error:
|
|
|
|
eldbus_message_unref(msg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Pending *
|
|
|
|
eldbus_proxy_property_get_all(Eldbus_Proxy *proxy, Eldbus_Message_Cb cb, const void *data)
|
2012-09-17 13:41:05 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
|
|
|
return eldbus_proxy_call(proxy->obj->properties, "GetAll", cb, data, -1,
|
2013-08-30 06:15:10 -07:00
|
|
|
"s", proxy->interface);
|
2012-09-17 13:41:05 -07:00
|
|
|
}
|
2012-10-26 11:19:32 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
EAPI Eldbus_Signal_Handler *
|
|
|
|
eldbus_proxy_properties_changed_callback_add(Eldbus_Proxy *proxy, Eldbus_Signal_Cb cb, const void *data)
|
2012-10-26 11:19:46 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Signal_Handler *sh;
|
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
|
|
|
sh = eldbus_proxy_signal_handler_add(proxy->obj->properties,
|
2013-08-30 06:15:10 -07:00
|
|
|
"PropertiesChanged", cb, data);
|
2012-10-26 11:19:46 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(sh, NULL);
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_signal_handler_match_extra_set(sh, "arg0", proxy->interface, NULL);
|
2012-10-26 11:19:46 -07:00
|
|
|
return sh;
|
|
|
|
}
|
|
|
|
|
2012-10-26 11:19:32 -07:00
|
|
|
static void
|
2013-04-23 07:40:05 -07:00
|
|
|
_property_iter(void *data, const void *key, Eldbus_Message_Iter *var)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy *proxy = data;
|
2012-10-26 11:19:32 -07:00
|
|
|
const char *skey = key;
|
|
|
|
|
2015-02-05 06:20:36 -08:00
|
|
|
_iter_hash_value_set(proxy->props, skey, var);
|
2012-10-26 11:19:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-11-29 11:21:14 -08:00
|
|
|
_on_monitored_proxy_del(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Eldbus_Pending *pending = data;
|
|
|
|
eldbus_pending_cancel(pending);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_props_get_all(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy *proxy = data;
|
|
|
|
Eldbus_Message_Iter *dict;
|
2013-07-25 10:22:10 -07:00
|
|
|
const char *name, *error_msg;
|
2013-08-30 06:15:10 -07:00
|
|
|
Eldbus_Proxy_Event_Property_Loaded event;
|
2013-07-25 10:22:10 -07:00
|
|
|
|
2013-11-29 11:21:14 -08:00
|
|
|
eldbus_proxy_event_callback_del(proxy, ELDBUS_PROXY_EVENT_DEL,
|
|
|
|
_on_monitored_proxy_del, pending);
|
|
|
|
|
2013-07-25 10:22:10 -07:00
|
|
|
if (eldbus_message_error_get(msg, &name, &error_msg))
|
|
|
|
{
|
|
|
|
ERR("Error getting all properties of %s %s, error message: %s %s",
|
|
|
|
proxy->obj->name, proxy->obj->path, name, error_msg);
|
|
|
|
return;
|
|
|
|
}
|
2012-10-26 11:19:32 -07:00
|
|
|
|
2013-04-23 07:40:05 -07:00
|
|
|
if (!eldbus_message_arguments_get(msg, "a{sv}", &dict))
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-06-20 00:13:25 -07:00
|
|
|
char *txt;
|
|
|
|
|
|
|
|
if (eldbus_message_arguments_get(msg, "s", &txt))
|
|
|
|
ERR("Error getting data from properties getAll: %s", txt);
|
2012-10-26 11:19:32 -07:00
|
|
|
return;
|
|
|
|
}
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_message_iter_dict_iterate(dict, "sv", _property_iter, proxy);
|
2013-08-30 06:15:10 -07:00
|
|
|
|
|
|
|
event.proxy = proxy;
|
|
|
|
_eldbus_proxy_event_callback_call(proxy, ELDBUS_PROXY_EVENT_PROPERTY_LOADED,
|
|
|
|
&event);
|
2012-10-26 11:19:32 -07:00
|
|
|
}
|
|
|
|
|
2013-08-30 06:15:35 -07:00
|
|
|
EAPI Eina_Bool
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_properties_monitor(Eldbus_Proxy *proxy, Eina_Bool enable)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-11-29 11:21:14 -08:00
|
|
|
Eldbus_Pending *pending;
|
2013-08-30 06:15:35 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, EINA_FALSE);
|
2012-10-26 11:19:32 -07:00
|
|
|
if (proxy->monitor_enabled == enable)
|
2013-08-30 06:15:35 -07:00
|
|
|
return proxy->props ? !!eina_hash_population(proxy->props) : EINA_FALSE;
|
2012-10-26 11:19:32 -07:00
|
|
|
|
|
|
|
proxy->monitor_enabled = enable;
|
2013-08-30 06:15:35 -07:00
|
|
|
if (!enable)
|
2012-10-26 11:19:32 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
Eldbus_Proxy_Context_Event *ce_prop_changed, *ce_prop_removed;
|
|
|
|
ce_prop_changed = proxy->event_handlers + ELDBUS_PROXY_EVENT_PROPERTY_CHANGED;
|
|
|
|
ce_prop_removed = proxy->event_handlers + ELDBUS_PROXY_EVENT_PROPERTY_REMOVED;
|
2012-10-26 11:19:32 -07:00
|
|
|
|
|
|
|
if (!ce_prop_changed->list)
|
|
|
|
{
|
|
|
|
eina_hash_free(proxy->props);
|
|
|
|
proxy->props = NULL;
|
|
|
|
}
|
|
|
|
if (!ce_prop_changed->list && !ce_prop_removed->list)
|
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_signal_handler_unref(proxy->properties_changed);
|
2012-10-26 11:19:32 -07:00
|
|
|
proxy->properties_changed = NULL;
|
|
|
|
}
|
2013-08-30 06:15:35 -07:00
|
|
|
return EINA_TRUE;
|
2012-10-26 11:19:32 -07:00
|
|
|
}
|
2013-08-30 06:15:35 -07:00
|
|
|
|
|
|
|
if (!proxy->props)
|
|
|
|
proxy->props = eina_hash_string_superfast_new(_props_cache_free);
|
|
|
|
|
2013-11-29 11:21:14 -08:00
|
|
|
pending = eldbus_proxy_property_get_all(proxy, _props_get_all, proxy);
|
|
|
|
eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_DEL,
|
|
|
|
_on_monitored_proxy_del, pending);
|
2013-08-30 06:15:35 -07:00
|
|
|
|
|
|
|
if (proxy->properties_changed)
|
|
|
|
return !!eina_hash_population(proxy->props);
|
|
|
|
proxy->properties_changed =
|
|
|
|
eldbus_proxy_properties_changed_callback_add(proxy,
|
|
|
|
_properties_changed,
|
|
|
|
proxy);
|
|
|
|
return !!eina_hash_population(proxy->props);
|
2012-10-26 11:19:32 -07:00
|
|
|
}
|
2012-10-26 11:19:42 -07:00
|
|
|
|
|
|
|
EAPI Eina_Value *
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_property_local_get(Eldbus_Proxy *proxy, const char *name)
|
2012-10-26 11:19:42 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-10-26 11:19:42 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy->props, NULL);
|
|
|
|
return eina_hash_find(proxy->props, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const Eina_Hash *
|
2013-04-23 07:40:05 -07:00
|
|
|
eldbus_proxy_property_local_get_all(Eldbus_Proxy *proxy)
|
2012-10-26 11:19:42 -07:00
|
|
|
{
|
2013-04-23 07:40:05 -07:00
|
|
|
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
|
2012-10-26 11:19:42 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy->props, NULL);
|
|
|
|
return proxy->props;
|
|
|
|
}
|