e_entry -> elm_entry conversion
[platform/upstream/enlightenment.git] / src / modules / mixer / app_mixer.c
1 #include "e_mod_main.h"
2
3 extern const char _e_mixer_Name[];
4
5 typedef struct E_Mixer_App_Dialog_Data
6 {
7    E_Mixer_System       *sys;
8    const char           *sys_card_name;
9    const char           *channel_name;
10    int                   lock_sliders;
11    Eina_List            *cards;
12    Eina_List            *channel_infos;
13    E_Mixer_Channel_Info *channel_info;
14    E_Mixer_Channel_State state;
15
16    struct e_mixer_app_ui
17    {
18       Evas_Object *hlayout;
19       struct e_mixer_app_ui_cards
20       {
21          Evas_Object *frame;
22          Evas_Object *list;
23       } cards;
24       struct e_mixer_app_ui_channels
25       {
26          Evas_Object *frame;
27          Evas_Object *list;
28       } channels;
29       struct e_mixer_app_ui_channel_editor
30       {
31          Evas_Object *frame;
32          Evas_Object *label_card;
33          Evas_Object *card;
34          Evas_Object *label_channel;
35          Evas_Object *channel;
36          Evas_Object *label_type;
37          Evas_Object *type;
38          Evas_Object *label_left;
39          Evas_Object *left;
40          Evas_Object *label_right;
41          Evas_Object *right;
42          Evas_Object *mute;
43          Evas_Object *lock_sliders;
44       } channel_editor;
45    } ui;
46
47    struct
48    {
49       void *data;
50       void (*func)(E_Dialog *dialog, void *data);
51    } del;
52 } E_Mixer_App_Dialog_Data;
53
54 static void
55 _cb_changed_left(void *data, Evas_Object *obj __UNUSED__)
56 {
57    E_Mixer_App_Dialog_Data *app = data;
58    E_Mixer_Channel_State *state;
59
60    state = &app->state;
61    if (app->lock_sliders && (state->left != state->right))
62      {
63         state->right = state->left;
64         e_widget_slider_value_int_set(app->ui.channel_editor.right,
65                                       state->right);
66      }
67
68    e_mod_mixer_volume_set(app->sys, app->channel_info,
69                           state->left, state->right);
70 }
71
72 static void
73 _cb_changed_right(void *data, Evas_Object *obj __UNUSED__)
74 {
75    E_Mixer_App_Dialog_Data *app = data;
76    E_Mixer_Channel_State *state;
77
78    state = &app->state;
79    if (app->lock_sliders && (state->right != state->left))
80      {
81         state->left = state->right;
82         e_widget_slider_value_int_set(app->ui.channel_editor.left,
83                                       state->left);
84      }
85
86    e_mod_mixer_volume_set(app->sys, app->channel_info,
87                           state->left, state->right);
88 }
89
90 static void
91 _cb_changed_mute(void *data, Evas_Object *obj __UNUSED__)
92 {
93    E_Mixer_App_Dialog_Data *app = data;
94
95    e_mod_mixer_mute_set(app->sys, app->channel_info, app->state.mute);
96 }
97
98 static void
99 _cb_changed_lock_sliders(void *data, Evas_Object *obj __UNUSED__)
100 {
101    E_Mixer_App_Dialog_Data *app = data;
102    E_Mixer_Channel_State *state;
103
104    if (!app->lock_sliders)
105      return;
106
107    state = &app->state;
108    if (state->left == state->right)
109      return;
110
111    state->left = state->right = (state->left + state->right) / 2;
112
113    e_widget_slider_value_int_set(app->ui.channel_editor.left, state->left);
114    e_widget_slider_value_int_set(app->ui.channel_editor.right, state->right);
115    e_mod_mixer_volume_set(app->sys, app->channel_info,
116                           state->left, state->right);
117 }
118
119 static void
120 _disable_channel_editor(E_Mixer_App_Dialog_Data *app)
121 {
122    struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor;
123
124    e_widget_entry_text_set(ui->card, "");
125    e_widget_entry_text_set(ui->channel, "");
126    e_widget_entry_text_set(ui->type, "");
127
128    e_widget_slider_value_int_set(ui->left, 0);
129    e_widget_slider_value_int_set(ui->right, 0);
130    e_widget_check_checked_set(ui->mute, 0);
131    e_widget_check_checked_set(ui->lock_sliders, 0);
132
133    e_widget_disabled_set(ui->left, 1);
134    e_widget_disabled_set(ui->right, 1);
135    e_widget_disabled_set(ui->mute, 1);
136    e_widget_disabled_set(ui->lock_sliders, 1);
137 }
138
139 static void
140 _update_channel_editor_state(E_Mixer_App_Dialog_Data *app, const E_Mixer_Channel_State state)
141 {
142    struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor;
143
144    if (!e_mod_mixer_channel_has_no_volume(app->channel_info))
145      {
146         if (e_mod_mixer_channel_is_mono(app->channel_info))
147           e_widget_slider_value_int_set(ui->left, state.left);
148         else
149           {
150              e_widget_slider_value_int_set(ui->left, state.left);
151              e_widget_slider_value_int_set(ui->right, state.right);
152           }
153      }
154
155    if (e_mod_mixer_channel_is_mutable(app->channel_info))
156      e_widget_check_checked_set(ui->mute, state.mute);
157 }
158
159 static void
160 _populate_channel_editor(E_Mixer_App_Dialog_Data *app)
161 {
162    struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor;
163    E_Mixer_Channel_State state;
164
165    if ((!app->sys_card_name) || (!app->channel_name))
166      {
167         _disable_channel_editor(app);
168         return;
169      }
170
171    e_widget_entry_text_set(ui->card, app->sys_card_name);
172    e_widget_entry_text_set(ui->channel, app->channel_name);
173
174    if (e_mod_mixer_channel_is_boost(app->channel_info))
175      e_widget_entry_text_set(ui->type, _("Boost"));
176    else if (e_mod_mixer_channel_has_playback(app->channel_info))
177      e_widget_entry_text_set(ui->type, _("Playback"));
178    else if (e_mod_mixer_channel_has_capture(app->channel_info))
179      e_widget_entry_text_set(ui->type, _("Capture"));
180    else
181       e_widget_entry_text_set(ui->type, _("Switch"));
182
183    e_mod_mixer_state_get(app->sys, app->channel_info, &state);
184    _update_channel_editor_state(app, state);
185
186    if (e_mod_mixer_channel_is_mutable(app->channel_info))
187      {
188         e_widget_disabled_set(ui->mute, 0);
189      }
190    else
191      {
192         e_widget_disabled_set(ui->mute, 1);
193         e_widget_check_checked_set(ui->mute, 0);
194      }
195
196    if (e_mod_mixer_channel_has_no_volume(app->channel_info))
197      {
198         app->lock_sliders = 1;
199         e_widget_slider_value_int_set(ui->left, 0);
200         e_widget_slider_value_int_set(ui->right, 0);
201         e_widget_disabled_set(ui->lock_sliders, 1);
202         e_widget_disabled_set(ui->left, 1);
203         e_widget_disabled_set(ui->right, 1);
204      }
205    else if (e_mod_mixer_channel_is_mono(app->channel_info))
206      {
207         app->lock_sliders = 0;
208         e_widget_slider_value_int_set(ui->right, 0);
209         e_widget_disabled_set(ui->lock_sliders, 1);
210         e_widget_disabled_set(ui->left, 0);
211         e_widget_disabled_set(ui->right, 1);
212      }
213    else
214      {
215         app->lock_sliders = (state.left == state.right);
216         e_widget_disabled_set(ui->lock_sliders, 0);
217         e_widget_disabled_set(ui->left, 0);
218         e_widget_disabled_set(ui->right, 0);
219      }
220    e_widget_check_checked_set(ui->lock_sliders, app->lock_sliders);
221 }
222
223 static void
224 _cb_channel_selected(void *data)
225 {
226    E_Mixer_Channel_Info *info = data;
227    E_Mixer_App_Dialog_Data *app;
228
229    app = info->app;
230    app->channel_info = info;
231    _populate_channel_editor(app);
232 }
233
234 static int
235 _cb_system_update(void *data, E_Mixer_System *sys __UNUSED__)
236 {
237    E_Mixer_App_Dialog_Data *app = data;
238    E_Mixer_Channel_State state;
239
240    if ((!app->sys) || (!app->channel_info))
241      return 1;
242
243    e_mod_mixer_state_get(app->sys, app->channel_info, &state);
244    _update_channel_editor_state(app, state);
245
246    return 1;
247 }
248
249 static void
250 _populate_channels(E_Mixer_App_Dialog_Data *app)
251 {
252    Eina_List *l;
253    Evas_Object *ilist;
254    int header_input;
255    int i, selected;
256
257    ilist = app->ui.channels.list;
258    edje_freeze();
259    e_widget_ilist_freeze(ilist);
260    e_widget_ilist_clear(ilist);
261
262    if (app->sys)
263      e_mod_mixer_del(app->sys);
264    app->sys = e_mod_mixer_new(app->sys_card_name);
265    if (_mixer_using_default)
266      e_mixer_system_callback_set(app->sys, _cb_system_update, app);
267
268    if (app->channel_infos)
269      e_mod_mixer_channel_infos_free(app->channel_infos);
270    app->channel_infos = e_mod_mixer_channel_infos_get(app->sys);
271
272    i = 0;
273    selected = 0;
274    header_input = 0;
275    for (l = app->channel_infos; l; l = l->next, i++)
276      {
277         E_Mixer_Channel_Info *info = l->data;
278
279         if (header_input != e_mod_mixer_channel_group_get(info))
280           {
281              if (e_mod_mixer_channel_is_boost(info))
282                e_widget_ilist_header_append(ilist, NULL, _("Boost"));
283              else if (e_mod_mixer_channel_has_playback(info))
284                e_widget_ilist_header_append(ilist, NULL, _("Playback"));
285              else if (e_mod_mixer_channel_has_capture(info))
286                e_widget_ilist_header_append(ilist, NULL, _("Capture"));
287              else
288                e_widget_ilist_header_append(ilist, NULL, _("Switch"));
289              header_input = e_mod_mixer_channel_group_get(info);
290              i++;
291           }
292
293         info->app = app;
294         e_widget_ilist_append(ilist, NULL, info->name, _cb_channel_selected,
295                               info, info->name);
296         if ((selected == 0) && app->channel_name && info->name &&
297             (strcmp(app->channel_name, info->name) == 0))
298           {
299              e_widget_ilist_selected_set(ilist, i);
300              app->channel_info = info;
301              selected = 1;
302           }
303      }
304
305    if ((selected == 0) && (i > 0))
306      e_widget_ilist_selected_set(ilist, 0);
307    else
308      app->channel_name = NULL;
309
310    e_widget_ilist_go(ilist);
311    e_widget_ilist_thaw(ilist);
312    edje_thaw();
313 }
314
315 static void
316 _cb_card_selected(void *data)
317 {
318    _populate_channels(data);
319 }
320
321 static void
322 _create_cards(E_Dialog *dialog __UNUSED__, Evas *evas, E_Mixer_App_Dialog_Data *app)
323 {
324    struct e_mixer_app_ui_cards *ui = &app->ui.cards;
325    const char *card;
326    Eina_List *l;
327
328    app->cards = e_mod_mixer_card_names_get();
329    if (eina_list_count(app->cards) < 2)
330      return;
331
332    ui->list = e_widget_ilist_add(evas, 32, 32, &app->sys_card_name);
333    e_widget_size_min_set(ui->list, 180, 100);
334    e_widget_ilist_go(ui->list);
335    EINA_LIST_FOREACH(app->cards, l, card)
336      {
337         const char *card_name;
338
339         card_name = e_mod_mixer_card_name_get(card);
340
341         if (!card_name)
342           continue;
343
344         e_widget_ilist_append(ui->list, NULL, card_name, _cb_card_selected,
345                               app, card);
346
347         eina_stringshare_del(card_name);
348      }
349
350    ui->frame = e_widget_framelist_add(evas, _("Cards"), 0);
351    e_widget_framelist_object_append(ui->frame, ui->list);
352    e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 0, 0.0);
353 }
354
355 static void
356 _create_channels(E_Dialog *dialog __UNUSED__, Evas *evas, E_Mixer_App_Dialog_Data *app)
357 {
358    struct e_mixer_app_ui_channels *ui = &app->ui.channels;
359    ui->list = e_widget_ilist_add(evas, 24, 24, &app->channel_name);
360    e_widget_size_min_set(ui->list, 180, 100);
361    e_widget_ilist_go(ui->list);
362
363    ui->frame = e_widget_framelist_add(evas, _("Channels"), 0);
364    e_widget_framelist_object_append(ui->frame, ui->list);
365    e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 1, 0.0);
366 }
367
368 static void
369 _create_channel_editor(E_Dialog *dialog, Evas *evas, E_Mixer_App_Dialog_Data *app)
370 {
371    struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor;
372
373    ui->label_card = e_widget_label_add(evas, _("Card:"));
374    ui->card = e_widget_entry_add(dialog->win, NULL, NULL, NULL, NULL);
375    e_widget_entry_readonly_set(ui->card, 1);
376
377    ui->label_channel = e_widget_label_add(evas, _("Channel:"));
378    ui->channel = e_widget_entry_add(dialog->win, NULL, NULL, NULL, NULL);
379    e_widget_entry_readonly_set(ui->channel, 1);
380
381    ui->label_type = e_widget_label_add(evas, _("Type:"));
382    ui->type = e_widget_entry_add(dialog->win, NULL, NULL, NULL, NULL);
383    e_widget_entry_readonly_set(ui->type, 1);
384
385    ui->label_left = e_widget_label_add(evas, _("Left:"));
386    ui->left = e_widget_slider_add(evas, 1, 0, "%3.0f", 0.0, 100.0, 10.0, 100.0,
387                                   NULL, &app->state.left, 150);
388    e_widget_on_change_hook_set(ui->left, _cb_changed_left, app);
389
390    ui->label_right = e_widget_label_add(evas, _("Right:"));
391    ui->right = e_widget_slider_add(evas, 1, 0, "%3.0f", 0.0, 100.0, 10.0, 100.0,
392                                    NULL, &app->state.right, 150);
393    e_widget_on_change_hook_set(ui->right, _cb_changed_right, app);
394
395    ui->mute = e_widget_check_add(evas, _("Mute"), &app->state.mute);
396    e_widget_on_change_hook_set(ui->mute, _cb_changed_mute, app);
397
398    ui->lock_sliders = e_widget_check_add(evas, _("Lock Sliders"),
399                                          &app->lock_sliders);
400    e_widget_on_change_hook_set(ui->lock_sliders, _cb_changed_lock_sliders, app);
401
402    ui->frame = e_widget_framelist_add(evas, _("Edit"), 0);
403    e_widget_framelist_object_append(ui->frame, ui->label_card);
404    e_widget_framelist_object_append(ui->frame, ui->card);
405    e_widget_framelist_object_append(ui->frame, ui->label_channel);
406    e_widget_framelist_object_append(ui->frame, ui->channel);
407    e_widget_framelist_object_append(ui->frame, ui->label_type);
408    e_widget_framelist_object_append(ui->frame, ui->type);
409    e_widget_framelist_object_append(ui->frame, ui->label_left);
410    e_widget_framelist_object_append(ui->frame, ui->left);
411    e_widget_framelist_object_append(ui->frame, ui->label_right);
412    e_widget_framelist_object_append(ui->frame, ui->right);
413    e_widget_framelist_object_append(ui->frame, ui->mute);
414    e_widget_framelist_object_append(ui->frame, ui->lock_sliders);
415
416    e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 1, 0.5);
417 }
418
419 static void
420 _create_ui(E_Dialog *dialog, E_Mixer_App_Dialog_Data *app)
421 {
422    struct e_mixer_app_ui *ui = &app->ui;
423    Evas *evas;
424    int mw, mh;
425
426    evas = evas_object_evas_get(dialog->win);
427
428    ui->hlayout = e_widget_list_add(evas, 0, 1);
429    _create_cards(dialog, evas, app);
430    _create_channels(dialog, evas, app);
431    _create_channel_editor(dialog, evas, app);
432
433    e_widget_size_min_get(ui->hlayout, &mw, &mh);
434    if (mw < 300)
435      mw = 300;
436    if (mh < 200)
437      mh = 200;
438    e_dialog_content_set(dialog, ui->hlayout, mw, mh);
439 }
440
441 static void
442 _mixer_app_dialog_del(E_Dialog *dialog, E_Mixer_App_Dialog_Data *app)
443 {
444    if (!app)
445      return;
446
447    if (app->del.func)
448      app->del.func(dialog, app->del.data);
449
450    if ((!app->ui.cards.list) && (app->ui.channels.list))
451      eina_stringshare_del(app->sys_card_name);
452
453    if (app->cards)
454      e_mod_mixer_card_names_free(app->cards);
455    if (app->channel_infos)
456      e_mod_mixer_channel_infos_free(app->channel_infos);
457    e_mod_mixer_del(app->sys);
458
459    e_util_defer_object_del(E_OBJECT(dialog));
460    dialog->data = NULL;
461    E_FREE(app);
462 }
463
464 static void
465 _cb_win_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
466 {
467    E_Dialog *dialog = data;
468    E_Mixer_App_Dialog_Data *app = dialog->data;
469    _mixer_app_dialog_del(dialog, app);
470 }
471
472 static void
473 _cb_dialog_dismiss(void *data, E_Dialog *dialog)
474 {
475    _mixer_app_dialog_del(dialog, data);
476 }
477
478 E_Dialog *
479 e_mixer_app_dialog_new(Evas_Object *parent EINA_UNUSED, void (*func)(E_Dialog *dialog, void *data), void *data)
480 {
481    E_Mixer_App_Dialog_Data *app;
482    E_Dialog *dialog;
483
484    dialog = e_dialog_new(NULL, _e_mixer_Name, "e_mixer_app_dialog");
485    if (!dialog)
486      return NULL;
487
488    app = E_NEW(E_Mixer_App_Dialog_Data, 1);
489    if (!app)
490      {
491         e_object_del(E_OBJECT(dialog));
492         return NULL;
493      }
494
495    dialog->data = app;
496    app->del.data = data;
497    app->del.func = func;
498
499    e_dialog_title_set(dialog, _(_e_mixer_Name));
500
501    evas_object_event_callback_add(dialog->win, EVAS_CALLBACK_DEL, _cb_win_del, dialog);
502
503    _create_ui(dialog, app);
504
505    e_dialog_button_add(dialog, _("Close"), NULL, _cb_dialog_dismiss, app);
506    e_dialog_button_focus_num(dialog, 1);
507    elm_win_center(dialog->win, 1, 1);
508    e_dialog_show(dialog);
509    e_dialog_border_icon_set(dialog, "preferences-desktop-mixer");
510
511    // FIXME: what if module unloaded while mixer_app dialog up? bad!
512
513    return dialog;
514 }
515
516 int
517 e_mixer_app_dialog_select(E_Dialog *dialog, const char *sys_card_name, const char *channel_name)
518 {
519    int n, i;
520    Eina_List *l;
521    E_Mixer_App_Dialog_Data *app;
522
523    if (!dialog)
524      return 0;
525
526    if ((!sys_card_name) || (!channel_name))
527      return 0;
528
529    app = dialog->data;
530    if (!app)
531      return 0;
532
533    n = -1;
534    for (i = 0, l = app->cards; l; i++, l = l->next)
535      {
536         if (strcmp(sys_card_name, l->data) == 0)
537           {
538              n = i;
539              break;
540           }
541      }
542
543    if (n < 0)
544      {
545         /* FIXME device disappeared, very bad !! */
546         return 0;
547      }
548
549    /* app->channel_name will be overriden by selection in _populate_channels */
550    app->channel_name = channel_name;
551
552    if (app->ui.cards.list)
553      e_widget_ilist_selected_set(app->ui.cards.list, n);
554    else if (app->ui.channels.list)
555      {
556         app->sys_card_name = eina_stringshare_add(sys_card_name);
557         _populate_channels(app);
558      }
559
560    return 1;
561 }
562