forked from enlightenment/efl
parent
99e3ce489a
commit
0a1cc79a91
13 changed files with 671 additions and 0 deletions
@ -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@ |
@ -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@ |
@ -0,0 +1 @@ |
||||
ecore_avahi_example |
@ -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
|
@ -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 |
@ -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 |
@ -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 |
||||
} |
||||
|
Loading…
Reference in new issue