cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=0a1cc79a917b770ef66afe8b99731f6d5754ca44

commit 0a1cc79a917b770ef66afe8b99731f6d5754ca44
Author: Cedric BAIL <ced...@efl.so>
Date:   Sun Nov 10 08:51:42 2013 +0100

    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(+)

diff --git a/Makefile.am b/Makefile.am
index 0e8d175..b446af7 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 29c67ae..788d392 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 c9e1de0..b6178fb 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 0000000..a5a5ce9
--- /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 2d7fdd1..e797d57 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 0000000..3dba43e
--- /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 0000000..7190ca0
--- /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 0000000..d447d65
--- /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 0000000..f9f247e
--- /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 d7d01ce..f1a73c1 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 5c03e80..e6e488c 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 0000000..a085e07
--- /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 0000000..93c5301
--- /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
+}
+

-- 


Reply via email to