1 #include "e_mod_main.h"
3 extern const char _e_mixer_Name[];
5 typedef struct E_Mixer_App_Dialog_Data
9 const char *channel_name;
12 Eina_List *channels_infos;
13 struct channel_info *channel_info;
14 E_Mixer_Channel_State state;
19 struct e_mixer_app_ui_cards
24 struct e_mixer_app_ui_channels
29 struct e_mixer_app_ui_channel_editor
32 Evas_Object *label_card;
34 Evas_Object *label_channel;
36 Evas_Object *label_type;
38 Evas_Object *label_left;
40 Evas_Object *label_right;
43 Evas_Object *lock_sliders;
50 void (*func)(E_Dialog *dialog, void *data);
52 } E_Mixer_App_Dialog_Data;
59 E_Mixer_App_Dialog_Data *app;
63 _cb_changed_left(void *data, Evas_Object *obj __UNUSED__)
65 E_Mixer_App_Dialog_Data *app = data;
66 E_Mixer_Channel_State *state;
69 if (app->lock_sliders && (state->left != state->right))
71 state->right = state->left;
72 e_widget_slider_value_int_set(app->ui.channel_editor.right,
76 e_mod_mixer_volume_set(app->sys, app->channel_info->id,
77 state->left, state->right);
81 _cb_changed_right(void *data, Evas_Object *obj __UNUSED__)
83 E_Mixer_App_Dialog_Data *app = data;
84 E_Mixer_Channel_State *state;
87 if (app->lock_sliders && (state->right != state->left))
89 state->left = state->right;
90 e_widget_slider_value_int_set(app->ui.channel_editor.left,
94 e_mod_mixer_volume_set(app->sys, app->channel_info->id,
95 state->left, state->right);
99 _cb_changed_mute(void *data, Evas_Object *obj __UNUSED__)
101 E_Mixer_App_Dialog_Data *app = data;
103 e_mod_mixer_mute_set(app->sys, app->channel_info->id, app->state.mute);
107 _cb_changed_lock_sliders(void *data, Evas_Object *obj __UNUSED__)
109 E_Mixer_App_Dialog_Data *app = data;
110 E_Mixer_Channel_State *state;
112 if (!app->lock_sliders)
116 if (state->left == state->right)
119 state->left = state->right = (state->left + state->right) / 2;
121 e_widget_slider_value_int_set(app->ui.channel_editor.left, state->left);
122 e_widget_slider_value_int_set(app->ui.channel_editor.right, state->right);
123 e_mod_mixer_volume_set(app->sys, app->channel_info->id,
124 state->left, state->right);
128 _update_channel_editor_state(E_Mixer_App_Dialog_Data *app, const E_Mixer_Channel_State state)
130 struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor;
132 e_widget_slider_value_int_set(ui->left, state.left);
133 e_widget_slider_value_int_set(ui->right, state.right);
135 if (e_mod_mixer_mutable_get(app->sys, app->channel_info->id))
137 e_widget_disabled_set(ui->mute, 0);
138 e_widget_check_checked_set(ui->mute, state.mute);
142 e_widget_disabled_set(ui->mute, 1);
143 e_widget_check_checked_set(ui->mute, 0);
148 _populate_channel_editor(E_Mixer_App_Dialog_Data *app)
150 struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor;
151 E_Mixer_Channel_State state;
152 const char *card_name;
154 card_name = e_mod_mixer_card_name_get(app->card);
159 e_widget_entry_text_set(ui->card, card_name);
160 eina_stringshare_del(card_name);
162 e_widget_entry_text_set(ui->channel, app->channel_name);
164 if (e_mod_mixer_capture_get(app->sys, app->channel_info->id))
165 e_widget_entry_text_set(ui->type, _("Capture"));
167 e_widget_entry_text_set(ui->type, _("Playback"));
169 e_mod_mixer_state_get(app->sys, app->channel_info->id, &state);
170 _update_channel_editor_state(app, state);
172 app->lock_sliders = (state.left == state.right);
173 e_widget_check_checked_set(ui->lock_sliders, app->lock_sliders);
177 _cb_channel_selected(void *data)
179 struct channel_info *info = data;
180 E_Mixer_App_Dialog_Data *app;
183 app->channel_info = info;
184 _populate_channel_editor(app);
188 _channel_info_cmp(const void *data_a, const void *data_b)
190 const struct channel_info *a = data_a, *b = data_b;
192 if (a->has_capture < b->has_capture)
194 else if (a->has_capture > b->has_capture)
197 return strcmp(a->name, b->name);
201 _channels_info_new(E_Mixer_System *sys)
203 Eina_List *channels, *channels_infos, *l;
205 channels = e_mod_mixer_channels_get(sys);
206 channels_infos = NULL;
207 for (l = channels; l; l = l->next)
209 struct channel_info *info;
211 info = malloc(sizeof(*info));
213 info->name = e_mod_mixer_channel_name_get(sys, info->id);
214 info->has_capture = e_mod_mixer_capture_get(sys, info->id);
216 channels_infos = eina_list_append(channels_infos, info);
218 e_mod_mixer_channels_free(channels);
220 return eina_list_sort(channels_infos, -1, _channel_info_cmp);
224 _channels_info_free(Eina_List *list)
226 struct channel_info *info;
228 EINA_LIST_FREE(list, info)
230 eina_stringshare_del(info->name);
236 _cb_system_update(void *data, E_Mixer_System *sys __UNUSED__)
238 E_Mixer_App_Dialog_Data *app = data;
239 E_Mixer_Channel_State state;
241 if ((!app->sys) || (!app->channel_info))
244 e_mod_mixer_state_get(app->sys, app->channel_info->id, &state);
245 _update_channel_editor_state(app, state);
251 _populate_channels(E_Mixer_App_Dialog_Data *app)
258 ilist = app->ui.channels.list;
260 e_widget_ilist_freeze(ilist);
261 e_widget_ilist_clear(ilist);
264 e_mod_mixer_del(app->sys);
265 app->sys = e_mod_mixer_new(app->card);
266 if (_mixer_using_default)
267 e_mixer_system_callback_set(app->sys, _cb_system_update, app);
269 eina_stringshare_del(app->channel_name);
270 app->channel_name = e_mod_mixer_channel_default_name_get(app->sys);
272 if (app->channels_infos)
273 _channels_info_free(app->channels_infos);
274 app->channels_infos = _channels_info_new(app->sys);
276 if (app->channels_infos)
278 struct channel_info *info = app->channels_infos->data;
279 if (info->has_capture)
281 e_widget_ilist_header_append(ilist, NULL, _("Input"));
287 e_widget_ilist_header_append(ilist, NULL, _("Output"));
293 for (l = app->channels_infos; l; l = l->next, i++)
295 struct channel_info *info = l->data;
297 if ((!header_input) && info->has_capture)
299 e_widget_ilist_header_append(ilist, NULL, _("Input"));
305 e_widget_ilist_append(ilist, NULL, info->name, _cb_channel_selected,
307 if (app->channel_name && info->name &&
308 (strcmp(app->channel_name, info->name) == 0))
310 e_widget_ilist_selected_set(ilist, i);
311 app->channel_info = info;
315 e_widget_ilist_go(ilist);
316 e_widget_ilist_thaw(ilist);
321 select_card(E_Mixer_App_Dialog_Data *app)
323 _populate_channels(app);
324 e_widget_ilist_selected_set(app->ui.channels.list, 1);
328 _cb_card_selected(void *data)
334 _create_cards(E_Dialog *dialog __UNUSED__, Evas *evas, E_Mixer_App_Dialog_Data *app)
336 struct e_mixer_app_ui_cards *ui = &app->ui.cards;
340 app->card = e_mod_mixer_card_default_get();
341 app->cards = e_mod_mixer_cards_get();
342 if (eina_list_count(app->cards) < 2)
345 ui->list = e_widget_ilist_add(evas, 32, 32, &app->card);
346 e_widget_size_min_set(ui->list, 180, 100);
347 e_widget_ilist_go(ui->list);
348 EINA_LIST_FOREACH(app->cards, l, card)
350 const char *card_name;
352 card_name = e_mod_mixer_card_name_get(card);
357 e_widget_ilist_append(ui->list, NULL, card_name, _cb_card_selected,
360 eina_stringshare_del(card_name);
363 ui->frame = e_widget_framelist_add(evas, _("Cards"), 0);
364 e_widget_framelist_object_append(ui->frame, ui->list);
365 e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 0, 0.0);
369 _create_channels(E_Dialog *dialog __UNUSED__, Evas *evas, E_Mixer_App_Dialog_Data *app)
371 struct e_mixer_app_ui_channels *ui = &app->ui.channels;
372 ui->list = e_widget_ilist_add(evas, 24, 24, &app->channel_name);
373 e_widget_size_min_set(ui->list, 180, 100);
374 e_widget_ilist_go(ui->list);
376 ui->frame = e_widget_framelist_add(evas, _("Channels"), 0);
377 e_widget_framelist_object_append(ui->frame, ui->list);
378 e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 1, 0.0);
382 _create_channel_editor(E_Dialog *dialog __UNUSED__, Evas *evas, E_Mixer_App_Dialog_Data *app)
384 struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor;
386 ui->label_card = e_widget_label_add(evas, _("Card:"));
387 ui->card = e_widget_entry_add(evas, NULL, NULL, NULL, NULL);
388 e_widget_entry_readonly_set(ui->card, 1);
390 ui->label_channel = e_widget_label_add(evas, _("Channel:"));
391 ui->channel = e_widget_entry_add(evas, NULL, NULL, NULL, NULL);
392 e_widget_entry_readonly_set(ui->channel, 1);
394 ui->label_type = e_widget_label_add(evas, _("Type:"));
395 ui->type = e_widget_entry_add(evas, NULL, NULL, NULL, NULL);
396 e_widget_entry_readonly_set(ui->type, 1);
398 ui->label_left = e_widget_label_add(evas, _("Left:"));
399 ui->left = e_widget_slider_add(evas, 1, 0, "%3.0f", 0.0, 100.0, 10.0, 100.0,
400 NULL, &app->state.left, 150);
401 e_widget_on_change_hook_set(ui->left, _cb_changed_left, app);
403 ui->label_right = e_widget_label_add(evas, _("Right:"));
404 ui->right = e_widget_slider_add(evas, 1, 0, "%3.0f", 0.0, 100.0, 10.0, 100.0,
405 NULL, &app->state.right, 150);
406 e_widget_on_change_hook_set(ui->right, _cb_changed_right, app);
408 ui->mute = e_widget_check_add(evas, _("Mute"), &app->state.mute);
409 e_widget_on_change_hook_set(ui->mute, _cb_changed_mute, app);
411 ui->lock_sliders = e_widget_check_add(evas, _("Lock Sliders"),
413 e_widget_on_change_hook_set(ui->lock_sliders, _cb_changed_lock_sliders, app);
415 ui->frame = e_widget_framelist_add(evas, _("Edit"), 0);
416 e_widget_framelist_object_append(ui->frame, ui->label_card);
417 e_widget_framelist_object_append(ui->frame, ui->card);
418 e_widget_framelist_object_append(ui->frame, ui->label_channel);
419 e_widget_framelist_object_append(ui->frame, ui->channel);
420 e_widget_framelist_object_append(ui->frame, ui->label_type);
421 e_widget_framelist_object_append(ui->frame, ui->type);
422 e_widget_framelist_object_append(ui->frame, ui->label_left);
423 e_widget_framelist_object_append(ui->frame, ui->left);
424 e_widget_framelist_object_append(ui->frame, ui->label_right);
425 e_widget_framelist_object_append(ui->frame, ui->right);
426 e_widget_framelist_object_append(ui->frame, ui->mute);
427 e_widget_framelist_object_append(ui->frame, ui->lock_sliders);
429 e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 1, 0.5);
433 _create_ui(E_Dialog *dialog, E_Mixer_App_Dialog_Data *app)
435 struct e_mixer_app_ui *ui = &app->ui;
439 evas = e_win_evas_get(dialog->win);
441 ui->hlayout = e_widget_list_add(evas, 0, 1);
442 _create_cards(dialog, evas, app);
443 _create_channels(dialog, evas, app);
444 _create_channel_editor(dialog, evas, app);
447 e_widget_ilist_selected_set(ui->cards.list, 0);
450 e_widget_ilist_selected_set(ui->channels.list, 1);
452 e_widget_size_min_get(ui->hlayout, &mw, &mh);
457 e_dialog_content_set(dialog, ui->hlayout, mw, mh);
461 _mixer_app_dialog_del(E_Dialog *dialog, E_Mixer_App_Dialog_Data *app)
464 app->del.func(dialog, app->del.data);
466 eina_stringshare_del(app->card);
467 eina_stringshare_del(app->channel_name);
469 e_mod_mixer_cards_free(app->cards);
470 if (app->channels_infos)
471 _channels_info_free(app->channels_infos);
472 e_mod_mixer_del(app->sys);
474 e_util_defer_object_del(E_OBJECT(dialog));
480 _cb_win_del(E_Win *win)
482 E_Dialog *dialog = win->data;
483 E_Mixer_App_Dialog_Data *app = dialog->data;
484 _mixer_app_dialog_del(dialog, app);
488 _cb_dialog_dismiss(void *data, E_Dialog *dialog)
490 _mixer_app_dialog_del(dialog, data);
494 e_mixer_app_dialog_new(E_Container *con, void (*func)(E_Dialog *dialog, void *data), void *data)
496 E_Mixer_App_Dialog_Data *app;
499 dialog = e_dialog_new(con, _e_mixer_Name, "e_mixer_app_dialog");
503 app = E_NEW(E_Mixer_App_Dialog_Data, 1);
506 e_object_del(E_OBJECT(dialog));
511 app->del.data = data;
512 app->del.func = func;
514 e_dialog_title_set(dialog, _(_e_mixer_Name));
515 e_dialog_resizable_set(dialog, 1);
517 e_win_delete_callback_set(dialog->win, _cb_win_del);
519 _create_ui(dialog, app);
521 e_dialog_button_add(dialog, _("Close"), NULL, _cb_dialog_dismiss, app);
522 e_dialog_button_focus_num(dialog, 1);
523 e_win_centered_set(dialog->win, 1);
524 e_dialog_show(dialog);
525 e_dialog_border_icon_set(dialog, "preferences-desktop-mixer");
527 // FIXME: what if module unloaded while mixer_app dialog up? bad!
533 _find_card_by_name(E_Mixer_App_Dialog_Data *app, const char *card_name)
541 for (i = 0, l = app->cards; l; i++, l = l->next)
542 if (strcmp(card_name, l->data) == 0)
549 _find_channel_by_name(E_Mixer_App_Dialog_Data *app, const char *channel_name)
551 struct channel_info *info;
559 if (app->channels_infos)
561 info = app->channels_infos->data;
563 header_input = !!info->has_capture;
567 EINA_LIST_FOREACH(app->channels_infos, l, info)
569 if ((!header_input) && info->has_capture)
575 if (strcmp(channel_name, info->name) == 0)
585 e_mixer_app_dialog_select(E_Dialog *dialog, const char *card_name, const char *channel_name)
587 E_Mixer_App_Dialog_Data *app;
593 if ((!card_name) || (!channel_name))
600 n = _find_card_by_name(app, card_name);
603 if (app->ui.cards.list)
604 e_widget_ilist_selected_set(app->ui.cards.list, n);
606 n = _find_channel_by_name(app, channel_name);
609 e_widget_ilist_selected_set(app->ui.channels.list, n);