forked from enlightenment/enlightenment
Add mixer module.
This is the mixer modules as in: git://staff.get-e.org/users/barbieri/e_module-mixer.git it's being used with ALSA backend for some time without problems and it's ready for inclusion. We still lack OSS4 engine. SVN revision: 35282
This commit is contained in:
parent
d6badc27c2
commit
c28047e3a1
31
configure.in
31
configure.in
|
@ -262,6 +262,35 @@ AC_SUBST(edje_cc)
|
||||||
AC_DEFINE(E_INTERNAL, 1, "This define can be used to wrap internal E stuff, as config.h isn't exported")
|
AC_DEFINE(E_INTERNAL, 1, "This define can be used to wrap internal E stuff, as config.h isn't exported")
|
||||||
|
|
||||||
|
|
||||||
|
dnl Check for Alsa
|
||||||
|
AC_ARG_ENABLE(alsa, AS_HELP_STRING([--enable-alsa],
|
||||||
|
[enable support for alsa(default=autodetect)]),
|
||||||
|
[ enable_alsa=$enableval ], [ enable_alsa=default ])
|
||||||
|
|
||||||
|
AM_CONDITIONAL(HAVE_ALSA, false)
|
||||||
|
if test "x$enable_alsa" = "xdefault" || test "x$enable_alsa" = "xyes"; then
|
||||||
|
PKG_CHECK_MODULES(ALSA, [alsa >= 1.0.8],
|
||||||
|
[ SOUND_CFLAGS="$ALSA_CFLAGS -DHAVE_ALSA $SOUND_CFLAGS"
|
||||||
|
SOUND_LDFLAGS="$ALSA_LIBS $SOUND_LDFLAGS"
|
||||||
|
AM_CONDITIONAL(HAVE_ALSA, true)
|
||||||
|
have_alsa=yes ],
|
||||||
|
[ if test "x$enable_alsa" = "xyes"; then
|
||||||
|
AC_MSG_ERROR([alsa library >= 1.0.8 not found])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
else
|
||||||
|
have_alsa=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$have_alsa" = "yes"; then
|
||||||
|
AC_DEFINE(HAVE_ALSA, 1, [Define if the ALSA output plugin should be built])
|
||||||
|
else
|
||||||
|
have_alsa=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(SOUND_CFLAGS)
|
||||||
|
AC_SUBST(SOUND_LDFLAGS)
|
||||||
|
|
||||||
AC_OUTPUT([
|
AC_OUTPUT([
|
||||||
Makefile
|
Makefile
|
||||||
enlightenment.spec
|
enlightenment.spec
|
||||||
|
@ -375,6 +404,8 @@ src/modules/conf_interaction/Makefile
|
||||||
src/modules/conf_interaction/module.desktop
|
src/modules/conf_interaction/module.desktop
|
||||||
src/modules/gadman/Makefile
|
src/modules/gadman/Makefile
|
||||||
src/modules/gadman/module.desktop
|
src/modules/gadman/module.desktop
|
||||||
|
src/modules/mixer/Makefile
|
||||||
|
src/modules/mixer/module.desktop
|
||||||
src/preload/Makefile
|
src/preload/Makefile
|
||||||
data/Makefile
|
data/Makefile
|
||||||
data/fonts/Makefile
|
data/fonts/Makefile
|
||||||
|
|
|
@ -62,7 +62,8 @@ default_deskpreview.edc \
|
||||||
default_fontpreview.edc \
|
default_fontpreview.edc \
|
||||||
default_wizard.edc \
|
default_wizard.edc \
|
||||||
default_toolbar.edc \
|
default_toolbar.edc \
|
||||||
default_slidesel.edc
|
default_slidesel.edc \
|
||||||
|
default_mixer.edc
|
||||||
|
|
||||||
default.edj: Makefile $(EXTRA_DIST)
|
default.edj: Makefile $(EXTRA_DIST)
|
||||||
$(EDJE_CC) $(EDJE_FLAGS) \
|
$(EDJE_CC) $(EDJE_FLAGS) \
|
||||||
|
|
|
@ -86,4 +86,5 @@ collections {
|
||||||
#include "default_wizard.edc"
|
#include "default_wizard.edc"
|
||||||
#include "default_toolbar.edc"
|
#include "default_toolbar.edc"
|
||||||
#include "default_slidesel.edc"
|
#include "default_slidesel.edc"
|
||||||
|
#include "default_mixer.edc"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
images {
|
||||||
|
image: "e17_mixer_base.png" COMP;
|
||||||
|
image: "e17_mixer_mute.png" COMP;
|
||||||
|
image: "e17_mixer_left_low.png" COMP;
|
||||||
|
image: "e17_mixer_left_medium.png" COMP;
|
||||||
|
image: "e17_mixer_left_high.png" COMP;
|
||||||
|
image: "e17_mixer_right_low.png" COMP;
|
||||||
|
image: "e17_mixer_right_medium.png" COMP;
|
||||||
|
image: "e17_mixer_right_high.png" COMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
group {
|
||||||
|
name: "e/modules/mixer/main";
|
||||||
|
max: 128 128;
|
||||||
|
min: 1 1;
|
||||||
|
|
||||||
|
script {
|
||||||
|
public message(Msg_Type:type, id, ...) {
|
||||||
|
if ((type == MSG_INT_SET) && (id == 0)) {
|
||||||
|
new mute, left, right;
|
||||||
|
|
||||||
|
mute = getarg(2);
|
||||||
|
left = getarg(3);
|
||||||
|
right = getarg(4);
|
||||||
|
|
||||||
|
if (mute)
|
||||||
|
run_program(PROGRAM:"mute");
|
||||||
|
else
|
||||||
|
run_program(PROGRAM:"unmute");
|
||||||
|
|
||||||
|
if (left <= 0)
|
||||||
|
run_program(PROGRAM:"left_none");
|
||||||
|
else if (left < 33)
|
||||||
|
run_program(PROGRAM:"left_low");
|
||||||
|
else if (left < 66)
|
||||||
|
run_program(PROGRAM:"left_medium");
|
||||||
|
else if (left >= 66)
|
||||||
|
run_program(PROGRAM:"left_high");
|
||||||
|
|
||||||
|
if (right <= 0)
|
||||||
|
run_program(PROGRAM:"right_none");
|
||||||
|
else if (right < 33)
|
||||||
|
run_program(PROGRAM:"right_low");
|
||||||
|
else if (right < 66)
|
||||||
|
run_program(PROGRAM:"right_medium");
|
||||||
|
else if (right >= 66)
|
||||||
|
run_program(PROGRAM:"right_high");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parts {
|
||||||
|
part {
|
||||||
|
name: "base";
|
||||||
|
mouse_events: 0;
|
||||||
|
type: RECT;
|
||||||
|
description {
|
||||||
|
state: "default" 0.0;
|
||||||
|
color: 255 255 255 0;
|
||||||
|
aspect: 1 1;
|
||||||
|
aspect_preference: BOTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part {
|
||||||
|
name: "speaker";
|
||||||
|
mouse_events: 0;
|
||||||
|
type: IMAGE;
|
||||||
|
description {
|
||||||
|
state: "default" 0.0;
|
||||||
|
aspect: 1 1;
|
||||||
|
aspect_preference: BOTH;
|
||||||
|
rel1.to: "base";
|
||||||
|
rel2.to: "base";
|
||||||
|
image.normal: "e17_mixer_base.png";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part {
|
||||||
|
name: "left";
|
||||||
|
mouse_events: 0;
|
||||||
|
type: IMAGE;
|
||||||
|
description {
|
||||||
|
state: "default" 0.0;
|
||||||
|
visible: 0;
|
||||||
|
aspect: 1 1;
|
||||||
|
aspect_preference: BOTH;
|
||||||
|
rel1.to: "base";
|
||||||
|
rel2.to: "base";
|
||||||
|
image.normal: "e17_mixer_left_low.png";
|
||||||
|
}
|
||||||
|
description {
|
||||||
|
state: "low" 0.0;
|
||||||
|
inherit: "default" 0.0;
|
||||||
|
visible: 1;
|
||||||
|
}
|
||||||
|
description {
|
||||||
|
state: "medium" 0.0;
|
||||||
|
inherit: "default" 0.0;
|
||||||
|
visible: 1;
|
||||||
|
image.normal: "e17_mixer_left_medium.png";
|
||||||
|
}
|
||||||
|
description {
|
||||||
|
state: "high" 0.0;
|
||||||
|
inherit: "default" 0.0;
|
||||||
|
visible: 1;
|
||||||
|
image.normal: "e17_mixer_left_high.png";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part {
|
||||||
|
name: "right";
|
||||||
|
mouse_events: 0;
|
||||||
|
type: IMAGE;
|
||||||
|
description {
|
||||||
|
state: "default" 0.0;
|
||||||
|
visible: 0;
|
||||||
|
aspect: 1 1;
|
||||||
|
aspect_preference: BOTH;
|
||||||
|
rel1.to: "base";
|
||||||
|
rel2.to: "base";
|
||||||
|
image.normal: "e17_mixer_right_low.png";
|
||||||
|
}
|
||||||
|
description {
|
||||||
|
state: "low" 0.0;
|
||||||
|
inherit: "default" 0.0;
|
||||||
|
visible: 1;
|
||||||
|
}
|
||||||
|
description {
|
||||||
|
state: "medium" 0.0;
|
||||||
|
inherit: "default" 0.0;
|
||||||
|
visible: 1;
|
||||||
|
image.normal: "e17_mixer_right_medium.png";
|
||||||
|
}
|
||||||
|
description {
|
||||||
|
state: "high" 0.0;
|
||||||
|
inherit: "default" 0.0;
|
||||||
|
visible: 1;
|
||||||
|
image.normal: "e17_mixer_right_high.png";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part {
|
||||||
|
name: "mute";
|
||||||
|
mouse_events: 0;
|
||||||
|
type: IMAGE;
|
||||||
|
description {
|
||||||
|
state: "default" 0.0;
|
||||||
|
aspect: 1 1;
|
||||||
|
aspect_preference: BOTH;
|
||||||
|
visible: 0;
|
||||||
|
rel1.to: "base";
|
||||||
|
rel2.to: "base";
|
||||||
|
image.normal: "e17_mixer_mute.png";
|
||||||
|
}
|
||||||
|
description {
|
||||||
|
state: "active" 0.0;
|
||||||
|
inherit: "default" 0.0;
|
||||||
|
visible: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part {
|
||||||
|
name: "over";
|
||||||
|
type: RECT;
|
||||||
|
description {
|
||||||
|
state: "default" 0.0;
|
||||||
|
rel1.to: "base";
|
||||||
|
rel2.to: "base";
|
||||||
|
color: 255 255 255 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
programs {
|
||||||
|
program {
|
||||||
|
name: "mute";
|
||||||
|
action: STATE_SET "active" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "mute";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "unmute";
|
||||||
|
action: STATE_SET "default" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "mute";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "left_none";
|
||||||
|
action: STATE_SET "default" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "left";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "left_low";
|
||||||
|
action: STATE_SET "low" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "left";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "left_medium";
|
||||||
|
action: STATE_SET "medium" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "left";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "left_high";
|
||||||
|
action: STATE_SET "high" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "left";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "right_none";
|
||||||
|
action: STATE_SET "default" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "right";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "right_low";
|
||||||
|
action: STATE_SET "low" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "right";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "right_medium";
|
||||||
|
action: STATE_SET "medium" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "right";
|
||||||
|
}
|
||||||
|
|
||||||
|
program {
|
||||||
|
name: "right_high";
|
||||||
|
action: STATE_SET "high" 0.0;
|
||||||
|
transition: LINEAR 0.1;
|
||||||
|
target: "right";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -51,6 +51,7 @@ conf_paths \
|
||||||
conf_mime \
|
conf_mime \
|
||||||
conf_interaction \
|
conf_interaction \
|
||||||
gadman \
|
gadman \
|
||||||
|
mixer \
|
||||||
conf_window_remembers
|
conf_window_remembers
|
||||||
|
|
||||||
if HAVE_TEMPERATURE
|
if HAVE_TEMPERATURE
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
MODULE = mixer
|
||||||
|
|
||||||
|
# data files for the module
|
||||||
|
filesdir = $(libdir)/enlightenment/modules/$(MODULE)
|
||||||
|
files_DATA = e-module-$(MODULE).edj module.desktop
|
||||||
|
|
||||||
|
EXTRA_DIST = $(files_DATA)
|
||||||
|
|
||||||
|
# the module .so file
|
||||||
|
INCLUDES = -I. \
|
||||||
|
-I$(top_srcdir) \
|
||||||
|
-I$(top_srcdir)/src/modules/$(MODULE) \
|
||||||
|
-I$(top_srcdir)/src/bin \
|
||||||
|
-I$(top_srcdir)/src/lib \
|
||||||
|
-I$(top_srcdir)/src/modules \
|
||||||
|
@e_cflags@ @SOUND_CFLAGS@
|
||||||
|
pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH)
|
||||||
|
pkg_LTLIBRARIES = module.la
|
||||||
|
|
||||||
|
module_la_SOURCES = e_mod_main.h \
|
||||||
|
e_mod_main.c \
|
||||||
|
e_mod_system.h \
|
||||||
|
conf_gadget.c \
|
||||||
|
conf_module.c \
|
||||||
|
app_mixer.c
|
||||||
|
|
||||||
|
if HAVE_ALSA
|
||||||
|
module_la_SOURCES += sys_alsa.c
|
||||||
|
else
|
||||||
|
module_la_SOURCES += sys_dummy.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
module_la_LIBADD = @SOUND_LDFLAGS@ @e_libs@ @dlopen_libs@
|
||||||
|
module_la_LDFLAGS = -module -avoid-version
|
||||||
|
module_la_DEPENDENCIES = $(top_builddir)/config.h
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE)
|
|
@ -0,0 +1,614 @@
|
||||||
|
#include "e_mod_main.h"
|
||||||
|
|
||||||
|
extern const char _Name[];
|
||||||
|
|
||||||
|
typedef struct E_Mixer_App_Dialog_Data
|
||||||
|
{
|
||||||
|
E_Mixer_System *sys;
|
||||||
|
char *card;
|
||||||
|
char *channel_name;
|
||||||
|
int lock_sliders;
|
||||||
|
Evas_List *cards;
|
||||||
|
Evas_List *channels_infos;
|
||||||
|
struct channel_info *channel_info;
|
||||||
|
E_Mixer_Channel_State state;
|
||||||
|
|
||||||
|
struct e_mixer_app_ui
|
||||||
|
{
|
||||||
|
Evas_Object *hlayout;
|
||||||
|
struct e_mixer_app_ui_cards
|
||||||
|
{
|
||||||
|
Evas_Object *frame;
|
||||||
|
Evas_Object *list;
|
||||||
|
} cards;
|
||||||
|
struct e_mixer_app_ui_channels
|
||||||
|
{
|
||||||
|
Evas_Object *frame;
|
||||||
|
Evas_Object *list;
|
||||||
|
} channels;
|
||||||
|
struct e_mixer_app_ui_channel_editor
|
||||||
|
{
|
||||||
|
Evas_Object *frame;
|
||||||
|
Evas_Object *label_card;
|
||||||
|
Evas_Object *card;
|
||||||
|
Evas_Object *label_channel;
|
||||||
|
Evas_Object *channel;
|
||||||
|
Evas_Object *label_type;
|
||||||
|
Evas_Object *type;
|
||||||
|
Evas_Object *label_left;
|
||||||
|
Evas_Object *left;
|
||||||
|
Evas_Object *label_right;
|
||||||
|
Evas_Object *right;
|
||||||
|
Evas_Object *mute;
|
||||||
|
Evas_Object *lock_sliders;
|
||||||
|
} channel_editor;
|
||||||
|
} ui;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
void (*func)(E_Dialog *dialog, void *data);
|
||||||
|
} del;
|
||||||
|
} E_Mixer_App_Dialog_Data;
|
||||||
|
|
||||||
|
struct channel_info
|
||||||
|
{
|
||||||
|
int has_capture;
|
||||||
|
char *name;
|
||||||
|
E_Mixer_Channel *id;
|
||||||
|
E_Mixer_App_Dialog_Data *app;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_changed_left(void *data, Evas_Object *obj)
|
||||||
|
{
|
||||||
|
E_Mixer_App_Dialog_Data *app = data;
|
||||||
|
E_Mixer_Channel_State *state;
|
||||||
|
|
||||||
|
state = &app->state;
|
||||||
|
if (app->lock_sliders && (state->left != state->right))
|
||||||
|
{
|
||||||
|
state->right = state->left;
|
||||||
|
e_widget_slider_value_int_set(app->ui.channel_editor.right,
|
||||||
|
state->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_mixer_system_set_volume(app->sys, app->channel_info->id,
|
||||||
|
state->left, state->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_changed_right(void *data, Evas_Object *obj)
|
||||||
|
{
|
||||||
|
E_Mixer_App_Dialog_Data *app = data;
|
||||||
|
E_Mixer_Channel_State *state;
|
||||||
|
|
||||||
|
state = &app->state;
|
||||||
|
if (app->lock_sliders && (state->right != state->left))
|
||||||
|
{
|
||||||
|
state->left = state->right;
|
||||||
|
e_widget_slider_value_int_set(app->ui.channel_editor.left,
|
||||||
|
state->left);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_mixer_system_set_volume(app->sys, app->channel_info->id,
|
||||||
|
state->left, state->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_changed_mute(void *data, Evas_Object *obj)
|
||||||
|
{
|
||||||
|
E_Mixer_App_Dialog_Data *app = data;
|
||||||
|
|
||||||
|
e_mixer_system_set_mute(app->sys, app->channel_info->id, app->state.mute);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_changed_lock_sliders(void *data, Evas_Object *obj)
|
||||||
|
{
|
||||||
|
E_Mixer_App_Dialog_Data *app = data;
|
||||||
|
E_Mixer_Channel_State *state;
|
||||||
|
|
||||||
|
if (!app->lock_sliders)
|
||||||
|
return;
|
||||||
|
|
||||||
|
state = &app->state;
|
||||||
|
if (state->left == state->right)
|
||||||
|
return;
|
||||||
|
|
||||||
|
state->left = state->right = (state->left + state->right) / 2;
|
||||||
|
|
||||||
|
e_widget_slider_value_int_set(app->ui.channel_editor.left, state->left);
|
||||||
|
e_widget_slider_value_int_set(app->ui.channel_editor.right, state->right);
|
||||||
|
e_mixer_system_set_volume(app->sys, app->channel_info->id,
|
||||||
|
state->left, state->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_update_channel_editor_state(E_Mixer_App_Dialog_Data *app, const E_Mixer_Channel_State state)
|
||||||
|
{
|
||||||
|
struct e_mixer_app_ui_channel_editor *ui;
|
||||||
|
|
||||||
|
ui = &app->ui.channel_editor;
|
||||||
|
|
||||||
|
e_widget_slider_value_int_set(ui->left, state.left);
|
||||||
|
e_widget_slider_value_int_set(ui->right, state.right);
|
||||||
|
|
||||||
|
if (e_mixer_system_can_mute(app->sys, app->channel_info->id))
|
||||||
|
{
|
||||||
|
e_widget_disabled_set(ui->mute, 0);
|
||||||
|
e_widget_check_checked_set(ui->mute, state.mute);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e_widget_disabled_set(ui->mute, 1);
|
||||||
|
e_widget_check_checked_set(ui->mute, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_populate_channel_editor(E_Mixer_App_Dialog_Data *app)
|
||||||
|
{
|
||||||
|
struct e_mixer_app_ui_channel_editor *ui;
|
||||||
|
E_Mixer_Channel_State state;
|
||||||
|
char *card_name;
|
||||||
|
|
||||||
|
ui = &app->ui.channel_editor;
|
||||||
|
|
||||||
|
card_name = e_mixer_system_get_card_name(app->card);
|
||||||
|
e_widget_entry_text_set(ui->card, card_name);
|
||||||
|
if (card_name)
|
||||||
|
free(card_name);
|
||||||
|
|
||||||
|
e_widget_entry_text_set(ui->channel, app->channel_name);
|
||||||
|
|
||||||
|
if (e_mixer_system_has_capture(app->sys, app->channel_info->id))
|
||||||
|
e_widget_entry_text_set(ui->type, D_("Capture"));
|
||||||
|
else
|
||||||
|
e_widget_entry_text_set(ui->type, D_("Playback"));
|
||||||
|
|
||||||
|
e_mixer_system_get_state(app->sys, app->channel_info->id, &state);
|
||||||
|
_update_channel_editor_state(app, state);
|
||||||
|
|
||||||
|
app->lock_sliders = (state.left == state.right);
|
||||||
|
e_widget_check_checked_set(ui->lock_sliders, app->lock_sliders);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_channel_selected(void *data)
|
||||||
|
{
|
||||||
|
struct channel_info *info = data;
|
||||||
|
E_Mixer_App_Dialog_Data *app;
|
||||||
|
|
||||||
|
app = info->app;
|
||||||
|
app->channel_info = info;
|
||||||
|
_populate_channel_editor(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_channel_info_cmp(void *data_a, void *data_b)
|
||||||
|
{
|
||||||
|
struct channel_info *a = data_a, *b = data_b;
|
||||||
|
|
||||||
|
if (a->has_capture < b->has_capture)
|
||||||
|
return -1;
|
||||||
|
else if (a->has_capture > b->has_capture)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return strcmp(a->name, b->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Evas_List *
|
||||||
|
_channels_info_new(E_Mixer_System *sys)
|
||||||
|
{
|
||||||
|
Evas_List *channels, *channels_infos, *l;
|
||||||
|
|
||||||
|
channels = e_mixer_system_get_channels(sys);
|
||||||
|
channels_infos = NULL;
|
||||||
|
for (l = channels; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
struct channel_info *info;
|
||||||
|
|
||||||
|
info = malloc(sizeof(*info));
|
||||||
|
info->id = l->data;
|
||||||
|
info->name = e_mixer_system_get_channel_name(sys, info->id);
|
||||||
|
info->has_capture = e_mixer_system_has_capture(sys, info->id);
|
||||||
|
|
||||||
|
channels_infos = evas_list_append(channels_infos, info);
|
||||||
|
}
|
||||||
|
e_mixer_system_free_channels(channels);
|
||||||
|
|
||||||
|
return evas_list_sort(channels_infos, -1, _channel_info_cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_channels_info_free(Evas_List *list)
|
||||||
|
{
|
||||||
|
Evas_List *l;
|
||||||
|
|
||||||
|
for (l = list; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
struct channel_info *info = l->data;
|
||||||
|
free(info->name);
|
||||||
|
free(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
evas_list_free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_cb_system_update(void *data, E_Mixer_System *sys)
|
||||||
|
{
|
||||||
|
E_Mixer_App_Dialog_Data *app;
|
||||||
|
E_Mixer_Channel_State state;
|
||||||
|
|
||||||
|
app = data;
|
||||||
|
|
||||||
|
if ((!app->sys) || (!app->channel_info))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
e_mixer_system_get_state(app->sys, app->channel_info->id, &state);
|
||||||
|
_update_channel_editor_state(app, state);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_populate_channels(E_Mixer_App_Dialog_Data *app)
|
||||||
|
{
|
||||||
|
Evas_List *l;
|
||||||
|
Evas_Object *ilist;
|
||||||
|
int header_input;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ilist = app->ui.channels.list;
|
||||||
|
edje_freeze();
|
||||||
|
e_widget_ilist_freeze(ilist);
|
||||||
|
e_widget_ilist_clear(ilist);
|
||||||
|
|
||||||
|
if (app->sys)
|
||||||
|
e_mixer_system_del(app->sys);
|
||||||
|
app->sys = e_mixer_system_new(app->card);
|
||||||
|
e_mixer_system_callback_set(app->sys, _cb_system_update, app);
|
||||||
|
|
||||||
|
if (app->channel_name)
|
||||||
|
free(app->channel_name);
|
||||||
|
app->channel_name = e_mixer_system_get_default_channel_name(app->sys);
|
||||||
|
|
||||||
|
if (app->channels_infos)
|
||||||
|
_channels_info_free(app->channels_infos);
|
||||||
|
app->channels_infos = _channels_info_new(app->sys);
|
||||||
|
|
||||||
|
if (app->channels_infos)
|
||||||
|
{
|
||||||
|
struct channel_info *info = app->channels_infos->data;
|
||||||
|
if (info->has_capture)
|
||||||
|
{
|
||||||
|
e_widget_ilist_header_append(ilist, NULL, D_("Input"));
|
||||||
|
header_input = 1;
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e_widget_ilist_header_append(ilist, NULL, D_("Output"));
|
||||||
|
header_input = 0;
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = app->channels_infos; l != NULL; l = l->next, i++)
|
||||||
|
{
|
||||||
|
struct channel_info *info = l->data;
|
||||||
|
|
||||||
|
if ((!header_input) && info->has_capture)
|
||||||
|
{
|
||||||
|
e_widget_ilist_header_append(ilist, NULL, D_("Input"));
|
||||||
|
header_input = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->app = app;
|
||||||
|
e_widget_ilist_append(ilist, NULL, info->name, _cb_channel_selected,
|
||||||
|
info, info->name);
|
||||||
|
if (app->channel_name && info->name &&
|
||||||
|
(strcmp(app->channel_name, info->name) == 0))
|
||||||
|
{
|
||||||
|
e_widget_ilist_selected_set(ilist, i);
|
||||||
|
app->channel_info = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e_widget_ilist_go(ilist);
|
||||||
|
e_widget_ilist_thaw(ilist);
|
||||||
|
edje_thaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
select_card(E_Mixer_App_Dialog_Data *app)
|
||||||
|
{
|
||||||
|
_populate_channels(app);
|
||||||
|
e_widget_ilist_selected_set(app->ui.channels.list, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_card_selected(void *data)
|
||||||
|
{
|
||||||
|
select_card(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_create_cards(E_Dialog *dialog, Evas *evas, E_Mixer_App_Dialog_Data *app)
|
||||||
|
{
|
||||||
|
struct e_mixer_app_ui_cards *ui;
|
||||||
|
Evas_List *l;
|
||||||
|
|
||||||
|
app->card = e_mixer_system_get_default_card();
|
||||||
|
app->cards = e_mixer_system_get_cards();
|
||||||
|
if (evas_list_count(app->cards) < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ui = &app->ui.cards;
|
||||||
|
ui->list = e_widget_tlist_add(evas, &app->card);
|
||||||
|
e_widget_tlist_go(ui->list);
|
||||||
|
for (l = app->cards; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
char *card, *card_name;
|
||||||
|
|
||||||
|
card = l->data;
|
||||||
|
card_name = e_mixer_system_get_card_name(card);
|
||||||
|
|
||||||
|
e_widget_tlist_append(ui->list, card_name, _cb_card_selected,
|
||||||
|
app, card);
|
||||||
|
|
||||||
|
free(card_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->frame = e_widget_framelist_add(evas, D_("Cards"), 0);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->list);
|
||||||
|
e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_create_channels(E_Dialog *dialog, Evas *evas, E_Mixer_App_Dialog_Data *app)
|
||||||
|
{
|
||||||
|
struct e_mixer_app_ui_channels *ui;
|
||||||
|
|
||||||
|
ui = &app->ui.channels;
|
||||||
|
ui->list = e_widget_ilist_add(evas, 24, 24, &app->channel_name);
|
||||||
|
e_widget_min_size_set(ui->list, 180, 100);
|
||||||
|
e_widget_ilist_go(ui->list);
|
||||||
|
|
||||||
|
ui->frame = e_widget_framelist_add(evas, D_("Channels"), 0);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->list);
|
||||||
|
e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 1, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_create_channel_editor(E_Dialog *dialog, Evas *evas, E_Mixer_App_Dialog_Data *app)
|
||||||
|
{
|
||||||
|
struct e_mixer_app_ui_channel_editor *ui;
|
||||||
|
|
||||||
|
ui = &app->ui.channel_editor;
|
||||||
|
|
||||||
|
ui->label_card = e_widget_label_add(evas, D_("Card:"));
|
||||||
|
ui->card = e_widget_entry_add(evas, NULL, NULL, NULL, NULL);
|
||||||
|
e_widget_entry_readonly_set(ui->card, 1);
|
||||||
|
|
||||||
|
ui->label_channel = e_widget_label_add(evas, D_("Channel:"));
|
||||||
|
ui->channel = e_widget_entry_add(evas, NULL, NULL, NULL, NULL);
|
||||||
|
e_widget_entry_readonly_set(ui->channel, 1);
|
||||||
|
|
||||||
|
ui->label_type = e_widget_label_add(evas, D_("Type:"));
|
||||||
|
ui->type = e_widget_entry_add(evas, NULL, NULL, NULL, NULL);
|
||||||
|
e_widget_entry_readonly_set(ui->type, 1);
|
||||||
|
|
||||||
|
ui->label_left = e_widget_label_add(evas, D_("Left:"));
|
||||||
|
ui->left = e_widget_slider_add(evas, 1, 0, "%3.0f", 0.0, 100.0, 10.0, 100.0,
|
||||||
|
NULL, &app->state.left, 150);
|
||||||
|
e_widget_on_change_hook_set(ui->left, _cb_changed_left, app);
|
||||||
|
|
||||||
|
ui->label_right = e_widget_label_add(evas, D_("Right:"));
|
||||||
|
ui->right = e_widget_slider_add(evas, 1, 0, "%3.0f", 0.0, 100.0, 10.0, 100.0,
|
||||||
|
NULL, &app->state.right, 150);
|
||||||
|
e_widget_on_change_hook_set(ui->right, _cb_changed_right, app);
|
||||||
|
|
||||||
|
ui->mute = e_widget_check_add(evas, D_("Mute"), &app->state.mute);
|
||||||
|
e_widget_on_change_hook_set(ui->mute, _cb_changed_mute, app);
|
||||||
|
|
||||||
|
ui->lock_sliders = e_widget_check_add(evas, D_("Lock Sliders"),
|
||||||
|
&app->lock_sliders);
|
||||||
|
e_widget_on_change_hook_set(ui->lock_sliders, _cb_changed_lock_sliders, app);
|
||||||
|
|
||||||
|
ui->frame = e_widget_framelist_add(evas, D_("Edit"), 0);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->label_card);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->card);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->label_channel);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->channel);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->label_type);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->type);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->label_left);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->left);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->label_right);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->right);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->mute);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->lock_sliders);
|
||||||
|
|
||||||
|
e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 1, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_create_ui(E_Dialog *dialog, E_Mixer_App_Dialog_Data *app)
|
||||||
|
{
|
||||||
|
struct e_mixer_app_ui *ui;
|
||||||
|
Evas *evas;
|
||||||
|
int mw, mh;
|
||||||
|
|
||||||
|
evas = e_win_evas_get(dialog->win);
|
||||||
|
|
||||||
|
ui = &app->ui;
|
||||||
|
|
||||||
|
ui->hlayout = e_widget_list_add(evas, 0, 1);
|
||||||
|
_create_cards(dialog, evas, app);
|
||||||
|
_create_channels(dialog, evas, app);
|
||||||
|
_create_channel_editor(dialog, evas, app);
|
||||||
|
|
||||||
|
if (ui->cards.list)
|
||||||
|
e_widget_tlist_selected_set(ui->cards.list, 0);
|
||||||
|
else
|
||||||
|
select_card(app);
|
||||||
|
e_widget_ilist_selected_set(ui->channels.list, 1);
|
||||||
|
|
||||||
|
e_widget_min_size_get(ui->hlayout, &mw, &mh);
|
||||||
|
if (mw < 300)
|
||||||
|
mw = 300;
|
||||||
|
if (mh < 200)
|
||||||
|
mh = 200;
|
||||||
|
e_dialog_content_set(dialog, ui->hlayout, mw, mh);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_mixer_app_dialog_del(E_Dialog *dialog, E_Mixer_App_Dialog_Data *app)
|
||||||
|
{
|
||||||
|
if (app->del.func)
|
||||||
|
app->del.func(dialog, app->del.data);
|
||||||
|
|
||||||
|
if (app->card)
|
||||||
|
free(app->card);
|
||||||
|
if (app->channel_name)
|
||||||
|
free(app->channel_name);
|
||||||
|
if (app->cards)
|
||||||
|
e_mixer_system_free_cards(app->cards);
|
||||||
|
if (app->channels_infos)
|
||||||
|
_channels_info_free(app->channels_infos);
|
||||||
|
e_mixer_system_del(app->sys);
|
||||||
|
|
||||||
|
e_util_defer_object_del(E_OBJECT(dialog));
|
||||||
|
dialog->data = NULL;
|
||||||
|
E_FREE(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_win_del(E_Win *win)
|
||||||
|
{
|
||||||
|
E_Dialog *dialog;
|
||||||
|
E_Mixer_App_Dialog_Data *app;
|
||||||
|
|
||||||
|
dialog = win->data;
|
||||||
|
app = dialog->data;
|
||||||
|
|
||||||
|
_mixer_app_dialog_del(dialog, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cb_dialog_dismiss(void *data, E_Dialog *dialog)
|
||||||
|
{
|
||||||
|
_mixer_app_dialog_del(dialog, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
E_Dialog *
|
||||||
|
e_mixer_app_dialog_new(E_Container *con, void (*func)(E_Dialog *dialog, void *data), void *data)
|
||||||
|
{
|
||||||
|
E_Mixer_App_Dialog_Data *app;
|
||||||
|
E_Dialog *dialog;
|
||||||
|
|
||||||
|
dialog = e_dialog_new(con, _Name, "e_mixer_app_dialog");
|
||||||
|
if (!dialog)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
app = E_NEW(E_Mixer_App_Dialog_Data, 1);
|
||||||
|
if (!app)
|
||||||
|
{
|
||||||
|
e_object_del(E_OBJECT(dialog));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog->data = app;
|
||||||
|
app->del.data = data;
|
||||||
|
app->del.func = func;
|
||||||
|
|
||||||
|
e_dialog_title_set(dialog, D_(_Name));
|
||||||
|
e_dialog_resizable_set(dialog, 1);
|
||||||
|
|
||||||
|
e_win_delete_callback_set(dialog->win, _cb_win_del);
|
||||||
|
|
||||||
|
_create_ui(dialog, app);
|
||||||
|
|
||||||
|
e_dialog_button_add(dialog, D_("Close"), NULL, _cb_dialog_dismiss, app);
|
||||||
|
e_dialog_button_focus_num(dialog, 1);
|
||||||
|
e_win_centered_set(dialog->win, 1);
|
||||||
|
e_dialog_show(dialog);
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
_find_card_by_name(E_Mixer_App_Dialog_Data *app, const char *card_name)
|
||||||
|
{
|
||||||
|
Evas_List *l;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0, l = app->cards; l != NULL; i++, l = l->next)
|
||||||
|
if (strcmp(card_name, l->data) == 0)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
_find_channel_by_name(E_Mixer_App_Dialog_Data *app, const char *channel_name)
|
||||||
|
{
|
||||||
|
Evas_List *l;
|
||||||
|
int i, header_input;
|
||||||
|
|
||||||
|
if (app->channels_infos)
|
||||||
|
{
|
||||||
|
struct channel_info *info = app->channels_infos->data;
|
||||||
|
|
||||||
|
header_input = !!info->has_capture;
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = app->channels_infos; l != NULL; l = l->next, i++)
|
||||||
|
{
|
||||||
|
struct channel_info *info = l->data;
|
||||||
|
|
||||||
|
if ((!header_input) && info->has_capture)
|
||||||
|
{
|
||||||
|
header_input = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(channel_name, info->name) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_app_dialog_select(E_Dialog *dialog, const char *card_name, const char *channel_name)
|
||||||
|
{
|
||||||
|
E_Mixer_App_Dialog_Data *app;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (!dialog)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
app = dialog->data;
|
||||||
|
if (!app)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
n = _find_card_by_name(app, card_name);
|
||||||
|
if (n < 0)
|
||||||
|
return 0;
|
||||||
|
if (app->ui.cards.list)
|
||||||
|
e_widget_tlist_selected_set(app->ui.cards.list, n);
|
||||||
|
|
||||||
|
n = _find_channel_by_name(app, channel_name);
|
||||||
|
if (n < 0)
|
||||||
|
return 0;
|
||||||
|
e_widget_ilist_selected_set(app->ui.channels.list, n);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -0,0 +1,389 @@
|
||||||
|
#include "e_mod_main.h"
|
||||||
|
|
||||||
|
extern const char _Name[];
|
||||||
|
|
||||||
|
struct _E_Config_Dialog_Data
|
||||||
|
{
|
||||||
|
int lock_sliders;
|
||||||
|
int show_locked;
|
||||||
|
int card_num;
|
||||||
|
int channel;
|
||||||
|
const char *card;
|
||||||
|
const char *channel_name;
|
||||||
|
Evas_List *cards;
|
||||||
|
Evas_List *cards_names;
|
||||||
|
Evas_List *channels_names;
|
||||||
|
struct mixer_config_ui
|
||||||
|
{
|
||||||
|
Evas_Object *table;
|
||||||
|
struct mixer_config_ui_general
|
||||||
|
{
|
||||||
|
Evas_Object *frame;
|
||||||
|
Evas_Object *lock_sliders;
|
||||||
|
Evas_Object *show_locked;
|
||||||
|
} general;
|
||||||
|
struct mixer_config_ui_cards
|
||||||
|
{
|
||||||
|
Evas_Object *frame;
|
||||||
|
E_Radio_Group *radio;
|
||||||
|
} cards;
|
||||||
|
struct mixer_config_ui_channels
|
||||||
|
{
|
||||||
|
Evas_Object *frame;
|
||||||
|
Evas_Object *scroll;
|
||||||
|
Evas_Object *list;
|
||||||
|
E_Radio_Group *radio;
|
||||||
|
Evas_List *radios;
|
||||||
|
} channels;
|
||||||
|
} ui;
|
||||||
|
E_Mixer_Gadget_Config *conf;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_mixer_fill_cards_info(E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
Evas_List *l;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cfdata->card_num = -1;
|
||||||
|
cfdata->cards = e_mixer_system_get_cards();
|
||||||
|
cfdata->cards_names = NULL;
|
||||||
|
for (l = cfdata->cards, i = 0; l != NULL; l = l->next, i++)
|
||||||
|
{
|
||||||
|
char *card, *name;
|
||||||
|
|
||||||
|
card = l->data;
|
||||||
|
name = e_mixer_system_get_card_name(card);
|
||||||
|
if ((cfdata->card_num < 0) && card && cfdata->card &&
|
||||||
|
(strcmp(card, cfdata->card) == 0))
|
||||||
|
cfdata->card_num = i;
|
||||||
|
|
||||||
|
cfdata->cards_names = evas_list_append(cfdata->cards_names, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfdata->card_num < 0)
|
||||||
|
cfdata->card_num = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_mixer_fill_channels_info(E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
E_Mixer_System *sys;
|
||||||
|
Evas_List *l;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sys = e_mixer_system_new(cfdata->card);
|
||||||
|
if (!sys)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cfdata->channel = 0;
|
||||||
|
cfdata->channel_name = evas_stringshare_add(cfdata->conf->channel_name);
|
||||||
|
cfdata->channels_names = e_mixer_system_get_channels_names(sys);
|
||||||
|
for (l = cfdata->channels_names, i = 0; l != NULL; l = l->next, i++)
|
||||||
|
{
|
||||||
|
char *channel;
|
||||||
|
|
||||||
|
channel = l->data;
|
||||||
|
if (channel && cfdata->channel_name &&
|
||||||
|
(strcmp(channel, cfdata->channel_name) == 0))
|
||||||
|
{
|
||||||
|
cfdata->channel = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e_mixer_system_del(sys);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
_create_data(E_Config_Dialog *dialog)
|
||||||
|
{
|
||||||
|
E_Config_Dialog_Data *cfdata;
|
||||||
|
E_Mixer_Gadget_Config *conf;
|
||||||
|
|
||||||
|
cfdata = E_NEW(E_Config_Dialog_Data, 1);
|
||||||
|
if (!cfdata)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
conf = dialog->data;
|
||||||
|
cfdata->conf = conf;
|
||||||
|
cfdata->lock_sliders = conf->lock_sliders;
|
||||||
|
cfdata->show_locked = conf->show_locked;
|
||||||
|
cfdata->card = evas_stringshare_add(conf->card);
|
||||||
|
_mixer_fill_cards_info(cfdata);
|
||||||
|
_mixer_fill_channels_info(cfdata);
|
||||||
|
|
||||||
|
return cfdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_free_data(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
E_Mixer_Gadget_Config *conf;
|
||||||
|
Evas_List *l;
|
||||||
|
|
||||||
|
conf = dialog->data;
|
||||||
|
if (conf)
|
||||||
|
conf->dialog = NULL;
|
||||||
|
|
||||||
|
if (!cfdata)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (l = cfdata->cards_names; l != NULL; l = l->next)
|
||||||
|
if (l->data)
|
||||||
|
free(l->data);
|
||||||
|
evas_list_free(cfdata->cards_names);
|
||||||
|
|
||||||
|
if (cfdata->channels_names)
|
||||||
|
e_mixer_system_free_channels_names(cfdata->channels_names);
|
||||||
|
if (cfdata->cards)
|
||||||
|
e_mixer_system_free_cards(cfdata->cards);
|
||||||
|
|
||||||
|
if (cfdata->card)
|
||||||
|
evas_stringshare_del(cfdata->card);
|
||||||
|
if (cfdata->channel_name)
|
||||||
|
evas_stringshare_del(cfdata->channel_name);
|
||||||
|
|
||||||
|
evas_list_free(cfdata->ui.channels.radios);
|
||||||
|
|
||||||
|
E_FREE(cfdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_basic_apply(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
E_Mixer_Gadget_Config *conf;
|
||||||
|
const char *card, *channel;
|
||||||
|
|
||||||
|
conf = dialog->data;
|
||||||
|
conf->lock_sliders = cfdata->lock_sliders;
|
||||||
|
conf->show_locked = cfdata->show_locked;
|
||||||
|
|
||||||
|
card = evas_list_nth(cfdata->cards, cfdata->card_num);
|
||||||
|
if (card)
|
||||||
|
{
|
||||||
|
if (conf->card && (strcmp(card, conf->card) != 0))
|
||||||
|
evas_stringshare_del(conf->card);
|
||||||
|
conf->card = evas_stringshare_add(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
channel = evas_list_nth(cfdata->channels_names, cfdata->channel);
|
||||||
|
if (channel)
|
||||||
|
{
|
||||||
|
if (conf->channel_name && (strcmp(channel, conf->channel_name) != 0))
|
||||||
|
evas_stringshare_del(conf->channel_name);
|
||||||
|
conf->channel_name = evas_stringshare_add(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_mixer_update(conf->instance);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_lock_change(void *data, Evas_Object *obj, void *event)
|
||||||
|
{
|
||||||
|
E_Config_Dialog_Data *cfdata;
|
||||||
|
|
||||||
|
cfdata = data;
|
||||||
|
e_widget_disabled_set(cfdata->ui.general.show_locked, !cfdata->lock_sliders);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_basic_create_general(Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
struct mixer_config_ui_general *ui;
|
||||||
|
|
||||||
|
ui = &cfdata->ui.general;
|
||||||
|
|
||||||
|
ui->frame = e_widget_framelist_add(evas, D_("General Settings"), 0);
|
||||||
|
|
||||||
|
ui->lock_sliders = e_widget_check_add(
|
||||||
|
evas, D_("Lock Sliders"), &cfdata->lock_sliders);
|
||||||
|
evas_object_smart_callback_add(
|
||||||
|
ui->lock_sliders, "changed", _lock_change, cfdata);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->lock_sliders);
|
||||||
|
|
||||||
|
ui->show_locked = e_widget_check_add(
|
||||||
|
evas, D_("Show both sliders when locked"), &cfdata->show_locked);
|
||||||
|
e_widget_disabled_set(ui->show_locked, !cfdata->lock_sliders);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->show_locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_clear_channels(E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
Evas_List *l;
|
||||||
|
|
||||||
|
for (l = cfdata->ui.channels.radios; l != NULL; l = l->next)
|
||||||
|
evas_object_del(l->data);
|
||||||
|
cfdata->ui.channels.radios = evas_list_free(cfdata->ui.channels.radios);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_fill_channels(Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
struct mixer_config_ui_channels *ui;
|
||||||
|
Evas_Object *selected;
|
||||||
|
Evas_Coord mw, mh;
|
||||||
|
Evas_List *l;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ui = &cfdata->ui.channels;
|
||||||
|
ui->radio = e_widget_radio_group_new(&cfdata->channel);
|
||||||
|
for (i = 0, l = cfdata->channels_names; l != NULL; l = l->next, i++)
|
||||||
|
{
|
||||||
|
Evas_Object *ow;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = l->data;
|
||||||
|
if (!name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ow = e_widget_radio_add(evas, name, i, ui->radio);
|
||||||
|
ui->radios = evas_list_append(ui->radios, ow);
|
||||||
|
e_widget_list_object_append(ui->list, ow, 1, 1, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_widget_min_size_get(ui->list, &mw, &mh);
|
||||||
|
evas_object_resize(ui->list, mw, mh);
|
||||||
|
|
||||||
|
selected = evas_list_nth(ui->radios, cfdata->channel);
|
||||||
|
if (selected)
|
||||||
|
{
|
||||||
|
Evas_Coord x, y, w, h, lx, ly;
|
||||||
|
evas_object_geometry_get(selected, &x, &y, &w, &h);
|
||||||
|
evas_object_geometry_get(ui->list, &lx, &ly, NULL, NULL);
|
||||||
|
x -= lx;
|
||||||
|
y -= ly - 10;
|
||||||
|
h += 20;
|
||||||
|
e_widget_scrollframe_child_region_show(ui->scroll, x, y, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_channel_scroll_set_min_size(struct mixer_config_ui_channels *ui)
|
||||||
|
{
|
||||||
|
Evas_Coord w, h;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = evas_list_count(ui->radios);
|
||||||
|
if (len < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
e_widget_min_size_get(ui->list, &w, &h);
|
||||||
|
h = 4 * h / len;
|
||||||
|
e_widget_min_size_set(ui->scroll, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_basic_create_channels(Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
struct mixer_config_ui_channels *ui;
|
||||||
|
|
||||||
|
ui = &cfdata->ui.channels;
|
||||||
|
ui->list = e_widget_list_add(evas, 1, 0);
|
||||||
|
ui->scroll = e_widget_scrollframe_simple_add(evas, ui->list);
|
||||||
|
ui->frame = e_widget_framelist_add(evas, D_("Channels"), 0);
|
||||||
|
|
||||||
|
_fill_channels(evas, cfdata);
|
||||||
|
|
||||||
|
_channel_scroll_set_min_size(ui);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ui->scroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_card_change(void *data, Evas_Object *obj, void *event)
|
||||||
|
{
|
||||||
|
E_Config_Dialog_Data *cfdata;
|
||||||
|
Evas *evas;
|
||||||
|
char *card;
|
||||||
|
|
||||||
|
cfdata = data;
|
||||||
|
|
||||||
|
if (cfdata->card)
|
||||||
|
evas_stringshare_del(cfdata->card);
|
||||||
|
|
||||||
|
e_mixer_system_free_channels_names(cfdata->channels_names);
|
||||||
|
if (cfdata->channel_name)
|
||||||
|
evas_stringshare_del(cfdata->channel_name);
|
||||||
|
|
||||||
|
card = evas_list_nth(cfdata->cards, cfdata->card_num);
|
||||||
|
cfdata->card = evas_stringshare_add(card);
|
||||||
|
_mixer_fill_channels_info(cfdata);
|
||||||
|
|
||||||
|
evas = evas_object_evas_get(obj);
|
||||||
|
_clear_channels(cfdata);
|
||||||
|
_fill_channels(evas, cfdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_basic_create_cards(Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
struct mixer_config_ui_cards *ui;
|
||||||
|
Evas_List *l;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ui = &cfdata->ui.cards;
|
||||||
|
|
||||||
|
ui->frame = e_widget_framelist_add(evas, D_("Sound Cards"), 0);
|
||||||
|
ui->radio = e_widget_radio_group_new(&cfdata->card_num);
|
||||||
|
for (i = 0, l = cfdata->cards_names; l != NULL; l = l->next, i++)
|
||||||
|
{
|
||||||
|
Evas_Object *ow;
|
||||||
|
const char *card;
|
||||||
|
|
||||||
|
card = l->data;
|
||||||
|
if (!card)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ow = e_widget_radio_add(evas, card, i, ui->radio);
|
||||||
|
e_widget_framelist_object_append(ui->frame, ow);
|
||||||
|
evas_object_smart_callback_add(ow, "changed", _card_change, cfdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Evas_Object *
|
||||||
|
_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
if (!cfdata)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cfdata->ui.table = e_widget_table_add(evas, 0);
|
||||||
|
_basic_create_general(evas, cfdata);
|
||||||
|
_basic_create_cards(evas, cfdata);
|
||||||
|
_basic_create_channels(evas, cfdata);
|
||||||
|
|
||||||
|
e_widget_table_object_append(cfdata->ui.table, cfdata->ui.general.frame,
|
||||||
|
0, 0, 1, 1, 1, 1, 1, 0);
|
||||||
|
e_widget_table_object_append(cfdata->ui.table, cfdata->ui.cards.frame,
|
||||||
|
0, 1, 1, 1, 1, 1, 1, 0);
|
||||||
|
e_widget_table_object_append(cfdata->ui.table, cfdata->ui.channels.frame,
|
||||||
|
0, 2, 1, 1, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
return cfdata->ui.table;
|
||||||
|
}
|
||||||
|
|
||||||
|
E_Config_Dialog *
|
||||||
|
e_mixer_config_dialog_new(E_Container *con, E_Mixer_Gadget_Config *conf)
|
||||||
|
{
|
||||||
|
E_Config_Dialog *dialog;
|
||||||
|
E_Config_Dialog_View *view;
|
||||||
|
|
||||||
|
if (e_config_dialog_find(_Name, "e_mixer_config_dialog_new"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
view = E_NEW(E_Config_Dialog_View, 1);
|
||||||
|
if (!view)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
view->create_cfdata = _create_data;
|
||||||
|
view->free_cfdata = _free_data;
|
||||||
|
view->basic.create_widgets = _basic_create;
|
||||||
|
view->basic.apply_cfdata = _basic_apply;
|
||||||
|
|
||||||
|
dialog = e_config_dialog_new(con, D_("Mixer Configuration"),
|
||||||
|
_Name, "e_mixer_config_dialog_new",
|
||||||
|
e_mixer_theme_path(), 0, view, conf);
|
||||||
|
e_dialog_resizable_set(dialog->dia, 1);
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
|
@ -0,0 +1,192 @@
|
||||||
|
#include "e_mod_main.h"
|
||||||
|
|
||||||
|
extern const char _Name[];
|
||||||
|
|
||||||
|
struct _E_Config_Dialog_Data
|
||||||
|
{
|
||||||
|
int default_instance;
|
||||||
|
struct mixer_config_ui
|
||||||
|
{
|
||||||
|
Evas_Object *list;
|
||||||
|
struct mixer_config_ui_general
|
||||||
|
{
|
||||||
|
Evas_Object *frame;
|
||||||
|
E_Radio_Group *radio;
|
||||||
|
} general;
|
||||||
|
} ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
_find_default_instance_index(E_Mixer_Module_Context *ctxt)
|
||||||
|
{
|
||||||
|
Evas_List *l;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0, l = ctxt->instances; l != NULL; l = l->next, i++)
|
||||||
|
if (l->data == ctxt->default_instance)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
_create_data(E_Config_Dialog *dialog)
|
||||||
|
{
|
||||||
|
E_Config_Dialog_Data *cfdata;
|
||||||
|
E_Mixer_Module_Context *ctxt;
|
||||||
|
|
||||||
|
cfdata = E_NEW(E_Config_Dialog_Data, 1);
|
||||||
|
if (!cfdata)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctxt = dialog->data;
|
||||||
|
cfdata->default_instance = _find_default_instance_index(ctxt);
|
||||||
|
|
||||||
|
return cfdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_free_data(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
E_Mixer_Module_Context *ctxt;
|
||||||
|
|
||||||
|
ctxt = dialog->data;
|
||||||
|
if (ctxt)
|
||||||
|
ctxt->conf_dialog = NULL;
|
||||||
|
|
||||||
|
E_FREE(cfdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_basic_apply(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
E_Mixer_Module_Context *ctxt;
|
||||||
|
|
||||||
|
ctxt = dialog->data;
|
||||||
|
ctxt->default_instance = evas_list_nth(ctxt->instances,
|
||||||
|
cfdata->default_instance);
|
||||||
|
if (ctxt->default_instance)
|
||||||
|
{
|
||||||
|
E_Mixer_Module_Config *conf;
|
||||||
|
const char *id;
|
||||||
|
|
||||||
|
conf = ctxt->conf;
|
||||||
|
if (conf->default_gc_id)
|
||||||
|
evas_stringshare_del(conf->default_gc_id);
|
||||||
|
|
||||||
|
id = ctxt->default_instance->gcc->cf->id;
|
||||||
|
conf->default_gc_id = evas_stringshare_add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_basic_create_general(E_Config_Dialog *dialog, Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
struct mixer_config_ui_general *ui;
|
||||||
|
E_Mixer_Module_Context *ctxt;
|
||||||
|
Evas_Object *label;
|
||||||
|
Evas_List *l;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ui = &cfdata->ui.general;
|
||||||
|
ctxt = dialog->data;
|
||||||
|
|
||||||
|
ui->frame = e_widget_framelist_add(evas, D_("General Settings"), 0);
|
||||||
|
|
||||||
|
label = e_widget_label_add(evas, D_("Mixer to use for global actions:"));
|
||||||
|
e_widget_framelist_object_append(ui->frame, label);
|
||||||
|
|
||||||
|
ui->radio = e_widget_radio_group_new(&cfdata->default_instance);
|
||||||
|
for (i = 0, l = ctxt->instances; l != NULL; l = l->next, i++)
|
||||||
|
{
|
||||||
|
E_Mixer_Instance *inst;
|
||||||
|
E_Mixer_Gadget_Config *conf;
|
||||||
|
Evas_Object *o;
|
||||||
|
char name[128];
|
||||||
|
char *card_name;
|
||||||
|
|
||||||
|
inst = l->data;
|
||||||
|
conf = inst->conf;
|
||||||
|
|
||||||
|
card_name = e_mixer_system_get_card_name(conf->card);
|
||||||
|
snprintf(name, sizeof(name), "%s: %s", card_name, conf->channel_name);
|
||||||
|
free(card_name);
|
||||||
|
|
||||||
|
o = e_widget_radio_add(evas, name, i, ui->radio);
|
||||||
|
e_widget_framelist_object_append(ui->frame, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
e_widget_list_object_append(cfdata->ui.list, ui->frame, 1, 1, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cb_mixer_app_del(E_Dialog *dialog, void *data)
|
||||||
|
{
|
||||||
|
E_Mixer_Module_Context *ctxt = data;
|
||||||
|
ctxt->mixer_dialog = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cb_mixer_call(void *data, void *data2)
|
||||||
|
{
|
||||||
|
E_Mixer_Module_Context *ctxt = data;
|
||||||
|
E_Container *con;
|
||||||
|
|
||||||
|
if (ctxt->mixer_dialog)
|
||||||
|
{
|
||||||
|
e_dialog_show(ctxt->mixer_dialog);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
con = e_container_current_get(e_manager_current_get());
|
||||||
|
ctxt->mixer_dialog = e_mixer_app_dialog_new(con, cb_mixer_app_del, ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_basic_create_mixer_call(E_Config_Dialog *dialog, Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
Evas_Object *button;
|
||||||
|
|
||||||
|
button = e_widget_button_add(evas, D_("Launch mixer..."), NULL,
|
||||||
|
cb_mixer_call, dialog->data, NULL);
|
||||||
|
e_widget_list_object_append(cfdata->ui.list, button, 0, 0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Evas_Object *
|
||||||
|
_basic_create(E_Config_Dialog *dialog, Evas *evas, E_Config_Dialog_Data *cfdata)
|
||||||
|
{
|
||||||
|
if (!cfdata)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cfdata->ui.list = e_widget_list_add(evas, 0, 0);
|
||||||
|
_basic_create_general(dialog, evas, cfdata);
|
||||||
|
_basic_create_mixer_call(dialog, evas, cfdata);
|
||||||
|
return cfdata->ui.list;
|
||||||
|
}
|
||||||
|
|
||||||
|
E_Config_Dialog *
|
||||||
|
e_mixer_config_module_dialog_new(E_Container *con, E_Mixer_Module_Context *ctxt)
|
||||||
|
{
|
||||||
|
E_Config_Dialog *dialog;
|
||||||
|
E_Config_Dialog_View *view;
|
||||||
|
|
||||||
|
if (e_config_dialog_find(_Name, "e_mixer_config_module_dialog_new"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
view = E_NEW(E_Config_Dialog_View, 1);
|
||||||
|
if (!view)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
view->create_cfdata = _create_data;
|
||||||
|
view->free_cfdata = _free_data;
|
||||||
|
view->basic.create_widgets = _basic_create;
|
||||||
|
view->basic.apply_cfdata = _basic_apply;
|
||||||
|
|
||||||
|
dialog = e_config_dialog_new(con, D_("Mixer Module Configuration"),
|
||||||
|
_Name, "e_mixer_config_module_dialog_new",
|
||||||
|
e_mixer_theme_path(), 0, view, ctxt);
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,89 @@
|
||||||
|
#define D_(str) dgettext(PACKAGE, str)
|
||||||
|
|
||||||
|
#ifndef E_MOD_MAIN_H
|
||||||
|
#define E_MOD_MAIN_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "e_mod_system.h"
|
||||||
|
#include <e.h>
|
||||||
|
|
||||||
|
#define MOD_CONF_VERSION 3
|
||||||
|
|
||||||
|
typedef struct E_Mixer_Gadget_Config
|
||||||
|
{
|
||||||
|
int lock_sliders;
|
||||||
|
int show_locked;
|
||||||
|
const char *card;
|
||||||
|
const char *channel_name;
|
||||||
|
const char *id;
|
||||||
|
E_Config_Dialog *dialog;
|
||||||
|
struct E_Mixer_Instance *instance;
|
||||||
|
} E_Mixer_Gadget_Config;
|
||||||
|
|
||||||
|
typedef struct E_Mixer_Module_Config
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
const char *default_gc_id;
|
||||||
|
Evas_Hash *gadgets;
|
||||||
|
} E_Mixer_Module_Config;
|
||||||
|
|
||||||
|
typedef struct E_Mixer_Instance
|
||||||
|
{
|
||||||
|
E_Gadcon_Client *gcc;
|
||||||
|
E_Gadcon_Popup *popup;
|
||||||
|
E_Menu *menu;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Evas_Object *gadget;
|
||||||
|
Evas_Object *label;
|
||||||
|
Evas_Object *left;
|
||||||
|
Evas_Object *right;
|
||||||
|
Evas_Object *mute;
|
||||||
|
Evas_Object *table;
|
||||||
|
Evas_Object *button;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Ecore_X_Window win;
|
||||||
|
Ecore_Event_Handler *mouse_up;
|
||||||
|
Ecore_Event_Handler *key_down;
|
||||||
|
} input;
|
||||||
|
} ui;
|
||||||
|
|
||||||
|
E_Mixer_System *sys;
|
||||||
|
E_Mixer_Channel *channel;
|
||||||
|
E_Mixer_Channel_State mixer_state;
|
||||||
|
E_Mixer_Gadget_Config *conf;
|
||||||
|
} E_Mixer_Instance;
|
||||||
|
|
||||||
|
typedef struct E_Mixer_Module_Context
|
||||||
|
{
|
||||||
|
E_Config_DD *module_conf_edd;
|
||||||
|
E_Config_DD *gadget_conf_edd;
|
||||||
|
E_Mixer_Module_Config *conf;
|
||||||
|
E_Config_Dialog *conf_dialog;
|
||||||
|
E_Mixer_Instance *default_instance;
|
||||||
|
Evas_List *instances;
|
||||||
|
E_Dialog *mixer_dialog;
|
||||||
|
struct st_mixer_actions
|
||||||
|
{
|
||||||
|
E_Action *incr;
|
||||||
|
E_Action *decr;
|
||||||
|
E_Action *mute;
|
||||||
|
} actions;
|
||||||
|
} E_Mixer_Module_Context;
|
||||||
|
|
||||||
|
EAPI extern E_Module_Api e_modapi;
|
||||||
|
EAPI void *e_modapi_init(E_Module *m);
|
||||||
|
EAPI int e_modapi_shutdown(E_Module *m);
|
||||||
|
EAPI int e_modapi_save(E_Module *m);
|
||||||
|
|
||||||
|
E_Config_Dialog *e_mixer_config_module_dialog_new(E_Container *con, E_Mixer_Module_Context *ctxt);
|
||||||
|
E_Config_Dialog *e_mixer_config_dialog_new(E_Container *con, E_Mixer_Gadget_Config *conf);
|
||||||
|
E_Dialog *e_mixer_app_dialog_new(E_Container *con, void (*func)(E_Dialog *dialog, void *data), void *data);
|
||||||
|
int e_mixer_app_dialog_select(E_Dialog *dialog, const char *card_name, const char *channel_name);
|
||||||
|
|
||||||
|
int e_mixer_update(E_Mixer_Instance *inst);
|
||||||
|
const char *e_mixer_theme_path(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef E_MOD_SYSTEM_H
|
||||||
|
#define E_MOD_SYSTEM_H
|
||||||
|
|
||||||
|
#include <Evas.h>
|
||||||
|
|
||||||
|
typedef void E_Mixer_System;
|
||||||
|
typedef void E_Mixer_Channel;
|
||||||
|
|
||||||
|
struct E_Mixer_Channel_State
|
||||||
|
{
|
||||||
|
int mute;
|
||||||
|
int left;
|
||||||
|
int right;
|
||||||
|
};
|
||||||
|
typedef struct E_Mixer_Channel_State E_Mixer_Channel_State;
|
||||||
|
|
||||||
|
Evas_List *e_mixer_system_get_cards(void);
|
||||||
|
void e_mixer_system_free_cards(Evas_List *cards);
|
||||||
|
char *e_mixer_system_get_default_card(void);
|
||||||
|
char *e_mixer_system_get_card_name(const char *card);
|
||||||
|
|
||||||
|
|
||||||
|
E_Mixer_System *e_mixer_system_new(const char *card);
|
||||||
|
void e_mixer_system_del(E_Mixer_System *self);
|
||||||
|
|
||||||
|
int e_mixer_system_callback_set(E_Mixer_System *self, int (*func)(void *data, E_Mixer_System *self), void *data);
|
||||||
|
|
||||||
|
Evas_List *e_mixer_system_get_channels(E_Mixer_System *self);
|
||||||
|
void e_mixer_system_free_channels(Evas_List *channels);
|
||||||
|
Evas_List *e_mixer_system_get_channels_names(E_Mixer_System *self);
|
||||||
|
void e_mixer_system_free_channels_names(Evas_List *channels_names);
|
||||||
|
char *e_mixer_system_get_default_channel_name(E_Mixer_System *self);
|
||||||
|
E_Mixer_Channel *e_mixer_system_get_channel_by_name(E_Mixer_System *self, const char *name);
|
||||||
|
char *e_mixer_system_get_channel_name(E_Mixer_System *self, E_Mixer_Channel *channel);
|
||||||
|
void e_mixer_system_channel_del(E_Mixer_Channel *channel);
|
||||||
|
|
||||||
|
|
||||||
|
int e_mixer_system_get_state(E_Mixer_System *self, E_Mixer_Channel *channel, E_Mixer_Channel_State *state);
|
||||||
|
int e_mixer_system_set_state(E_Mixer_System *self, E_Mixer_Channel *channel, const E_Mixer_Channel_State *state);
|
||||||
|
int e_mixer_system_get_volume(E_Mixer_System *self, E_Mixer_Channel *channel, int *left, int *right);
|
||||||
|
int e_mixer_system_set_volume(E_Mixer_System *self, E_Mixer_Channel *channel, int left, int right);
|
||||||
|
int e_mixer_system_get_mute(E_Mixer_System *self, E_Mixer_Channel *channel, int *mute);
|
||||||
|
int e_mixer_system_set_mute(E_Mixer_System *self, E_Mixer_Channel *channel, int mute);
|
||||||
|
int e_mixer_system_can_mute(E_Mixer_System *self, E_Mixer_Channel *channel);
|
||||||
|
int e_mixer_system_has_capture(E_Mixer_System *self, E_Mixer_Channel *channel);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* E_MOD_SYSTEM_H */
|
|
@ -0,0 +1,5 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Link
|
||||||
|
Name=Mixer
|
||||||
|
Icon=e-module-mixer
|
||||||
|
Comment=<hilight>Mixer Gadget</hilight><br><br>A module to provide a mixer for changing volume.
|
|
@ -0,0 +1,618 @@
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <Ecore.h>
|
||||||
|
#include "e_mod_system.h"
|
||||||
|
|
||||||
|
struct e_mixer_callback_desc
|
||||||
|
{
|
||||||
|
int (*func)(void *data, E_Mixer_System *self);
|
||||||
|
void *data;
|
||||||
|
E_Mixer_System *self;
|
||||||
|
Ecore_Idler *idler;
|
||||||
|
Evas_List *handlers;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int _mixer_callback_add(E_Mixer_System *self, int (*func)(void *data, E_Mixer_System *self), void *data);
|
||||||
|
static int _mixer_callback_del(E_Mixer_System *self, struct e_mixer_callback_desc *desc);
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
_cb_dispatch(void *data)
|
||||||
|
{
|
||||||
|
struct e_mixer_callback_desc *desc;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
desc = data;
|
||||||
|
snd_mixer_handle_events(desc->self);
|
||||||
|
r = desc->func(desc->data, desc->self);
|
||||||
|
desc->idler = NULL;
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
_mixer_callback_del(desc->self, desc); /* desc is invalid then. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_cb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
||||||
|
{
|
||||||
|
struct e_mixer_callback_desc *desc;
|
||||||
|
|
||||||
|
desc = data;
|
||||||
|
|
||||||
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
|
||||||
|
{
|
||||||
|
desc->handlers = evas_list_remove(desc->handlers, fd_handler);
|
||||||
|
if (!desc->handlers)
|
||||||
|
{
|
||||||
|
E_Mixer_System *s;
|
||||||
|
int (*f)(void *, E_Mixer_System *);
|
||||||
|
void *d;
|
||||||
|
|
||||||
|
s = desc->self;
|
||||||
|
f = desc->func;
|
||||||
|
d = desc->data;
|
||||||
|
_mixer_callback_del(s, desc);
|
||||||
|
_mixer_callback_add(s, f, d);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!desc->idler)
|
||||||
|
desc->idler = ecore_idler_add(_cb_dispatch, desc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_mixer_callback_add(E_Mixer_System *self, int (*func)(void *data, E_Mixer_System *self), void *data)
|
||||||
|
{
|
||||||
|
struct e_mixer_callback_desc *desc;
|
||||||
|
struct pollfd *pfds;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = snd_mixer_poll_descriptors_count(self);
|
||||||
|
if (len <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
desc = malloc(sizeof(struct e_mixer_callback_desc));
|
||||||
|
if (!desc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
desc->func = func;
|
||||||
|
desc->data = data;
|
||||||
|
desc->self = self;
|
||||||
|
desc->idler = NULL;
|
||||||
|
desc->handlers = NULL;
|
||||||
|
|
||||||
|
pfds = alloca(len * sizeof(struct pollfd));
|
||||||
|
len = snd_mixer_poll_descriptors(self, pfds, len);
|
||||||
|
if (len <= 0)
|
||||||
|
{
|
||||||
|
free(desc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
Ecore_Fd_Handler *fd_handler;
|
||||||
|
|
||||||
|
len--;
|
||||||
|
fd_handler = ecore_main_fd_handler_add(
|
||||||
|
pfds[len].fd, ECORE_FD_READ, _cb_fd_handler, desc, NULL, NULL);
|
||||||
|
desc->handlers = evas_list_prepend(desc->handlers, fd_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_mixer_set_callback_private(self, desc);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_mixer_callback_del(E_Mixer_System *self, struct e_mixer_callback_desc *desc)
|
||||||
|
{
|
||||||
|
Evas_List *l;
|
||||||
|
|
||||||
|
snd_mixer_set_callback_private(self, NULL);
|
||||||
|
|
||||||
|
for (l = desc->handlers; l != NULL; l = l->next)
|
||||||
|
ecore_main_fd_handler_del(l->data);
|
||||||
|
|
||||||
|
evas_list_free(desc->handlers);
|
||||||
|
free(desc);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_mixer_callback_replace(E_Mixer_System *self, struct e_mixer_callback_desc *desc, int (*func)(void *data, E_Mixer_System *self), void *data)
|
||||||
|
{
|
||||||
|
desc->func = func;
|
||||||
|
desc->data = data;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
E_Mixer_System *
|
||||||
|
e_mixer_system_new(const char *name)
|
||||||
|
{
|
||||||
|
snd_mixer_t *handle;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
err = snd_mixer_open(&handle, 0);
|
||||||
|
if (err < 0)
|
||||||
|
goto error_open;
|
||||||
|
|
||||||
|
err = snd_mixer_attach(handle, name);
|
||||||
|
if (err < 0)
|
||||||
|
goto error_load;
|
||||||
|
|
||||||
|
err = snd_mixer_selem_register(handle, NULL, NULL);
|
||||||
|
if (err < 0)
|
||||||
|
goto error_load;
|
||||||
|
|
||||||
|
err = snd_mixer_load(handle);
|
||||||
|
if (err < 0)
|
||||||
|
goto error_load;
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
|
||||||
|
error_load:
|
||||||
|
snd_mixer_close(handle);
|
||||||
|
error_open:
|
||||||
|
fprintf(stderr, "MIXER: Cannot get hardware info: %s\n", snd_strerror(err));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_del(E_Mixer_System *self)
|
||||||
|
{
|
||||||
|
struct e_mixer_callback_desc *desc;
|
||||||
|
|
||||||
|
if (self <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
desc = snd_mixer_get_callback_private(self);
|
||||||
|
if (desc)
|
||||||
|
_mixer_callback_del(self, desc);
|
||||||
|
|
||||||
|
snd_mixer_close(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_callback_set(E_Mixer_System *self, int (*func)(void *data, E_Mixer_System *self), void *data)
|
||||||
|
{
|
||||||
|
struct e_mixer_callback_desc *desc;
|
||||||
|
|
||||||
|
if (!self)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
desc = snd_mixer_get_callback_private(self);
|
||||||
|
if (!desc)
|
||||||
|
{
|
||||||
|
if (func)
|
||||||
|
return _mixer_callback_add(self, func, data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (func)
|
||||||
|
return _mixer_callback_replace(self, desc, func, data);
|
||||||
|
else
|
||||||
|
return _mixer_callback_del(self, desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Evas_List *
|
||||||
|
e_mixer_system_get_cards(void)
|
||||||
|
{
|
||||||
|
int err, card_num;
|
||||||
|
Evas_List *cards;
|
||||||
|
|
||||||
|
cards = NULL;
|
||||||
|
card_num = -1;
|
||||||
|
while (((err = snd_card_next(&card_num)) == 0) && (card_num >= 0))
|
||||||
|
{
|
||||||
|
snd_ctl_t *control;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "hw:%d", card_num);
|
||||||
|
|
||||||
|
if (snd_ctl_open(&control, buf, 0) < 0)
|
||||||
|
break;
|
||||||
|
snd_ctl_close(control);
|
||||||
|
cards = evas_list_append(cards, strdup(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
fprintf(stderr, "MIXER: Cannot get available card number: %s\n",
|
||||||
|
snd_strerror(err));
|
||||||
|
|
||||||
|
return cards;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_free_cards(Evas_List *cards)
|
||||||
|
{
|
||||||
|
Evas_List *e;
|
||||||
|
|
||||||
|
for (e = cards; e != NULL; e = e->next)
|
||||||
|
free(e->data);
|
||||||
|
|
||||||
|
evas_list_free(cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
e_mixer_system_get_default_card(void)
|
||||||
|
{
|
||||||
|
static const char buf[] = "hw:0";
|
||||||
|
snd_ctl_t *control;
|
||||||
|
|
||||||
|
if (snd_ctl_open(&control, buf, 0) < 0)
|
||||||
|
return NULL;
|
||||||
|
snd_ctl_close(control);
|
||||||
|
return strdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
e_mixer_system_get_card_name(const char *card)
|
||||||
|
{
|
||||||
|
snd_ctl_card_info_t *hw_info;
|
||||||
|
const char *name;
|
||||||
|
snd_ctl_t *control;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!card)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
snd_ctl_card_info_alloca(&hw_info);
|
||||||
|
|
||||||
|
err = snd_ctl_open(&control, card, 0);
|
||||||
|
if (err < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
err = snd_ctl_card_info(control, hw_info);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "MIXER: Cannot get hardware info: %s: %s\n", card,
|
||||||
|
snd_strerror(err));
|
||||||
|
snd_ctl_close(control);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_ctl_close(control);
|
||||||
|
name = snd_ctl_card_info_get_name(hw_info);
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "MIXER: Cannot get hardware name: %s\n", card);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strdup(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Evas_List *
|
||||||
|
e_mixer_system_get_channels(E_Mixer_System *self)
|
||||||
|
{
|
||||||
|
Evas_List *channels;
|
||||||
|
snd_mixer_elem_t *elem;
|
||||||
|
|
||||||
|
if (!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
channels = NULL;
|
||||||
|
|
||||||
|
elem = snd_mixer_first_elem(self);
|
||||||
|
for (; elem != NULL; elem = snd_mixer_elem_next(elem))
|
||||||
|
{
|
||||||
|
if ((!snd_mixer_selem_is_active(elem)) ||
|
||||||
|
(!snd_mixer_selem_has_playback_volume(elem)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
channels = evas_list_append(channels, elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_free_channels(Evas_List *channels)
|
||||||
|
{
|
||||||
|
evas_list_free(channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
Evas_List *
|
||||||
|
e_mixer_system_get_channels_names(E_Mixer_System *self)
|
||||||
|
{
|
||||||
|
Evas_List *channels;
|
||||||
|
snd_mixer_elem_t *elem;
|
||||||
|
snd_mixer_selem_id_t *sid;
|
||||||
|
|
||||||
|
if (!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
channels = NULL;
|
||||||
|
snd_mixer_selem_id_alloca(&sid);
|
||||||
|
|
||||||
|
elem = snd_mixer_first_elem(self);
|
||||||
|
for (; elem != NULL; elem = snd_mixer_elem_next(elem))
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
if ((!snd_mixer_selem_is_active(elem)) ||
|
||||||
|
(!snd_mixer_selem_has_playback_volume(elem)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snd_mixer_selem_get_id(elem, sid);
|
||||||
|
name = snd_mixer_selem_id_get_name(sid);
|
||||||
|
if (name)
|
||||||
|
channels = evas_list_append(channels, strdup(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_free_channels_names(Evas_List *channels_names)
|
||||||
|
{
|
||||||
|
Evas_List *e;
|
||||||
|
|
||||||
|
for (e = channels_names; e != NULL; e = e->next)
|
||||||
|
free(e->data);
|
||||||
|
|
||||||
|
evas_list_free(channels_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
e_mixer_system_get_default_channel_name(E_Mixer_System *self)
|
||||||
|
{
|
||||||
|
snd_mixer_elem_t *elem;
|
||||||
|
snd_mixer_selem_id_t *sid;
|
||||||
|
|
||||||
|
if (!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
snd_mixer_selem_id_alloca(&sid);
|
||||||
|
|
||||||
|
elem = snd_mixer_first_elem(self);
|
||||||
|
for (; elem != NULL; elem = snd_mixer_elem_next(elem))
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
if ((!snd_mixer_selem_is_active(elem)) ||
|
||||||
|
(!snd_mixer_selem_has_playback_volume(elem)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snd_mixer_selem_get_id(elem, sid);
|
||||||
|
name = snd_mixer_selem_id_get_name(sid);
|
||||||
|
if (name)
|
||||||
|
return strdup(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
E_Mixer_Channel *
|
||||||
|
e_mixer_system_get_channel_by_name(E_Mixer_System *self, const char *name)
|
||||||
|
{
|
||||||
|
snd_mixer_elem_t *elem;
|
||||||
|
snd_mixer_selem_id_t *sid;
|
||||||
|
|
||||||
|
if ((!self) || (!name))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
snd_mixer_selem_id_alloca(&sid);
|
||||||
|
|
||||||
|
elem = snd_mixer_first_elem(self);
|
||||||
|
for (; elem != NULL; elem = snd_mixer_elem_next(elem))
|
||||||
|
{
|
||||||
|
const char *n;
|
||||||
|
if ((!snd_mixer_selem_is_active(elem)) ||
|
||||||
|
(!snd_mixer_selem_has_playback_volume(elem)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snd_mixer_selem_get_id(elem, sid);
|
||||||
|
n = snd_mixer_selem_id_get_name(sid);
|
||||||
|
if (n && (strcmp(n, name) == 0))
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_channel_del(E_Mixer_Channel *channel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
e_mixer_system_get_channel_name(E_Mixer_System *self, E_Mixer_Channel *channel)
|
||||||
|
{
|
||||||
|
snd_mixer_selem_id_t *sid;
|
||||||
|
const char *n;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
if ((!self) || (!channel))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
snd_mixer_selem_id_alloca(&sid);
|
||||||
|
snd_mixer_selem_get_id(channel, sid);
|
||||||
|
n = snd_mixer_selem_id_get_name(sid);
|
||||||
|
if (n)
|
||||||
|
name = strdup(n);
|
||||||
|
else
|
||||||
|
name = NULL;
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_get_volume(E_Mixer_System *self, E_Mixer_Channel *channel, int *left, int *right)
|
||||||
|
{
|
||||||
|
long lvol, rvol, range, min, max;
|
||||||
|
|
||||||
|
if ((!self) || (!channel) || (!left) || (!right))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snd_mixer_handle_events(self);
|
||||||
|
snd_mixer_selem_get_playback_volume_range(channel, &min, &max);
|
||||||
|
range = max - min;
|
||||||
|
if (range < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (snd_mixer_selem_has_playback_channel(channel, 0))
|
||||||
|
snd_mixer_selem_get_playback_volume(channel, 0, &lvol);
|
||||||
|
else
|
||||||
|
lvol = min;
|
||||||
|
|
||||||
|
if (snd_mixer_selem_has_playback_channel(channel, 1))
|
||||||
|
snd_mixer_selem_get_playback_volume(channel, 1, &rvol);
|
||||||
|
else
|
||||||
|
rvol = min;
|
||||||
|
|
||||||
|
if (snd_mixer_selem_is_playback_mono(channel) ||
|
||||||
|
snd_mixer_selem_has_playback_volume_joined(channel))
|
||||||
|
rvol = lvol;
|
||||||
|
|
||||||
|
*left = rint((double)(lvol - min) * 100 / (double)range);
|
||||||
|
*right = rint((double)(rvol - min) * 100 / (double)range);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_set_volume(E_Mixer_System *self, E_Mixer_Channel *channel, int left, int right)
|
||||||
|
{
|
||||||
|
long range, min, max, div;
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
if ((!self) || (!channel))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snd_mixer_handle_events(self);
|
||||||
|
snd_mixer_selem_get_playback_volume_range(channel, &min, &max);
|
||||||
|
div = 100 + min;
|
||||||
|
if (div == 0)
|
||||||
|
{
|
||||||
|
div = 1; /* no zero-division */
|
||||||
|
min++;
|
||||||
|
}
|
||||||
|
|
||||||
|
range = max - min;
|
||||||
|
if (range < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mode = 0;
|
||||||
|
if (left >= 0)
|
||||||
|
{
|
||||||
|
left = (((range * left) + (range / 2)) / div) - min;
|
||||||
|
mode |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right >= 0)
|
||||||
|
{
|
||||||
|
right = (((range * right) + (range / 2)) / div) - min;
|
||||||
|
mode |= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode & 1)
|
||||||
|
snd_mixer_selem_set_playback_volume(channel, 0, left);
|
||||||
|
|
||||||
|
if ((!snd_mixer_selem_is_playback_mono(channel)) &&
|
||||||
|
(!snd_mixer_selem_has_playback_volume_joined(channel)) &&
|
||||||
|
(mode & 2))
|
||||||
|
{
|
||||||
|
if (snd_mixer_selem_has_playback_channel(channel, 1))
|
||||||
|
snd_mixer_selem_set_playback_volume(channel, 1, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_can_mute(E_Mixer_System *self, E_Mixer_Channel *channel)
|
||||||
|
{
|
||||||
|
if ((!self) || (!channel))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snd_mixer_handle_events(self);
|
||||||
|
return (snd_mixer_selem_has_playback_switch(channel) ||
|
||||||
|
snd_mixer_selem_has_playback_switch_joined(channel));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_get_mute(E_Mixer_System *self, E_Mixer_Channel *channel, int *mute)
|
||||||
|
{
|
||||||
|
if ((!self) || (!channel) || (!mute))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snd_mixer_handle_events(self);
|
||||||
|
if (snd_mixer_selem_has_playback_switch(channel) ||
|
||||||
|
snd_mixer_selem_has_playback_switch_joined(channel))
|
||||||
|
{
|
||||||
|
int m;
|
||||||
|
|
||||||
|
/* XXX: not checking for return, always returns 0 even if it worked.
|
||||||
|
* alsamixer also don't check it. Bug?
|
||||||
|
*/
|
||||||
|
snd_mixer_selem_get_playback_switch(channel, 0, &m);
|
||||||
|
*mute = !m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*mute = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_set_mute(E_Mixer_System *self, E_Mixer_Channel *channel, int mute)
|
||||||
|
{
|
||||||
|
if ((!self) || (!channel))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snd_mixer_handle_events(self);
|
||||||
|
if (snd_mixer_selem_has_playback_switch(channel) ||
|
||||||
|
snd_mixer_selem_has_playback_switch_joined(channel))
|
||||||
|
return snd_mixer_selem_set_playback_switch_all(channel, !mute);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_get_state(E_Mixer_System *self, E_Mixer_Channel *channel, E_Mixer_Channel_State *state)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = e_mixer_system_get_mute(self, channel, &state->mute);
|
||||||
|
r &= e_mixer_system_get_volume(self, channel, &state->left, &state->right);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_set_state(E_Mixer_System *self, E_Mixer_Channel *channel, const E_Mixer_Channel_State *state)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = e_mixer_system_set_mute(self, channel, state->mute);
|
||||||
|
r &= e_mixer_system_set_volume(self, channel, state->left, state->right);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_has_capture(E_Mixer_System *self, E_Mixer_Channel *channel)
|
||||||
|
{
|
||||||
|
if ((!self) || (!channel))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return snd_mixer_selem_has_capture_switch(channel);
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
#include "e_mod_system.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static const char _name[] = "dummy";
|
||||||
|
|
||||||
|
E_Mixer_System *
|
||||||
|
e_mixer_system_new(const char *name)
|
||||||
|
{
|
||||||
|
if (strcmp(name, _name) == 0)
|
||||||
|
return (E_Mixer_System *)-1;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_del(E_Mixer_System *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_callback_set(E_Mixer_System *self, int (*func)(void *data, E_Mixer_System *self), void *data)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Evas_List *
|
||||||
|
e_mixer_system_get_cards(void)
|
||||||
|
{
|
||||||
|
return evas_list_append(NULL, _name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_free_cards(Evas_List *cards)
|
||||||
|
{
|
||||||
|
evas_list_free(cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
e_mixer_system_get_default_card(void)
|
||||||
|
{
|
||||||
|
return strdup(_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
e_mixer_system_get_card_name(const char *card)
|
||||||
|
{
|
||||||
|
if (strcmp(card, _name) == 0)
|
||||||
|
return strdup(_name);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Evas_List *
|
||||||
|
e_mixer_system_get_channels(E_Mixer_System *self)
|
||||||
|
{
|
||||||
|
return evas_list_append(NULL, (void *)-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_free_channels(Evas_List *channels)
|
||||||
|
{
|
||||||
|
evas_list_free(channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
Evas_List *
|
||||||
|
e_mixer_system_get_channels_names(E_Mixer_System *self)
|
||||||
|
{
|
||||||
|
return evas_list_append(NULL, _name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_free_channels_names(Evas_List *channels_names)
|
||||||
|
{
|
||||||
|
evas_list_free(channels_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
e_mixer_system_get_default_channel_name(E_Mixer_System *self)
|
||||||
|
{
|
||||||
|
return strdup(_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
E_Mixer_Channel *
|
||||||
|
e_mixer_system_get_channel_by_name(E_Mixer_System *self, const char *name)
|
||||||
|
{
|
||||||
|
if (strcmp(name, _name) == 0)
|
||||||
|
return (E_Mixer_Channel *)-2;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_mixer_system_channel_del(E_Mixer_Channel *channel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
e_mixer_system_get_channel_name(E_Mixer_System *self, E_Mixer_Channel *channel)
|
||||||
|
{
|
||||||
|
if (channel == (E_Mixer_Channel *)-2)
|
||||||
|
return strdup(_name);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_get_volume(E_Mixer_System *self, E_Mixer_Channel *channel, int *left, int *right)
|
||||||
|
{
|
||||||
|
if (left)
|
||||||
|
*left = 0;
|
||||||
|
if (right)
|
||||||
|
*right = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_set_volume(E_Mixer_System *self, E_Mixer_Channel *channel, int left, int right)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_can_mute(E_Mixer_System *self, E_Mixer_Channel *channel)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_get_mute(E_Mixer_System *self, E_Mixer_Channel *channel, int *mute)
|
||||||
|
{
|
||||||
|
if (mute)
|
||||||
|
*mute = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_set_mute(E_Mixer_System *self, E_Mixer_Channel *channel, int mute)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_get_state(E_Mixer_System *self, E_Mixer_Channel *channel, E_Mixer_Channel_State *state)
|
||||||
|
{
|
||||||
|
const E_Mixer_Channel_State def = {1, 0, 0};
|
||||||
|
|
||||||
|
if (state)
|
||||||
|
*state = def;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_set_state(E_Mixer_System *self, E_Mixer_Channel *channel, const E_Mixer_Channel_State *state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
e_mixer_system_has_capture(E_Mixer_System *self, E_Mixer_Channel *channel)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue