summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlavio Ceolin <flavio.ceolin@gmail.com>2013-09-01 19:30:02 -0300
committerFlavio Ceolin <flavio.ceolin@profusion.mobi>2013-09-01 21:46:03 -0300
commitc984cf740b8625571a5d1617e0c3911fc27c11f9 (patch)
tree74c1065045af1651ac55e064bcbc7bf90d3b6373 /src
parentd483719a4c4a92751b264d84340ec5d1236dc5fc (diff)
Copying the ecore_audio_pulse_ml.c from efl repository
Contains the mainloop integration with pulseadio. The file was renamed to epulse_ml.c.
Diffstat (limited to 'src')
-rw-r--r--src/epulse_ml.c309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/epulse_ml.c b/src/epulse_ml.c
new file mode 100644
index 0000000..6686d3c
--- /dev/null
+++ b/src/epulse_ml.c
@@ -0,0 +1,309 @@
1#ifdef HAVE_CONFIG_H
2#include <config.h>
3#endif
4
5#include "common.h"
6
7#include <ctype.h>
8#include <errno.h>
9
10#include <pulse/pulseaudio.h>
11
12#include <sys/time.h>
13#include <sys/types.h>
14#include <sys/socket.h>
15
16/* Ecore mainloop integration start */
17struct pa_io_event
18{
19 pa_mainloop_api *mainloop;
20 Ecore_Fd_Handler *handler;
21
22 void *userdata;
23
24 pa_io_event_flags_t flags;
25 pa_io_event_cb_t callback;
26 pa_io_event_destroy_cb_t destroy_callback;
27};
28
29static Ecore_Fd_Handler_Flags
30map_flags_to_ecore(pa_io_event_flags_t flags)
31{
32 return (Ecore_Fd_Handler_Flags)((flags & PA_IO_EVENT_INPUT ? ECORE_FD_READ : 0) |
33 (flags & PA_IO_EVENT_OUTPUT ? ECORE_FD_WRITE : 0) |
34 (flags & PA_IO_EVENT_ERROR ? ECORE_FD_ERROR : 0) |
35 (flags & PA_IO_EVENT_HANGUP ? ECORE_FD_READ : 0));
36}
37
38static Eina_Bool
39_ecore_io_wrapper(void *data, Ecore_Fd_Handler *handler)
40{
41 char buf[64];
42 pa_io_event_flags_t flags = 0;
43 pa_io_event *event = (pa_io_event *)data;
44 int fd = 0;
45
46 fd = ecore_main_fd_handler_fd_get(handler);
47 if (fd < 0) return ECORE_CALLBACK_RENEW;
48
49 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ))
50 {
51 flags |= PA_IO_EVENT_INPUT;
52
53 /* Check for HUP and report */
54 if (recv(fd, buf, 64, MSG_PEEK))
55 {
56 if (errno == ESHUTDOWN || errno == ECONNRESET || errno == ECONNABORTED || errno == ENETRESET)
57 {
58 DBG("HUP condition detected");
59 flags |= PA_IO_EVENT_HANGUP;
60 }
61 }
62 }
63
64 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_WRITE))
65 flags |= PA_IO_EVENT_OUTPUT;
66 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR))
67 flags |= PA_IO_EVENT_ERROR;
68
69 event->callback(event->mainloop, event, fd, flags, event->userdata);
70
71 return ECORE_CALLBACK_RENEW;
72}
73
74static pa_io_event *
75_ecore_pa_io_new(pa_mainloop_api *api, int fd, pa_io_event_flags_t flags, pa_io_event_cb_t cb, void *userdata)
76{
77 pa_io_event *event;
78
79 event = calloc(1, sizeof(pa_io_event));
80 event->mainloop = api;
81 event->userdata = userdata;
82 event->callback = cb;
83 event->flags = flags;
84 event->handler = ecore_main_fd_handler_add(fd, map_flags_to_ecore(flags), _ecore_io_wrapper, event, NULL, NULL);
85
86 return event;
87}
88
89static void
90_ecore_pa_io_enable(pa_io_event *event, pa_io_event_flags_t flags)
91{
92 event->flags = flags;
93 ecore_main_fd_handler_active_set(event->handler, map_flags_to_ecore(flags));
94}
95
96static void
97_ecore_pa_io_free(pa_io_event *event)
98{
99 ecore_main_fd_handler_del(event->handler);
100 free(event);
101}
102
103static void
104_ecore_pa_io_set_destroy(pa_io_event *event, pa_io_event_destroy_cb_t cb)
105{
106 event->destroy_callback = cb;
107}
108
109/* Timed events */
110struct pa_time_event
111{
112 pa_mainloop_api *mainloop;
113 Ecore_Timer *timer;
114 struct timeval tv;
115
116 void *userdata;
117
118 pa_time_event_cb_t callback;
119 pa_time_event_destroy_cb_t destroy_callback;
120};
121
122Eina_Bool
123_ecore_time_wrapper(void *data)
124{
125 pa_time_event *event = (pa_time_event *)data;
126
127 event->callback(event->mainloop, event, &event->tv, event->userdata);
128
129 return ECORE_CALLBACK_CANCEL;
130}
131
132pa_time_event *
133_ecore_pa_time_new(pa_mainloop_api *api, const struct timeval *tv, pa_time_event_cb_t cb, void *userdata)
134{
135 pa_time_event *event;
136 struct timeval now;
137 double interval;
138
139 event = calloc(1, sizeof(pa_time_event));
140 event->mainloop = api;
141 event->userdata = userdata;
142 event->callback = cb;
143 event->tv = *tv;
144
145 if (gettimeofday(&now, NULL) == -1)
146 {
147 ERR("Failed to get the current time!");
148 free(event);
149 return NULL;
150 }
151
152 interval = (tv->tv_sec - now.tv_sec) + (tv->tv_usec - now.tv_usec) / 1000;
153 event->timer = ecore_timer_add(interval, _ecore_time_wrapper, event);
154
155 return event;
156}
157
158void
159_ecore_pa_time_restart(pa_time_event *event, const struct timeval *tv)
160{
161 struct timeval now;
162 double interval;
163
164 /* If tv is NULL disable timer */
165 if (!tv)
166 {
167 ecore_timer_del(event->timer);
168 event->timer = NULL;
169 return;
170 }
171
172 event->tv = *tv;
173
174 if (gettimeofday(&now, NULL) == -1)
175 {
176 ERR("Failed to get the current time!");
177 return;
178 }
179
180 interval = (tv->tv_sec - now.tv_sec) + (tv->tv_usec - now.tv_usec) / 1000;
181 if (event->timer)
182 {
183 event->timer = ecore_timer_add(interval, _ecore_time_wrapper, event);
184 }
185 else
186 {
187 ecore_timer_interval_set(event->timer, interval);
188 ecore_timer_reset(event->timer);
189 }
190}
191
192void
193_ecore_pa_time_free(pa_time_event *event)
194{
195 if (event->timer)
196 ecore_timer_del(event->timer);
197
198 event->timer = NULL;
199
200 free(event);
201}
202
203void
204_ecore_pa_time_set_destroy(pa_time_event *event, pa_time_event_destroy_cb_t cb)
205{
206 event->destroy_callback = cb;
207}
208
209/* Deferred events */
210struct pa_defer_event
211{
212 pa_mainloop_api *mainloop;
213 Ecore_Idler *idler;
214
215 void *userdata;
216
217 pa_defer_event_cb_t callback;
218 pa_defer_event_destroy_cb_t destroy_callback;
219};
220
221Eina_Bool
222_ecore_defer_wrapper(void *data)
223{
224 pa_defer_event *event = (pa_defer_event *)data;
225
226 event->idler = NULL;
227 event->callback(event->mainloop, event, event->userdata);
228
229 return ECORE_CALLBACK_CANCEL;
230}
231
232pa_defer_event *
233_ecore_pa_defer_new(pa_mainloop_api *api, pa_defer_event_cb_t cb, void *userdata)
234{
235 pa_defer_event *event;
236
237 event = calloc(1, sizeof(pa_defer_event));
238 event->mainloop = api;
239 event->userdata = userdata;
240 event->callback = cb;
241
242 event->idler = ecore_idler_add(_ecore_defer_wrapper, event);
243
244 return event;
245}
246
247void
248_ecore_pa_defer_enable(pa_defer_event *event, int b)
249{
250 if (!b && event->idler)
251 {
252 ecore_idler_del(event->idler);
253 event->idler = NULL;
254 }
255 else if (b && !event->idler)
256 {
257 event->idler = ecore_idler_add(_ecore_defer_wrapper, event);
258 }
259}
260
261void
262_ecore_pa_defer_free(pa_defer_event *event)
263{
264 if (event->idler)
265 ecore_idler_del(event->idler);
266
267 event->idler = NULL;
268
269 free(event);
270}
271
272void
273_ecore_pa_defer_set_destroy(pa_defer_event *event, pa_defer_event_destroy_cb_t cb)
274{
275 event->destroy_callback = cb;
276}
277
278static void
279_ecore_pa_quit(pa_mainloop_api *api EINA_UNUSED, int retval EINA_UNUSED)
280{
281 /* FIXME: Need to clean up timers, etc.? */
282 WRN("Not quitting mainloop, although PA requested it");
283}
284
285/* Function table for PA mainloop integration */
286const pa_mainloop_api functable = {
287 .userdata = NULL,
288
289 .io_new = _ecore_pa_io_new,
290 .io_enable = _ecore_pa_io_enable,
291 .io_free = _ecore_pa_io_free,
292 .io_set_destroy = _ecore_pa_io_set_destroy,
293
294 .time_new = _ecore_pa_time_new,
295 .time_restart = _ecore_pa_time_restart,
296 .time_free = _ecore_pa_time_free,
297 .time_set_destroy = _ecore_pa_time_set_destroy,
298
299 .defer_new = _ecore_pa_defer_new,
300 .defer_enable = _ecore_pa_defer_enable,
301 .defer_free = _ecore_pa_defer_free,
302 .defer_set_destroy = _ecore_pa_defer_set_destroy,
303
304 .quit = _ecore_pa_quit,
305};
306
307/* *****************************************************
308 * Ecore mainloop integration end
309 */