diff options
Diffstat (limited to 'src/pulsecore/avahi-wrap.c')
-rw-r--r-- | src/pulsecore/avahi-wrap.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/pulsecore/avahi-wrap.c b/src/pulsecore/avahi-wrap.c new file mode 100644 index 0000000..dc586cb --- /dev/null +++ b/src/pulsecore/avahi-wrap.c @@ -0,0 +1,193 @@ +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pulse/timeval.h> +#include <pulse/xmalloc.h> + +#include <pulsecore/macro.h> + +#include "avahi-wrap.h" + +typedef struct { + AvahiPoll api; + pa_mainloop_api *mainloop; +} pa_avahi_poll; + +struct AvahiWatch { + pa_io_event *io_event; + pa_avahi_poll *avahi_poll; + AvahiWatchEvent current_event; + AvahiWatchCallback callback; + void *userdata; +}; + +static AvahiWatchEvent translate_io_flags_back(pa_io_event_flags_t e) { + return + (e & PA_IO_EVENT_INPUT ? AVAHI_WATCH_IN : 0) | + (e & PA_IO_EVENT_OUTPUT ? AVAHI_WATCH_OUT : 0) | + (e & PA_IO_EVENT_ERROR ? AVAHI_WATCH_ERR : 0) | + (e & PA_IO_EVENT_HANGUP ? AVAHI_WATCH_HUP : 0); +} + +static pa_io_event_flags_t translate_io_flags(AvahiWatchEvent e) { + return + (e & AVAHI_WATCH_IN ? PA_IO_EVENT_INPUT : 0) | + (e & AVAHI_WATCH_OUT ? PA_IO_EVENT_OUTPUT : 0) | + (e & AVAHI_WATCH_ERR ? PA_IO_EVENT_ERROR : 0) | + (e & AVAHI_WATCH_HUP ? PA_IO_EVENT_HANGUP : 0); +} + +static void watch_callback(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { + AvahiWatch *w = userdata; + + pa_assert(a); + pa_assert(e); + pa_assert(w); + + w->current_event = translate_io_flags_back(events); + w->callback(w, fd, w->current_event, w->userdata); + w->current_event = 0; +} + +static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata) { + pa_avahi_poll *p; + AvahiWatch *w; + + pa_assert(api); + pa_assert(fd >= 0); + pa_assert(callback); + pa_assert_se(p = api->userdata); + + w = pa_xnew(AvahiWatch, 1); + w->avahi_poll = p; + w->current_event = 0; + w->callback = callback; + w->userdata = userdata; + w->io_event = p->mainloop->io_new(p->mainloop, fd, translate_io_flags(event), watch_callback, w); + + return w; +} + +static void watch_update(AvahiWatch *w, AvahiWatchEvent event) { + pa_assert(w); + + w->avahi_poll->mainloop->io_enable(w->io_event, translate_io_flags(event)); +} + +static AvahiWatchEvent watch_get_events(AvahiWatch *w) { + pa_assert(w); + + return w->current_event; +} + +static void watch_free(AvahiWatch *w) { + pa_assert(w); + + w->avahi_poll->mainloop->io_free(w->io_event); + pa_xfree(w); +} + +struct AvahiTimeout { + pa_time_event *time_event; + pa_avahi_poll *avahi_poll; + AvahiTimeoutCallback callback; + void *userdata; +}; + +static void timeout_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) { + AvahiTimeout *to = userdata; + + pa_assert(a); + pa_assert(e); + + to->callback(to, to->userdata); +} + +static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback, void *userdata) { + pa_avahi_poll *p; + AvahiTimeout *t; + + pa_assert(api); + pa_assert(callback); + pa_assert_se(p = api->userdata); + + t = pa_xnew(AvahiTimeout, 1); + t->avahi_poll = p; + t->callback = callback; + t->userdata = userdata; + + t->time_event = tv ? p->mainloop->time_new(p->mainloop, tv, timeout_callback, t) : NULL; + + return t; +} + +static void timeout_update(AvahiTimeout *t, const struct timeval *tv) { + + pa_assert(t); + + if (t->time_event && tv) + t->avahi_poll->mainloop->time_restart(t->time_event, tv); + else if (!t->time_event && tv) + t->time_event = t->avahi_poll->mainloop->time_new(t->avahi_poll->mainloop, tv, timeout_callback, t); + else if (t->time_event && !tv) { + t->avahi_poll->mainloop->time_free(t->time_event); + t->time_event = NULL; + } +} + +static void timeout_free(AvahiTimeout *t) { + pa_assert(t); + + if (t->time_event) + t->avahi_poll->mainloop->time_free(t->time_event); + pa_xfree(t); +} + +AvahiPoll* pa_avahi_poll_new(pa_mainloop_api *m) { + pa_avahi_poll *p; + + pa_assert(m); + + p = pa_xnew(pa_avahi_poll, 1); + + p->api.userdata = p; + p->api.watch_new = watch_new; + p->api.watch_update = watch_update; + p->api.watch_get_events = watch_get_events; + p->api.watch_free = watch_free; + p->api.timeout_new = timeout_new; + p->api.timeout_update = timeout_update; + p->api.timeout_free = timeout_free; + p->mainloop = m; + + return &p->api; +} + +void pa_avahi_poll_free(AvahiPoll *api) { + pa_avahi_poll *p; + pa_assert(api); + pa_assert_se(p = api->userdata); + + pa_xfree(p); +} + |