summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavio Ceolin <flavio.ceolin@gmail.com>2014-10-26 22:13:22 -0200
committerFlavio Ceolin <flavio.ceolin@gmail.com>2014-10-29 23:57:10 -0200
commit1324b2b07d36a5fed73837c769b0d3af57dff283 (patch)
tree3d67bb6bb9e240e597b3dc09b116f58bb5962665
parentd25435a066491ce2dd4d740313af3b4db817e450 (diff)
Using callbacks instead of Ecore_Events
Also the volume meter functionality was removed.
-rw-r--r--src/bin/main.c14
-rw-r--r--src/bin/playbacks_view.c110
-rw-r--r--src/bin/sinks_view.c79
-rw-r--r--src/bin/sources_view.c79
-rw-r--r--src/lib/backends/alsa/alsa.c52
-rw-r--r--src/lib/backends/pulseaudio/pulse.c189
-rw-r--r--src/lib/emix.c146
-rw-r--r--src/lib/emix.h53
-rw-r--r--src/module/e_mod_config.c24
-rw-r--r--src/module/e_mod_config.h3
-rw-r--r--src/module/e_mod_main.c132
11 files changed, 275 insertions, 606 deletions
diff --git a/src/bin/main.c b/src/bin/main.c
index 276a0d4..2077176 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -16,10 +16,6 @@ elm_main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
16 EINA_SAFETY_ON_FALSE_RETURN_VAL(emixer_common_init("emixer"), EXIT_FAILURE); 16 EINA_SAFETY_ON_FALSE_RETURN_VAL(emixer_common_init("emixer"), EXIT_FAILURE);
17 EINA_SAFETY_ON_FALSE_RETURN_VAL(emix_init() == EINA_TRUE, EXIT_FAILURE); 17 EINA_SAFETY_ON_FALSE_RETURN_VAL(emix_init() == EINA_TRUE, EXIT_FAILURE);
18 18
19 win = main_window_add();
20 evas_object_resize(win, DEFAULT_WIDTH, DEFAULT_HEIGHT);
21 evas_object_show(win);
22
23 if (emix_backend_set("PULSEAUDIO") == EINA_FALSE) 19 if (emix_backend_set("PULSEAUDIO") == EINA_FALSE)
24 { 20 {
25 WRN("Could not load PULSEAUDIO, trying another one ..."); 21 WRN("Could not load PULSEAUDIO, trying another one ...");
@@ -37,9 +33,15 @@ elm_main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
37 else 33 else
38 backend_loaded = EINA_TRUE; 34 backend_loaded = EINA_TRUE;
39 35
40 if (backend_loaded) 36 if (!backend_loaded)
41 elm_run(); 37 goto end;
38
39 win = main_window_add();
40 evas_object_resize(win, DEFAULT_WIDTH, DEFAULT_HEIGHT);
41 evas_object_show(win);
42 elm_run();
42 43
44end:
43 emixer_common_shutdown(); 45 emixer_common_shutdown();
44 emix_shutdown(); 46 emix_shutdown();
45 return 0; 47 return 0;
diff --git a/src/bin/playbacks_view.c b/src/bin/playbacks_view.c
index 3483f06..43b818a 100644
--- a/src/bin/playbacks_view.c
+++ b/src/bin/playbacks_view.c
@@ -10,40 +10,27 @@ struct Playbacks_View
10 Evas_Object *self; 10 Evas_Object *self;
11 Evas_Object *genlist; 11 Evas_Object *genlist;
12 Elm_Genlist_Item_Class *itc; 12 Elm_Genlist_Item_Class *itc;
13
14 Ecore_Event_Handler *disconnected;
15 Ecore_Event_Handler *sink_input_added;
16 Ecore_Event_Handler *sink_input_changed;
17 Ecore_Event_Handler *sink_input_removed;
18 Ecore_Event_Handler *sink_added;
19 Ecore_Event_Handler *sink_removed;
20}; 13};
21 14
22 static Eina_Bool 15 static void
23_disconnected_cb(void *data, int type EINA_UNUSED, void *info EINA_UNUSED) 16_disconnected(void *data)
24{ 17{
25 struct Playbacks_View *pv = data; 18 struct Playbacks_View *pv = data;
26 elm_genlist_clear(pv->genlist); 19 elm_genlist_clear(pv->genlist);
27
28 return ECORE_CALLBACK_PASS_ON;
29} 20}
30 21
31static Eina_Bool 22static void
32_sink_input_add_cb(void *data, int type EINA_UNUSED, 23_sink_input_added(void *data, void *info)
33 void *info)
34{ 24{
35 struct Playbacks_View *pv = data; 25 struct Playbacks_View *pv = data;
36 Emix_Sink_Input *input = info; 26 Emix_Sink_Input *input = info;
37 27
38 elm_genlist_item_append(pv->genlist, pv->itc, input, NULL, 28 elm_genlist_item_append(pv->genlist, pv->itc, input, NULL,
39 ELM_GENLIST_ITEM_NONE, NULL, pv); 29 ELM_GENLIST_ITEM_NONE, NULL, pv);
40
41 return ECORE_CALLBACK_DONE;
42} 30}
43 31
44static Eina_Bool 32static void
45_sink_input_removed_cb(void *data, int type EINA_UNUSED, 33_sink_input_removed(void *data, void *info)
46 void *info)
47{ 34{
48 struct Playbacks_View *pv = data; 35 struct Playbacks_View *pv = data;
49 Emix_Sink_Input *ev = info; 36 Emix_Sink_Input *ev = info;
@@ -61,20 +48,17 @@ _sink_input_removed_cb(void *data, int type EINA_UNUSED,
61 } 48 }
62 while ((item = elm_genlist_item_next_get(item))); 49 while ((item = elm_genlist_item_next_get(item)));
63 } 50 }
64
65 return ECORE_CALLBACK_PASS_ON;
66} 51}
67 52
68static Eina_Bool 53static void
69_sink_input_changed_cb(void *data, int type EINA_UNUSED, 54_sink_input_changed(void *data, void *info)
70 void *info)
71{ 55{
72 struct Playbacks_View *pv = data; 56 struct Playbacks_View *pv = data;
73 Emix_Sink_Input *ev = info; 57 Emix_Sink_Input *ev = info;
74 Elm_Object_Item *item = elm_genlist_first_item_get(pv->genlist); 58 Elm_Object_Item *item = elm_genlist_first_item_get(pv->genlist);
75 Evas_Object *it; 59 Evas_Object *it;
76 60
77 while (item) 61 while (item)
78 { 62 {
79 if (ev == elm_object_item_data_get(item)) 63 if (ev == elm_object_item_data_get(item))
80 { 64 {
@@ -89,50 +73,46 @@ _sink_input_changed_cb(void *data, int type EINA_UNUSED,
89 } 73 }
90 item = elm_genlist_item_next_get(item); 74 item = elm_genlist_item_next_get(item);
91 } 75 }
92
93 return ECORE_CALLBACK_PASS_ON;
94} 76}
95 77
96static Eina_Bool 78static void
97_sink_added_cb(void *data, int type EINA_UNUSED, void *info EINA_UNUSED) 79_sink_event(void *data)
98{ 80{
99 struct Playbacks_View *pv = data; 81 struct Playbacks_View *pv = data;
100 elm_genlist_realized_items_update(pv->genlist); 82 elm_genlist_realized_items_update(pv->genlist);
101
102 return ECORE_CALLBACK_PASS_ON;
103} 83}
104 84
105static Eina_Bool 85static void
106_sink_removed_cb(void *data, int type EINA_UNUSED, void *info EINA_UNUSED) 86_events_cb(void *data, enum Emix_Event type, void *event_info)
107{ 87{
108 struct Playbacks_View *pv = data; 88 switch (type)
109 89 {
110 elm_genlist_realized_items_update(pv->genlist); 90 case EMIX_SINK_ADDED_EVENT:
111 return ECORE_CALLBACK_PASS_ON; 91 case EMIX_SINK_REMOVED_EVENT:
92 _sink_event(data);
93 break;
94 case EMIX_DISCONNECTED_EVENT:
95 _disconnected(data);
96 break;
97 case EMIX_SINK_INPUT_ADDED_EVENT:
98 _sink_input_added(data, event_info);
99 break;
100 case EMIX_SINK_INPUT_CHANGED_EVENT:
101 _sink_input_changed(data, event_info);
102 break;
103 case EMIX_SINK_INPUT_REMOVED_EVENT:
104 _sink_input_removed(data, event_info);
105 break;
106 default:
107 break;
108 }
112} 109}
113 110
114static void 111static void
115_del_cb(void *data, 112_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED,
116 Evas *e EINA_UNUSED,
117 Evas_Object *o EINA_UNUSED,
118 void *event_info EINA_UNUSED) 113 void *event_info EINA_UNUSED)
119{ 114{
120 struct Playbacks_View *pv = data; 115 emix_event_callback_del(_events_cb);
121
122#define ECORE_EVENT_HANDLER_DEL(_handle) \
123 if (pv->_handle) \
124 { \
125 ecore_event_handler_del(pv->_handle); \
126 pv->_handle = NULL; \
127 }
128
129 ECORE_EVENT_HANDLER_DEL(disconnected)
130 ECORE_EVENT_HANDLER_DEL(sink_input_added)
131 ECORE_EVENT_HANDLER_DEL(sink_input_changed)
132 ECORE_EVENT_HANDLER_DEL(sink_input_removed)
133 ECORE_EVENT_HANDLER_DEL(sink_removed)
134 ECORE_EVENT_HANDLER_DEL(sink_added)
135#undef ECORE_EVENT_HANDLER_DEL
136} 116}
137 117
138static char * 118static char *
@@ -267,18 +247,7 @@ playbacks_view_add(Evas_Object *parent)
267 pv->genlist = elm_genlist_add(layout); 247 pv->genlist = elm_genlist_add(layout);
268 EINA_SAFETY_ON_NULL_GOTO(pv->genlist, err_genlist); 248 EINA_SAFETY_ON_NULL_GOTO(pv->genlist, err_genlist);
269 249
270 pv->disconnected = ecore_event_handler_add(EMIX_DISCONNECTED_EVENT, 250 emix_event_callback_add(_events_cb, pv);
271 _disconnected_cb, pv);
272 pv->sink_input_added = ecore_event_handler_add(EMIX_SINK_INPUT_ADDED_EVENT,
273 _sink_input_add_cb, pv);
274 pv->sink_input_added = ecore_event_handler_add(EMIX_SINK_INPUT_CHANGED_EVENT,
275 _sink_input_changed_cb, pv);
276 pv->sink_input_removed = ecore_event_handler_add(EMIX_SINK_INPUT_REMOVED_EVENT,
277 _sink_input_removed_cb, pv);
278 pv->sink_removed = ecore_event_handler_add(EMIX_SINK_REMOVED_EVENT,
279 _sink_removed_cb, pv);
280 pv->sink_added = ecore_event_handler_add(EMIX_SINK_ADDED_EVENT,
281 _sink_added_cb, pv);
282 251
283 pv->itc = elm_genlist_item_class_new(); 252 pv->itc = elm_genlist_item_class_new();
284 EINA_SAFETY_ON_NULL_GOTO(pv->itc, err_genlist); 253 EINA_SAFETY_ON_NULL_GOTO(pv->itc, err_genlist);
@@ -303,11 +272,6 @@ playbacks_view_add(Evas_Object *parent)
303 return layout; 272 return layout;
304 273
305 err_genlist: 274 err_genlist:
306 ecore_event_handler_del(pv->sink_input_added);
307 ecore_event_handler_del(pv->sink_input_changed);
308 ecore_event_handler_del(pv->sink_input_removed);
309 ecore_event_handler_del(pv->sink_added);
310 ecore_event_handler_del(pv->sink_removed);
311 free(layout); 275 free(layout);
312 err: 276 err:
313 free(pv); 277 free(pv);
diff --git a/src/bin/sinks_view.c b/src/bin/sinks_view.c
index eb0c275..dbbfabc 100644
--- a/src/bin/sinks_view.c
+++ b/src/bin/sinks_view.c
@@ -9,36 +9,27 @@ struct Sinks_View
9 Evas_Object *self; 9 Evas_Object *self;
10 Evas_Object *genlist; 10 Evas_Object *genlist;
11 Elm_Genlist_Item_Class *itc; 11 Elm_Genlist_Item_Class *itc;
12
13 Ecore_Event_Handler *disconnected;
14 Ecore_Event_Handler *sink_added;
15 Ecore_Event_Handler *sink_changed;
16 Ecore_Event_Handler *sink_removed;
17}; 12};
18 13
19static Eina_Bool 14static void
20_disconnected_cb(void *data, int type EINA_UNUSED, void *info EINA_UNUSED) 15_disconnected(void *data)
21{ 16{
22 struct Sinks_View *sv = data; 17 struct Sinks_View *sv = data;
23 elm_genlist_clear(sv->genlist); 18 elm_genlist_clear(sv->genlist);
24
25 return ECORE_CALLBACK_PASS_ON;
26} 19}
27 20
28static Eina_Bool 21static void
29_sink_add_cb(void *data, int type EINA_UNUSED, void *info) 22_sink_added(void *data, void *info)
30{ 23{
31 struct Sinks_View *sv = data; 24 struct Sinks_View *sv = data;
32 Emix_Sink *sink = info; 25 Emix_Sink *sink = info;
33 26
34 elm_genlist_item_append(sv->genlist, sv->itc, sink, NULL, 27 elm_genlist_item_append(sv->genlist, sv->itc, sink, NULL,
35 ELM_GENLIST_ITEM_NONE, NULL, sv); 28 ELM_GENLIST_ITEM_NONE, NULL, sv);
36
37 return ECORE_CALLBACK_PASS_ON;
38} 29}
39 30
40static Eina_Bool 31static void
41_sink_removed_cb(void *data, int type EINA_UNUSED, void *info) 32_sink_removed(void *data, void *info)
42{ 33{
43 struct Sinks_View *sv = data; 34 struct Sinks_View *sv = data;
44 Emix_Sink *ev = info; 35 Emix_Sink *ev = info;
@@ -56,12 +47,10 @@ _sink_removed_cb(void *data, int type EINA_UNUSED, void *info)
56 } 47 }
57 while ((item = elm_genlist_item_next_get(item))); 48 while ((item = elm_genlist_item_next_get(item)));
58 } 49 }
59
60 return ECORE_CALLBACK_PASS_ON;
61} 50}
62 51
63static Eina_Bool 52static void
64_sink_changed_cb(void *data, int type EINA_UNUSED, void *info) 53_sink_changed(void *data, void *info)
65{ 54{
66 struct Sinks_View *sv = data; 55 struct Sinks_View *sv = data;
67 Emix_Sink *sink = info; 56 Emix_Sink *sink = info;
@@ -98,28 +87,35 @@ _sink_changed_cb(void *data, int type EINA_UNUSED, void *info)
98 } 87 }
99 item = elm_genlist_item_next_get(item); 88 item = elm_genlist_item_next_get(item);
100 } 89 }
101
102 return ECORE_CALLBACK_PASS_ON;
103} 90}
104 91
105static void 92static void
106_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, 93_events_cb(void *data, enum Emix_Event type, void *event_info)
107 void *event_info EINA_UNUSED)
108{ 94{
109 struct Sinks_View *sv = data; 95 switch (type)
110 96 {
111#define ECORE_EVENT_HANDLER_DEL(_handle) \ 97 case EMIX_SINK_ADDED_EVENT:
112 if (sv->_handle) \ 98 _sink_added(data, event_info);
113 { \ 99 break;
114 ecore_event_handler_del(sv->_handle); \ 100 case EMIX_SINK_CHANGED_EVENT:
115 sv->_handle = NULL; \ 101 _sink_changed(data, event_info);
102 break;
103 case EMIX_SINK_REMOVED_EVENT:
104 _sink_removed(data, event_info);
105 break;
106 case EMIX_DISCONNECTED_EVENT:
107 _disconnected(data);
108 break;
109 default:
110 break;
116 } 111 }
112}
117 113
118 ECORE_EVENT_HANDLER_DEL(disconnected) 114static void
119 ECORE_EVENT_HANDLER_DEL(sink_removed) 115_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED,
120 ECORE_EVENT_HANDLER_DEL(sink_changed) 116 void *event_info EINA_UNUSED)
121 ECORE_EVENT_HANDLER_DEL(sink_added) 117{
122#undef ECORE_EVENT_HANDLER_DEL 118 emix_event_callback_del(_events_cb);
123} 119}
124 120
125static char * 121static char *
@@ -231,7 +227,6 @@ _item_content_get(void *data, Evas_Object *obj, const char *part)
231 return item; 227 return item;
232} 228}
233 229
234
235Evas_Object * 230Evas_Object *
236sinks_view_add(Evas_Object *parent) 231sinks_view_add(Evas_Object *parent)
237{ 232{
@@ -251,14 +246,7 @@ sinks_view_add(Evas_Object *parent)
251 sv->genlist = elm_genlist_add(layout); 246 sv->genlist = elm_genlist_add(layout);
252 EINA_SAFETY_ON_NULL_GOTO(sv->genlist, err_genlist); 247 EINA_SAFETY_ON_NULL_GOTO(sv->genlist, err_genlist);
253 248
254 sv->disconnected = ecore_event_handler_add(EMIX_DISCONNECTED_EVENT, 249 emix_event_callback_add(_events_cb, sv);
255 _disconnected_cb, sv);
256 sv->sink_added = ecore_event_handler_add(EMIX_SINK_ADDED_EVENT,
257 _sink_add_cb, sv);
258 sv->sink_added = ecore_event_handler_add(EMIX_SINK_CHANGED_EVENT,
259 _sink_changed_cb, sv);
260 sv->sink_removed = ecore_event_handler_add(EMIX_SINK_REMOVED_EVENT,
261 _sink_removed_cb, sv);
262 250
263 sv->itc = elm_genlist_item_class_new(); 251 sv->itc = elm_genlist_item_class_new();
264 EINA_SAFETY_ON_NULL_GOTO(sv->itc, err_genlist); 252 EINA_SAFETY_ON_NULL_GOTO(sv->itc, err_genlist);
@@ -283,9 +271,6 @@ sinks_view_add(Evas_Object *parent)
283 return layout; 271 return layout;
284 272
285 err_genlist: 273 err_genlist:
286 ecore_event_handler_del(sv->sink_added);
287 ecore_event_handler_del(sv->sink_changed);
288 ecore_event_handler_del(sv->sink_removed);
289 free(layout); 274 free(layout);
290 err: 275 err:
291 free(sv); 276 free(sv);
diff --git a/src/bin/sources_view.c b/src/bin/sources_view.c
index 12b0f04..470dfba 100644
--- a/src/bin/sources_view.c
+++ b/src/bin/sources_view.c
@@ -9,36 +9,27 @@ struct Sources_View
9 Evas_Object *self; 9 Evas_Object *self;
10 Evas_Object *genlist; 10 Evas_Object *genlist;
11 Elm_Genlist_Item_Class *itc; 11 Elm_Genlist_Item_Class *itc;
12
13 Ecore_Event_Handler *disconnected;
14 Ecore_Event_Handler *source_added;
15 Ecore_Event_Handler *source_changed;
16 Ecore_Event_Handler *source_removed;
17}; 12};
18 13
19static Eina_Bool 14static void
20_disconnected_cb(void *data, int type EINA_UNUSED, void *info EINA_UNUSED) 15_disconnected(void *data)
21{ 16{
22 struct Sources_View *sv = data; 17 struct Sources_View *sv = data;
23 elm_genlist_clear(sv->genlist); 18 elm_genlist_clear(sv->genlist);
24
25 return ECORE_CALLBACK_PASS_ON;
26} 19}
27 20
28static Eina_Bool 21static void
29_source_add_cb(void *data, int type EINA_UNUSED, void *info) 22_source_added(void *data, void *info)
30{ 23{
31 struct Sources_View *sv = data; 24 struct Sources_View *sv = data;
32 Emix_Source *source= info; 25 Emix_Source *source= info;
33 26
34 elm_genlist_item_append(sv->genlist, sv->itc, source, NULL, 27 elm_genlist_item_append(sv->genlist, sv->itc, source, NULL,
35 ELM_GENLIST_ITEM_NONE, NULL, sv); 28 ELM_GENLIST_ITEM_NONE, NULL, sv);
36
37 return ECORE_CALLBACK_PASS_ON;
38} 29}
39 30
40static Eina_Bool 31static void
41_source_removed_cb(void *data, int type EINA_UNUSED, void *info) 32_source_removed(void *data, void *info)
42{ 33{
43 struct Sources_View *sv = data; 34 struct Sources_View *sv = data;
44 Emix_Source *source = info; 35 Emix_Source *source = info;
@@ -56,12 +47,10 @@ _source_removed_cb(void *data, int type EINA_UNUSED, void *info)
56 } 47 }
57 while ((item = elm_genlist_item_next_get(item))); 48 while ((item = elm_genlist_item_next_get(item)));
58 } 49 }
59
60 return ECORE_CALLBACK_PASS_ON;
61} 50}
62 51
63static Eina_Bool 52static void
64_source_changed_cb(void *data, int type EINA_UNUSED, void *info) 53_source_changed(void *data, void *info)
65{ 54{
66 struct Sources_View *sv = data; 55 struct Sources_View *sv = data;
67 Emix_Source *source = info; 56 Emix_Source *source = info;
@@ -83,28 +72,35 @@ _source_changed_cb(void *data, int type EINA_UNUSED, void *info)
83 } 72 }
84 item = elm_genlist_item_next_get(item); 73 item = elm_genlist_item_next_get(item);
85 } 74 }
86
87 return ECORE_CALLBACK_PASS_ON;
88} 75}
89 76
90static void 77static void
91_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED, 78_events_cb(void *data, enum Emix_Event type, void *event_info)
92 void *event_info EINA_UNUSED)
93{ 79{
94 struct Sources_View *sv = data; 80 switch (type)
95 81 {
96#define ECORE_EVENT_HANDLER_DEL(_handle) \ 82 case EMIX_SOURCE_ADDED_EVENT:
97 if (sv->_handle) \ 83 _source_added(data, event_info);
98 { \ 84 break;
99 ecore_event_handler_del(sv->_handle); \ 85 case EMIX_SOURCE_CHANGED_EVENT:
100 sv->_handle = NULL; \ 86 _source_changed(data, event_info);
87 break;
88 case EMIX_SOURCE_REMOVED_EVENT:
89 _source_removed(data, event_info);
90 break;
91 case EMIX_DISCONNECTED_EVENT:
92 _disconnected(data);
93 break;
94 default:
95 break;
101 } 96 }
97}
102 98
103 ECORE_EVENT_HANDLER_DEL(disconnected) 99static void
104 ECORE_EVENT_HANDLER_DEL(source_removed) 100_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *o EINA_UNUSED,
105 ECORE_EVENT_HANDLER_DEL(source_changed) 101 void *event_info EINA_UNUSED)
106 ECORE_EVENT_HANDLER_DEL(source_added) 102{
107#undef ECORE_EVENT_HANDLER_DEL 103 emix_event_callback_del(_events_cb);
108} 104}
109 105
110static char * 106static char *
@@ -201,14 +197,7 @@ sources_view_add(Evas_Object *parent)
201 sv->genlist = elm_genlist_add(layout); 197 sv->genlist = elm_genlist_add(layout);
202 EINA_SAFETY_ON_NULL_GOTO(sv->genlist, err_genlist); 198 EINA_SAFETY_ON_NULL_GOTO(sv->genlist, err_genlist);
203 199
204 sv->disconnected = ecore_event_handler_add(EMIX_DISCONNECTED_EVENT, 200 emix_event_callback_add(_events_cb, sv);
205 _disconnected_cb, sv);
206 sv->source_added = ecore_event_handler_add(EMIX_SOURCE_ADDED_EVENT,
207 _source_add_cb, sv);
208 sv->source_added = ecore_event_handler_add(EMIX_SOURCE_CHANGED_EVENT,
209 _source_changed_cb, sv);
210 sv->source_removed = ecore_event_handler_add(EMIX_SOURCE_REMOVED_EVENT,
211 _source_removed_cb, sv);
212 201
213 sv->itc = elm_genlist_item_class_new(); 202 sv->itc = elm_genlist_item_class_new();
214 EINA_SAFETY_ON_NULL_GOTO(sv->itc, err_genlist); 203 EINA_SAFETY_ON_NULL_GOTO(sv->itc, err_genlist);
@@ -227,10 +216,6 @@ sources_view_add(Evas_Object *parent)
227 return layout; 216 return layout;
228 217
229 err_genlist: 218 err_genlist:
230 ecore_event_handler_del(sv->disconnected);
231 ecore_event_handler_del(sv->source_added);
232 ecore_event_handler_del(sv->source_changed);
233 ecore_event_handler_del(sv->source_removed);
234 free(layout); 219 free(layout);
235 err: 220 err:
236 free(sv); 221 free(sv);
diff --git a/src/lib/backends/alsa/alsa.c b/src/lib/backends/alsa/alsa.c
index ff9c588..5bbd028 100644
--- a/src/lib/backends/alsa/alsa.c
+++ b/src/lib/backends/alsa/alsa.c
@@ -6,11 +6,8 @@
6#define WRN(...) EINA_LOG_WARN(__VA_ARGS__) 6#define WRN(...) EINA_LOG_WARN(__VA_ARGS__)
7 7
8typedef struct _Context { 8typedef struct _Context {
9 sink_event_cb sink_cb; 9 Emix_Event_Cb cb;
10 sink_input_event_cb sink_input_cb; 10 const void *userdata;
11 source_event_cb source_cb;
12 disconnect_event_cb disconnect_cb;
13 ready_event_cb ready_cb;
14 Eina_List *sinks; 11 Eina_List *sinks;
15 Eina_List *sources; 12 Eina_List *sources;
16 Eina_List *cards; 13 Eina_List *cards;
@@ -45,7 +42,10 @@ _alsa_mixer_sink_changed_cb(snd_mixer_t *ctl, unsigned int mask EINA_UNUSED,
45 snd_mixer_elem_t *elem EINA_UNUSED) 42 snd_mixer_elem_t *elem EINA_UNUSED)
46{ 43{
47 Alsa_Emix_Sink *sink = snd_mixer_get_callback_private(ctl); 44 Alsa_Emix_Sink *sink = snd_mixer_get_callback_private(ctl);
48 ctx->sink_cb((Emix_Sink *)sink, EMIX_EVENT_CHANGED); 45
46 if (ctx->cb)
47 ctx->cb((void *)ctx->userdata, EMIX_SINK_CHANGED_EVENT,
48 (Emix_Sink *)sink);
49 return 0; 49 return 0;
50} 50}
51 51
@@ -54,7 +54,10 @@ _alsa_mixer_source_changed_cb(snd_mixer_t *ctl, unsigned int mask EINA_UNUSED,
54 snd_mixer_elem_t *elem EINA_UNUSED) 54 snd_mixer_elem_t *elem EINA_UNUSED)
55{ 55{
56 Alsa_Emix_Source *source = snd_mixer_get_callback_private(ctl); 56 Alsa_Emix_Source *source = snd_mixer_get_callback_private(ctl);
57 ctx->source_cb((Emix_Source *)source, EMIX_EVENT_CHANGED); 57
58 if (ctx->cb)
59 ctx->cb((void *)ctx->userdata, EMIX_SOURCE_CHANGED_EVENT,
60 (Emix_Source *)source);
58 return 0; 61 return 0;
59} 62}
60 63
@@ -187,9 +190,13 @@ _alsa_device_sink_create(const char *name, const char* hw_name,
187 sink->hw_name = eina_stringshare_add(hw_name); 190 sink->hw_name = eina_stringshare_add(hw_name);
188 sink->channels = channels; 191 sink->channels = channels;
189 _alsa_sink_mute_get(sink); 192 _alsa_sink_mute_get(sink);
190 ctx->sink_cb((Emix_Sink*) sink, EMIX_EVENT_ADDED); 193 if (ctx->cb)
194 {
195 ctx->cb((void *)ctx->userdata, EMIX_SINK_ADDED_EVENT,
196 (Emix_Sink *)sink);
197 ctx->cb((void *)ctx->userdata, EMIX_READY_EVENT, NULL);
198 }
191 ctx->sinks = eina_list_append(ctx->sinks, sink); 199 ctx->sinks = eina_list_append(ctx->sinks, sink);
192 ctx->ready_cb();
193 return sink; 200 return sink;
194} 201}
195 202
@@ -209,7 +216,9 @@ _alsa_device_source_create(const char *name, const char* hw_name,
209 source->hw_name = eina_stringshare_add(hw_name); 216 source->hw_name = eina_stringshare_add(hw_name);
210 source->channels = channels; 217 source->channels = channels;
211 _alsa_sources_mute_get(source); 218 _alsa_sources_mute_get(source);
212 ctx->source_cb((Emix_Source*) source, EMIX_EVENT_ADDED); 219 if (ctx->cb)
220 ctx->cb((void *)ctx->userdata, EMIX_SOURCE_ADDED_EVENT,
221 (Emix_Sink *)source);
213 ctx->sources = eina_list_append(ctx->sources, source); 222 ctx->sources = eina_list_append(ctx->sources, source);
214 return source; 223 return source;
215} 224}
@@ -322,19 +331,14 @@ _alsa_cards_refresh(void)
322} 331}
323 332
324static Eina_Bool 333static Eina_Bool
325_alsa_init(sink_event_cb sink_cb, sink_input_event_cb input_cb, 334_alsa_init(Emix_Event_Cb cb, const void *data)
326 source_event_cb source_cb, disconnect_event_cb disconnect_cb,
327 ready_event_cb ready_cb EINA_UNUSED)
328{ 335{
329 if (!ctx) 336 if (!ctx)
330 ctx = calloc(1, sizeof(Context)); 337 ctx = calloc(1, sizeof(Context));
331 338
332 ctx->sink_cb = sink_cb;
333 ctx->sink_input_cb = input_cb;
334 ctx->source_cb = source_cb;
335 ctx->disconnect_cb = disconnect_cb;
336 ctx->ready_cb = ready_cb;
337 _alsa_cards_refresh(); 339 _alsa_cards_refresh();
340 ctx->cb = cb;
341 ctx->userdata = data;
338 342
339 return EINA_TRUE; 343 return EINA_TRUE;
340} 344}
@@ -353,7 +357,6 @@ _alsa_shutdown(void)
353 EINA_LIST_FREE(ctx->cards, mixer) 357 EINA_LIST_FREE(ctx->cards, mixer)
354 snd_mixer_close(mixer); 358 snd_mixer_close(mixer);
355 359
356 ctx->disconnect_cb();
357 free(ctx); 360 free(ctx);
358 ctx = NULL; 361 ctx = NULL;
359} 362}
@@ -380,7 +383,9 @@ _alsa_sources_mute_set(Emix_Source *source, Eina_Bool mute)
380 } 383 }
381 384
382 source->mute = mute; 385 source->mute = mute;
383 ctx->source_cb(source, EMIX_EVENT_CHANGED); 386 if (ctx->cb)
387 ctx->cb((void *)ctx->userdata, EMIX_SOURCE_CHANGED_EVENT,
388 (Emix_Source *)source);
384} 389}
385 390
386static void 391static void
@@ -441,7 +446,9 @@ _alsa_sink_mute_set(Emix_Sink *sink, Eina_Bool mute)
441 } 446 }
442 447
443 sink->mute = mute; 448 sink->mute = mute;
444 ctx->sink_cb(sink, EMIX_EVENT_CHANGED); 449 if (ctx->cb)
450 ctx->cb((void *)ctx->userdata, EMIX_SINK_CHANGED_EVENT,
451 (Emix_Sink *)sink);
445} 452}
446 453
447static void 454static void
@@ -483,8 +490,7 @@ _alsa_backend = {
483 _alsa_sources_get,/*source*/ 490 _alsa_sources_get,/*source*/
484 _alsa_sources_mute_set,/* source mute set */ 491 _alsa_sources_mute_set,/* source mute set */
485 _alsa_sources_volume_set, /* source volume set */ 492 _alsa_sources_volume_set, /* source volume set */
486 NULL, /* advanced options */ 493 NULL /* advanced options */
487 NULL
488}; 494};
489 495
490EAPI Emix_Backend * 496EAPI Emix_Backend *
diff --git a/src/lib/backends/pulseaudio/pulse.c b/src/lib/backends/pulseaudio/pulse.c
index 248d978..91efe7f 100644
--- a/src/lib/backends/pulseaudio/pulse.c
+++ b/src/lib/backends/pulseaudio/pulse.c
@@ -18,31 +18,24 @@ typedef struct _Context {
18 pa_mainloop_api api; 18 pa_mainloop_api api;
19 pa_context *context; 19 pa_context *context;
20 pa_context_state_t state; 20 pa_context_state_t state;
21 sink_event_cb sink_cb; 21 Emix_Event_Cb cb;
22 sink_input_event_cb sink_input_cb; 22 const void *userdata;
23 source_event_cb source_cb;
24 disconnect_event_cb disconnect_cb;
25 ready_event_cb ready_cb;
26 volume_meter_cb meter_cb;
27 Ecore_Timer *connect; 23 Ecore_Timer *connect;
28 int default_sink; 24 int default_sink;
29 25
30 Eina_List *sinks, *sources, *inputs; 26 Eina_List *sinks, *sources, *inputs;
31 Eina_Bool connected; 27 Eina_Bool connected;
32 const void *meter_data;
33} Context; 28} Context;
34 29
35typedef struct _Sink { 30typedef struct _Sink {
36 Emix_Sink base; 31 Emix_Sink base;
37 int idx; 32 int idx;
38 int source_idx;
39} Sink; 33} Sink;
40 34
41typedef struct _Sink_Input { 35typedef struct _Sink_Input {
42 Emix_Sink_Input base; 36 Emix_Sink_Input base;
43 const char *icon; 37 const char *icon;
44 int idx; 38 int idx;
45 pa_stream *peak;
46} Sink_Input; 39} Sink_Input;
47 40
48typedef struct _Source { 41typedef struct _Source {
@@ -127,95 +120,6 @@ _source_del(Source *source)
127} 120}
128 121
129static void 122static void
130_suspended_cb(pa_stream *s, void *userdata EINA_UNUSED)
131{
132 if (pa_stream_is_suspended(s))
133 ERR("stream suspended");
134}
135
136static void
137_read_cb(pa_stream *s, size_t length, void *userdata)
138{
139 const void *data;
140 double v;
141 Sink_Input *si = userdata;
142
143 if (!ctx->meter_cb)
144 return;
145
146 if (pa_stream_peek(s, &data, &length) < 0)
147 {
148 ERR("Failed to read data from stream");
149 return;
150 }
151
152 EINA_SAFETY_ON_FALSE_RETURN(length > 0);
153 EINA_SAFETY_ON_FALSE_RETURN(length % sizeof(float) == 0);
154
155 v = ((const float*) data)[length / sizeof(float) -1];
156
157 pa_stream_drop(s);
158
159 if (v < 0)
160 v = 0;
161 if (v > 1)
162 v = 1;
163
164 ctx->meter_cb(si->base.sink, v, (void *)ctx->meter_data);
165}
166
167static void
168_create_sink_monitor(Sink_Input *si)
169{
170 pa_stream *s;
171 char t[16];
172 pa_buffer_attr attr;
173 pa_sample_spec ss;
174 pa_stream_flags_t flags;
175 uint32_t source_idx = ((Sink *)si->base.sink)->source_idx;
176 uint32_t stream_idx = si->idx;
177
178 if (si->peak)
179 {
180 pa_stream_disconnect(si->peak);
181 si->peak = NULL;
182 }
183
184 ss.channels = 1;
185 ss.format = PA_SAMPLE_FLOAT32;
186 ss.rate = 25;
187
188 memset(&attr, 0, sizeof(attr));
189 attr.fragsize = sizeof(float);
190 attr.maxlength = (uint32_t) -1;
191
192 snprintf(t, sizeof(t), "%u", source_idx);
193
194 if (!(s = pa_stream_new(ctx->context, "Peak detect", &ss, NULL)))
195 {
196 ERR("Failed to create monitoring stream");
197 return;
198 }
199
200 if (stream_idx != (uint32_t) -1)
201 pa_stream_set_monitor_stream(s, stream_idx);
202
203 pa_stream_set_read_callback(s, _read_cb, si);
204 pa_stream_set_suspended_callback(s, _suspended_cb, si);
205 flags = (pa_stream_flags_t) (PA_STREAM_DONT_MOVE | PA_STREAM_PEAK_DETECT |
206 PA_STREAM_ADJUST_LATENCY | PA_STREAM_NOFLAGS);
207
208 if (pa_stream_connect_record(s, t, &attr, flags) < 0)
209 {
210 ERR("Failed to connect monitoring stream");
211 pa_stream_unref(s);
212 return;
213 }
214
215 si->peak = s;
216}
217
218static void
219_sink_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol, 123_sink_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
220 void *userdata EINA_UNUSED) 124 void *userdata EINA_UNUSED)
221{ 125{
@@ -240,7 +144,6 @@ _sink_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
240 144
241 sink = calloc(1, sizeof(Sink)); 145 sink = calloc(1, sizeof(Sink));
242 sink->idx = info->index; 146 sink->idx = info->index;
243 sink->source_idx = info->monitor_source;
244 sink->base.name = eina_stringshare_add(info->description); 147 sink->base.name = eina_stringshare_add(info->description);
245 sink->base.volume = _pa_cvolume_convert(info->volume); 148 sink->base.volume = _pa_cvolume_convert(info->volume);
246 sink->base.mute = !!info->mute; 149 sink->base.mute = !!info->mute;
@@ -263,8 +166,9 @@ _sink_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
263 } 166 }
264 167
265 ctx->sinks = eina_list_append(ctx->sinks, sink); 168 ctx->sinks = eina_list_append(ctx->sinks, sink);
266 if (ctx->sink_cb) 169 if (ctx->cb)
267 ctx->sink_cb((Emix_Sink *)sink, EMIX_EVENT_ADDED); 170 ctx->cb((void *)ctx->userdata, EMIX_SINK_ADDED_EVENT,
171 (Emix_Sink *)sink);
268} 172}
269 173
270static void 174static void
@@ -275,7 +179,6 @@ _sink_changed_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
275 Emix_Port *port; 179 Emix_Port *port;
276 uint32_t i; 180 uint32_t i;
277 Eina_List *l; 181 Eina_List *l;
278 Emix_Event_Type ev = EMIX_EVENT_CHANGED;
279 182
280 if (eol < 0) 183 if (eol < 0)
281 { 184 {
@@ -333,8 +236,9 @@ _sink_changed_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
333 port->active = EINA_TRUE; 236 port->active = EINA_TRUE;
334 } 237 }
335 238
336 if (ctx->sink_cb) 239 if (ctx->cb)
337 ctx->sink_cb((Emix_Sink *)sink, ev); 240 ctx->cb((void *)ctx->userdata, EMIX_SINK_CHANGED_EVENT,
241 (Emix_Sink *)sink);
338} 242}
339 243
340static void 244static void
@@ -348,8 +252,9 @@ _sink_remove_cb(int index, void *data EINA_UNUSED)
348 { 252 {
349 if (sink->idx == index) 253 if (sink->idx == index)
350 { 254 {
351 if (ctx->sink_cb) 255 if (ctx->cb)
352 ctx->sink_cb((Emix_Sink *)sink, EMIX_EVENT_REMOVED); 256 ctx->cb((void *)ctx->userdata, EMIX_SINK_REMOVED_EVENT,
257 (Emix_Sink *)sink);
353 _sink_del(sink); 258 _sink_del(sink);
354 ctx->sinks = eina_list_remove_list(ctx->sinks, l); 259 ctx->sinks = eina_list_remove_list(ctx->sinks, l);
355 break; 260 break;
@@ -430,14 +335,9 @@ _sink_input_cb(pa_context *c EINA_UNUSED, const pa_sink_input_info *info,
430 input->icon = eina_stringshare_add(_icon_from_properties(info->proplist)); 335 input->icon = eina_stringshare_add(_icon_from_properties(info->proplist));
431 ctx->inputs = eina_list_append(ctx->inputs, input); 336 ctx->inputs = eina_list_append(ctx->inputs, input);
432 337
433 if (pa_context_get_server_protocol_version(ctx->context) >= 13 && 338 if (ctx->cb)
434 ctx->meter_cb) 339 ctx->cb((void *)ctx->userdata, EMIX_SINK_INPUT_ADDED_EVENT,
435 { 340 (Emix_Sink_Input *)input);
436 _create_sink_monitor(input);
437 }
438
439 if (ctx->sink_input_cb)
440 ctx->sink_input_cb((Emix_Sink_Input *)input, EMIX_EVENT_ADDED);
441} 341}
442 342
443static void 343static void
@@ -447,7 +347,7 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
447{ 347{
448 Sink_Input *input = NULL, *i; 348 Sink_Input *input = NULL, *i;
449 Eina_List *l; 349 Eina_List *l;
450 Emix_Event_Type ev = EMIX_EVENT_CHANGED; 350
451 EINA_SAFETY_ON_NULL_RETURN(ctx); 351 EINA_SAFETY_ON_NULL_RETURN(ctx);
452 if (eol < 0) 352 if (eol < 0)
453 { 353 {
@@ -474,7 +374,6 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
474 374
475 if (!input) 375 if (!input)
476 { 376 {
477 ev = EMIX_EVENT_ADDED;
478 input = calloc(1, sizeof(Sink_Input)); 377 input = calloc(1, sizeof(Sink_Input));
479 EINA_SAFETY_ON_NULL_RETURN(input); 378 EINA_SAFETY_ON_NULL_RETURN(input);
480 ctx->inputs = eina_list_append(ctx->inputs, input); 379 ctx->inputs = eina_list_append(ctx->inputs, input);
@@ -483,8 +382,9 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
483 input->base.volume = _pa_cvolume_convert(info->volume); 382 input->base.volume = _pa_cvolume_convert(info->volume);
484 input->base.mute = !!info->mute; 383 input->base.mute = !!info->mute;
485 384
486 if (ctx->sink_input_cb) 385 if (ctx->cb)
487 ctx->sink_input_cb((Emix_Sink_Input *)input, ev); 386 ctx->cb((void *)ctx->userdata, EMIX_SINK_INPUT_CHANGED_EVENT,
387 (Emix_Sink_Input *)input);
488} 388}
489 389
490static void 390static void
@@ -500,8 +400,10 @@ _sink_input_remove_cb(int index, void *data EINA_UNUSED)
500 { 400 {
501 if (input->idx == index) 401 if (input->idx == index)
502 { 402 {
503 if (ctx->sink_input_cb) 403 if (ctx->cb)
504 ctx->sink_input_cb((Emix_Sink_Input *)input, EMIX_EVENT_REMOVED); 404 ctx->cb((void *)ctx->userdata,
405 EMIX_SINK_INPUT_REMOVED_EVENT,
406 (Emix_Sink_Input *)input);
505 _sink_input_del(input); 407 _sink_input_del(input);
506 408
507 ctx->inputs = eina_list_remove_list(ctx->inputs, l); 409 ctx->inputs = eina_list_remove_list(ctx->inputs, l);
@@ -538,8 +440,9 @@ _source_cb(pa_context *c EINA_UNUSED, const pa_source_info *info,
538 source->base.mute = !!info->mute; 440 source->base.mute = !!info->mute;
539 441
540 ctx->sources = eina_list_append(ctx->sources, source); 442 ctx->sources = eina_list_append(ctx->sources, source);
541 if (ctx->source_cb) 443 if (ctx->cb)
542 ctx->source_cb((Emix_Source *)source, EMIX_EVENT_ADDED); 444 ctx->cb((void *)ctx->userdata, EMIX_SOURCE_ADDED_EVENT,
445 (Emix_Source *)source);
543} 446}
544 447
545static void 448static void
@@ -549,7 +452,6 @@ _source_changed_cb(pa_context *c EINA_UNUSED,
549{ 452{
550 Source *source = NULL, *s; 453 Source *source = NULL, *s;
551 Eina_List *l; 454 Eina_List *l;
552 Emix_Event_Type ev = EMIX_EVENT_CHANGED;
553 EINA_SAFETY_ON_NULL_RETURN(ctx); 455 EINA_SAFETY_ON_NULL_RETURN(ctx);
554 456
555 if (eol < 0) 457 if (eol < 0)
@@ -579,15 +481,15 @@ _source_changed_cb(pa_context *c EINA_UNUSED,
579 { 481 {
580 source = calloc(1, sizeof(Source)); 482 source = calloc(1, sizeof(Source));
581 EINA_SAFETY_ON_NULL_RETURN(source); 483 EINA_SAFETY_ON_NULL_RETURN(source);
582 ev = EMIX_EVENT_ADDED;
583 ctx->sources = eina_list_append(ctx->sources, source); 484 ctx->sources = eina_list_append(ctx->sources, source);
584 } 485 }
585 source->idx= info->index; 486 source->idx= info->index;
586 source->base.volume = _pa_cvolume_convert(info->volume); 487 source->base.volume = _pa_cvolume_convert(info->volume);
587 source->base.mute = !!info->mute; 488 source->base.mute = !!info->mute;
588 489
589 if (ctx->source_cb) 490 if (ctx->cb)
590 ctx->source_cb((Emix_Source *)source, ev); 491 ctx->cb((void *)ctx->userdata, EMIX_SOURCE_CHANGED_EVENT,
492 (Emix_Source *)source);
591} 493}
592 494
593static void 495static void
@@ -603,8 +505,9 @@ _source_remove_cb(int index, void *data EINA_UNUSED)
603 { 505 {
604 if (source->idx == index) 506 if (source->idx == index)
605 { 507 {
606 if (ctx->source_cb) 508 if (ctx->cb)
607 ctx->source_cb((Emix_Source *)source, EMIX_EVENT_REMOVED); 509 ctx->cb((void *)ctx->userdata, EMIX_SOURCE_REMOVED_EVENT,
510 (Emix_Source *)source);
608 511
609 _source_del(source); 512 _source_del(source);
610 ctx->sources = eina_list_remove_list(ctx->sources, l); 513 ctx->sources = eina_list_remove_list(ctx->sources, l);
@@ -633,8 +536,8 @@ _sink_default_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
633 info->name); 536 info->name);
634 537
635 ctx->default_sink = info->index; 538 ctx->default_sink = info->index;
636 if (ctx->ready_cb) 539 if (ctx->cb)
637 ctx->ready_cb(); 540 ctx->cb((void *)ctx->userdata, EMIX_READY_EVENT, NULL);
638} 541}
639 542
640static void 543static void
@@ -899,9 +802,7 @@ _shutdown(void)
899} 802}
900 803
901static Eina_Bool 804static Eina_Bool
902_init(sink_event_cb sink_cb, sink_input_event_cb input_cb, 805_init(Emix_Event_Cb cb, const void *data)
903 source_event_cb source_cb, disconnect_event_cb disconnect_cb,
904 ready_event_cb ready_cb)
905{ 806{
906 if (ctx) 807 if (ctx)
907 return EINA_TRUE; 808 return EINA_TRUE;
@@ -913,12 +814,6 @@ _init(sink_event_cb sink_cb, sink_input_event_cb input_cb,
913 return EINA_FALSE; 814 return EINA_FALSE;
914 } 815 }
915 816
916 ctx->sink_cb = sink_cb;
917 ctx->sink_input_cb = input_cb;
918 ctx->source_cb = source_cb;
919 ctx->disconnect_cb = disconnect_cb;
920 ctx->ready_cb = ready_cb;
921
922 ctx->api = functable; 817 ctx->api = functable;
923 ctx->api.userdata = ctx; 818 ctx->api.userdata = ctx;
924 819
@@ -932,6 +827,9 @@ _init(sink_event_cb sink_cb, sink_input_event_cb input_cb,
932 return EINA_FALSE; 827 return EINA_FALSE;
933 } 828 }
934 829
830 ctx->cb = cb;
831 ctx->userdata = data;
832
935 return EINA_TRUE; 833 return EINA_TRUE;
936 } 834 }
937 835
@@ -942,8 +840,8 @@ _disconnect_cb()
942 Sink *sink; 840 Sink *sink;
943 Sink_Input *input; 841 Sink_Input *input;
944 842
945 if (ctx->disconnect_cb) 843 if (ctx->cb)
946 ctx->disconnect_cb(); 844 ctx->cb((void *)ctx->userdata, EMIX_DISCONNECTED_EVENT, NULL);
947 845
948 EINA_LIST_FREE(ctx->sources, source) 846 EINA_LIST_FREE(ctx->sources, source)
949 _source_del(source); 847 _source_del(source);
@@ -1114,14 +1012,6 @@ _sink_change_support(void)
1114 return EINA_TRUE; 1012 return EINA_TRUE;
1115} 1013}
1116 1014
1117static void
1118_volume_meter_callback_set(volume_meter_cb cb, const void *userdata)
1119{
1120 EINA_SAFETY_ON_NULL_RETURN(ctx);
1121 ctx->meter_cb = cb;
1122 ctx->meter_data = userdata;
1123}
1124
1125static Emix_Backend 1015static Emix_Backend
1126_pulseaudio_backend = { 1016_pulseaudio_backend = {
1127 _init, 1017 _init,
@@ -1142,7 +1032,6 @@ _pulseaudio_backend = {
1142 _source_mute_set, 1032 _source_mute_set,
1143 _source_volume_set, 1033 _source_volume_set,
1144 NULL, 1034 NULL,
1145 _volume_meter_callback_set
1146}; 1035};
1147 1036
1148EAPI Emix_Backend * 1037EAPI Emix_Backend *
diff --git a/src/lib/emix.c b/src/lib/emix.c
index d8f6517..cd2490e 100644
--- a/src/lib/emix.c
+++ b/src/lib/emix.c
@@ -12,10 +12,16 @@ static int _log_domain;
12#define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__) 12#define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__)
13#define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__) 13#define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__)
14 14
15struct Callback_Data {
16 Emix_Event_Cb cb;
17 const void *data;
18};
19
15typedef struct Context { 20typedef struct Context {
16 /* Valid backends *.so */ 21 /* Valid backends *.so */
17 Eina_Array *backends; 22 Eina_Array *backends;
18 Eina_List *backends_names; 23 Eina_List *backends_names;
24 Eina_List *callbacks;
19 25
20 Emix_Backend *loaded; 26 Emix_Backend *loaded;
21} Context; 27} Context;
@@ -23,93 +29,14 @@ typedef struct Context {
23static int _init_count = 0; 29static int _init_count = 0;
24static Context *ctx = NULL; 30static Context *ctx = NULL;
25 31
26int EMIX_DISCONNECTED_EVENT = 0;
27int EMIX_READY_EVENT = 0;
28int EMIX_SINK_ADDED_EVENT = 0;
29int EMIX_SINK_REMOVED_EVENT = 0;
30int EMIX_SINK_CHANGED_EVENT = 0;
31int EMIX_SINK_INPUT_ADDED_EVENT = 0;
32int EMIX_SINK_INPUT_REMOVED_EVENT = 0;
33int EMIX_SINK_INPUT_CHANGED_EVENT = 0;
34int EMIX_SOURCE_ADDED_EVENT = 0;
35int EMIX_SOURCE_REMOVED_EVENT = 0;
36int EMIX_SOURCE_CHANGED_EVENT = 0;
37
38static void
39_disconnect_cb(void)
40{
41 ecore_event_add(EMIX_DISCONNECTED_EVENT, NULL, NULL, NULL);
42}
43
44static void
45_ready_cb(void)
46{
47 ecore_event_add(EMIX_READY_EVENT, NULL, NULL, NULL);
48}
49
50static void
51_useless_free(void *udata EINA_UNUSED, void *fdata EINA_UNUSED)
52{
53}
54
55static void 32static void
56_sink_cb(Emix_Sink *sink, Emix_Event_Type type) 33_events_cb(void *data EINA_UNUSED, enum Emix_Event event, void *event_info)
57{ 34{
58 switch (type) 35 Eina_List *l;
59 { 36 struct Callback_Data *callback;
60 case EMIX_EVENT_ADDED:
61 ecore_event_add(EMIX_SINK_ADDED_EVENT, sink, _useless_free, NULL);
62 break;
63 case EMIX_EVENT_REMOVED:
64 ecore_event_add(EMIX_SINK_REMOVED_EVENT, sink, _useless_free, NULL);
65 break;
66 case EMIX_EVENT_CHANGED:
67 ecore_event_add(EMIX_SINK_CHANGED_EVENT, sink, _useless_free, NULL);
68 break;
69 default:
70 WRN("Event not handled");
71 }
72}
73
74static void
75_sink_input_cb(Emix_Sink_Input *input, Emix_Event_Type type)
76{
77 switch (type)
78 {
79 case EMIX_EVENT_ADDED:
80 ecore_event_add(EMIX_SINK_INPUT_ADDED_EVENT, input,
81 _useless_free, NULL);
82 break;
83 case EMIX_EVENT_REMOVED:
84 ecore_event_add(EMIX_SINK_INPUT_REMOVED_EVENT, input,
85 _useless_free, NULL);
86 break;
87 case EMIX_EVENT_CHANGED:
88 ecore_event_add(EMIX_SINK_INPUT_CHANGED_EVENT, input,
89 _useless_free, NULL);
90 break;
91 default:
92 WRN("Event not handled");
93 }
94}
95 37
96static void 38 EINA_LIST_FOREACH(ctx->callbacks, l, callback)
97_source_cb(Emix_Source *source, Emix_Event_Type type) 39 callback->cb((void *)callback->data, event, event_info);
98{
99 switch (type)
100 {
101 case EMIX_EVENT_ADDED:
102 ecore_event_add(EMIX_SOURCE_ADDED_EVENT, source, _useless_free, NULL);
103 break;
104 case EMIX_EVENT_REMOVED:
105 ecore_event_add(EMIX_SOURCE_REMOVED_EVENT, source, _useless_free, NULL);
106 break;
107 case EMIX_EVENT_CHANGED:
108 ecore_event_add(EMIX_SOURCE_CHANGED_EVENT, source, _useless_free, NULL);
109 break;
110 default:
111 WRN("Event not handled");
112 }
113} 40}
114 41
115static Eina_Bool 42static Eina_Bool
@@ -181,18 +108,6 @@ emix_init(void)
181 goto err; 108 goto err;
182 } 109 }
183 110
184 EMIX_DISCONNECTED_EVENT = ecore_event_type_new();
185 EMIX_READY_EVENT = ecore_event_type_new();
186 EMIX_SINK_ADDED_EVENT = ecore_event_type_new();
187 EMIX_SINK_CHANGED_EVENT = ecore_event_type_new();
188 EMIX_SINK_REMOVED_EVENT = ecore_event_type_new();
189 EMIX_SINK_INPUT_ADDED_EVENT = ecore_event_type_new();
190 EMIX_SINK_INPUT_REMOVED_EVENT = ecore_event_type_new();
191 EMIX_SINK_INPUT_CHANGED_EVENT = ecore_event_type_new();
192 EMIX_SOURCE_ADDED_EVENT = ecore_event_type_new();
193 EMIX_SOURCE_REMOVED_EVENT = ecore_event_type_new();
194 EMIX_SOURCE_CHANGED_EVENT = ecore_event_type_new();
195
196 end: 111 end:
197 _init_count++; 112 _init_count++;
198 return EINA_TRUE; 113 return EINA_TRUE;
@@ -281,8 +196,7 @@ emix_backend_set(const char *backend)
281 if (!ctx->loaded || !ctx->loaded->ebackend_init) 196 if (!ctx->loaded || !ctx->loaded->ebackend_init)
282 return EINA_FALSE; 197 return EINA_FALSE;
283 198
284 return ctx->loaded->ebackend_init(_sink_cb, _sink_input_cb, _source_cb, 199 return ctx->loaded->ebackend_init(_events_cb, NULL);
285 _disconnect_cb, _ready_cb);
286} 200}
287 201
288const Eina_List* 202const Eina_List*
@@ -438,12 +352,36 @@ emix_advanced_options_add(Evas_Object *parent)
438 return ctx->loaded->ebackend_advanced_options_add(parent); 352 return ctx->loaded->ebackend_advanced_options_add(parent);
439} 353}
440 354
441void 355Eina_Bool
442emix_volume_meter_callback_set(volume_meter_cb cb, const void *userdata) 356emix_event_callback_add(Emix_Event_Cb cb, const void *data)
443{ 357{
444 EINA_SAFETY_ON_FALSE_RETURN((ctx && ctx->loaded && 358 struct Callback_Data *callback;
445 ctx->loaded->ebackend_volume_meter_callback_set && 359 EINA_SAFETY_ON_FALSE_RETURN_VAL((ctx && cb), EINA_FALSE);
446 cb)); 360
361 callback = calloc(1, sizeof(*callback));
362 callback->cb = cb;
363 callback->data = data;
447 364
448 ctx->loaded->ebackend_volume_meter_callback_set(cb, userdata); 365 ctx->callbacks = eina_list_append(ctx->callbacks, callback);
366 return EINA_TRUE;
367}
368
369Eina_Bool
370emix_event_callback_del(Emix_Event_Cb cb)
371{
372 struct Callback_Data *callback;
373 Eina_List *l;
374 EINA_SAFETY_ON_FALSE_RETURN_VAL((ctx && cb), EINA_FALSE);
375
376 EINA_LIST_FOREACH(ctx->callbacks, l, callback)
377 {
378 if (callback->cb == cb)
379 {
380 ctx->callbacks = eina_list_remove_list(ctx->callbacks, l);
381 free(callback);
382 return EINA_TRUE;
383 }
384 }
385
386 return EINA_FALSE;
449} 387}
diff --git a/src/lib/emix.h b/src/lib/emix.h
index 222991a..6d46741 100644
--- a/src/lib/emix.h
+++ b/src/lib/emix.h
@@ -6,17 +6,19 @@
6 6
7#define EMIX_VOLUME_MAX 100 7#define EMIX_VOLUME_MAX 100
8 8
9EAPI extern int EMIX_READY_EVENT; 9enum Emix_Event {
10EAPI extern int EMIX_DISCONNECTED_EVENT; 10 EMIX_READY_EVENT = 0,
11EAPI extern int EMIX_SINK_ADDED_EVENT; 11 EMIX_DISCONNECTED_EVENT,
12EAPI extern int EMIX_SINK_REMOVED_EVENT; 12 EMIX_SINK_ADDED_EVENT,
13EAPI extern int EMIX_SINK_CHANGED_EVENT; 13 EMIX_SINK_REMOVED_EVENT,
14EAPI extern int EMIX_SINK_INPUT_ADDED_EVENT; 14 EMIX_SINK_CHANGED_EVENT,
15EAPI extern int EMIX_SINK_INPUT_REMOVED_EVENT; 15 EMIX_SINK_INPUT_ADDED_EVENT,
16EAPI extern int EMIX_SINK_INPUT_CHANGED_EVENT; 16 EMIX_SINK_INPUT_REMOVED_EVENT,
17EAPI extern int EMIX_SOURCE_ADDED_EVENT; 17 EMIX_SINK_INPUT_CHANGED_EVENT,
18EAPI extern int EMIX_SOURCE_REMOVED_EVENT; 18 EMIX_SOURCE_ADDED_EVENT,
19EAPI extern int EMIX_SOURCE_CHANGED_EVENT; 19 EMIX_SOURCE_REMOVED_EVENT,
20 EMIX_SOURCE_CHANGED_EVENT
21};
20 22
21typedef struct _Emix_Volume { 23typedef struct _Emix_Volume {
22 unsigned int channel_count; 24 unsigned int channel_count;
@@ -51,26 +53,11 @@ typedef struct _Emix_Source {
51 Eina_Bool mute; 53 Eina_Bool mute;
52} Emix_Source; 54} Emix_Source;
53 55
54typedef enum _Emix_Event_Type { 56typedef void (*Emix_Event_Cb)(void *data, enum Emix_Event event,
55 EMIX_EVENT_ADDED, 57 void *event_info);
56 EMIX_EVENT_CHANGED,
57 EMIX_EVENT_REMOVED
58} Emix_Event_Type;
59
60typedef void (*sink_event_cb)(Emix_Sink *sink, Emix_Event_Type type);
61typedef void (*sink_input_event_cb)(Emix_Sink_Input *input,
62 Emix_Event_Type type);
63typedef void (*source_event_cb)(Emix_Source *source, Emix_Event_Type type);
64typedef void (*disconnect_event_cb)(void);
65typedef void (*ready_event_cb)(void);
66typedef void (*volume_meter_cb)(Emix_Sink *sink, double value, void *userdata);
67 58
68typedef struct _Emix_Backend { 59typedef struct _Emix_Backend {
69 Eina_Bool (*ebackend_init)(sink_event_cb sink_cb, 60 Eina_Bool (*ebackend_init)(Emix_Event_Cb cb, const void *data);
70 sink_input_event_cb input_cb,
71 source_event_cb source_cb,
72 disconnect_event_cb disconnect_cb,
73 ready_event_cb ready_cb);
74 void (*ebackend_shutdown)(void); 61 void (*ebackend_shutdown)(void);
75 62
76 const Eina_List* (*ebackend_sinks_get)(void); 63 const Eina_List* (*ebackend_sinks_get)(void);
@@ -100,8 +87,6 @@ typedef struct _Emix_Backend {
100 Emix_Volume volume); 87 Emix_Volume volume);
101 88
102 Evas_Object* (*ebackend_advanced_options_add)(Evas_Object *parent); 89 Evas_Object* (*ebackend_advanced_options_add)(Evas_Object *parent);
103 void (*ebackend_volume_meter_callback_set)
104 (volume_meter_cb cb, const void *userdata);
105} Emix_Backend; 90} Emix_Backend;
106 91
107 92
@@ -110,6 +95,10 @@ EAPI void emix_shutdown(void);
110EAPI const Eina_List* emix_backends_available(void); 95EAPI const Eina_List* emix_backends_available(void);
111EAPI Eina_Bool emix_backend_set(const char *backend); 96EAPI Eina_Bool emix_backend_set(const char *backend);
112 97
98EAPI Eina_Bool emix_event_callback_add(Emix_Event_Cb cb,
99 const void *data);
100EAPI Eina_Bool emix_event_callback_del(Emix_Event_Cb cb);
101
113EAPI const Eina_List* emix_sinks_get(void); 102EAPI const Eina_List* emix_sinks_get(void);
114EAPI Eina_Bool emix_sink_default_support(void); 103EAPI Eina_Bool emix_sink_default_support(void);
115EAPI const Emix_Sink* emix_sink_default_get(void); 104EAPI const Emix_Sink* emix_sink_default_get(void);
@@ -135,7 +124,5 @@ EAPI void emix_source_volume_set(Emix_Source *source,
135 Emix_Volume volume); 124 Emix_Volume volume);
136 125
137EAPI Evas_Object* emix_advanced_options_add(Evas_Object *parent); 126EAPI Evas_Object* emix_advanced_options_add(Evas_Object *parent);
138EAPI void emix_volume_meter_callback_set(volume_meter_cb cb,
139 const void *userdata);
140 127
141#endif /* EMIX_H */ 128#endif /* EMIX_H */
diff --git a/src/module/e_mod_config.c b/src/module/e_mod_config.c
index f723e89..3446a71 100644
--- a/src/module/e_mod_config.c
+++ b/src/module/e_mod_config.c
@@ -9,10 +9,8 @@ typedef struct _Emix_Config
9 const char *backend; 9 const char *backend;
10 int notify; 10 int notify;
11 int mute; 11 int mute;
12 int meter;
13 12
14 emix_config_backend_changed cb; 13 emix_config_backend_changed cb;
15 emix_config_meter_changed meter_cb;
16 const void *userdata; 14 const void *userdata;
17} Emix_Config; 15} Emix_Config;
18 16
@@ -33,7 +31,6 @@ _emix_config_dd_new(void)
33 E_CONFIG_VAL(result, Emix_Config, backend, STR); 31 E_CONFIG_VAL(result, Emix_Config, backend, STR);
34 E_CONFIG_VAL(result, Emix_Config, notify, INT); 32 E_CONFIG_VAL(result, Emix_Config, notify, INT);
35 E_CONFIG_VAL(result, Emix_Config, mute, INT); 33 E_CONFIG_VAL(result, Emix_Config, mute, INT);
36 E_CONFIG_VAL(result, Emix_Config, meter, INT);
37 34
38 return result; 35 return result;
39} 36}
@@ -63,12 +60,6 @@ emix_config_desklock_mute_get(void)
63 return _config->mute; 60 return _config->mute;
64} 61}
65 62
66Eina_Bool
67emix_config_meter_get(void)
68{
69 return _config->meter;
70}
71
72static void 63static void
73_config_set(Emix_Config *config) 64_config_set(Emix_Config *config)
74{ 65{
@@ -77,16 +68,14 @@ _config_set(Emix_Config *config)
77 68
78 _config->notify = config->notify; 69 _config->notify = config->notify;
79 _config->mute = config->mute; 70 _config->mute = config->mute;
80 _config->meter = config->meter;
81 71
82 DBG("SAVING CONFIG %s %d %d %d", _config->backend, config->notify, 72 DBG("SAVING CONFIG %s %d %d", _config->backend, config->notify,
83 config->mute, config->meter); 73 config->mute);
84 e_config_domain_save("module.emix", cd, config); 74 e_config_domain_save("module.emix", cd, config);
85} 75}
86 76
87void 77void
88emix_config_init(emix_config_backend_changed cb, 78emix_config_init(emix_config_backend_changed cb, const void *userdata)
89 emix_config_meter_changed meter_cb, const void *userdata)
90{ 79{
91 const Eina_List *l; 80 const Eina_List *l;
92 81
@@ -102,7 +91,6 @@ emix_config_init(emix_config_backend_changed cb,
102 } 91 }
103 92
104 _config->cb = cb; 93 _config->cb = cb;
105 _config->meter_cb = meter_cb;
106 _config->userdata = userdata; 94 _config->userdata = userdata;
107 DBG("Config loaded, backend to use: %s", _config->backend); 95 DBG("Config loaded, backend to use: %s", _config->backend);
108} 96}
@@ -126,7 +114,6 @@ _create_data(E_Config_Dialog *cfg EINA_UNUSED)
126 d->config.backend = eina_stringshare_add(_config->backend); 114 d->config.backend = eina_stringshare_add(_config->backend);
127 d->config.notify = _config->notify; 115 d->config.notify = _config->notify;
128 d->config.mute = _config->mute; 116 d->config.mute = _config->mute;
129 d->config.meter = _config->meter;
130 117
131 return d; 118 return d;
132} 119}
@@ -155,9 +142,6 @@ _basic_create_widgets(E_Config_Dialog *cfd EINA_UNUSED, Evas *evas,
155 l = e_widget_check_add(evas, "Mute on lock", &cfdata->config.mute); 142 l = e_widget_check_add(evas, "Mute on lock", &cfdata->config.mute);
156 e_widget_list_object_append(o, l, 0, 0, 0); 143 e_widget_list_object_append(o, l, 0, 0, 0);
157 144
158 l = e_widget_check_add(evas, "Enable volume meter", &cfdata->config.meter);
159 e_widget_list_object_append(o, l, 0, 0, 0);
160
161 l = e_widget_label_add(evas, "Backend to use:"); 145 l = e_widget_label_add(evas, "Backend to use:");
162 e_widget_list_object_append(o, l, 0, 0, 0); 146 e_widget_list_object_append(o, l, 0, 0, 0);
163 147
@@ -191,8 +175,6 @@ _basic_apply_data(E_Config_Dialog *cfd EINA_UNUSED,
191 _config_set(&cfdata->config); 175 _config_set(&cfdata->config);
192 if (_config->cb) 176 if (_config->cb)
193 _config->cb(new_backend, (void *)_config->userdata); 177 _config->cb(new_backend, (void *)_config->userdata);
194 if (_config->meter_cb)
195 _config->meter_cb(!!_config->meter, (void *)_config->userdata);
196 return 1; 178 return 1;
197} 179}
198 180
diff --git a/src/module/e_mod_config.h b/src/module/e_mod_config.h
index 09ee461..5d019aa 100644
--- a/src/module/e_mod_config.h
+++ b/src/module/e_mod_config.h
@@ -6,8 +6,7 @@
6typedef void (*emix_config_backend_changed)(const char *backend, void *data); 6typedef void (*emix_config_backend_changed)(const char *backend, void *data);
7typedef void (*emix_config_meter_changed)(Eina_Bool enable, void *data); 7typedef void (*emix_config_meter_changed)(Eina_Bool enable, void *data);
8 8
9void emix_config_init(emix_config_backend_changed cb, 9void emix_config_init(emix_config_backend_changed cb, const void *userdata);
10 emix_config_meter_changed meter_cb, const void *userdata);
11void emix_config_shutdown(void); 10void emix_config_shutdown(void);
12const char *emix_config_backend_get(void); 11const char *emix_config_backend_get(void);
13void emix_config_backend_set(const char *backend); 12void emix_config_backend_set(const char *backend);
diff --git a/src/module/e_mod_main.c b/src/module/e_mod_main.c
index cae84f0..1dd5121 100644
--- a/src/module/e_mod_main.c
+++ b/src/module/e_mod_main.c
@@ -44,23 +44,13 @@ struct _Context
44{ 44{
45 char *theme; 45 char *theme;
46 Ecore_Exe *emixer; 46 Ecore_Exe *emixer;
47 Ecore_Event_Handler *disconnected_handler;
48 Ecore_Event_Handler *ready_handler;
49 Ecore_Event_Handler *emix_event_handler;
50 Ecore_Event_Handler *sink_added_handler;
51 Ecore_Event_Handler *sink_changed_handler;
52 Ecore_Event_Handler *sink_removed_handler;
53 Ecore_Event_Handler *desklock_handler; 47 Ecore_Event_Handler *desklock_handler;
48 Ecore_Event_Handler *emix_event_handler;
54 const Emix_Sink *sink_default; 49 const Emix_Sink *sink_default;
55 E_Module *module; 50 E_Module *module;
56 Eina_List *instances; 51 Eina_List *instances;
57 E_Menu *menu; 52 E_Menu *menu;
58 unsigned int notification_id; 53 unsigned int notification_id;
59 struct {
60 int value;
61 Emix_Sink *sink;
62 Ecore_Timer *timer;
63 } meter;
64 54
65 struct { 55 struct {
66 E_Action *incr; 56 E_Action *incr;
@@ -137,23 +127,6 @@ _mixer_popup_update(Instance *inst, int mute, int vol)
137 127
138static void _popup_del(Instance *inst); 128static void _popup_del(Instance *inst);
139 129
140static Eina_Bool
141_mixer_gadget_meter_update(void *data EINA_UNUSED)
142{
143 Edje_Message_Int msg;
144 Instance *inst;
145 Eina_List *l;
146
147 EINA_LIST_FOREACH(mixer_context->instances, l, inst)
148 {
149 msg.val = mixer_context->meter.value;
150 if (mixer_context->sink_default == mixer_context->meter.sink)
151 edje_object_message_send(inst->gadget, EDJE_MESSAGE_INT, 1, &msg);
152 }
153
154 return ECORE_CALLBACK_RENEW;
155}
156
157static void 130static void
158_mixer_gadget_update(void) 131_mixer_gadget_update(void)
159{ 132{
@@ -488,7 +461,8 @@ _menu_cb(void *data, E_Menu *menu EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED)
488} 461}
489 462
490static void 463static void
491_settings_cb(void *data EINA_UNUSED, E_Menu *menu EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) 464_settings_cb(void *data EINA_UNUSED, E_Menu *menu EINA_UNUSED,
465 E_Menu_Item *mi EINA_UNUSED)
492{ 466{
493 emix_config_popup_new(NULL, NULL); 467 emix_config_popup_new(NULL, NULL);
494} 468}
@@ -655,8 +629,8 @@ _gc_id_new(const E_Gadcon_Client_Class *client_class EINA_UNUSED)
655 return _gadcon_class.name; 629 return _gadcon_class.name;
656} 630}
657 631
658static Eina_Bool 632static void
659_sink_event_cb(void *data EINA_UNUSED, int type, void *info) 633_sink_event(int type, void *info)
660{ 634{
661 Emix_Sink *sink = info; 635 Emix_Sink *sink = info;
662 const Eina_List *l; 636 const Eina_List *l;
@@ -669,7 +643,6 @@ _sink_event_cb(void *data EINA_UNUSED, int type, void *info)
669 mixer_context->sink_default = l->data; 643 mixer_context->sink_default = l->data;
670 _mixer_gadget_update(); 644 _mixer_gadget_update();
671 } 645 }
672 return ECORE_CALLBACK_DONE;
673 } 646 }
674 else if (type == EMIX_SINK_CHANGED_EVENT) 647 else if (type == EMIX_SINK_CHANGED_EVENT)
675 { 648 {
@@ -683,23 +656,17 @@ _sink_event_cb(void *data EINA_UNUSED, int type, void *info)
683 { 656 {
684 DBG("Sink added"); 657 DBG("Sink added");
685 } 658 }
686
687 return ECORE_CALLBACK_DONE;
688} 659}
689 660
690static Eina_Bool 661static void
691_disconnected_cb(void *data EINA_UNUSED, int type EINA_UNUSED, 662_disconnected(void)
692 void *info EINA_UNUSED)
693{ 663{
694 mixer_context->sink_default = NULL; 664 mixer_context->sink_default = NULL;
695 _mixer_gadget_update(); 665 _mixer_gadget_update();
696
697 return ECORE_CALLBACK_DONE;
698} 666}
699 667
700static Eina_Bool 668static void
701_ready_cb(void *data EINA_UNUSED, int type EINA_UNUSED, 669_ready(void)
702 void *info EINA_UNUSED)
703{ 670{
704 if (emix_sink_default_support()) 671 if (emix_sink_default_support())
705 mixer_context->sink_default = emix_sink_default_get(); 672 mixer_context->sink_default = emix_sink_default_get();
@@ -707,8 +674,27 @@ _ready_cb(void *data EINA_UNUSED, int type EINA_UNUSED,
707 mixer_context->sink_default = emix_sinks_get()->data; 674 mixer_context->sink_default = emix_sinks_get()->data;
708 675
709 _mixer_gadget_update(); 676 _mixer_gadget_update();
677}
710 678
711 return ECORE_CALLBACK_DONE; 679static void
680_events_cb(void *data EINA_UNUSED, enum Emix_Event type, void *event_info)
681{
682 switch (type)
683 {
684 case EMIX_SINK_ADDED_EVENT:
685 case EMIX_SINK_CHANGED_EVENT:
686 case EMIX_SINK_REMOVED_EVENT:
687 _sink_event(type, event_info);
688 break;
689 case EMIX_DISCONNECTED_EVENT:
690 _disconnected();
691 break;
692 case EMIX_READY_EVENT:
693 _ready();
694 break;
695 default:
696 break;
697 }
712} 698}
713 699
714static Eina_Bool 700static Eina_Bool
@@ -738,44 +724,12 @@ _desklock_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *info)
738static void 724static void
739_backend_changed(const char *backend, void *data EINA_UNUSED) 725_backend_changed(const char *backend, void *data EINA_UNUSED)
740{ 726{
741 _disconnected_cb(NULL, -1, NULL); 727 _disconnected();
742 728
743 if (emix_backend_set(backend) == EINA_FALSE) 729 if (emix_backend_set(backend) == EINA_FALSE)
744 ERR("Could not load backend: %s", backend); 730 ERR("Could not load backend: %s", backend);
745} 731}
746 732
747static void
748_volume_meter_cb(Emix_Sink *sink, double value, void *data EINA_UNUSED)
749{
750 mixer_context->meter.sink = sink;
751 mixer_context->meter.value = (int) (value * 100);
752
753 if (value == -1)
754 {
755 if (mixer_context->meter.timer)
756 {
757 ecore_timer_del(mixer_context->meter.timer);
758 mixer_context->meter.timer = NULL;
759 }
760 }
761 else
762 {
763 if (!mixer_context->meter.timer)
764 mixer_context->meter.timer = ecore_timer_add(0.2,
765 _mixer_gadget_meter_update,
766 NULL);
767 }
768}
769
770void
771_volume_meter_changed(Eina_Bool enable, void *data EINA_UNUSED)
772{
773 if (enable)
774 emix_volume_meter_callback_set(_volume_meter_cb, NULL);
775 else
776 emix_volume_meter_callback_set(NULL, NULL);
777}
778
779EAPI void * 733EAPI void *
780e_modapi_init(E_Module *m) 734e_modapi_init(E_Module *m)
781{ 735{
@@ -787,7 +741,8 @@ e_modapi_init(E_Module *m)
787 _e_emix_log_domain = eina_log_domain_register("emix_module", EINA_COLOR_RED); 741 _e_emix_log_domain = eina_log_domain_register("emix_module", EINA_COLOR_RED);
788 742
789 EINA_SAFETY_ON_FALSE_RETURN_VAL(emix_init(), NULL); 743 EINA_SAFETY_ON_FALSE_RETURN_VAL(emix_init(), NULL);
790 emix_config_init(_backend_changed, _volume_meter_changed, NULL); 744 emix_config_init(_backend_changed, NULL);
745 emix_event_callback_add(_events_cb, NULL);
791 746
792 backend = emix_config_backend_get(); 747 backend = emix_config_backend_get();
793 if (!backend) 748 if (!backend)
@@ -814,27 +769,10 @@ e_modapi_init(E_Module *m)
814 if (backend_loaded == EINA_FALSE) 769 if (backend_loaded == EINA_FALSE)
815 goto err; 770 goto err;
816 771
817 if (emix_config_meter_get())
818 emix_volume_meter_callback_set(_volume_meter_cb, NULL);
819
820 if (!mixer_context) 772 if (!mixer_context)
821 { 773 {
822 mixer_context = E_NEW(Context, 1); 774 mixer_context = E_NEW(Context, 1);
823 775
824 mixer_context->sink_added_handler =
825 ecore_event_handler_add(EMIX_SINK_ADDED_EVENT, _sink_event_cb,
826 NULL);
827 mixer_context->sink_changed_handler =
828 ecore_event_handler_add(EMIX_SINK_CHANGED_EVENT, _sink_event_cb,
829 NULL);
830 mixer_context->sink_removed_handler =
831 ecore_event_handler_add(EMIX_SINK_REMOVED_EVENT, _sink_event_cb,
832 NULL);
833 mixer_context->disconnected_handler =
834 ecore_event_handler_add(EMIX_DISCONNECTED_EVENT, _disconnected_cb,
835 NULL);
836 mixer_context->ready_handler =
837 ecore_event_handler_add(EMIX_READY_EVENT, _ready_cb, NULL);
838 mixer_context->desklock_handler = 776 mixer_context->desklock_handler =
839 ecore_event_handler_add(E_EVENT_DESKLOCK, _desklock_cb, NULL); 777 ecore_event_handler_add(E_EVENT_DESKLOCK, _desklock_cb, NULL);
840 mixer_context->module = m; 778 mixer_context->module = m;
@@ -871,12 +809,6 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED)
871 if (mixer_context->theme) 809 if (mixer_context->theme)
872 free(mixer_context->theme); 810 free(mixer_context->theme);
873 811
874 ecore_event_handler_del(mixer_context->sink_added_handler);
875 ecore_event_handler_del(mixer_context->sink_changed_handler);
876 ecore_event_handler_del(mixer_context->sink_removed_handler);
877 ecore_event_handler_del(mixer_context->disconnected_handler);
878 ecore_event_handler_del(mixer_context->ready_handler);
879
880 E_FREE(mixer_context); 812 E_FREE(mixer_context);
881 } 813 }
882 814