/src/lib/ecore_audio/ecore_audio_pulse_ml.c
https://github.com/Enlightenment/efl · C · 355 lines · 279 code · 66 blank · 10 comment · 35 complexity · 8d6d25e928604dd9a2aac11486940cc0 MD5 · raw file
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #ifdef HAVE_FEATURES_H
- #include <features.h>
- #endif
- #include <ctype.h>
- #include <errno.h>
- #include <pulse/pulseaudio.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include "ecore_audio_private.h"
- /* Ecore mainloop integration start */
- struct pa_io_event
- {
- pa_mainloop_api *mainloop;
- Ecore_Fd_Handler *handler;
- void *userdata;
- pa_io_event_flags_t flags;
- pa_io_event_cb_t callback;
- pa_io_event_destroy_cb_t destroy_callback;
- };
- static Ecore_Fd_Handler_Flags
- map_flags_to_ecore(pa_io_event_flags_t flags)
- {
- return (Ecore_Fd_Handler_Flags)((flags & PA_IO_EVENT_INPUT ? ECORE_FD_READ : 0) | (flags & PA_IO_EVENT_OUTPUT ? ECORE_FD_WRITE : 0) | (flags & PA_IO_EVENT_ERROR ? ECORE_FD_ERROR : 0) | (flags & PA_IO_EVENT_HANGUP ? ECORE_FD_READ : 0));
- }
- static Eina_Bool
- _ecore_io_wrapper(void *data, Ecore_Fd_Handler *handler)
- {
- char buf[64];
- pa_io_event_flags_t flags = 0;
- pa_io_event *event = (pa_io_event *)data;
- int fd = 0;
- char *disp = NULL;
- fd = ecore_main_fd_handler_fd_get(handler);
- if (fd < 0) return ECORE_CALLBACK_RENEW;
- if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ))
- {
- flags |= PA_IO_EVENT_INPUT;
- /* Check for HUP and report */
- if (recv(fd, buf, 64, MSG_PEEK))
- {
- if (errno == ESHUTDOWN || errno == ECONNRESET || errno == ECONNABORTED || errno == ENETRESET)
- {
- DBG("HUP condition detected");
- flags |= PA_IO_EVENT_HANGUP;
- }
- }
- }
- if (ecore_main_fd_handler_active_get(handler, ECORE_FD_WRITE))
- flags |= PA_IO_EVENT_OUTPUT;
- if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR))
- flags |= PA_IO_EVENT_ERROR;
- if (getenv("WAYLAND_DISPLAY"))
- {
- disp = eina_strdup(getenv("DISPLAY"));
- unsetenv("DISPLAY");
- }
- event->callback(event->mainloop, event, fd, flags, event->userdata);
- if (disp) setenv("DISPLAY", disp, 1);
- free(disp);
- return ECORE_CALLBACK_RENEW;
- }
- static pa_io_event *
- _ecore_pa_io_new(pa_mainloop_api *api, int fd, pa_io_event_flags_t flags, pa_io_event_cb_t cb, void *userdata)
- {
- pa_io_event *event;
- event = calloc(1, sizeof(pa_io_event));
- if (!event)
- {
- ERR("Failed to allocate memory!");
- return NULL;
- }
- event->mainloop = api;
- event->userdata = userdata;
- event->callback = cb;
- event->flags = flags;
- event->handler = ecore_main_fd_handler_add(fd, map_flags_to_ecore(flags), _ecore_io_wrapper, event, NULL, NULL);
- return event;
- }
- static void
- _ecore_pa_io_enable(pa_io_event *event, pa_io_event_flags_t flags)
- {
- event->flags = flags;
- ecore_main_fd_handler_active_set(event->handler, map_flags_to_ecore(flags));
- }
- static void
- _ecore_pa_io_free(pa_io_event *event)
- {
- ecore_main_fd_handler_del(event->handler);
- free(event);
- }
- static void
- _ecore_pa_io_set_destroy(pa_io_event *event, pa_io_event_destroy_cb_t cb)
- {
- event->destroy_callback = cb;
- }
- /* Timed events */
- struct pa_time_event
- {
- pa_mainloop_api *mainloop;
- Ecore_Timer *timer;
- struct timeval tv;
- void *userdata;
- pa_time_event_cb_t callback;
- pa_time_event_destroy_cb_t destroy_callback;
- Eina_Bool in_event : 1;
- Eina_Bool dead : 1;
- };
- void
- _ecore_pa_time_free(pa_time_event *event)
- {
- event->dead = 1;
- if (event->in_event) return;
- if (event->timer)
- ecore_timer_del(event->timer);
- event->timer = NULL;
- free(event);
- }
- Eina_Bool
- _ecore_time_wrapper(void *data)
- {
- pa_time_event *event = (pa_time_event *)data;
- char *disp = NULL;
- if (getenv("WAYLAND_DISPLAY"))
- {
- disp = eina_strdup(getenv("DISPLAY"));
- unsetenv("DISPLAY");
- }
- event->in_event = 1;
- event->callback(event->mainloop, event, &event->tv, event->userdata);
- if (disp) setenv("DISPLAY", disp, 1);
- free(disp);
- event->in_event = 0;
- event->timer = NULL;
- if (event->dead)
- _ecore_pa_time_free(event);
- return ECORE_CALLBACK_CANCEL;
- }
- pa_time_event *
- _ecore_pa_time_new(pa_mainloop_api *api, const struct timeval *tv, pa_time_event_cb_t cb, void *userdata)
- {
- pa_time_event *event;
- struct timeval now;
- double interval;
- event = calloc(1, sizeof(pa_time_event));
- if (!event)
- {
- ERR("Failed to allocate memory!");
- return NULL;
- }
- event->mainloop = api;
- event->userdata = userdata;
- event->callback = cb;
- event->tv = *tv;
- if (gettimeofday(&now, NULL) == -1)
- {
- ERR("Failed to get the current time!");
- free(event);
- return NULL;
- }
- interval = (tv->tv_sec - now.tv_sec) + (tv->tv_usec - now.tv_usec) / 1000;
- event->timer = ecore_timer_add(interval, _ecore_time_wrapper, event);
- return event;
- }
- void
- _ecore_pa_time_restart(pa_time_event *event, const struct timeval *tv)
- {
- struct timeval now;
- double interval;
- /* If tv is NULL disable timer */
- if (!tv)
- {
- ecore_timer_del(event->timer);
- event->timer = NULL;
- return;
- }
- event->tv = *tv;
- if (gettimeofday(&now, NULL) == -1)
- {
- ERR("Failed to get the current time!");
- return;
- }
- interval = (tv->tv_sec - now.tv_sec) + (tv->tv_usec - now.tv_usec) / 1000;
- if (!event->timer)
- {
- event->timer = ecore_timer_add(interval, _ecore_time_wrapper, event);
- }
- else
- {
- ecore_timer_interval_set(event->timer, interval);
- ecore_timer_reset(event->timer);
- }
- }
- void
- _ecore_pa_time_set_destroy(pa_time_event *event, pa_time_event_destroy_cb_t cb)
- {
- event->destroy_callback = cb;
- }
- /* Deferred events */
- struct pa_defer_event
- {
- pa_mainloop_api *mainloop;
- Ecore_Idler *idler;
- void *userdata;
- pa_defer_event_cb_t callback;
- pa_defer_event_destroy_cb_t destroy_callback;
- };
- Eina_Bool
- _ecore_defer_wrapper(void *data)
- {
- pa_defer_event *event = (pa_defer_event *)data;
- event->idler = NULL;
- event->callback(event->mainloop, event, event->userdata);
- return ECORE_CALLBACK_CANCEL;
- }
- pa_defer_event *
- _ecore_pa_defer_new(pa_mainloop_api *api, pa_defer_event_cb_t cb, void *userdata)
- {
- pa_defer_event *event;
- event = calloc(1, sizeof(pa_defer_event));
- if (!event)
- {
- ERR("Failed to allocate memory!");
- return NULL;
- }
- event->mainloop = api;
- event->userdata = userdata;
- event->callback = cb;
- event->idler = ecore_idler_add(_ecore_defer_wrapper, event);
- return event;
- }
- void
- _ecore_pa_defer_enable(pa_defer_event *event, int b)
- {
- if (!b && event->idler)
- {
- ecore_idler_del(event->idler);
- event->idler = NULL;
- }
- else if (b && !event->idler)
- {
- event->idler = ecore_idler_add(_ecore_defer_wrapper, event);
- }
- }
- void
- _ecore_pa_defer_free(pa_defer_event *event)
- {
- if (event->idler)
- ecore_idler_del(event->idler);
- event->idler = NULL;
- free(event);
- }
- void
- _ecore_pa_defer_set_destroy(pa_defer_event *event, pa_defer_event_destroy_cb_t cb)
- {
- event->destroy_callback = cb;
- }
- static void
- _ecore_pa_quit(pa_mainloop_api *api EINA_UNUSED, int retval EINA_UNUSED)
- {
- /* FIXME: Need to clean up timers, etc.? */
- WRN("Not quitting mainloop, although PA requested it");
- }
- /* Function table for PA mainloop integration */
- const pa_mainloop_api functable = {
- .userdata = NULL,
- .io_new = _ecore_pa_io_new,
- .io_enable = _ecore_pa_io_enable,
- .io_free = _ecore_pa_io_free,
- .io_set_destroy = _ecore_pa_io_set_destroy,
- .time_new = _ecore_pa_time_new,
- .time_restart = _ecore_pa_time_restart,
- .time_free = _ecore_pa_time_free,
- .time_set_destroy = _ecore_pa_time_set_destroy,
- .defer_new = _ecore_pa_defer_new,
- .defer_enable = _ecore_pa_defer_enable,
- .defer_free = _ecore_pa_defer_free,
- .defer_set_destroy = _ecore_pa_defer_set_destroy,
- .quit = _ecore_pa_quit,
- };
- /* *****************************************************
- * Ecore mainloop integration end
- */