aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCedric BAIL <cedric@efl.so>2013-11-10 08:51:42 +0100
committerCedric BAIL <cedric.bail@samsung.com>2013-12-17 19:37:05 +0900
commit0a1cc79a917b770ef66afe8b99731f6d5754ca44 (patch)
tree99d52907af9d893cb1fc08d75cd1b9f2ab2bfd0c
parentOne ) too many. (diff)
downloadefl-0a1cc79a917b770ef66afe8b99731f6d5754ca44.tar.gz
Ecore_Avahi: initial commit.
TODO: - Add tests, how ? - Integrate with Eo, needed ?
-rw-r--r--Makefile.am1
-rw-r--r--configure.ac59
-rw-r--r--pc/.gitignore1
-rw-r--r--pc/ecore-avahi.pc.in12
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile_Ecore_Avahi.am16
-rw-r--r--src/examples/ecore_avahi/.gitignore1
-rw-r--r--src/examples/ecore_avahi/Makefile.am35
-rw-r--r--src/examples/ecore_avahi/ecore_avahi_example.c187
-rw-r--r--src/lib/ecore/Ecore_Legacy.h1
-rw-r--r--src/lib/ecore/ecore_timer.c21
-rw-r--r--src/lib/ecore_avahi/Ecore_Avahi.h88
-rw-r--r--src/lib/ecore_avahi/ecore_avahi.c247
13 files changed, 671 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 0e8d175f90..b446af786a 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 29c67aeb56..788d39224d 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 c9e1de0010..b6178fb51b 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 0000000000..a5a5ce9418
--- /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 2d7fdd1801..e797d57820 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 0000000000..3dba43e6ca
--- /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 0000000000..7190ca0c94
--- /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 0000000000..d447d658b4
--- /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 0000000000..f9f247ef2d
--- /dev/null
+++ b/src/examples/ecore_avahi/ecore_avahi_example.c
@@ -0,0 +1,187 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef HAVE_AVAHI
+
+#include <avahi-client/client.h>
+#include <avahi-client/lookup.h>
+#include <avahi-client/publish.h>
+
+#include <avahi-common/simple-watch.h>
+#include <avahi-common/malloc.h>
+#include <avahi-common/error.h>
+#include <avahi-common/alternative.h>
+#include <avahi-common/timeval.h>
+
+#include <Ecore.h>
+#include <Ecore_Avahi.h>
+
+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 d7d01cef27..f1a73c1ca1 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 5c03e805b6..e6e488c67a 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 0000000000..a085e07f3c
--- /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 0000000000..93c5301bdb
--- /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
+}
+