diff options
Diffstat (limited to 'src/lib/ecore_avahi/ecore_avahi.c')
-rw-r--r-- | src/lib/ecore_avahi/ecore_avahi.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/src/lib/ecore_avahi/ecore_avahi.c b/src/lib/ecore_avahi/ecore_avahi.c new file mode 100644 index 000000000..93c5301bd --- /dev/null +++ b/src/lib/ecore_avahi/ecore_avahi.c @@ -0,0 +1,247 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <Eina.h> +#include <Ecore.h> + +#include "Ecore_Avahi.h" + +#ifdef HAVE_AVAHI +#include <avahi-common/watch.h> + +typedef struct _Ecore_Avahi_Watch Ecore_Avahi_Watch; +typedef struct _Ecore_Avahi_Timeout Ecore_Avahi_Timeout; + +struct _Ecore_Avahi_Watch +{ + Ecore_Fd_Handler *handler; + Ecore_Avahi *parent; + + AvahiWatchCallback callback; + void *callback_data; +}; + +struct _Ecore_Avahi_Timeout +{ + Ecore_Timer *timer; + Ecore_Avahi *parent; + + AvahiTimeoutCallback callback; + void *callback_data; +}; + +struct _Ecore_Avahi +{ + AvahiPoll api; + + Eina_List *watches; + Eina_List *timeouts; +}; + +static Ecore_Fd_Handler_Flags +_ecore_avahi_events2ecore(AvahiWatchEvent events) +{ + return (events & AVAHI_WATCH_IN ? ECORE_FD_READ : 0) | + (events & AVAHI_WATCH_OUT ? ECORE_FD_WRITE : 0) | + (events & AVAHI_WATCH_ERR ? ECORE_FD_ERROR : 0); +} + +static Eina_Bool +_ecore_avahi_watch_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + Ecore_Avahi_Watch *watch = data; + AvahiWatchEvent flags = 0; + + flags = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ) ? AVAHI_WATCH_IN : 0; + flags |= ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE) ? AVAHI_WATCH_OUT : 0; + flags |= ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR) ? AVAHI_WATCH_ERR : 0; + + watch->callback((AvahiWatch*) watch, ecore_main_fd_handler_fd_get(fd_handler), flags, watch->callback_data); + + return ECORE_CALLBACK_RENEW; +} + +static AvahiWatch * +_ecore_avahi_watch_new(const AvahiPoll *api, + int fd, AvahiWatchEvent events, + AvahiWatchCallback callback, void *userdata) +{ + Ecore_Avahi_Watch *watch; + Ecore_Avahi *ea; + + ea = api->userdata; + watch = calloc(1, sizeof (Ecore_Avahi_Watch)); + if (!watch) return NULL; + + watch->handler = ecore_main_fd_handler_add(fd, _ecore_avahi_events2ecore(events), + _ecore_avahi_watch_cb, watch, NULL, NULL); + watch->callback = callback; + watch->callback_data = userdata; + watch->parent = ea; + + ea->watches = eina_list_append(ea->watches, watch); + + return (AvahiWatch*) watch; +} + +static void +_ecore_avahi_watch_update(AvahiWatch *w, AvahiWatchEvent events) +{ + Ecore_Avahi_Watch *watch = (Ecore_Avahi_Watch *) w; + + ecore_main_fd_handler_active_set(watch->handler, _ecore_avahi_events2ecore(events)); +} + +static void +_ecore_avahi_watch_free(AvahiWatch *w) +{ + Ecore_Avahi_Watch *watch = (Ecore_Avahi_Watch *) w; + + ecore_main_fd_handler_del(watch->handler); + watch->parent->watches = eina_list_remove(watch->parent->watches, watch); + free(watch); +} + +static AvahiWatchEvent +_ecore_avahi_watch_get_events(AvahiWatch *w) +{ + Ecore_Avahi_Watch *watch = (Ecore_Avahi_Watch *) w; + AvahiWatchEvent flags = 0; + + flags = ecore_main_fd_handler_active_get(watch->handler, ECORE_FD_READ) ? AVAHI_WATCH_IN : 0; + flags |= ecore_main_fd_handler_active_get(watch->handler, ECORE_FD_WRITE) ? AVAHI_WATCH_OUT : 0; + flags |= ecore_main_fd_handler_active_get(watch->handler, ECORE_FD_ERROR) ? AVAHI_WATCH_ERR : 0; + + return flags; +} + +static double +_ecore_avahi_timeval2double(const struct timeval *tv) +{ + if (!tv) return 3600; + return tv->tv_sec + (double) tv->tv_usec / 1000000; +} + +static Eina_Bool +_ecore_avahi_timeout_cb(void *data) +{ + Ecore_Avahi_Timeout *timeout = data; + + ecore_timer_freeze(timeout->timer); + timeout->callback((AvahiTimeout*) timeout, timeout->callback_data); + + return ECORE_CALLBACK_RENEW; +} + +static AvahiTimeout * +_ecore_avahi_timeout_new(const AvahiPoll *api, const struct timeval *tv, + AvahiTimeoutCallback callback, void *userdata) +{ + Ecore_Avahi_Timeout *timeout; + Ecore_Avahi *ea; + + ea = api->userdata; + timeout = calloc(1, sizeof (Ecore_Avahi_Timeout)); + if (!timeout) return NULL; + + timeout->timer = ecore_timer_add(_ecore_avahi_timeval2double(tv), _ecore_avahi_timeout_cb, timeout); + if (!tv) ecore_timer_freeze(timeout->timer); + timeout->callback = callback; + timeout->callback_data = userdata; + timeout->parent = ea; + + ea->timeouts = eina_list_append(ea->timeouts, timeout); + + return (AvahiTimeout*) timeout; +} + +static void +_ecore_avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv) +{ + Ecore_Avahi_Timeout *timeout = (Ecore_Avahi_Timeout *) t; + + if (tv) + { + ecore_timer_interval_set(timeout->timer, _ecore_avahi_timeval2double(tv)); + if (ecore_timer_freeze_get(timeout->timer)) + ecore_timer_thaw(timeout->timer); + } + else + { + ecore_timer_freeze(timeout->timer); + } +} + +static void +_ecore_avahi_timeout_free(AvahiTimeout *t) +{ + Ecore_Avahi_Timeout *timeout = (Ecore_Avahi_Timeout *) t; + + ecore_timer_del(timeout->timer); + timeout->parent->timeouts = eina_list_remove(timeout->parent->timeouts, timeout); + free(timeout); +} +#endif + +EAPI Ecore_Avahi * +ecore_avahi_add(void) +{ +#ifdef HAVE_AVAHI + Ecore_Avahi *handler; + + handler = calloc(1, sizeof (Ecore_Avahi)); + if (!handler) return NULL; + + handler->api.userdata = handler; + handler->api.watch_new = _ecore_avahi_watch_new; + handler->api.watch_free = _ecore_avahi_watch_free; + handler->api.watch_update = _ecore_avahi_watch_update; + handler->api.watch_get_events = _ecore_avahi_watch_get_events; + + handler->api.timeout_new = _ecore_avahi_timeout_new; + handler->api.timeout_free = _ecore_avahi_timeout_free; + handler->api.timeout_update = _ecore_avahi_timeout_update; + + return handler; +#else + return NULL; +#endif +} + +EAPI void +ecore_avahi_del(Ecore_Avahi *handler) +{ +#ifdef HAVE_AVAHI + Ecore_Avahi_Timeout *timeout; + Ecore_Avahi_Watch *watch; + + EINA_LIST_FREE(handler->watches, watch) + { + ecore_main_fd_handler_del(watch->handler); + free(watch); + } + + EINA_LIST_FREE(handler->timeouts, timeout) + { + ecore_timer_del(timeout->timer); + free(timeout); + } + + free(handler); +#else + (void) handler; +#endif +} + +EAPI const void * +ecore_avahi_poll_get(Ecore_Avahi *handler) +{ +#ifdef HAVE_AVAHI + if (!handler) return NULL; + return &handler->api; +#else + return NULL; +#endif +} + |