From 0a1cc79a917b770ef66afe8b99731f6d5754ca44 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Sun, 10 Nov 2013 08:51:42 +0100 Subject: Ecore_Avahi: initial commit. TODO: - Add tests, how ? - Integrate with Eo, needed ? --- Makefile.am | 1 + configure.ac | 59 ++++++ pc/.gitignore | 1 + pc/ecore-avahi.pc.in | 12 ++ src/Makefile.am | 2 + src/Makefile_Ecore_Avahi.am | 16 ++ src/examples/ecore_avahi/.gitignore | 1 + src/examples/ecore_avahi/Makefile.am | 35 ++++ src/examples/ecore_avahi/ecore_avahi_example.c | 187 +++++++++++++++++++ src/lib/ecore/Ecore_Legacy.h | 1 + src/lib/ecore/ecore_timer.c | 21 +++ src/lib/ecore_avahi/Ecore_Avahi.h | 88 +++++++++ src/lib/ecore_avahi/ecore_avahi.c | 247 +++++++++++++++++++++++++ 13 files changed, 671 insertions(+) create mode 100644 pc/ecore-avahi.pc.in create mode 100644 src/Makefile_Ecore_Avahi.am create mode 100644 src/examples/ecore_avahi/.gitignore create mode 100644 src/examples/ecore_avahi/Makefile.am create mode 100644 src/examples/ecore_avahi/ecore_avahi_example.c create mode 100644 src/lib/ecore_avahi/Ecore_Avahi.h create mode 100644 src/lib/ecore_avahi/ecore_avahi.c diff --git a/Makefile.am b/Makefile.am index 0e8d175f9..b446af786 100644 --- a/Makefile.am +++ b/Makefile.am @@ -131,6 +131,7 @@ pc/ecore-input-evas.pc \ pc/ecore-imf.pc \ pc/ecore-imf-evas.pc \ pc/ecore-evas.pc \ +pc/ecore-avahi.pc \ pc/embryo.pc \ pc/eio.pc \ pc/eldbus.pc \ diff --git a/configure.ac b/configure.ac index 29c67aeb5..788d39224 100644 --- a/configure.ac +++ b/configure.ac @@ -2568,6 +2568,62 @@ AC_SUBST([ECORE_WIN32_LIBS]) EFL_LIB_END_OPTIONAL([Ecore_Win32]) #### End of Ecore_Win32 +#### Ecore_Avahi + +EFL_LIB_START([Ecore_Avahi]) + +### Default values + +### Additional options to configure + +want_avahi="yes" + +AC_ARG_ENABLE([avahi], + [AC_HELP_STRING([--disable-avahi], + [disable avahi support. @<:@default=enabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_avahi="yes" + else + want_avahi="no" + fi + ], [ + want_avahi="yes" + ]) + +### Checks for programs + +### Checks for libraries +EFL_INTERNAL_DEPEND_PKG([ECORE_AVAHI], [ecore]) +EFL_INTERNAL_DEPEND_PKG([ECORE_AVAHI], [eina]) +EFL_INTERNAL_DEPEND_PKG([ECORE_AVAHI], [eo]) + +EFL_OPTIONAL_DEPEND_PKG([ECORE_AVAHI], [${want_avahi}], [AVAHI], [avahi-client]) + +EFL_ADD_FEATURE([ECORE_AVAHI], [avahi-client], [${have_avahi}]) + +# Needed bu example as they use avahi directly in that case +if test "x${have_avahi}" = "xyes"; then + PKG_CHECK_MODULES([AVAHI_CLIENT], [avahi-client]) +fi + +EFL_EVAL_PKGS([Ecore_Avahi]) + +### Checks for header files + +### Checks for types + +### Checks for structures + +### Checks for compiler characteristics + +### Checks for linker characteristics + +### Checks for library functions + +EFL_LIB_END([Ecore_Avahi]) + +#### End of Ecore_Avahi #### Ecore_WinCE EFL_LIB_START_OPTIONAL([Ecore_WinCE], [test "${have_wince}" = "yes"]) @@ -3748,6 +3804,7 @@ src/examples/eet/Makefile src/examples/eo/Makefile src/examples/evas/Makefile src/examples/ecore/Makefile +src/examples/ecore_avahi/Makefile src/examples/eio/Makefile src/examples/eldbus/Makefile src/examples/ephysics/Makefile @@ -3795,6 +3852,7 @@ pc/ecore-evas.pc pc/ecore-imf.pc pc/ecore-imf-evas.pc pc/ecore-audio.pc +pc/ecore-avahi.pc pc/embryo.pc pc/eio.pc pc/eldbus.pc @@ -3914,6 +3972,7 @@ echo "Ecore_Win32.....: $have_win32" echo "Ecore_WinCE.....: $have_wince" fi echo "Ecore_Audio.....: ${efl_lib_optional_ecore_audio} (${features_ecore_audio})" +echo "Ecore_Avahi.....: yes (${features_ecore_avahi})" echo "Ecore_Evas......: yes (${features_ecore_evas})" echo "Eeze............: ${efl_lib_optional_eeze} (${features_eeze})" echo "EPhysics........: ${efl_lib_optional_ephysics}" diff --git a/pc/.gitignore b/pc/.gitignore index c9e1de001..b6178fb51 100644 --- a/pc/.gitignore +++ b/pc/.gitignore @@ -1,3 +1,4 @@ +/ecore-avahi.pc /ecore-audio.pc /ecore-cocoa.pc /ecore-con.pc diff --git a/pc/ecore-avahi.pc.in b/pc/ecore-avahi.pc.in new file mode 100644 index 000000000..a5a5ce941 --- /dev/null +++ b/pc/ecore-avahi.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore-avahi +Description: E core library, avahi integration +Requires.private: @requirements_pc_ecore_avahi@ +Version: @VERSION@ +Libs: -L${libdir} -lecore_avahi +Libs.private: @requirements_libs_ecore_avahi@ +Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/efl-@VMAJ@ -I${includedir}/ecore-avahi-@VMAJ@ diff --git a/src/Makefile.am b/src/Makefile.am index 2d7fdd180..e797d5782 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -44,6 +44,7 @@ include Makefile_Ecore_IMF.am include Makefile_Ecore_IMF_Evas.am include Makefile_Ecore_Evas.am include Makefile_Ecore_Audio.am +include Makefile_Ecore_Avahi.am include Makefile_Embryo.am include Makefile_Eio.am include Makefile_Eldbus.am @@ -74,6 +75,7 @@ examples/eo \ examples/eet \ examples/evas \ examples/ecore \ +examples/ecore_avahi \ examples/eio \ examples/eldbus \ examples/ephysics \ diff --git a/src/Makefile_Ecore_Avahi.am b/src/Makefile_Ecore_Avahi.am new file mode 100644 index 000000000..3dba43e6c --- /dev/null +++ b/src/Makefile_Ecore_Avahi.am @@ -0,0 +1,16 @@ + +### Library + +lib_LTLIBRARIES += lib/ecore_avahi/libecore_avahi.la + +installed_ecoreavahimainheadersdir = $(includedir)/ecore-avahi-@VMAJ@ +dist_installed_ecoreavahimainheaders_DATA = \ +lib/ecore_avahi/Ecore_Avahi.h + +lib_ecore_avahi_libecore_avahi_la_SOURCES = \ +lib/ecore_avahi/ecore_avahi.c + +lib_ecore_avahi_libecore_avahi_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_AVAHI_CFLAGS@ +lib_ecore_avahi_libecore_avahi_la_LIBADD = @ECORE_AVAHI_LIBS@ +lib_ecore_avahi_libecore_avahi_la_DEPENDENCIES = @ECORE_AVAHI_INTERNAL_LIBS@ +lib_ecore_avahi_libecore_avahi_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ diff --git a/src/examples/ecore_avahi/.gitignore b/src/examples/ecore_avahi/.gitignore new file mode 100644 index 000000000..7190ca0c9 --- /dev/null +++ b/src/examples/ecore_avahi/.gitignore @@ -0,0 +1 @@ +ecore_avahi_example diff --git a/src/examples/ecore_avahi/Makefile.am b/src/examples/ecore_avahi/Makefile.am new file mode 100644 index 000000000..d447d658b --- /dev/null +++ b/src/examples/ecore_avahi/Makefile.am @@ -0,0 +1,35 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_builddir)/src/lib/efl \ +-I$(top_srcdir)/src/lib/eina \ +-I$(top_srcdir)/src/lib/eo \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_avahi\ +-I$(top_builddir)/src/lib/eina \ +-I$(top_builddir)/src/lib/eo \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_avahi \ +@AVAHI_CLIENT_CFLAGS@ + +EXTRA_PROGRAMS = \ +ecore_avahi_example + +ecore_avahi_example_SOURCES = ecore_avahi_example.c +ecore_avahi_example_LDADD = $(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_avahi/libecore_avahi.la \ +$(top_builddir)/src/lib/eo/libeo.la \ +$(top_builddir)/src/lib/eina/libeina.la \ +@AVAHI_CLIENT_LIBS@ + +examples: $(EXTRA_PROGRAMS) + +clean-local: + rm -f $(EXTRA_PROGRAMS) + +install-examples: + mkdir -p $(datadir)/ecore_avahi/examples + $(install_sh_DATA) -c ecore_avahi_example.c $(datadir)/ecore_avahi/examples + +uninstall-local: + rm -f $(datadir)/ecore_avahi/examples/ecore_avahi_example.c diff --git a/src/examples/ecore_avahi/ecore_avahi_example.c b/src/examples/ecore_avahi/ecore_avahi_example.c new file mode 100644 index 000000000..f9f247ef2 --- /dev/null +++ b/src/examples/ecore_avahi/ecore_avahi_example.c @@ -0,0 +1,187 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#ifdef HAVE_AVAHI + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +typedef struct _Ecore_Avahi_Example Ecore_Avahi_Example; +struct _Ecore_Avahi_Example +{ + AvahiClient *client; + AvahiEntryGroup *group; + const char *server; + int port; +}; + +static void +_ecore_avahi_group_cb(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) +{ + Ecore_Avahi_Example *example = userdata; + + switch (state) + { + case AVAHI_ENTRY_GROUP_ESTABLISHED : + /* The entry group has been established successfully */ + fprintf(stderr, "Service '%s' successfully established.\n", example->server); + break; + + case AVAHI_ENTRY_GROUP_COLLISION : + fprintf(stderr, "Service name collision.\n"); + ecore_main_loop_quit(); + break; + + case AVAHI_ENTRY_GROUP_FAILURE : + + fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g)))); + /* Some kind of failure happened while we were registering our services */ + ecore_main_loop_quit(); + break; + + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING: + ; + } +} + +static void +_ecore_avahi_service_create(AvahiClient *c, Ecore_Avahi_Example *example) +{ + int error; + + example->group = avahi_entry_group_new(c, _ecore_avahi_group_cb, example); + if (!example->group) + { + fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_client_errno(c))); + goto fail; + } + + /* If the group is empty (either because it was just created, or + * because it was reset previously, add our entries. */ + if (!avahi_entry_group_is_empty(example->group)) return ; + + error = avahi_entry_group_add_service(example->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, + example->server, "_ipp._tcp", NULL, NULL, example->port, "name=ThisIsATest", NULL); + if (error < 0) + { + fprintf(stderr, "Failed to add _ipp._tcp service with error: %s.\n", avahi_strerror(error)); + goto fail; + } + + error = avahi_entry_group_commit(example->group); + if (error < 0) + { + fprintf(stderr, "Failed to commit entry group with error: %s\n", avahi_strerror(error)); + goto fail; + } + + return ; + + fail: + ecore_main_loop_quit(); +} + +static void +_ecore_avahi_client_cb(AvahiClient *c, AvahiClientState state, void * userdata) +{ + Ecore_Avahi_Example *example = userdata; + + switch (state) + { + case AVAHI_CLIENT_S_RUNNING: + /* The server has started successfully and registered its host + * name on the network, so it's time to create our services */ + _ecore_avahi_service_create(c, example); + break; + case AVAHI_CLIENT_FAILURE: + fprintf(stderr, "Avahi client failure: %s\n", avahi_strerror(avahi_client_errno(c))); + break; + case AVAHI_CLIENT_S_COLLISION: + /* Let's drop our registered services. When the server is back + * in AVAHI_SERVER_RUNNING state we will register them + * again with the new host name. */ + case AVAHI_CLIENT_S_REGISTERING: + /* The server records are now being established. This + * might be caused by a host name change. We need to wait + * for our own records to register until the host name is + * properly esatblished. */ + if (example->group) avahi_entry_group_reset(example->group); + break; + case AVAHI_CLIENT_CONNECTING: + ; + } +} + +int +main(int argc, char **argv) +{ + Ecore_Avahi_Example example = { 0 }; + Ecore_Avahi *handler; + const AvahiPoll *poll_api; + int exit_code = 0; + int error = 0; + + if (argc < 3) + { + fprintf(stderr, "Usage : %s name port\n", argv[0]); + return -1; + } + + eina_init(); + ecore_init(); + + handler = ecore_avahi_add(); + poll_api = ecore_avahi_poll_get(handler); + + if (!poll_api) + { + fprintf(stderr, "Build EFL with Avahi support.\n"); + exit_code = -1; + goto fail; + } + + example.server = eina_stringshare_add(argv[1]); + example.port = atoi(argv[2]); + example.client = avahi_client_new(poll_api, AVAHI_CLIENT_NO_FAIL, _ecore_avahi_client_cb, &example, &error); + + if (!example.client) + { + fprintf(stderr, "Failed to create avahi client: %s.\n", avahi_strerror(error)); + exit_code = -1; + goto fail; + } + + ecore_main_loop_begin(); + + avahi_client_free(example.client); + + fail: + eina_stringshare_del(example.server); + + ecore_shutdown(); + eina_shutdown(); + + return exit_code; +} +#else +int +main(int argc, char **argv) +{ + fprintf(stderr, "This example require Avahi to be build !\n"); +} +#endif diff --git a/src/lib/ecore/Ecore_Legacy.h b/src/lib/ecore/Ecore_Legacy.h index d7d01cef2..f1a73c1ca 100644 --- a/src/lib/ecore/Ecore_Legacy.h +++ b/src/lib/ecore/Ecore_Legacy.h @@ -179,6 +179,7 @@ EAPI void *ecore_timer_del(Ecore_Timer *timer); EAPI void ecore_timer_interval_set(Ecore_Timer *timer, double in); EAPI double ecore_timer_interval_get(Ecore_Timer *timer); EAPI void ecore_timer_freeze(Ecore_Timer *timer); +EAPI Eina_Bool ecore_timer_freeze_get(Ecore_Timer *timer); EAPI void ecore_timer_thaw(Ecore_Timer *timer); EAPI void ecore_timer_delay(Ecore_Timer *timer, double add); EAPI void ecore_timer_reset(Ecore_Timer *timer); diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c index 5c03e805b..e6e488c67 100644 --- a/src/lib/ecore/ecore_timer.c +++ b/src/lib/ecore/ecore_timer.c @@ -485,6 +485,26 @@ unlock: _ecore_unlock(); } +EAPI Eina_Bool +ecore_timer_freeze_get(Ecore_Timer *timer) +{ + int r = 0; + + eo_do(timer, eo_event_freeze_get(&r)); + return !!r; +} + +static void +_timer_freeze_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + + Ecore_Timer_Private_Data *timer = _pd; + int *r = va_arg(*list, int*); + + if (r) *r = timer->frozen; +} + /** * Resumes a frozen (paused) timer. * @@ -989,6 +1009,7 @@ _class_constructor(Eo_Class *klass) EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE), _timer_freeze), EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW), _timer_thaw), + EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE_GET), _timer_freeze_get), EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_DELAY), _timer_delay), EO_OP_FUNC(ECORE_TIMER_ID(ECORE_TIMER_SUB_ID_RESET), _timer_reset), diff --git a/src/lib/ecore_avahi/Ecore_Avahi.h b/src/lib/ecore_avahi/Ecore_Avahi.h new file mode 100644 index 000000000..a085e07f3 --- /dev/null +++ b/src/lib/ecore_avahi/Ecore_Avahi.h @@ -0,0 +1,88 @@ +/** + @brief Ecore Avahi integration Library Public API Calls + + These routines are used for integrating Avahi with Ecore main loop + */ + +#ifndef _ECORE_AVAHI_H +# define _ECORE_AVAHI_H + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# ifdef EFL_ECORE_BUILD +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif /* ! DLL_EXPORT */ +# else +# define EAPI __declspec(dllimport) +# endif /* ! EFL_ECORE_BUILD */ +#else +# ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +# else +# define EAPI +# endif +#endif /* ! _WIN32 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup Ecore_Avahi Ecore main loop integration function. + * @ingroup Ecore + * + * @{ + */ + +/** + * @since 1.9 + */ +typedef struct _Ecore_Avahi Ecore_Avahi; /**< A handle for an Avahi instance. */ + +/** + * @brief Create an AvahiPoll context and integrate it within Ecore main loop. + * + * @return A handler that reference the AvahiPoll context + * @since 1.9 + */ +EAPI Ecore_Avahi *ecore_avahi_add(void); + +/** + * @brief Delete the specified handler of an AvahiPoll. + * + * @param handler The actual handler to destroy. + * @since 1.9 + * + * Be aware there should not be any reference still using that handler before + * destroying it. + */ +EAPI void ecore_avahi_del(Ecore_Avahi *handler); + +/** + * @brief Get the AvahiPoll structure to integrate with Ecore main loop. + * + * @param handler The handler to get the AvahiPoll structure from. + * @return return the actual AvahiPoll structure to use with Avahi. + * @since 1.9 + */ +EAPI const void *ecore_avahi_poll_get(Ecore_Avahi *handler); // return AvahiPoll + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif 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 +#include + +#include "Ecore_Avahi.h" + +#ifdef HAVE_AVAHI +#include + +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 +} + -- cgit v1.2.3