forked from enlightenment/enlightenment
emixer: Add volume channels control on emixer
Summary: This commit allow the user to control each volumes channels in emixer. A lock flag is introduced to manage volume as before. @feature Reviewers: zmike!, devilhorns, raster Subscribers: cedric Tags: #enlightenment-git Differential Revision: https://phab.enlightenment.org/D7639
This commit is contained in:
parent
5cded14b76
commit
5aedf54042
|
@ -347,7 +347,7 @@ emix_config_save_state_restore(void)
|
|||
v.channel_count = emsink->volume.channel_count;
|
||||
for (i = 0; i < v.channel_count; i++)
|
||||
v.volumes[i] = sink->volume;
|
||||
emix_sink_volume_set(emsink, v);
|
||||
emix_sink_volume_set(emsink, &v);
|
||||
free(v.volumes);
|
||||
}
|
||||
emix_sink_mute_set(emsink, sink->mute);
|
||||
|
@ -373,7 +373,7 @@ emix_config_save_state_restore(void)
|
|||
v.channel_count = emsource->volume.channel_count;
|
||||
for (i = 0; i < v.channel_count; i++)
|
||||
v.volumes[i] = source->volume;
|
||||
emix_source_volume_set(emsource, v);
|
||||
emix_source_volume_set(emsource, &v);
|
||||
free(v.volumes);
|
||||
}
|
||||
emix_source_mute_set(emsource, source->mute);
|
||||
|
|
|
@ -9,6 +9,8 @@ Eina_List *source_list = NULL, *sink_input_list = NULL, *sink_list = NULL, *card
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void _emix_sink_volume_fill(Emix_Sink *sink, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked);
|
||||
|
||||
static Eina_Bool
|
||||
_backend_init(const char *back)
|
||||
{
|
||||
|
@ -48,6 +50,20 @@ _cb_sink_volume_change(void *data,
|
|||
elm_slider_value_set(obj, vol);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_sink_volume_channel_change(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Sink *sink = evas_object_data_get(bxv, "sink");
|
||||
double vol = elm_slider_value_get(obj);
|
||||
sink->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")] = vol;
|
||||
elm_slider_value_set(obj, vol);
|
||||
emix_sink_volume_set(sink, &sink->volume);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_cb_sink_mute_change(void *data,
|
||||
Evas_Object *obj,
|
||||
|
@ -55,18 +71,147 @@ _cb_sink_mute_change(void *data,
|
|||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Sink *sink = evas_object_data_get(bxv, "sink");
|
||||
Evas_Object *sl = evas_object_data_get(bxv, "volume");
|
||||
Evas_Object *lock = evas_object_data_get(bxv, "lock");
|
||||
Eina_Bool mute = elm_check_state_get(obj);
|
||||
elm_object_disabled_set(sl, mute);
|
||||
Eina_List *l;
|
||||
Evas_Object *o;
|
||||
|
||||
if (lock && !elm_check_state_get(lock))
|
||||
{
|
||||
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), l, o)
|
||||
{
|
||||
elm_object_disabled_set(o, mute);
|
||||
o = evas_object_data_get(o, "lb");
|
||||
elm_object_disabled_set(o, mute);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
o = evas_object_data_get(bxv, "volume");
|
||||
elm_object_disabled_set(o, mute);
|
||||
}
|
||||
emix_sink_mute_set(sink, mute);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_sink_lock_change(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Sink *sink = evas_object_data_get(bxv, "sink");
|
||||
Evas_Object *bx = evas_object_data_get(bxv, "volume_bx");
|
||||
Eina_Bool lock = elm_check_state_get(obj);
|
||||
if (lock)
|
||||
VOLSET(sink->volume.volumes[0], sink->volume,
|
||||
sink, emix_sink_volume_set);
|
||||
_emix_sink_volume_fill(sink, bxv, bx, lock);
|
||||
}
|
||||
|
||||
static void
|
||||
_emix_sink_volume_fill(Emix_Sink *sink, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked)
|
||||
{
|
||||
Evas_Object *bxhv, *sl, *ck, *lb;
|
||||
Eina_List *sls = NULL;
|
||||
unsigned int i;
|
||||
|
||||
eina_list_free(evas_object_data_get(bxv, "volumes"));
|
||||
elm_box_clear(bx);
|
||||
|
||||
bxhv = elm_box_add(bx);
|
||||
evas_object_size_hint_weight_set(bxhv, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(bxhv, EVAS_HINT_FILL, 0.5);
|
||||
elm_box_pack_end(bx, bxhv);
|
||||
evas_object_show(bxhv);
|
||||
|
||||
if (locked)
|
||||
{
|
||||
sl = elm_slider_add(bx);
|
||||
evas_object_data_set(bxv, "volume", sl);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, emix_max_volume_get() * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_slider_value_set(sl, sink->volume.volumes[0]);
|
||||
elm_box_pack_end(bxhv, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed", _cb_sink_volume_change, bxv);
|
||||
elm_object_disabled_set(sl, sink->mute);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < sink->volume.channel_count; ++i)
|
||||
{
|
||||
lb = elm_label_add(bx);
|
||||
if (!sink->volume.channel_names)
|
||||
{
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "Channel %d", i);
|
||||
elm_object_text_set(lb, buf);
|
||||
}
|
||||
else
|
||||
elm_object_text_set(lb, sink->volume.channel_names[i]);
|
||||
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
|
||||
evas_object_size_hint_align_set(lb, 0.0, 0.5);
|
||||
elm_box_pack_end(bxhv, lb);
|
||||
elm_object_disabled_set(lb, sink->mute);
|
||||
evas_object_show(lb);
|
||||
|
||||
sl = elm_slider_add(bx);
|
||||
evas_object_data_set(sl, "lb", lb);
|
||||
evas_object_data_set(sl, "channel", (uintptr_t *)(uintptr_t)i);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_slider_value_set(sl, sink->volume.volumes[i]);
|
||||
elm_box_pack_end(bxhv, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed", _cb_sink_volume_channel_change, bxv);
|
||||
elm_object_disabled_set(sl, sink->mute);
|
||||
sls = eina_list_append(sls, sl);
|
||||
}
|
||||
}
|
||||
evas_object_data_set(bxv, "volumes", sls);
|
||||
|
||||
bxhv = elm_box_add(bx);
|
||||
elm_box_pack_end(bx, bxhv);
|
||||
evas_object_show(bxhv);
|
||||
|
||||
ck = elm_check_add(bx);
|
||||
evas_object_data_set(bxv, "mute", ck);
|
||||
elm_object_text_set(ck, "Mute");
|
||||
elm_check_state_set(ck, sink->mute);
|
||||
elm_box_pack_end(bxhv, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed", _cb_sink_mute_change, bxv);
|
||||
|
||||
if (sink->volume.channel_count > 1)
|
||||
{
|
||||
ck = elm_check_add(bx);
|
||||
elm_object_text_set(ck, "Lock");
|
||||
evas_object_data_set(bxv, "lock", ck);
|
||||
elm_check_state_set(ck, locked);
|
||||
elm_box_pack_end(bxhv, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed", _cb_sink_lock_change, bxv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
_emix_sink_add(Emix_Sink *sink)
|
||||
{
|
||||
Evas_Object *bxv, *bx, *lb, *ck, *sl, *hv, *sep;
|
||||
Evas_Object *bxv, *bx, *lb, *hv, *sep;
|
||||
const Eina_List *l;
|
||||
Emix_Port *port;
|
||||
Eina_Bool locked = EINA_TRUE;
|
||||
unsigned int i;
|
||||
|
||||
bxv = elm_box_add(win);
|
||||
sink_list = eina_list_append(sink_list, bxv);
|
||||
|
@ -104,34 +249,27 @@ _emix_sink_add(Emix_Sink *sink)
|
|||
elm_box_pack_end(bx, hv);
|
||||
evas_object_show(hv);
|
||||
|
||||
bx = elm_box_add(win);
|
||||
/* Compare each volume level and check if they differ. If they differ unlock
|
||||
the volume control and let user set each channel volume level */
|
||||
for (i = 1; i < sink->volume.channel_count; ++i)
|
||||
{
|
||||
if (sink->volume.volumes[i - 1] != sink->volume.volumes[i])
|
||||
{
|
||||
locked = EINA_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bx = elm_box_add(bxv);
|
||||
evas_object_data_set(bxv, "volume_bx", bx);
|
||||
elm_box_horizontal_set(bx, EINA_TRUE);
|
||||
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
|
||||
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
|
||||
elm_box_pack_end(bxv, bx);
|
||||
evas_object_show(bx);
|
||||
|
||||
sl = elm_slider_add(win);
|
||||
evas_object_data_set(bxv, "volume", sl);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, emix_max_volume_get() * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.5);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
|
||||
elm_slider_value_set(sl, sink->volume.volumes[0]);
|
||||
elm_box_pack_end(bx, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed", _cb_sink_volume_change, bxv);
|
||||
|
||||
ck = elm_check_add(win);
|
||||
evas_object_data_set(bxv, "mute", ck);
|
||||
elm_object_text_set(ck, "Mute");
|
||||
elm_check_state_set(ck, sink->mute);
|
||||
elm_object_disabled_set(sl, sink->mute);
|
||||
elm_box_pack_end(bx, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed", _cb_sink_mute_change, bxv);
|
||||
_emix_sink_volume_fill(sink, bxv, bx, locked);
|
||||
|
||||
sep = elm_separator_add(win);
|
||||
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||
|
@ -164,7 +302,8 @@ static void
|
|||
_emix_sink_change(Emix_Sink *sink)
|
||||
{
|
||||
const Eina_List *l;
|
||||
Evas_Object *bxv, *hv, *ck, *sl;
|
||||
Eina_List *ll;
|
||||
Evas_Object *bxv, *hv, *ck, *sl, *lb;
|
||||
Emix_Port *port;
|
||||
|
||||
EINA_LIST_FOREACH(sink_list, l, bxv)
|
||||
|
@ -181,15 +320,35 @@ _emix_sink_change(Emix_Sink *sink)
|
|||
_cb_sink_port_change, port);
|
||||
if (port->active) elm_object_text_set(hv, port->description);
|
||||
}
|
||||
sl = evas_object_data_get(bxv, "volume");
|
||||
elm_slider_value_set(sl, sink->volume.volumes[0]);
|
||||
ck = evas_object_data_get(bxv, "lock");
|
||||
|
||||
if (ck && !elm_check_state_get(ck))
|
||||
{
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, sink->mute);
|
||||
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), ll, sl)
|
||||
{
|
||||
elm_slider_value_set(sl,
|
||||
sink->volume.volumes[(uintptr_t)evas_object_data_get(sl, "channel")]);
|
||||
elm_object_disabled_set(sl, sink->mute);
|
||||
lb = evas_object_data_get(sl, "lb");
|
||||
elm_object_disabled_set(lb, sink->mute);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, sink->mute);
|
||||
|
||||
sl = evas_object_data_get(bxv, "volume");
|
||||
elm_slider_value_set(sl, sink->volume.volumes[0]);
|
||||
elm_object_disabled_set(sl, sink->mute);
|
||||
}
|
||||
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, sink->mute);
|
||||
elm_object_disabled_set(sl, sink->mute);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
static void _emix_sink_input_volume_fill(Emix_Sink_Input *input, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked);
|
||||
|
||||
static void
|
||||
_cb_sink_input_port_change(void *data,
|
||||
|
@ -215,6 +374,19 @@ _cb_sink_input_volume_change(void *data,
|
|||
elm_slider_value_set(obj, vol);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_sink_input_volume_channel_change(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Sink_Input *input = evas_object_data_get(bxv, "input");
|
||||
double vol = elm_slider_value_get(obj);
|
||||
input->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")] = vol;
|
||||
elm_slider_value_set(obj, vol);
|
||||
emix_sink_input_volume_set(input, &input->volume);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_sink_input_volume_drag_stop(void *data,
|
||||
Evas_Object *obj,
|
||||
|
@ -226,6 +398,17 @@ _cb_sink_input_volume_drag_stop(void *data,
|
|||
elm_slider_value_set(obj, vol);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_sink_input_volume_channel_drag_stop(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Sink_Input *input = evas_object_data_get(bxv, "input");
|
||||
int vol = input->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")];
|
||||
elm_slider_value_set(obj, vol);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_sink_input_mute_change(void *data,
|
||||
Evas_Object *obj,
|
||||
|
@ -233,18 +416,156 @@ _cb_sink_input_mute_change(void *data,
|
|||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Sink_Input *input = evas_object_data_get(bxv, "input");
|
||||
Evas_Object *sl = evas_object_data_get(bxv, "volume");
|
||||
Evas_Object *sl;
|
||||
Evas_Object *lock = evas_object_data_get(bxv, "lock");
|
||||
Eina_Bool mute = elm_check_state_get(obj);
|
||||
elm_object_disabled_set(sl, mute);
|
||||
Evas_Object *lb;
|
||||
Eina_List *l;
|
||||
|
||||
if (lock && !elm_check_state_get(lock))
|
||||
{
|
||||
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), l, sl)
|
||||
{
|
||||
elm_object_disabled_set(sl, mute);
|
||||
lb = evas_object_data_get(sl, "lb");
|
||||
elm_object_disabled_set(lb, mute);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sl = evas_object_data_get(bxv, "volume");
|
||||
elm_object_disabled_set(sl, mute);
|
||||
}
|
||||
emix_sink_input_mute_set(input, mute);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_sink_input_lock_change(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Sink_Input *input = evas_object_data_get(bxv, "input");
|
||||
Evas_Object *bx = evas_object_data_get(bxv, "volume_bx");
|
||||
Eina_Bool lock = elm_check_state_get(obj);
|
||||
if (lock)
|
||||
VOLSET(input->volume.volumes[0], input->volume,
|
||||
input, emix_sink_input_volume_set);
|
||||
_emix_sink_input_volume_fill(input, bxv, bx, lock);
|
||||
}
|
||||
|
||||
static void
|
||||
_emix_sink_input_volume_fill(Emix_Sink_Input *input, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked)
|
||||
{
|
||||
Evas_Object *bxhv, *lb, *sl, *ck;
|
||||
unsigned int i;
|
||||
Eina_List *sls = NULL;
|
||||
|
||||
eina_list_free(evas_object_data_get(bxv, "volumes"));
|
||||
elm_box_clear(bx);
|
||||
|
||||
bxhv = elm_box_add(bx);
|
||||
evas_object_size_hint_weight_set(bxhv, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(bxhv, EVAS_HINT_FILL, 0.5);
|
||||
elm_box_pack_end(bx, bxhv);
|
||||
evas_object_show(bxhv);
|
||||
|
||||
if (locked)
|
||||
{
|
||||
sl = elm_slider_add(bx);
|
||||
evas_object_data_set(bxv, "volume", sl);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
|
||||
elm_slider_value_set(sl, input->volume.volumes[0]);
|
||||
elm_box_pack_end(bxhv, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed",
|
||||
_cb_sink_input_volume_change, bxv);
|
||||
evas_object_smart_callback_add(sl, "slider,drag,stop",
|
||||
_cb_sink_input_volume_drag_stop, bxv);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < input->volume.channel_count; ++i)
|
||||
{
|
||||
lb = elm_label_add(bx);
|
||||
if (!input->volume.channel_names)
|
||||
{
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "Channel %d", i);
|
||||
elm_object_text_set(lb, buf);
|
||||
}
|
||||
else
|
||||
elm_object_text_set(lb, input->volume.channel_names[i]);
|
||||
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
|
||||
evas_object_size_hint_align_set(lb, 0.0, 0.5);
|
||||
elm_box_pack_end(bxhv, lb);
|
||||
elm_object_disabled_set(lb, input->mute);
|
||||
evas_object_show(lb);
|
||||
|
||||
sl = elm_slider_add(bx);
|
||||
evas_object_data_set(sl, "lb", lb);
|
||||
evas_object_data_set(sl, "channel", (uintptr_t *)(uintptr_t)i);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_slider_value_set(sl, input->volume.volumes[i]);
|
||||
elm_box_pack_end(bxhv, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed",
|
||||
_cb_sink_input_volume_channel_change, bxv);
|
||||
evas_object_smart_callback_add(sl, "slider,drag,stop",
|
||||
_cb_sink_input_volume_channel_drag_stop, bxv);
|
||||
elm_object_disabled_set(sl, input->mute);
|
||||
sls = eina_list_append(sls, sl);
|
||||
}
|
||||
}
|
||||
evas_object_data_set(bxv, "volumes", sls);
|
||||
|
||||
bxhv = elm_box_add(bx);
|
||||
elm_box_pack_end(bx, bxhv);
|
||||
evas_object_show(bxhv);
|
||||
|
||||
ck = elm_check_add(bx);
|
||||
evas_object_data_set(bxv, "mute", ck);
|
||||
elm_object_text_set(ck, "Mute");
|
||||
elm_check_state_set(ck, input->mute);
|
||||
elm_object_disabled_set(sl, input->mute);
|
||||
elm_box_pack_end(bxhv, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed",
|
||||
_cb_sink_input_mute_change, bxv);
|
||||
|
||||
if (input->volume.channel_count > 1)
|
||||
{
|
||||
ck = elm_check_add(bx);
|
||||
evas_object_data_set(bxv, "lock", ck);
|
||||
elm_object_text_set(ck, "Lock");
|
||||
elm_check_state_set(ck, locked);
|
||||
elm_box_pack_end(bxhv, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed",
|
||||
_cb_sink_input_lock_change, bxv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_emix_sink_input_add(Emix_Sink_Input *input)
|
||||
{
|
||||
Evas_Object *bxv, *bx, *lb, *ck, *sl, *hv, *sep;
|
||||
Evas_Object *bxv, *bx, *lb, *hv, *sep;
|
||||
const Eina_List *l;
|
||||
Emix_Sink *sink;
|
||||
Eina_Bool locked = EINA_TRUE;
|
||||
unsigned int i;
|
||||
|
||||
bxv = elm_box_add(win);
|
||||
sink_input_list = eina_list_append(sink_input_list, bxv);
|
||||
|
@ -255,13 +576,13 @@ _emix_sink_input_add(Emix_Sink_Input *input)
|
|||
bx = elm_box_add(win);
|
||||
elm_box_horizontal_set(bx, EINA_TRUE);
|
||||
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
|
||||
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
|
||||
elm_box_pack_end(bxv, bx);
|
||||
evas_object_show(bx);
|
||||
|
||||
lb = elm_label_add(win);
|
||||
elm_object_text_set(lb, input->name);
|
||||
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
|
||||
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(lb, 0.0, 0.5);
|
||||
elm_box_pack_end(bx, lb);
|
||||
evas_object_show(lb);
|
||||
|
@ -283,37 +604,25 @@ _emix_sink_input_add(Emix_Sink_Input *input)
|
|||
evas_object_show(hv);
|
||||
|
||||
bx = elm_box_add(win);
|
||||
evas_object_data_set(bxv, "volume_bx", bx);
|
||||
elm_box_horizontal_set(bx, EINA_TRUE);
|
||||
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
|
||||
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
|
||||
elm_box_pack_end(bxv, bx);
|
||||
evas_object_show(bx);
|
||||
|
||||
sl = elm_slider_add(win);
|
||||
evas_object_data_set(bxv, "volume", sl);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.5);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
|
||||
elm_slider_value_set(sl, input->volume.volumes[0]);
|
||||
elm_box_pack_end(bx, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed",
|
||||
_cb_sink_input_volume_change, bxv);
|
||||
evas_object_smart_callback_add(sl, "slider,drag,stop",
|
||||
_cb_sink_input_volume_drag_stop, bxv);
|
||||
/* Compare each volume level and check if they differ. If they differ unlock
|
||||
the volume control and let user set each channel volume level */
|
||||
for (i = 1; i < input->volume.channel_count; ++i)
|
||||
{
|
||||
if (input->volume.volumes[i - 1] != input->volume.volumes[i])
|
||||
{
|
||||
locked = EINA_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ck = elm_check_add(win);
|
||||
evas_object_data_set(bxv, "mute", ck);
|
||||
elm_object_text_set(ck, "Mute");
|
||||
elm_check_state_set(ck, input->mute);
|
||||
elm_object_disabled_set(sl, input->mute);
|
||||
elm_box_pack_end(bx, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed",
|
||||
_cb_sink_input_mute_change, bxv);
|
||||
_emix_sink_input_volume_fill(input, bxv, bx, locked);
|
||||
|
||||
sep = elm_separator_add(win);
|
||||
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||
|
@ -346,7 +655,8 @@ static void
|
|||
_emix_sink_input_change(Emix_Sink_Input *input)
|
||||
{
|
||||
const Eina_List *l;
|
||||
Evas_Object *bxv, *hv, *ck, *sl;
|
||||
Eina_List *ll;
|
||||
Evas_Object *bxv, *hv, *ck, *sl, *lb;
|
||||
Emix_Sink *sink;
|
||||
|
||||
EINA_LIST_FOREACH(sink_input_list, l, bxv)
|
||||
|
@ -363,15 +673,35 @@ _emix_sink_input_change(Emix_Sink_Input *input)
|
|||
_cb_sink_input_port_change, sink);
|
||||
if (input->sink == sink) elm_object_text_set(hv, sink->name);
|
||||
}
|
||||
sl = evas_object_data_get(bxv, "volume");
|
||||
elm_slider_value_set(sl, input->volume.volumes[0]);
|
||||
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, input->mute);
|
||||
elm_object_disabled_set(sl, input->mute);
|
||||
ck = evas_object_data_get(bxv, "lock");
|
||||
|
||||
if (ck && !elm_check_state_get(ck))
|
||||
{
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, input->mute);
|
||||
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), ll, sl)
|
||||
{
|
||||
elm_slider_value_set(sl,
|
||||
input->volume.volumes[(uintptr_t)evas_object_data_get(sl, "channel")]);
|
||||
elm_object_disabled_set(sl, input->mute);
|
||||
lb = evas_object_data_get(sl, "lb");
|
||||
elm_object_disabled_set(lb, input->mute);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, input->mute);
|
||||
|
||||
sl = evas_object_data_get(bxv, "volume");
|
||||
elm_slider_value_set(sl, input->volume.volumes[0]);
|
||||
elm_object_disabled_set(sl, input->mute);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
static void _emix_source_volume_fill(Emix_Source *source, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked);
|
||||
|
||||
static void
|
||||
_cb_source_volume_change(void *data,
|
||||
|
@ -385,6 +715,20 @@ _cb_source_volume_change(void *data,
|
|||
elm_slider_value_set(obj, vol);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_source_volume_channel_change(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Source *source = evas_object_data_get(bxv, "source");
|
||||
double vol = elm_slider_value_get(obj);
|
||||
source->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")] = vol;
|
||||
elm_slider_value_set(obj, vol);
|
||||
emix_source_volume_set(source, &source->volume);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_cb_source_volume_drag_stop(void *data,
|
||||
Evas_Object *obj,
|
||||
|
@ -396,6 +740,17 @@ _cb_source_volume_drag_stop(void *data,
|
|||
elm_slider_value_set(obj, vol);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_source_volume_channel_drag_stop(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Source *source = evas_object_data_get(bxv, "source");
|
||||
int vol = source->volume.volumes[(uintptr_t)evas_object_data_get(obj, "channel")];
|
||||
elm_slider_value_set(obj, vol);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_source_mute_change(void *data,
|
||||
Evas_Object *obj,
|
||||
|
@ -403,16 +758,153 @@ _cb_source_mute_change(void *data,
|
|||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Source *source = evas_object_data_get(bxv, "source");
|
||||
Evas_Object *sl = evas_object_data_get(bxv, "volume");
|
||||
Evas_Object *sl;
|
||||
Evas_Object *lock = evas_object_data_get(bxv, "lock");
|
||||
Eina_Bool mute = elm_check_state_get(obj);
|
||||
elm_object_disabled_set(sl, mute);
|
||||
Evas_Object *lb;
|
||||
Eina_List *l;
|
||||
|
||||
if (lock && !elm_check_state_get(lock))
|
||||
{
|
||||
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), l, sl)
|
||||
{
|
||||
elm_object_disabled_set(sl, mute);
|
||||
lb = evas_object_data_get(sl, "lb");
|
||||
elm_object_disabled_set(lb, mute);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sl = evas_object_data_get(bxv, "volume");
|
||||
elm_object_disabled_set(sl, mute);
|
||||
}
|
||||
emix_source_mute_set(source, mute);
|
||||
}
|
||||
|
||||
static void
|
||||
_cb_source_lock_change(void *data,
|
||||
Evas_Object *obj,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
Evas_Object *bxv = data;
|
||||
Emix_Source *source = evas_object_data_get(bxv, "source");
|
||||
Evas_Object *bx = evas_object_data_get(bxv, "volume_bx");
|
||||
Eina_Bool lock = elm_check_state_get(obj);
|
||||
if (lock)
|
||||
VOLSET(source->volume.volumes[0], source->volume,
|
||||
source, emix_source_volume_set);
|
||||
_emix_source_volume_fill(source, bxv, bx, lock);
|
||||
}
|
||||
|
||||
static void
|
||||
_emix_source_volume_fill(Emix_Source *source, Evas_Object *bxv, Evas_Object *bx, Eina_Bool locked)
|
||||
{
|
||||
Evas_Object *bxhv, *lb, *sl, *ck;
|
||||
Eina_List *sls = NULL;
|
||||
unsigned int i;
|
||||
|
||||
eina_list_free(evas_object_data_get(bxv, "volumes"));
|
||||
elm_box_clear(bx);
|
||||
|
||||
bxhv = elm_box_add(bx);
|
||||
evas_object_size_hint_weight_set(bxhv, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(bxhv, EVAS_HINT_FILL, 0.5);
|
||||
elm_box_pack_end(bx, bxhv);
|
||||
evas_object_show(bxhv);
|
||||
|
||||
if (locked)
|
||||
{
|
||||
sl = elm_slider_add(bx);
|
||||
evas_object_data_set(bxv, "volume", sl);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_slider_value_set(sl, source->volume.volumes[0]);
|
||||
elm_box_pack_end(bxhv, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed",
|
||||
_cb_source_volume_change, bxv);
|
||||
evas_object_smart_callback_add(sl, "slider,drag,stop",
|
||||
_cb_source_volume_drag_stop, bxv);
|
||||
elm_object_disabled_set(sl, source->mute);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < source->volume.channel_count; ++i)
|
||||
{
|
||||
lb = elm_label_add(bx);
|
||||
if (!source->volume.channel_names)
|
||||
{
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "Channel %d", i);
|
||||
elm_object_text_set(lb, buf);
|
||||
}
|
||||
else
|
||||
elm_object_text_set(lb, source->volume.channel_names[i]);
|
||||
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
|
||||
evas_object_size_hint_align_set(lb, 0.0, 0.5);
|
||||
elm_box_pack_end(bxhv, lb);
|
||||
elm_object_disabled_set(lb, source->mute);
|
||||
evas_object_show(lb);
|
||||
|
||||
sl = elm_slider_add(bx);
|
||||
evas_object_data_set(sl, "lb", lb);
|
||||
evas_object_data_set(sl, "channel", (uintptr_t *)(uintptr_t)i);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_slider_value_set(sl, source->volume.volumes[i]);
|
||||
elm_box_pack_end(bxhv, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed",
|
||||
_cb_source_volume_channel_change, bxv);
|
||||
evas_object_smart_callback_add(sl, "slider,drag,stop",
|
||||
_cb_source_volume_channel_drag_stop, bxv);
|
||||
elm_object_disabled_set(sl, source->mute);
|
||||
sls = eina_list_append(sls, sl);
|
||||
}
|
||||
}
|
||||
evas_object_data_set(bxv, "volumes", sls);
|
||||
|
||||
bxhv = elm_box_add(bx);
|
||||
elm_box_pack_end(bx, bxhv);
|
||||
evas_object_show(bxhv);
|
||||
|
||||
ck = elm_check_add(bx);
|
||||
evas_object_data_set(bxv, "mute", ck);
|
||||
elm_object_text_set(ck, "Mute");
|
||||
elm_check_state_set(ck, source->mute);
|
||||
elm_box_pack_end(bxhv, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed",
|
||||
_cb_source_mute_change, bxv);
|
||||
|
||||
if (source->volume.channel_count > 1)
|
||||
{
|
||||
ck = elm_check_add(bx);
|
||||
evas_object_data_set(bxv, "lock", ck);
|
||||
elm_object_text_set(ck, "Lock");
|
||||
elm_check_state_set(ck, locked);
|
||||
elm_box_pack_end(bxhv, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed",
|
||||
_cb_source_lock_change, bxv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_emix_source_add(Emix_Source *source)
|
||||
{
|
||||
Evas_Object *bxv, *bx, *lb, *ck, *sl, *sep;
|
||||
Evas_Object *bxv, *bx, *lb, *sep;
|
||||
unsigned int i;
|
||||
Eina_Bool locked = EINA_TRUE;
|
||||
|
||||
bxv = elm_box_add(win);
|
||||
source_list = eina_list_append(source_list, bxv);
|
||||
|
@ -429,43 +921,32 @@ _emix_source_add(Emix_Source *source)
|
|||
|
||||
lb = elm_label_add(win);
|
||||
elm_object_text_set(lb, source->name);
|
||||
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.5);
|
||||
evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(lb, 0.0, 0.5);
|
||||
elm_box_pack_end(bx, lb);
|
||||
evas_object_show(lb);
|
||||
|
||||
bx = elm_box_add(win);
|
||||
evas_object_data_set(bxv, "volume_bx", bx);
|
||||
elm_box_horizontal_set(bx, EINA_TRUE);
|
||||
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
|
||||
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.0);
|
||||
evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
|
||||
elm_box_pack_end(bxv, bx);
|
||||
evas_object_show(bx);
|
||||
|
||||
sl = elm_slider_add(win);
|
||||
evas_object_data_set(bxv, "volume", sl);
|
||||
elm_slider_min_max_set(sl, 0.0, emix_max_volume_get());
|
||||
elm_slider_span_size_set(sl, (emix_max_volume_get()) * elm_config_scale_get());
|
||||
elm_slider_unit_format_set(sl, "%1.0f");
|
||||
elm_slider_indicator_format_set(sl, "%1.0f");
|
||||
evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.5);
|
||||
evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
|
||||
elm_slider_value_set(sl, source->volume.volumes[0]);
|
||||
elm_box_pack_end(bx, sl);
|
||||
evas_object_show(sl);
|
||||
evas_object_smart_callback_add(sl, "changed",
|
||||
_cb_source_volume_change, bxv);
|
||||
evas_object_smart_callback_add(sl, "slider,drag,stop",
|
||||
_cb_source_volume_drag_stop, bxv);
|
||||
/* Compare each volume level and check if they differ. If they differ unlock
|
||||
the volume control and let user set each channel volume level */
|
||||
for (i = 1; i < source->volume.channel_count; ++i)
|
||||
{
|
||||
if (source->volume.volumes[i - 1] != source->volume.volumes[i])
|
||||
{
|
||||
locked = EINA_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_emix_source_volume_fill(source, bxv, bx, locked);
|
||||
|
||||
ck = elm_check_add(win);
|
||||
evas_object_data_set(bxv, "mute", ck);
|
||||
elm_object_text_set(ck, "Mute");
|
||||
elm_check_state_set(ck, source->mute);
|
||||
elm_object_disabled_set(sl, source->mute);
|
||||
elm_box_pack_end(bx, ck);
|
||||
evas_object_show(ck);
|
||||
evas_object_smart_callback_add(ck, "changed",
|
||||
_cb_source_mute_change, bxv);
|
||||
|
||||
sep = elm_separator_add(win);
|
||||
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||
|
@ -498,19 +979,39 @@ static void
|
|||
_emix_source_change(Emix_Source *source)
|
||||
{
|
||||
const Eina_List *l;
|
||||
Evas_Object *bxv, *ck, *sl;
|
||||
Eina_List *ll;
|
||||
Evas_Object *bxv, *ck, *sl, *lb;
|
||||
|
||||
EINA_LIST_FOREACH(source_list, l, bxv)
|
||||
{
|
||||
if (evas_object_data_get(bxv, "source") == source) break;
|
||||
}
|
||||
if (!l) return;
|
||||
sl = evas_object_data_get(bxv, "volume");
|
||||
elm_slider_value_set(sl, source->volume.volumes[0]);
|
||||
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, source->mute);
|
||||
elm_object_disabled_set(sl, source->mute);
|
||||
ck = evas_object_data_get(bxv, "lock");
|
||||
|
||||
if (ck && !elm_check_state_get(ck))
|
||||
{
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, source->mute);
|
||||
EINA_LIST_FOREACH(evas_object_data_get(bxv, "volumes"), ll, sl)
|
||||
{
|
||||
elm_slider_value_set(sl,
|
||||
source->volume.volumes[(uintptr_t)evas_object_data_get(sl, "channel")]);
|
||||
elm_object_disabled_set(sl, source->mute);
|
||||
lb = evas_object_data_get(sl, "lb");
|
||||
elm_object_disabled_set(lb, source->mute);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ck = evas_object_data_get(bxv, "mute");
|
||||
elm_check_state_set(ck, source->mute);
|
||||
|
||||
sl = evas_object_data_get(bxv, "volume");
|
||||
elm_slider_value_set(sl, source->volume.volumes[0]);
|
||||
elm_object_disabled_set(sl, source->mute);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -158,7 +158,7 @@ _volume_increase_cb(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
|
|||
volume.volumes[i] = s->volume.volumes[i];
|
||||
}
|
||||
|
||||
emix_sink_volume_set(s, volume);
|
||||
emix_sink_volume_set(s, &volume);
|
||||
emix_config_save_state_get();
|
||||
if (emix_config_save_get()) e_config_save_queue();
|
||||
free(volume.volumes);
|
||||
|
@ -184,7 +184,7 @@ _volume_decrease_cb(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
|
|||
volume.volumes[i] = s->volume.volumes[i];
|
||||
}
|
||||
|
||||
emix_sink_volume_set((Emix_Sink *)_sink_default, volume);
|
||||
emix_sink_volume_set((Emix_Sink *)_sink_default, &volume);
|
||||
emix_config_save_state_get();
|
||||
if (emix_config_save_get()) e_config_save_queue();
|
||||
free(volume.volumes);
|
||||
|
|
|
@ -408,25 +408,25 @@ _alsa_sources_mute_set(Emix_Source *source, Eina_Bool mute)
|
|||
}
|
||||
|
||||
static void
|
||||
_alsa_sources_volume_set(Emix_Source *source, Emix_Volume v)
|
||||
_alsa_sources_volume_set(Emix_Source *source, Emix_Volume *v)
|
||||
{
|
||||
Alsa_Emix_Source *s = (Alsa_Emix_Source*) source;
|
||||
unsigned int i;
|
||||
snd_mixer_elem_t *elem;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN((ctx && source));
|
||||
EINA_SAFETY_ON_FALSE_RETURN((ctx && source && v));
|
||||
|
||||
if (v.channel_count != eina_list_count(s->channels))
|
||||
if (v->channel_count != eina_list_count(s->channels))
|
||||
{
|
||||
ERR("Volume struct doesn't have the same length than the channels");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < v.channel_count; i++ )
|
||||
for (i = 0; i < v->channel_count; i++ )
|
||||
{
|
||||
elem = eina_list_nth(s->channels, i);
|
||||
_alsa_channel_volume_set(elem, v.volumes[i], EINA_FALSE);
|
||||
s->source.volume.volumes[i] = v.volumes[i];
|
||||
_alsa_channel_volume_set(elem, v->volumes[i], EINA_FALSE);
|
||||
s->source.volume.volumes[i] = v->volumes[i];
|
||||
}
|
||||
if (ctx->cb)
|
||||
ctx->cb((void *)ctx->userdata, EMIX_SOURCE_CHANGED_EVENT,
|
||||
|
@ -480,25 +480,25 @@ _alsa_sink_mute_set(Emix_Sink *sink, Eina_Bool mute)
|
|||
}
|
||||
|
||||
static void
|
||||
_alsa_sink_volume_set(Emix_Sink *sink, Emix_Volume v)
|
||||
_alsa_sink_volume_set(Emix_Sink *sink, Emix_Volume *v)
|
||||
{
|
||||
Alsa_Emix_Sink *s = (Alsa_Emix_Sink *)sink;
|
||||
unsigned int i;
|
||||
snd_mixer_elem_t *elem;
|
||||
|
||||
EINA_SAFETY_ON_FALSE_RETURN((ctx && sink));
|
||||
EINA_SAFETY_ON_FALSE_RETURN((ctx && sink && v));
|
||||
|
||||
if (v.channel_count != eina_list_count(s->channels))
|
||||
if (v->channel_count != eina_list_count(s->channels))
|
||||
{
|
||||
ERR("Volume struct doesn't have the same length than the channels");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < v.channel_count; i++ )
|
||||
for (i = 0; i < v->channel_count; i++ )
|
||||
{
|
||||
elem = eina_list_nth(s->channels, i);
|
||||
_alsa_channel_volume_set(elem, v.volumes[i], EINA_FALSE);
|
||||
s->sink.volume.volumes[i] = v.volumes[i];
|
||||
_alsa_channel_volume_set(elem, v->volumes[i], EINA_FALSE);
|
||||
s->sink.volume.volumes[i] = v->volumes[i];
|
||||
}
|
||||
if (ctx->cb)
|
||||
ctx->cb((void *)ctx->userdata, EMIX_SINK_CHANGED_EVENT,
|
||||
|
|
|
@ -66,14 +66,14 @@ static Context *ctx = NULL;
|
|||
extern pa_mainloop_api functable;
|
||||
|
||||
static pa_cvolume
|
||||
_emix_volume_convert(const Emix_Volume volume)
|
||||
_emix_volume_convert(const Emix_Volume *volume)
|
||||
{
|
||||
pa_cvolume vol;
|
||||
unsigned int i;
|
||||
|
||||
vol.channels = volume.channel_count;
|
||||
for (i = 0; i < volume.channel_count; i++)
|
||||
vol.values[i] = INT_TO_PA_VOLUME(volume.volumes[i]);
|
||||
vol.channels = volume->channel_count;
|
||||
for (i = 0; i < volume->channel_count; i++)
|
||||
vol.values[i] = INT_TO_PA_VOLUME(volume->volumes[i]);
|
||||
return vol;
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,7 @@ _pa_cvolume_convert(const pa_cvolume *volume, Emix_Volume *vol)
|
|||
static void
|
||||
_sink_del(Sink *sink)
|
||||
{
|
||||
unsigned int i;
|
||||
Emix_Port *port;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(sink);
|
||||
|
@ -109,6 +110,9 @@ _sink_del(Sink *sink)
|
|||
}
|
||||
|
||||
free(sink->base.volume.volumes);
|
||||
for(i = 0; i < sink->base.volume.channel_count; ++i)
|
||||
eina_stringshare_del(sink->base.volume.channel_names[i]);
|
||||
free(sink->base.volume.channel_names);
|
||||
eina_stringshare_del(sink->base.name);
|
||||
free(sink);
|
||||
}
|
||||
|
@ -116,9 +120,13 @@ _sink_del(Sink *sink)
|
|||
static void
|
||||
_sink_input_del(Sink_Input *input)
|
||||
{
|
||||
unsigned int i;
|
||||
EINA_SAFETY_ON_NULL_RETURN(input);
|
||||
|
||||
free(input->base.volume.volumes);
|
||||
for(i = 0; i < input->base.volume.channel_count; ++i)
|
||||
eina_stringshare_del(input->base.volume.channel_names[i]);
|
||||
free(input->base.volume.channel_names);
|
||||
eina_stringshare_del(input->base.name);
|
||||
eina_stringshare_del(input->icon);
|
||||
free(input);
|
||||
|
@ -127,9 +135,13 @@ _sink_input_del(Sink_Input *input)
|
|||
static void
|
||||
_source_del(Source *source)
|
||||
{
|
||||
unsigned int i;
|
||||
EINA_SAFETY_ON_NULL_RETURN(source);
|
||||
|
||||
free(source->base.volume.volumes);
|
||||
for(i = 0; i < source->base.volume.channel_count; ++i)
|
||||
eina_stringshare_del(source->base.volume.channel_names[i]);
|
||||
free(source->base.volume.channel_names);
|
||||
eina_stringshare_del(source->base.name);
|
||||
free(source);
|
||||
}
|
||||
|
@ -177,6 +189,9 @@ _sink_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
|
|||
sink->idx = info->index;
|
||||
sink->base.name = eina_stringshare_add(info->description);
|
||||
_pa_cvolume_convert(&info->volume, &sink->base.volume);
|
||||
sink->base.volume.channel_names = calloc(sink->base.volume.channel_count, sizeof(Emix_Channel));
|
||||
for (i = 0; i < sink->base.volume.channel_count; ++i)
|
||||
sink->base.volume.channel_names[i] = eina_stringshare_add(pa_channel_position_to_pretty_string(info->channel_map.map[i]));
|
||||
sink->base.mute = !!info->mute;
|
||||
|
||||
for (i = 0; i < info->n_ports; i++)
|
||||
|
@ -238,7 +253,18 @@ _sink_changed_cb(pa_context *c EINA_UNUSED, const pa_sink_info *info, int eol,
|
|||
EINA_SAFETY_ON_NULL_RETURN(sink);
|
||||
|
||||
eina_stringshare_replace(&sink->base.name, info->description);
|
||||
|
||||
if (sink->base.volume.channel_count != info->volume.channels)
|
||||
{
|
||||
for (i = 0; i < sink->base.volume.channel_count; ++i)
|
||||
eina_stringshare_del(sink->base.volume.channel_names[i]);
|
||||
free(sink->base.volume.channel_names);
|
||||
sink->base.volume.channel_names = calloc(info->volume.channels, sizeof(Emix_Channel));
|
||||
}
|
||||
_pa_cvolume_convert(&info->volume, &sink->base.volume);
|
||||
for (i = 0; i < sink->base.volume.channel_count; ++i)
|
||||
eina_stringshare_replace(&sink->base.volume.channel_names[i],
|
||||
pa_channel_position_to_pretty_string(info->channel_map.map[i]));
|
||||
sink->base.mute = !!info->mute;
|
||||
|
||||
if (sink->base.ports)
|
||||
|
@ -335,6 +361,7 @@ _sink_input_cb(pa_context *c EINA_UNUSED, const pa_sink_input_info *info,
|
|||
Eina_List *l;
|
||||
Sink *s;
|
||||
const char *t;
|
||||
unsigned int i;
|
||||
EINA_SAFETY_ON_NULL_RETURN(ctx);
|
||||
|
||||
if (eol < 0)
|
||||
|
@ -374,6 +401,9 @@ _sink_input_cb(pa_context *c EINA_UNUSED, const pa_sink_input_info *info,
|
|||
input->base.name = eina_stringshare_add(eina_strbuf_string_get(input_name));
|
||||
eina_strbuf_free(input_name);
|
||||
_pa_cvolume_convert(&info->volume, &input->base.volume);
|
||||
input->base.volume.channel_names = calloc(input->base.volume.channel_count, sizeof(Emix_Channel));
|
||||
for (i = 0; i < input->base.volume.channel_count; ++i)
|
||||
input->base.volume.channel_names[i] = eina_stringshare_add(pa_channel_position_to_pretty_string(info->channel_map.map[i]));
|
||||
input->base.mute = !!info->mute;
|
||||
EINA_LIST_FOREACH(ctx->sinks, l, s)
|
||||
{
|
||||
|
@ -398,10 +428,11 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
|
|||
const pa_sink_input_info *info, int eol,
|
||||
void *userdata EINA_UNUSED)
|
||||
{
|
||||
Sink_Input *input = NULL, *i;
|
||||
Sink_Input *input = NULL, *si;
|
||||
Sink *s = NULL;
|
||||
Eina_List *l;
|
||||
const char *t;
|
||||
unsigned int i;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(ctx);
|
||||
if (eol < 0)
|
||||
|
@ -416,11 +447,11 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
|
|||
if (eol > 0)
|
||||
return;
|
||||
|
||||
EINA_LIST_FOREACH(ctx->inputs, l, i)
|
||||
EINA_LIST_FOREACH(ctx->inputs, l, si)
|
||||
{
|
||||
if (i->idx == (int)info->index)
|
||||
if (si->idx == (int)info->index)
|
||||
{
|
||||
input = i;
|
||||
input = si;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +465,18 @@ _sink_input_changed_cb(pa_context *c EINA_UNUSED,
|
|||
ctx->inputs = eina_list_append(ctx->inputs, input);
|
||||
}
|
||||
input->idx = info->index;
|
||||
if (input->base.volume.channel_count != info->volume.channels)
|
||||
{
|
||||
for (i = 0; i < input->base.volume.channel_count; ++i)
|
||||
eina_stringshare_del(input->base.volume.channel_names[i]);
|
||||
free(input->base.volume.channel_names);
|
||||
input->base.volume.channel_names = calloc(info->volume.channels, sizeof(Emix_Channel));
|
||||
}
|
||||
_pa_cvolume_convert(&info->volume, &input->base.volume);
|
||||
for (i = 0; i < input->base.volume.channel_count; ++i)
|
||||
eina_stringshare_replace(&input->base.volume.channel_names[i],
|
||||
pa_channel_position_to_pretty_string(info->channel_map.map[i]));
|
||||
|
||||
input->base.mute = !!info->mute;
|
||||
|
||||
EINA_LIST_FOREACH(ctx->sinks, l, s)
|
||||
|
@ -482,6 +524,7 @@ _source_cb(pa_context *c EINA_UNUSED, const pa_source_info *info,
|
|||
int eol, void *userdata EINA_UNUSED)
|
||||
{
|
||||
Source *source;
|
||||
unsigned int i;
|
||||
EINA_SAFETY_ON_NULL_RETURN(ctx);
|
||||
|
||||
if (eol < 0)
|
||||
|
@ -502,6 +545,9 @@ _source_cb(pa_context *c EINA_UNUSED, const pa_source_info *info,
|
|||
source->idx = info->index;
|
||||
source->base.name = eina_stringshare_add(info->name);
|
||||
_pa_cvolume_convert(&info->volume, &source->base.volume);
|
||||
source->base.volume.channel_names = calloc(source->base.volume.channel_count, sizeof(Emix_Channel));
|
||||
for (i = 0; i < source->base.volume.channel_count; ++i)
|
||||
source->base.volume.channel_names[i] = eina_stringshare_add(pa_channel_position_to_pretty_string(info->channel_map.map[i]));
|
||||
source->base.mute = !!info->mute;
|
||||
|
||||
ctx->sources = eina_list_append(ctx->sources, source);
|
||||
|
@ -517,6 +563,7 @@ _source_changed_cb(pa_context *c EINA_UNUSED,
|
|||
{
|
||||
Source *source = NULL, *s;
|
||||
Eina_List *l;
|
||||
unsigned int i;
|
||||
EINA_SAFETY_ON_NULL_RETURN(ctx);
|
||||
|
||||
if (eol < 0)
|
||||
|
@ -549,7 +596,17 @@ _source_changed_cb(pa_context *c EINA_UNUSED,
|
|||
ctx->sources = eina_list_append(ctx->sources, source);
|
||||
}
|
||||
source->idx= info->index;
|
||||
if (source->base.volume.channel_count != info->volume.channels)
|
||||
{
|
||||
for (i = 0; i < source->base.volume.channel_count; ++i)
|
||||
eina_stringshare_del(source->base.volume.channel_names[i]);
|
||||
free(source->base.volume.channel_names);
|
||||
source->base.volume.channel_names = calloc(info->volume.channels, sizeof(Emix_Channel));
|
||||
}
|
||||
_pa_cvolume_convert(&info->volume, &source->base.volume);
|
||||
for (i = 0; i < source->base.volume.channel_count; ++i)
|
||||
eina_stringshare_replace(&source->base.volume.channel_names[i],
|
||||
pa_channel_position_to_pretty_string(info->channel_map.map[i]));
|
||||
source->base.mute = !!info->mute;
|
||||
|
||||
if (ctx->cb)
|
||||
|
@ -1164,7 +1221,7 @@ _disconnect_cb()
|
|||
}
|
||||
|
||||
static void
|
||||
_source_volume_set(Emix_Source *source, Emix_Volume volume)
|
||||
_source_volume_set(Emix_Source *source, Emix_Volume *volume)
|
||||
{
|
||||
pa_operation* o;
|
||||
pa_cvolume vol = _emix_volume_convert(volume);
|
||||
|
@ -1211,7 +1268,7 @@ _sink_inputs_get(void)
|
|||
}
|
||||
|
||||
static void
|
||||
_sink_volume_set(Emix_Sink *sink, Emix_Volume volume)
|
||||
_sink_volume_set(Emix_Sink *sink, Emix_Volume *volume)
|
||||
{
|
||||
pa_operation* o;
|
||||
Sink *s = (Sink *)sink;
|
||||
|
@ -1236,7 +1293,7 @@ _sink_mute_set(Emix_Sink *sink, Eina_Bool mute)
|
|||
}
|
||||
|
||||
static void
|
||||
_sink_input_volume_set(Emix_Sink_Input *input, Emix_Volume volume)
|
||||
_sink_input_volume_set(Emix_Sink_Input *input, Emix_Volume *volume)
|
||||
{
|
||||
pa_operation* o;
|
||||
Sink_Input *sink_input = (Sink_Input *)input;
|
||||
|
|
|
@ -282,7 +282,7 @@ emix_sink_mute_set(Emix_Sink *sink, Eina_Bool mute)
|
|||
}
|
||||
|
||||
void
|
||||
emix_sink_volume_set(Emix_Sink *sink, Emix_Volume volume)
|
||||
emix_sink_volume_set(Emix_Sink *sink, Emix_Volume *volume)
|
||||
{
|
||||
EINA_SAFETY_ON_FALSE_RETURN((ctx && ctx->loaded &&
|
||||
ctx->loaded->ebackend_sink_volume_set &&
|
||||
|
@ -320,7 +320,7 @@ emix_sink_input_mute_set(Emix_Sink_Input *input, Eina_Bool mute)
|
|||
}
|
||||
|
||||
void
|
||||
emix_sink_input_volume_set(Emix_Sink_Input *input, Emix_Volume volume)
|
||||
emix_sink_input_volume_set(Emix_Sink_Input *input, Emix_Volume *volume)
|
||||
{
|
||||
EINA_SAFETY_ON_FALSE_RETURN((ctx && ctx->loaded &&
|
||||
ctx->loaded->ebackend_sink_input_volume_set &&
|
||||
|
@ -359,7 +359,7 @@ emix_source_mute_set(Emix_Source *source, Eina_Bool mute)
|
|||
}
|
||||
|
||||
void
|
||||
emix_source_volume_set(Emix_Source *source, Emix_Volume volume)
|
||||
emix_source_volume_set(Emix_Source *source, Emix_Volume *volume)
|
||||
{
|
||||
EINA_SAFETY_ON_FALSE_RETURN((ctx && ctx->loaded &&
|
||||
ctx->loaded->ebackend_source_volume_set &&
|
||||
|
|
|
@ -42,10 +42,13 @@ enum Emix_Event {
|
|||
EMIX_CARD_CHANGED_EVENT
|
||||
};
|
||||
|
||||
typedef const char * Emix_Channel;
|
||||
|
||||
typedef struct _Emix_Volume {
|
||||
unsigned int channel_count;
|
||||
// the index of the field is the id of the channel, the value the volume
|
||||
int *volumes;
|
||||
Emix_Channel *channel_names;
|
||||
} Emix_Volume;
|
||||
|
||||
typedef struct _Emix_Port {
|
||||
|
@ -104,7 +107,7 @@ typedef struct _Emix_Backend {
|
|||
void (*ebackend_sink_mute_set)(Emix_Sink *sink,
|
||||
Eina_Bool mute);
|
||||
void (*ebackend_sink_volume_set)(Emix_Sink *sink,
|
||||
Emix_Volume volume);
|
||||
Emix_Volume *volume);
|
||||
Eina_Bool (*ebackend_sink_port_set)(Emix_Sink *sink,
|
||||
const Emix_Port *port);
|
||||
Eina_Bool (*ebackend_sink_change_support)(void);
|
||||
|
@ -113,7 +116,7 @@ typedef struct _Emix_Backend {
|
|||
void (*ebackend_sink_input_mute_set)(
|
||||
Emix_Sink_Input *input, Eina_Bool mute);
|
||||
void (*ebackend_sink_input_volume_set)(
|
||||
Emix_Sink_Input *input, Emix_Volume volume);
|
||||
Emix_Sink_Input *input, Emix_Volume *volume);
|
||||
void (*ebackend_sink_input_sink_change)(
|
||||
Emix_Sink_Input *input, Emix_Sink *sink);
|
||||
|
||||
|
@ -121,7 +124,7 @@ typedef struct _Emix_Backend {
|
|||
void (*ebackend_source_mute_set)(Emix_Source *source,
|
||||
Eina_Bool mute);
|
||||
void (*ebackend_source_volume_set)(Emix_Source *source,
|
||||
Emix_Volume volume);
|
||||
Emix_Volume *volume);
|
||||
|
||||
Evas_Object* (*ebackend_advanced_options_add)(Evas_Object *parent);
|
||||
const Eina_List* (*ebackend_cards_get)(void);
|
||||
|
@ -132,17 +135,13 @@ typedef struct _Emix_Backend {
|
|||
|
||||
#define VOLSET(vol, srcvol, target, func) \
|
||||
do { \
|
||||
Emix_Volume _v; \
|
||||
int _pvol = srcvol.volumes[0]; \
|
||||
if ((_pvol > 80) && (_pvol <= 100) && \
|
||||
(vol > 100) && (vol < 120)) vol = 100; \
|
||||
_v.channel_count = srcvol.channel_count; \
|
||||
_v.volumes = calloc(srcvol.channel_count, sizeof(int)); \
|
||||
if (_v.volumes) { \
|
||||
if (srcvol.volumes) { \
|
||||
unsigned int _i; \
|
||||
for (_i = 0; _i < _v.channel_count; _i++) _v.volumes[_i] = vol; \
|
||||
func(target, _v); \
|
||||
free(_v.volumes); \
|
||||
for (_i = 0; _i < srcvol.channel_count; _i++) srcvol.volumes[_i] = vol; \
|
||||
func(target, &srcvol); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -167,14 +166,14 @@ E_API Eina_Bool emix_sink_port_set(Emix_Sink *sink, Emix_Port *port);
|
|||
E_API void emix_sink_default_set(Emix_Sink *sink);
|
||||
E_API void emix_sink_mute_set(Emix_Sink *sink, Eina_Bool mute);
|
||||
E_API void emix_sink_volume_set(Emix_Sink *sink,
|
||||
Emix_Volume volume);
|
||||
Emix_Volume *volume);
|
||||
E_API Eina_Bool emix_sink_change_support(void);
|
||||
|
||||
E_API const Eina_List* emix_sink_inputs_get(void);
|
||||
E_API void emix_sink_input_mute_set(Emix_Sink_Input *input,
|
||||
Eina_Bool mute);
|
||||
E_API void emix_sink_input_volume_set(Emix_Sink_Input *input,
|
||||
Emix_Volume volume);
|
||||
Emix_Volume *volume);
|
||||
E_API void emix_sink_input_sink_change(Emix_Sink_Input *input,
|
||||
Emix_Sink *sink);
|
||||
|
||||
|
@ -182,7 +181,7 @@ E_API const Eina_List* emix_sources_get(void);
|
|||
E_API void emix_source_mute_set(Emix_Source *source,
|
||||
Eina_Bool mute);
|
||||
E_API void emix_source_volume_set(Emix_Source *source,
|
||||
Emix_Volume volume);
|
||||
Emix_Volume *volume);
|
||||
E_API Evas_Object* emix_advanced_options_add(Evas_Object *parent);
|
||||
|
||||
E_API const Eina_List* emix_cards_get(void);
|
||||
|
|
Loading…
Reference in New Issue