]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Added gamix...
authorJaroslav Kysela <perex@perex.cz>
Thu, 29 Jul 1999 20:11:15 +0000 (20:11 +0000)
committerJaroslav Kysela <perex@perex.cz>
Thu, 29 Jul 1999 20:11:15 +0000 (20:11 +0000)
12 files changed:
Makefile.am
configure.in
gamix/ChangeLog [new file with mode: 0644]
gamix/Makefile [new file with mode: 0644]
gamix/Makefile.am [new file with mode: 0644]
gamix/Makefile.in [new file with mode: 0644]
gamix/catch.c [new file with mode: 0644]
gamix/conf_w.c [new file with mode: 0644]
gamix/gamix.h [new file with mode: 0644]
gamix/main.c [new file with mode: 0644]
gamix/mkmixer.c [new file with mode: 0644]
gamix/probe.c [new file with mode: 0644]

index cca444e31ee2587c74cfd37ba86621f6f66e5fbf..2d4168b5a37a48c2fe7a2787d0d92d5d7ec5c4be 100644 (file)
@@ -1,9 +1,14 @@
 INCLUDES=-I$(top_srcdir)/include
 SUBDIRS1=include alsactl alsamixer amixer aplay utils
 if COND_XAMIXER2
-SUBDIRS=$(SUBDIRS1) xamixer2
+SUBDIRS2=$(SUBDIRS1) xamixer2
 else
-SUBDIRS=$(SUBDIRS1)
+SUBDIRS2=$(SUBDIRS1)
+endif
+if COND_GAMIX
+SUBDIRS=$(SUBDIRS2) gamix
+else
+SUBDIRS=$(SUBDIRS2)
 endif
 EXTRA_DIST=ChangeLog INSTALL README configure cvscompile
 
index 1482bda5aeaeefc8221a036ebafe6641e7c443ac..632b70532fa8cbb012ab73b5edd177cd5b59f0bf 100644 (file)
@@ -45,5 +45,10 @@ AM_CONDITIONAL(COND_XAMIXER2, test "x$GTK_LIBS" != "x")
 if test "x$GTK_LIBS" = "x"; then
   AC_MSG_RESULT(Not building XAmixer2 as Gtk+ was not found.)
 fi
+AM_CONDITIONAL(COND_GAMIX, test "x$GTK_LIBS" != "x")
+if test "x$GTK_LIBS" = "x"; then
+  AC_MSG_RESULT(Not building gamix as Gtk+ was not found.)
+fi
 AC_OUTPUT(Makefile alsactl/Makefile alsamixer/Makefile amixer/Makefile aplay/Makefile \
-          include/Makefile utils/Makefile utils/alsa-utils.spec xamixer2/Makefile)
+          include/Makefile utils/Makefile utils/alsa-utils.spec xamixer2/Makefile
+         gamix/Makefile)
diff --git a/gamix/ChangeLog b/gamix/ChangeLog
new file mode 100644 (file)
index 0000000..09d5dc0
--- /dev/null
@@ -0,0 +1,4 @@
+1999-07-19  Fumihiko Murata  <fmurata@p1.tcnet.ne.jp>
+
+       * probe.c: fixed multi mixerdevices.
+
diff --git a/gamix/Makefile b/gamix/Makefile
new file mode 100644 (file)
index 0000000..38e279a
--- /dev/null
@@ -0,0 +1,329 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+prefix = /usr
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/alsa-utils
+pkglibdir = $(libdir)/alsa-utils
+pkgincludedir = $(includedir)/alsa-utils
+
+top_builddir = ..
+
+ACLOCAL = aclocal
+AUTOCONF = autoconf
+AUTOMAKE = automake
+AUTOHEADER = autoheader
+
+INSTALL = /usr/bin/ginstall -c
+INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+transform = s,x,x,
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+ALSA_CFLAGS = 
+ALSA_LIBS =  -lasound
+CC = gcc
+CURSESINC = <ncurses.h>
+CURSESLIB = -lncurses
+CXX = c++
+GTK_CFLAGS = -I/usr/X11R6/include -I/usr/lib/glib/include
+GTK_CONFIG = /usr/bin/gtk-config
+GTK_LIBS = -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXext -lX11 -lm
+LEX = flex
+LN_S = ln -s
+MAKEINFO = makeinfo
+PACKAGE = alsa-utils
+SND_UTIL_MAJOR = 0
+SND_UTIL_MINOR = 4
+SND_UTIL_SUBMINOR = 0
+SND_UTIL_VERSION = 0.4.0
+VERSION = 0.4.0
+YACC = bison -y
+
+bin_PROGRAMS = gamix
+
+INCLUDES = -DLOCALEDIR=\""$(datadir)/locale"\"
+
+gamix_SOURCES = gamix.h main.c mkmixer.c probe.c catch.c conf_w.c
+gamix_LDFLAGS = $(GTK_LIBS)
+
+EXTRA_DIST = ChangeLog
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/aconfig.h
+CONFIG_CLEAN_FILES = 
+PROGRAMS =  $(bin_PROGRAMS)
+
+
+DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I../include
+CPPFLAGS = 
+LDFLAGS =  -lasound -lasound
+LIBS = -lasound 
+gamix_OBJECTS =  main.o mkmixer.o probe.o catch.o conf_w.o
+gamix_LDADD = $(LDADD)
+gamix_DEPENDENCIES = 
+CFLAGS = -g -O2 -I/usr/X11R6/include -I/usr/lib/glib/include
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DEP_FILES =  .deps/catch.P .deps/conf_w.P .deps/main.P .deps/mkmixer.P \
+.deps/probe.P
+SOURCES = $(gamix_SOURCES)
+OBJECTS = $(gamix_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu gamix/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+       -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(bindir)
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo "  $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+            $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+         else :; fi; \
+       done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       list='$(bin_PROGRAMS)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+       done
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+gamix: $(gamix_OBJECTS) $(gamix_DEPENDENCIES)
+       @rm -f gamix
+       $(LINK) $(gamix_LDFLAGS) $(gamix_OBJECTS) $(gamix_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = gamix
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu gamix/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+       $(mkinstalldirs)  $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-binPROGRAMS mostlyclean-compile \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-binPROGRAMS clean-compile clean-tags clean-depend \
+               clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-binPROGRAMS distclean-compile distclean-tags \
+               distclean-depend distclean-generic clean-am
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-binPROGRAMS \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-depend maintainer-clean-generic \
+               distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gamix/Makefile.am b/gamix/Makefile.am
new file mode 100644 (file)
index 0000000..3cddd87
--- /dev/null
@@ -0,0 +1,8 @@
+bin_PROGRAMS = gamix
+
+INCLUDES = -DLOCALEDIR=\""$(datadir)/locale"\"
+
+gamix_SOURCES = gamix.h main.c mkmixer.c probe.c catch.c conf_w.c
+gamix_LDFLAGS = $(GTK_LIBS)
+
+EXTRA_DIST = ChangeLog
diff --git a/gamix/Makefile.in b/gamix/Makefile.in
new file mode 100644 (file)
index 0000000..c099fb0
--- /dev/null
@@ -0,0 +1,329 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+ALSA_CFLAGS = @ALSA_CFLAGS@
+ALSA_LIBS = @ALSA_LIBS@
+CC = @CC@
+CURSESINC = @CURSESINC@
+CURSESLIB = @CURSESLIB@
+CXX = @CXX@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_CONFIG = @GTK_CONFIG@
+GTK_LIBS = @GTK_LIBS@
+LEX = @LEX@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+SND_UTIL_MAJOR = @SND_UTIL_MAJOR@
+SND_UTIL_MINOR = @SND_UTIL_MINOR@
+SND_UTIL_SUBMINOR = @SND_UTIL_SUBMINOR@
+SND_UTIL_VERSION = @SND_UTIL_VERSION@
+VERSION = @VERSION@
+YACC = @YACC@
+
+bin_PROGRAMS = gamix
+
+INCLUDES = -DLOCALEDIR=\""$(datadir)/locale"\"
+
+gamix_SOURCES = gamix.h main.c mkmixer.c probe.c catch.c conf_w.c
+gamix_LDFLAGS = $(GTK_LIBS)
+
+EXTRA_DIST = ChangeLog
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/aconfig.h
+CONFIG_CLEAN_FILES = 
+PROGRAMS =  $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+gamix_OBJECTS =  main.o mkmixer.o probe.o catch.o conf_w.o
+gamix_LDADD = $(LDADD)
+gamix_DEPENDENCIES = 
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+DEP_FILES =  .deps/catch.P .deps/conf_w.P .deps/main.P .deps/mkmixer.P \
+.deps/probe.P
+SOURCES = $(gamix_SOURCES)
+OBJECTS = $(gamix_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu gamix/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+       -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(bindir)
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         if test -f $$p; then \
+           echo "  $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+            $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+         else :; fi; \
+       done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       list='$(bin_PROGRAMS)'; for p in $$list; do \
+         rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+       done
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+gamix: $(gamix_OBJECTS) $(gamix_DEPENDENCIES)
+       @rm -f gamix
+       $(LINK) $(gamix_LDFLAGS) $(gamix_OBJECTS) $(gamix_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = gamix
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu gamix/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+       $(mkinstalldirs)  $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-binPROGRAMS mostlyclean-compile \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-binPROGRAMS clean-compile clean-tags clean-depend \
+               clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-binPROGRAMS distclean-compile distclean-tags \
+               distclean-depend distclean-generic clean-am
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-binPROGRAMS \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-depend maintainer-clean-generic \
+               distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gamix/catch.c b/gamix/catch.c
new file mode 100644 (file)
index 0000000..889d598
--- /dev/null
@@ -0,0 +1,185 @@
+
+#include "gamix.h"
+
+static snd_mixer_callbacks_t cb_mix;
+
+static void cb_rb(void *);
+static void element_callback(void *,int,snd_mixer_eid_t *);
+static void cb_gp(void *,int,snd_mixer_gid_t *);
+static void s_e_chk(s_element *);
+
+static void cb_rb(void *pd ) {
+       printf("cb rb hoe\n");
+}
+
+static void element_callback(void *pd,int cmd,snd_mixer_eid_t *eid) {
+       int i,j,k;
+       gint ccc;
+       s_group *group;
+       s_element *e;
+       s_eelements *ee;
+       s_mixer *mixer=(s_mixer *)pd;
+
+
+       if( cmd != SND_MIXER_READ_ELEMENT_VALUE ) return;
+       /*
+       if( eid->type != SND_MIXER_ETYPE_VOLUME1 ||
+               eid->type != SND_MIXER_ETYPE_SWITCH1 ||
+               eid->type != SND_MIXER_ETYPE_SWITCH1 ) {
+               return;
+       }
+       */
+       //printf("hoe '%s',%d,%d\n",eid->name,eid->index,eid->type);
+       for( i=0 ; i<mixer->groups.groups ; i++ ) {
+               group=&mixer->group[i];
+               for( j=0 ; j<group->g.elements ; j++ ) {
+                       e=&group->e[j];
+                       if( strcmp(e->e.eid.name,eid->name) == 0 &&
+                               e->e.eid.index == eid->index) {
+                               snd_mixer_element_read(mixer->handle,&e->e);
+                               if( group->enabled ) {
+                                       ccc=group->chain;
+                                       s_e_chk(e);
+                                       group->chain=FALSE;
+                                       group->chain=ccc;
+                               }
+                               return;
+                       }
+               }
+       }
+       for( i=0 ; i < mixer->ee_n ; i++ ) {
+               ee=&mixer->ee[i];
+               if( strcmp(ee->e.e.eid.name,eid->name)==0 &&
+                       ee->e.e.eid.index==eid->index ) {
+                       snd_mixer_element_read(mixer->handle,&ee->e.e);
+                       if( ee->enabled ) {
+                               ccc=ee->chain;
+                               ee->chain=FALSE;
+                               s_e_chk(&ee->e);
+                               ee->chain=ccc;
+                       }
+                       return;
+               }
+       }
+
+
+       printf("elem hoe %d %s %d %d\n",cmd,eid->name,eid->index,eid->type);
+}
+static void cb_gp(void *pd,int cmd,snd_mixer_gid_t *gid) {
+       printf("cb_gp hoe\n");
+}
+
+void tc_init( void ) {
+       cb_mix.rebuild=*cb_rb;
+       cb_mix.element=*element_callback;
+       cb_mix.group=*cb_gp;
+}
+gint time_callback(gpointer data) {
+       int i,j,err;
+
+       for( i=0 ; i<card_num ; i++ ) {
+               for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
+                       cb_mix.private_data=(void *)&cards[i].mixer[j];
+                       snd_mixer_read(cards[i].mixer[j].handle,&cb_mix);
+               }
+       }
+       return 1;
+}
+
+void s_e_chk( s_element *e ) {
+       int i,j,err;
+       switch( e->e.eid.type ) {
+       case SND_MIXER_ETYPE_VOLUME1:
+               for( i=0 ; i<e->e.data.volume1.voices; i++ ) {
+                       if( (e->info.data.volume1.prange[i].max-
+                                e->info.data.volume1.prange[i].min) == 1 ) {
+                               gtk_toggle_button_set_active(
+                                                                                        GTK_TOGGLE_BUTTON(e->w[i]),
+                                                                                        e->e.data.volume1.pvoices[i]);
+                       } else {
+                               e->adj[i]->value=(gfloat)
+                                       -e->e.data.volume1.pvoices[i];
+                               gtk_signal_emit_by_name(GTK_OBJECT(e->adj[i]),"value_changed");
+                       }
+               }
+               break;
+       case SND_MIXER_ETYPE_SWITCH1:
+               for( i=0 ; i<e->e.data.switch1.sw; i++) {
+                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->w[i]),
+                                                                        snd_mixer_get_bit(e->e.data.switch1.psw,i)
+                                                                                );
+               }
+               break;
+       case SND_MIXER_ETYPE_SWITCH2:
+               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->w[0]),
+                                                                        e->e.data.switch2.sw);
+               break;
+       case SND_MIXER_ETYPE_ACCU3:
+               for( i=0 ; i<e->e.data.accu3.voices ; i++ ) {
+                       e->adj[i]->value=(gfloat)
+                               -e->e.data.volume1.pvoices[i];
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[i]),"value_changed");
+               }
+               break;
+       case SND_MIXER_ETYPE_MUX1:
+               for( i=0 ; i<e->e.data.mux1.output ; i++ ) {
+                       for( j=0; j<e->mux_n ; j++ ) {
+                               if( strcmp(e->mux[j].name,e->e.data.mux1.poutput[i].name)==0 &&
+                                       e->mux[j].index == e->e.data.mux1.poutput[i].index &&
+                                       e->mux[j].type == e->e.data.mux1.poutput[i].type ) break;
+                       }
+                       if( j < e->mux_n )
+                               gtk_option_menu_set_history(GTK_OPTION_MENU(e->w[i]),j);
+               }
+               break;
+       case SND_MIXER_ETYPE_MUX2:
+               for( i=0; i<e->mux_n ; i++ ) {
+                       if( strcmp(e->mux[i].name,e->e.data.mux2.output.name)==0 &&
+                               e->mux[i].index == e->e.data.mux2.output.index &&
+                               e->mux[i].type == e->e.data.mux2.output.type )
+                               break;
+               }
+               if( i < e->mux_n )
+                       gtk_option_menu_set_history(GTK_OPTION_MENU(e->w[0]),i);
+               break;
+       case SND_MIXER_ETYPE_3D_EFFECT1:
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_SW ) {
+                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->w[0]),
+                                                                                e->e.data.teffect1.sw);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_MONO_SW ) {
+                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->w[0]),
+                                                                                e->e.data.teffect1.sw);
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_WIDE ) {
+                       e->adj[0]->value=(gfloat)e->e.data.teffect1.wide;
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[0]),"value_changed");
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_VOLUME ) {
+                       e->adj[1]->value=(gfloat)e->e.data.teffect1.volume;
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[1]),"value_changed");
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_CENTER ) {
+                       e->adj[2]->value=(gfloat)e->e.data.teffect1.center;
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[2]),
+                                                                       "value_changed");
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_SPACE ) {
+                       e->adj[3]->value=(gfloat)e->e.data.teffect1.space;
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[3]),"value_changed");
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_DEPTH ) {
+                       e->adj[4]->value=(gfloat)e->e.data.teffect1.depth;
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[4]),"value_changed");
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_DELAY ) {
+                       e->adj[5]->value=(gfloat)e->e.data.teffect1.delay;
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[5]),"value_changed");
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK ) {
+                       e->adj[6]->value=(gfloat)e->e.data.teffect1.feedback;
+                       gtk_signal_emit_by_name(GTK_OBJECT(e->adj[6]),"value_changed");
+               }
+               break;
+       }
+}
diff --git a/gamix/conf_w.c b/gamix/conf_w.c
new file mode 100644 (file)
index 0000000..6c3ff77
--- /dev/null
@@ -0,0 +1,635 @@
+
+#include "gamix.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+s_conf conf;
+
+static GtkWidget *c_win;
+
+typedef struct {
+       gboolean m_en;
+       gboolean *g_en;
+       gboolean *ee_en;
+       GSList *gp;
+       gboolean p_e;
+       gboolean p_f;
+} c_mixer;
+
+typedef struct {
+       c_mixer *m;
+} c_card;
+
+static c_card *ccard;
+static gboolean scrolled;
+static gboolean ok_pushed;
+static gboolean Esaved;
+static gboolean Tosave;
+
+static void close_win(GtkWidget *,gpointer);
+static void cancel_b(GtkWidget *,gpointer);
+static void ok_b(GtkWidget *,gpointer);
+static void tb_callback(GtkToggleButton *,gint *);
+
+static void cread_err(gchar *,int );
+static void chk_cfile(void);
+
+static void close_win(GtkWidget *w,gpointer data) {
+       gtk_grab_remove(c_win);
+       gtk_main_quit();
+}
+
+static void cancel_b(GtkWidget *w,gpointer data) {
+       gtk_widget_destroy(c_win);
+}
+static void ok_b(GtkWidget *w,gpointer data) {
+       int i,j,k;
+       GSList *n;
+       GtkWidget *b;
+
+       Tosave=(gboolean)data;
+
+       ok_pushed=TRUE;
+
+       for( i=0 ; i<card_num ; i++ ) {
+               for( j=0 ; j<cards[i].info.mixerdevs; j++ ) {
+                       for( k=0 ; (n = g_slist_nth(ccard[i].m[j].gp,k)) != NULL ; k++ ) {
+                               b=(GtkWidget *)n->data;
+                               if( GTK_TOGGLE_BUTTON(b)->active ) break;
+                       }
+                       switch(k) {
+                       case 2:
+                               ccard[i].m[j].p_e=FALSE;
+                               ccard[i].m[j].p_f=FALSE;
+                               break;
+                       case 1:
+                               ccard[i].m[j].p_e=TRUE;
+                               ccard[i].m[j].p_f=FALSE;
+                               break;
+                       case 0:
+                               ccard[i].m[j].p_e=TRUE;
+                               ccard[i].m[j].p_f=TRUE;
+                               break;
+                       }
+               }
+       }
+       gtk_widget_destroy(c_win);
+}
+
+gint conf_win( void ) {
+       int i,j,k,l;
+       gint changed;
+       GtkWidget *b;
+       GtkWidget *vbox,*box,*frame,*hbox,*hhbox,*box1,*box2;
+       GtkWidget *nb,*n_label;
+       unsigned char gname[256];
+       GSList *gp;
+
+       ok_pushed=FALSE;
+
+       c_win=gtk_window_new(GTK_WINDOW_DIALOG);
+       gtk_signal_connect(GTK_OBJECT(c_win),"destroy",GTK_SIGNAL_FUNC(close_win),
+                                          NULL);
+
+       vbox=gtk_vbox_new(FALSE,10);
+       gtk_container_add(GTK_CONTAINER(c_win),vbox);
+       
+       /* options */
+       nb=gtk_notebook_new();
+       gtk_notebook_set_tab_pos(GTK_NOTEBOOK(nb),GTK_POS_TOP);
+       gtk_box_pack_start(GTK_BOX(vbox),nb,FALSE,FALSE,0);
+       
+       /*  OPT */
+       frame=gtk_frame_new(NULL);
+       gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_IN);
+       gtk_container_set_border_width(GTK_CONTAINER(frame),20);
+       box=gtk_vbox_new(FALSE,10);
+       gtk_container_set_border_width(GTK_CONTAINER(box),10);
+       gtk_container_add(GTK_CONTAINER(frame),box);
+
+       hbox=gtk_hbox_new(FALSE,4);
+       gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
+       scrolled=conf.scroll;
+       b=gtk_toggle_button_new();
+       gtk_widget_set_usize(b,10,10);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),conf.scroll);
+       gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+       gtk_signal_connect(GTK_OBJECT(b),"toggled",GTK_SIGNAL_FUNC(tb_callback),
+                                          (gpointer)&scrolled);
+       gtk_widget_show(b);
+       n_label=gtk_label_new(_("Scroll window enable"));
+       gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
+       gtk_widget_show(n_label);
+       gtk_widget_show(hbox);
+
+       hbox=gtk_hbox_new(FALSE,4);
+       gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
+       Esaved=conf.Esave;
+       b=gtk_toggle_button_new();
+       gtk_widget_set_usize(b,10,10);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),conf.Esave);
+       gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+       gtk_signal_connect(GTK_OBJECT(b),"toggled",GTK_SIGNAL_FUNC(tb_callback),
+                                          (gpointer)&Esaved);
+       gtk_widget_show(b);
+       n_label=gtk_label_new(_("Config save when exit"));
+       gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
+       gtk_widget_show(n_label);
+       gtk_widget_show(hbox);
+
+       n_label=gtk_label_new("OPT");
+       gtk_widget_show(box);
+       gtk_widget_show(frame);
+       gtk_notebook_append_page(GTK_NOTEBOOK(nb),frame,n_label);
+       
+       /* Mixer */
+       ccard=(c_card *)g_malloc(card_num*sizeof(c_card));
+       if( ccard == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+       }
+       for( i=0 ; i<card_num ; i++ ) {
+               ccard[i].m=(c_mixer *)g_malloc(cards[i].info.mixerdevs*sizeof(c_mixer));
+               if( ccard[i].m == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               for( j=0 ; j<cards[i].info.mixerdevs; j++ ) {
+                       n_label=gtk_label_new(cards[i].mixer[j].info.name);
+                       frame=gtk_frame_new(NULL);
+                       gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_IN);
+                       gtk_container_set_border_width(GTK_CONTAINER(frame),20);
+                       gtk_notebook_append_page(GTK_NOTEBOOK(nb),frame,n_label);
+
+                       box=gtk_vbox_new(FALSE,2);
+                       gtk_container_set_border_width(GTK_CONTAINER(box),10);
+                       gtk_container_add(GTK_CONTAINER(frame),box);
+
+                       hbox=gtk_hbox_new(FALSE,4);
+                       gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
+                       
+                       ccard[i].m[j].m_en=cards[i].mixer[j].enable;
+                       b=gtk_toggle_button_new();
+                       gtk_widget_set_usize(b,10,10);
+                       gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+                       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
+                                                                                ccard[i].m[j].m_en);
+                       gtk_signal_connect(GTK_OBJECT(b),"toggled",
+                                                          GTK_SIGNAL_FUNC(tb_callback),
+                                                          (gpointer)&ccard[i].m[j].m_en);
+                       gtk_widget_show(b);
+                       n_label=gtk_label_new(cards[i].mixer[j].info.name);
+                       gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
+                       gtk_widget_show(n_label);
+                       gtk_widget_show(hbox);
+                       
+                       if( cards[i].mixer[j].p_e ) {
+                               if( cards[i].mixer[j].p_f ) k=2; else k=1;
+                       } else k=0;
+                       hbox=gtk_hbox_new(FALSE,4);
+                       gtk_box_pack_start(GTK_BOX(box),hbox,FALSE,FALSE,0);
+                       n_label=gtk_label_new(_("Spacing: "));
+                       gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
+                       gtk_widget_show(n_label);
+
+                       b=gtk_radio_button_new_with_label(NULL,_("NONE"));
+                       gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+                       gtk_widget_show(b);
+                       if( k==0 ) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
+                                                                                                       TRUE);
+                       gp=gtk_radio_button_group(GTK_RADIO_BUTTON(b));
+
+                       b=gtk_radio_button_new_with_label(gp,_("space"));
+                       gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+                       gtk_widget_show(b);
+                       if( k==1 ) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
+                                                                                                       TRUE);
+                       gp=gtk_radio_button_group(GTK_RADIO_BUTTON(b));
+
+                       b=gtk_radio_button_new_with_label(gp,_("expand"));
+                       gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+                       gtk_widget_show(b);
+                       if( k==2 ) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
+                                                                                                       TRUE);
+                       ccard[i].m[j].gp=gtk_radio_button_group(GTK_RADIO_BUTTON(b));
+                       gtk_widget_show(hbox);
+
+                       hhbox=gtk_hbox_new(TRUE,20);
+                       gtk_container_set_border_width(GTK_CONTAINER(hhbox),8);
+                       gtk_box_pack_start(GTK_BOX(box),hhbox,FALSE,FALSE,0);
+                       box1=gtk_vbox_new(FALSE,4);
+                       gtk_box_pack_start(GTK_BOX(hhbox),box1,FALSE,FALSE,0);
+                       box2=gtk_vbox_new(FALSE,4);
+                       gtk_box_pack_start(GTK_BOX(hhbox),box2,FALSE,FALSE,0);
+
+                       ccard[i].m[j].g_en=(gint *)g_malloc(cards[i].mixer[j].groups.groups
+                                                                                          * sizeof(gint));
+                       if( ccard[i].m[j].g_en == NULL ) {
+                               fprintf(stderr,nomem_msg);
+                               g_free(ccard);
+                               return -1;
+                       }
+                       l=0;
+                       for( k=0 ; k<cards[i].mixer[j].groups.groups ; k++ ) {
+                               ccard[i].m[j].g_en[k]=cards[i].mixer[j].group[k].enable;
+                               hbox=gtk_hbox_new(FALSE,2);
+                               b=gtk_toggle_button_new();
+                               gtk_widget_set_usize(b,10,10);
+                               gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+                               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
+                                                                                       ccard[i].m[j].g_en[k]);
+                               gtk_signal_connect(GTK_OBJECT(b),"toggled",
+                                                                  GTK_SIGNAL_FUNC(tb_callback),
+                                                                  (gpointer)&ccard[i].m[j].g_en[k]);
+                               gtk_widget_show(b);
+                               if( cards[i].mixer[j].groups.pgroups[k].index > 0 ) {
+                                       sprintf(gname,"%s %d",
+                                                       cards[i].mixer[j].groups.pgroups[k].name,
+                                                       cards[i].mixer[j].groups.pgroups[k].index);
+                               } else {
+                                       strcpy(gname,cards[i].mixer[j].groups.pgroups[k].name);
+                               }
+                               n_label=gtk_label_new(gname);
+                               gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
+                               gtk_widget_show(n_label);
+                               if( (l&1) ) {
+                                       gtk_box_pack_start(GTK_BOX(box2),hbox,FALSE,FALSE,0);
+                               } else {
+                                       gtk_box_pack_start(GTK_BOX(box1),hbox,FALSE,FALSE,0);
+                               }
+                               l++;
+                               gtk_widget_show(hbox);
+                       }
+                       ccard[i].m[j].ee_en=(gint *)g_malloc(cards[i].mixer[j].ee_n *
+                                                                                                sizeof(gint));
+                       if( ccard[i].m[j].ee_en == NULL ) {
+                               fprintf(stderr,nomem_msg);
+                               g_free(ccard[i].m);
+                               g_free(ccard[i].m[j].g_en);
+                               g_free(ccard);
+                               return -1;
+                       }
+                       for( k=0 ; k<cards[i].mixer[j].ee_n ; k++ ) {
+                               ccard[i].m[j].ee_en[k]=cards[i].mixer[j].ee[k].enable;
+                               hbox=gtk_hbox_new(FALSE,2);
+                               b=gtk_toggle_button_new();
+                               gtk_widget_set_usize(b,10,10);
+                               gtk_box_pack_start(GTK_BOX(hbox),b,FALSE,FALSE,0);
+                               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b),
+                                                                                       ccard[i].m[j].ee_en[k]);
+                               gtk_signal_connect(GTK_OBJECT(b),"toggled",
+                                                                  GTK_SIGNAL_FUNC(tb_callback),
+                                                                  (gpointer)&ccard[i].m[j].ee_en[k]);
+                               gtk_widget_show(b);
+                               if( cards[i].mixer[j].ee[k].e.e.eid.index > 0 ) {
+                                       sprintf(gname,"%s %d",
+                                                       cards[i].mixer[j].ee[k].e.e.eid.name,
+                                                       cards[i].mixer[j].ee[k].e.e.eid.index);
+                               } else {
+                                       strcpy(gname,cards[i].mixer[j].ee[k].e.e.eid.name);
+                               }
+                               n_label=gtk_label_new(gname);
+                               gtk_box_pack_start(GTK_BOX(hbox),n_label,FALSE,FALSE,0);
+                               gtk_widget_show(n_label);
+                               if( (l&1) ) {
+                                       gtk_box_pack_start(GTK_BOX(box2),hbox,FALSE,FALSE,0);
+                               } else {
+                                       gtk_box_pack_start(GTK_BOX(box1),hbox,FALSE,FALSE,0);
+                               }
+                               l++;
+                               gtk_widget_show(hbox);
+                       }
+                       gtk_widget_show(box1);
+                       gtk_widget_show(box2);
+                       gtk_widget_show(hhbox);
+                       gtk_widget_show(box);
+                       gtk_widget_show(frame);
+               }
+       }
+       
+       gtk_widget_show(nb);
+       /* buttons */
+       box=gtk_hbutton_box_new();
+       gtk_button_box_set_layout(GTK_BUTTON_BOX(box),GTK_BUTTONBOX_END);
+       gtk_button_box_set_spacing(GTK_BUTTON_BOX(box),5);
+       gtk_box_pack_end(GTK_BOX(vbox),box,FALSE,FALSE,0);
+
+       b=gtk_button_new_with_label(_("OK"));
+       gtk_box_pack_start(GTK_BOX(box),b,TRUE,TRUE,0);
+       gtk_signal_connect(GTK_OBJECT(b),"clicked",GTK_SIGNAL_FUNC(ok_b),
+                                          (gpointer)FALSE);
+       GTK_WIDGET_SET_FLAGS(b,GTK_CAN_DEFAULT);
+       gtk_widget_show(b);
+       gtk_widget_grab_default(b);
+
+       Tosave=FALSE;
+       b=gtk_button_new_with_label(_("SAVE"));
+       gtk_box_pack_start(GTK_BOX(box),b,TRUE,TRUE,0);
+       gtk_signal_connect(GTK_OBJECT(b),"clicked",GTK_SIGNAL_FUNC(ok_b),
+                                          (gpointer)TRUE);
+       GTK_WIDGET_SET_FLAGS(b,GTK_CAN_DEFAULT);
+       gtk_widget_show(b);
+
+       b=gtk_button_new_with_label(_("CANCEL"));
+       gtk_box_pack_start(GTK_BOX(box),b,TRUE,TRUE,0);
+       gtk_signal_connect(GTK_OBJECT(b),"clicked",GTK_SIGNAL_FUNC(cancel_b),NULL);
+       GTK_WIDGET_SET_FLAGS(b,GTK_CAN_DEFAULT);
+       gtk_widget_show(b);
+
+       gtk_widget_show(box);
+
+       gtk_widget_show(vbox);
+       gtk_widget_show(c_win);
+
+       gtk_grab_add(c_win);
+       gtk_main();
+
+       changed=FALSE;
+
+       if( ok_pushed ) {
+               if ( conf.scroll != scrolled ) changed=TRUE;
+               conf.scroll=scrolled;
+               conf.Esave = Esaved;
+       }
+       
+       for( i=0 ; i<card_num ; i++ ) {
+               for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
+                       if( ok_pushed ) {
+                               if( !changed ) {
+                                       if( cards[i].mixer[j].enable != ccard[i].m[j].m_en )
+                                               changed = TRUE;
+                               }
+                               cards[i].mixer[j].enable=ccard[i].m[j].m_en;
+                               cards[i].mixer[j].enabled=FALSE;
+                               if( !changed ) {
+                                       if( cards[i].mixer[j].p_e != ccard[i].m[j].p_e ||
+                                               cards[i].mixer[j].p_f != ccard[i].m[j].p_f )
+                                               changed=TRUE;
+                               }
+                               cards[i].mixer[j].p_e=ccard[i].m[j].p_e;
+                               cards[i].mixer[j].p_f=ccard[i].m[j].p_f;
+                               for( k=0 ; k<cards[i].mixer[j].groups.groups ; k++ ) {
+                                       if( !changed ) 
+                                               if( cards[i].mixer[j].group[k].enable !=
+                                                       ccard[i].m[j].g_en[k] ) {
+                                                       changed = TRUE;
+                                               }
+                                       cards[i].mixer[j].group[k].enable = ccard[i].m[j].g_en[k];
+                                       cards[i].mixer[j].group[k].enabled=FALSE;
+                               }
+                               for( k=0 ; k<cards[i].mixer[j].ee_n ; k++ ) {
+                                       if( !changed ) 
+                                               if( cards[i].mixer[j].ee[k].enable !=
+                                                       ccard[i].m[j].ee_en[k] ) {
+                                                       changed = TRUE;
+                                               }
+                                       cards[i].mixer[j].ee[k].enable = ccard[i].m[j].ee_en[k];
+                                       cards[i].mixer[j].ee[k].enabled=FALSE;
+                               }
+                       }
+                       g_free(ccard[i].m[j].g_en);
+                       g_free(ccard[i].m[j].ee_en);
+               }
+               g_free(ccard[i].m);
+       }
+       g_free(ccard);
+       if( Tosave ) {
+               conf_write();
+               conf.F_save=FALSE;
+       }
+
+       return changed;
+}
+
+static void tb_callback(GtkToggleButton *b,gint *c) {
+       *c=b->active;
+}
+
+void conf_read( void ) {
+       int i,j,k,err,ln;
+       FILE *fp;
+       gchar rbuf[256],*s;
+       s_mixer *m=NULL;
+       snd_mixer_gid_t gid;
+       snd_mixer_eid_t eid;
+
+       fp=fopen(conf.fna,"rt");
+       if( fp == NULL ) {
+               conf.F_save=TRUE;
+               return;
+       }
+       ln=1;
+       err=0;
+       while( !feof(fp) && err>-5 ) {
+               fgets(rbuf,255,fp);
+               rbuf[255]=0;
+               s=rbuf+2;
+               err=0;
+               switch( rbuf[0] ) {
+               case 'S':
+                       conf.scroll=atoi(s)?TRUE:FALSE;
+                       break;
+               case 'C':
+                       i=atoi(s);
+                       if( i<0 || i>2 ) {
+                               err=-1;
+                       } else conf.wmode=i;
+                       break;
+               case 'W':
+                       sscanf(s,"%d,%d\n",&conf.width,&conf.height);
+                       break;
+               case 'A':
+                       conf.Esave=atoi(s)?TRUE:FALSE;
+                       break;
+               case 'M':
+                       sscanf(s,"%d,%d=%d\n",&i,&j,&k);
+                       if( i<0 || i>=card_num ) {
+                               cread_err(_("Invalied card No."),ln);
+                               err=-10;
+                               break;
+                       }
+                       if( j<0 || j>=cards[i].info.mixerdevs ) {
+                               cread_err(_("Invalied mixer device No."),ln);
+                               err=-10;
+                       }
+                       m=&cards[i].mixer[j];
+                       m->enable=k?TRUE:FALSE;
+                       break;
+               case 'X':
+                       if( m == NULL ) {
+                               cread_err(_("No mixer selected"),ln);
+                               err=-1;
+                       }
+                       switch(i) {
+                       case 0:
+                               m->p_e=FALSE;
+                               m->p_f=FALSE;
+                               break;
+                       case 1:
+                               m->p_e=TRUE;
+                               m->p_f=FALSE;
+                               break;
+                       case 2:
+                               m->p_e=TRUE;
+                               m->p_f=TRUE;
+                       default:
+                               cread_err(_("Invalied value for X"),ln);
+                               err=-1;
+                               break;
+                       }
+                       break;
+               case 'G':
+                       if( m == NULL ) {
+                               cread_err(_("No mixer selected"),ln);
+                               err=-1;
+                       }
+                       s++;
+                       for( i=0 ; *s!='\'' && *s>0 ; i++ ) gid.name[i]=*(s++);
+                       gid.name[i]=0;
+                       if( *s == 0 ) {
+                               cread_err(_("Invalied argument"),ln);
+                               err=-1;
+                               break;
+                       }
+                       s+=2;
+                       sscanf(s,"%d=%d\n",&gid.index,&i);
+                       for( j=0; j<m->groups.groups ; j++ ) {
+                               if( strcmp(gid.name,m->groups.pgroups[j].name) == 0 &&
+                                       gid.index == m->groups.pgroups[j].index ) {
+                                       m->group[j].enable=i?TRUE:FALSE;
+                                       break;
+                               }
+                       }
+                       if( j>=m->groups.groups ) {
+                               cread_err(_("There is no such mixer group"),ln);
+                               err=-1;
+                       }
+                       break;
+               case 'E':
+                       if( m == NULL ) {
+                               cread_err(_("No mixer selected"),ln);
+                               err=-1;
+                       }
+                       s++;
+                       for( i=0 ; *s!='\'' && *s>0 ; i++ ) eid.name[i]=*(s++);
+                       eid.name[i]=0;
+                       if( *s == 0 ) {
+                               cread_err(_("Invalied argument"),ln);
+                               err=-1;
+                               break;
+                       }
+                       s+=2;
+                       sscanf(s,"%d,%d=%d\n",&eid.index,&eid.type,&i);
+                       for( j=0; j<m->ee_n ; j++ ) {
+                               if( strcmp(eid.name,m->ee[j].e.e.eid.name) == 0 &&
+                                       eid.index == m->ee[j].e.e.eid.index &&
+                                       eid.type == m->ee[j].e.e.eid.type ) {
+                                       m->ee[j].enable=i?TRUE:FALSE;
+                                       break;
+                               }
+                       }
+                       if( j>=m->ee_n ) {
+                               cread_err(_("There is no such mixer element"),ln);
+                               err=-1;
+                       }
+                       break;
+               }
+               if( err<0 ) conf.F_save=TRUE;
+               ln++;
+       }
+       fclose(fp);
+}
+static void cread_err(gchar *s,int n ) {
+       fprintf(stderr,_("config %d:%s\n"),n,s);
+}
+
+void conf_write(void) {
+       int i,j,k;
+       FILE *fp;
+       s_mixer *m;
+       s_group *g;
+       s_eelements *ee;
+
+       fp=fopen(conf.fna,"wt");
+       if( fp == NULL ) {
+               chk_cfile();
+               fp=fopen(conf.fna,"wt");
+       }
+       if( fp == NULL ) {
+               fprintf(stderr,_("gamix: config file not saved.\n"));
+               return;
+       }
+       fprintf(fp,"# OPT\n");
+       fprintf(fp,"S %d\n",conf.scroll);
+       fprintf(fp,"C %d\n",conf.wmode);
+       fprintf(fp,"A %d\n",conf.Esave);
+       gdk_window_get_size(window->window,&i,&j);
+       fprintf(fp,"W %d,%d\n",i,j);
+       for( i=0 ; i<card_num ; i++ ) {
+               for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
+                       m=&cards[i].mixer[j];
+                       fprintf(fp,"# Card: %s\n#   Mixer: %s\n",cards[i].info.name,
+                                       m->info.name);
+                       fprintf(fp,"M %d,%d=%d\n",i,j,m->enable);
+                       if( m->p_e ) {
+                               if( m->p_f ) k=2; else k=3;
+                       } else k=0;
+                       fprintf(fp,"X %d\n",k);
+                       for( k=0; k<m->groups.groups ; k++ ) {
+                               g=&cards[i].mixer[j].group[k];
+                               fprintf(fp,"G '%s',%d=%d\n",
+                                               m->groups.pgroups[k].name,m->groups.pgroups[k].index,
+                                               g->enable);
+                       }
+                       for( k=0; k<m->ee_n ; k++ ) {
+                               ee=&cards[i].mixer[j].ee[k];
+                               fprintf(fp,"E '%s',%d,%d=%d\n",
+                                               ee->e.e.eid.name,ee->e.e.eid.index,ee->e.e.eid.type,
+                                               ee->enable);
+                       }
+               }
+       }
+       fclose(fp);
+}
+
+static void chk_cfile( void ) {
+       int i,j,k,err;
+       FILE *fp;
+       DIR *dp;
+       gchar *name;
+
+       k=strlen(g_get_home_dir());
+       name=g_strdup(conf.fna);
+       i=1;
+       j=strlen(name)-1;
+       err=-1;
+       while( i>0 ) {
+               if( err<0 ) {
+                       while( name[j] != '/' ) j--;
+                       name[j]=0;
+                       if( j <= k ) {
+                               fprintf(stderr,"Can not make dir ~/.gamix\n");
+                               g_free(name);
+                               return;
+                       }
+               } else {
+                       while( name[j] != 0 ) j++;
+                       name[j]='/';
+               }
+               err=mkdir(name,S_IRUSR|S_IWUSR|S_IXUSR|
+                                      S_IRGRP|S_IXGRP| S_IROTH|S_IXOTH);
+               if( err<0 ) {
+                       if( errno == ENOENT ) {
+                               i++;
+                       } else {
+                               fprintf(stderr,"Can not make dir %s\n",name);
+                               g_free(name);
+                               return;
+                       }
+               } else {
+                       i--;
+               }
+       }
+}
diff --git a/gamix/gamix.h b/gamix/gamix.h
new file mode 100644 (file)
index 0000000..ee99b4d
--- /dev/null
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <glib.h>
+
+#include <sys/asoundlib.h>
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# undef _
+# undef N_
+# define _(String) dgettext(PACKAGE,String)
+# ifdef gettext_noop
+#  define N_(String) gettext_noop(String)
+# else
+#  define N_(String) (String)
+# endif
+#else
+# define textdomain(String) (String)
+# define gettext(String) (String)
+# define dgettext(Domain,Message) (Message)
+# define dcgettext(Domain,Message,Type) (Message)
+# define bindtextdomain(Domain,Directory) (Domain)
+# define _(String) (String)
+# define N_(String) (String)
+#endif
+
+#define preid(eid) printf("'%s',%d,%d\n",(eid).name,(eid).index,(eid).type)
+
+typedef struct {
+       snd_mixer_element_t e;
+       snd_mixer_element_info_t info;
+       GtkWidget **w;
+       GtkAdjustment **adj;
+       gint card,mdev;
+       gint *chain_en;
+       gint *chain;
+       gint mux_n;
+       snd_mixer_eid_t *mux;
+} s_element;
+
+typedef struct {
+       GtkWidget *v_frame;
+       s_element e;
+       gint enable;
+       gint enabled;
+       gint chain;
+       gint chain_en;
+       GtkWidget *cwb;
+} s_eelements;
+
+typedef struct {
+       snd_mixer_group_t g;
+       GtkWidget *v_frame;
+       s_element *e;
+       gint enable;
+       gint enabled;
+       gint chain_en;
+       gint chain;
+       GtkWidget *cwb;
+} s_group;
+
+typedef struct {
+       snd_mixer_t *handle;
+       snd_mixer_groups_t groups;
+       snd_mixer_info_t info;
+       s_group *group;
+       gint ee_n;
+       s_eelements *ee;
+       GtkWidget *w;
+       gint enable;
+       gint enabled;
+       gboolean p_e;
+       gboolean p_f;
+} s_mixer;
+
+typedef struct {
+       snd_ctl_hw_info_t info;
+       s_mixer *mixer;
+} s_card;
+
+typedef struct {
+       gint wmode;
+       gboolean scroll;
+       gchar *fna;
+       gboolean F_save;
+       gboolean Esave;
+       gint width;
+       gint height;
+} s_conf;
+
+extern GtkWidget *window;
+extern int card_num,mdev_num;
+extern gint card,mdev;
+extern s_card *cards;
+extern s_conf conf;
+extern unsigned char *nomem_msg;
+
+/* probe.c */
+gint probe_mixer( void );
+
+/* mkmixer.c */
+GtkWidget *make_mixer( gint , gint );
+
+/* catch.c */
+void tc_init(void);
+gint time_callback(gpointer);
+
+/* conf_w.c */
+gint conf_win( void );
+void conf_read( void );
+void conf_write( void );
diff --git a/gamix/main.c b/gamix/main.c
new file mode 100644 (file)
index 0000000..0fdb7b4
--- /dev/null
@@ -0,0 +1,241 @@
+
+#include "gamix.h"
+
+GtkWidget *window;
+GtkWidget *main_vbox;
+GtkWidget *mixer_container;
+GtkWidget *exit_item;
+unsigned char *nomem_msg = N_("No enough ememory.\n");
+
+int main(int , char **);
+int disp_mixer( void );
+void disp_toolbar(void);
+static void exit_gtk(GtkWidget *,gpointer);
+static void sel_mctype(GtkWidget *,gpointer);
+static void conf_callback(GtkWidget *,gpointer);
+
+static void exit_gtk(GtkWidget *w,gpointer data) {
+       gtk_main_quit();
+}
+
+int main( int argc , char **argv ) {
+       int i,j;
+       gchar *dirname,*filename;
+
+       i=probe_mixer();
+       if( i < 0 ) {
+               fprintf(stderr,_("Can not make mixer.\n"));
+               return -1;
+       }
+
+#ifdef ENABLE_NLS
+       bindtextdomain (PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
+#endif
+       gtk_set_locale();
+       gtk_init( &argc,&argv);
+
+       dirname = g_strconcat(g_get_home_dir(),"/.gamix",NULL);
+       filename = g_strconcat(dirname, "/gtkrc", NULL);
+       gtk_rc_init();
+       gtk_rc_parse(filename);
+       g_free(filename);
+
+       conf.scroll=TRUE;
+       conf.wmode=1;
+       conf.F_save=FALSE;
+       conf.Esave=FALSE;
+       conf.fna = g_strconcat(dirname,"/Config",NULL);
+       conf.width=0;
+       conf.height=0;
+
+       g_free(dirname);
+
+       conf_read();
+
+       window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+       gtk_signal_connect(GTK_OBJECT(window),"destroy",
+                                          GTK_SIGNAL_FUNC(gtk_main_quit),NULL);
+       gtk_widget_show(window);
+       main_vbox=gtk_vbox_new(FALSE,0);
+       gtk_container_add(GTK_CONTAINER(window),main_vbox);
+       gtk_widget_show(main_vbox);
+
+       disp_toolbar();
+
+       tc_init();
+       gtk_timeout_add(100,(GtkFunction)time_callback,NULL);
+
+       if( disp_mixer()<0 ) return 0;
+
+       gtk_main();
+       if( conf.F_save || conf.Esave ) {
+               conf_write();
+       }
+       g_free(conf.fna);
+       return 0;
+}
+
+void disp_toolbar(void) {
+       GtkWidget *menu,*sub_menu,*sub_item;
+       GtkWidget *frame;
+
+       frame=gtk_frame_new(NULL);
+       gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_OUT);
+       gtk_box_pack_start(GTK_BOX(main_vbox),frame,FALSE,FALSE,0);
+       gtk_widget_show(frame);
+
+       menu=gtk_menu_bar_new();
+       gtk_container_add(GTK_CONTAINER(frame),menu);
+       gtk_widget_show(menu);
+
+       /* Prg menu */
+       sub_menu=gtk_menu_new();
+
+       sub_item=gtk_menu_item_new_with_label(_("config"));
+       exit_item=sub_item;
+       gtk_menu_append(GTK_MENU(sub_menu),sub_item);
+       gtk_signal_connect(GTK_OBJECT(sub_item),"activate",
+                                          GTK_SIGNAL_FUNC(conf_callback),NULL);
+       gtk_widget_show(sub_item);
+
+       sub_item=gtk_menu_item_new_with_label(_("exit"));
+       exit_item=sub_item;
+       gtk_menu_append(GTK_MENU(sub_menu),sub_item);
+       gtk_signal_connect(GTK_OBJECT(sub_item),"activate",
+                                          GTK_SIGNAL_FUNC(exit_gtk),NULL);
+       gtk_widget_show(sub_item);
+
+       sub_item=gtk_menu_item_new_with_label(_("Prog"));
+       gtk_widget_show(sub_item);
+       gtk_menu_item_set_submenu(GTK_MENU_ITEM(sub_item),sub_menu);
+       gtk_menu_bar_append(GTK_MENU_BAR(menu),sub_item);
+
+       /* mixer container type menu*/
+       if( mdev_num > 1 ) {
+               sub_menu=gtk_menu_new();
+
+               sub_item=gtk_menu_item_new_with_label(_("Horizontal"));
+               gtk_menu_append(GTK_MENU(sub_menu),sub_item);
+               gtk_signal_connect(GTK_OBJECT(sub_item),"activate",
+                                                  GTK_SIGNAL_FUNC(sel_mctype),0);
+               gtk_widget_show(sub_item);
+
+               sub_item=gtk_menu_item_new_with_label(_("Vertical"));
+               gtk_menu_append(GTK_MENU(sub_menu),sub_item);
+               gtk_signal_connect(GTK_OBJECT(sub_item),"activate",
+                                                  GTK_SIGNAL_FUNC(sel_mctype),(gpointer)1);
+               gtk_widget_show(sub_item);
+
+               sub_item=gtk_menu_item_new_with_label(_("note book"));
+               gtk_menu_append(GTK_MENU(sub_menu),sub_item);
+               gtk_signal_connect(GTK_OBJECT(sub_item),"activate",
+                                                  GTK_SIGNAL_FUNC(sel_mctype),(gpointer)2);
+               gtk_widget_show(sub_item);
+
+               sub_item=gtk_menu_item_new_with_label(_("C-type"));
+               gtk_widget_show(sub_item);
+               gtk_menu_item_set_submenu(GTK_MENU_ITEM(sub_item),sub_menu);
+               gtk_menu_bar_append(GTK_MENU_BAR(menu),sub_item);
+       }
+}
+
+static void sel_mctype(GtkWidget *w,gpointer n) {
+       int i,j;
+       GtkRequisition rq;
+
+       i=(int)n;
+       if( i == conf.wmode ) return;
+       conf.wmode=i;
+       gtk_container_remove(GTK_CONTAINER(main_vbox),mixer_container);
+       if( (i=disp_mixer()) < 0 ) gtk_signal_emit_by_name(GTK_OBJECT(exit_item),
+                                                                  "activate");
+       gtk_widget_size_request(window,&rq);
+       gdk_window_resize(window->window,rq.width,rq.height);
+}
+
+int disp_mixer( void ) {
+       int i,j;
+       GtkWidget *n_label;
+       GtkWidget *sep,*frame;
+       GtkRequisition rq;
+
+       switch( conf.wmode ) {
+       case 0: /* H */
+               if( conf.scroll ) {
+                       mixer_container=gtk_hbox_new(TRUE,0);
+               } else {
+                       mixer_container=gtk_hbox_new(FALSE,0);
+               }
+               for( i=0 ; i<card_num ; i++ ) {
+                       for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
+                               if( cards[i].mixer[j].enable ) {
+                                       cards[i].mixer[j].w=gtk_frame_new(NULL);
+                                       gtk_frame_set_shadow_type(GTK_FRAME(cards[i].mixer[j].w),
+                                                                                         GTK_SHADOW_ETCHED_IN);
+                                       gtk_widget_show(cards[i].mixer[j].w);
+                                       frame=make_mixer(i,j);
+                                       if( !frame ) return -1;
+                                       gtk_container_add(GTK_CONTAINER(cards[i].mixer[j].w),
+                                                                         frame);
+                                       gtk_box_pack_start(GTK_BOX(mixer_container),
+                                                                          cards[i].mixer[j].w,TRUE,TRUE,2);
+                               }
+                       }
+               }
+               break;
+       case 1: /* V */
+               mixer_container=gtk_vbox_new(FALSE,0);
+               for( i=0 ; i<card_num ; i++ ) {
+                       for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
+                               if( cards[i].mixer[j].enable ) {
+                                       cards[i].mixer[j].w=make_mixer(i,j);
+                                       if( !cards[i].mixer[j].w ) return -1;
+                                       gtk_box_pack_start(GTK_BOX(mixer_container),
+                                                                          cards[i].mixer[j].w,TRUE,TRUE,0);
+                               }
+                       }
+               }
+               break;
+       case 2: /* NoteBook */
+               mixer_container=gtk_notebook_new();
+               gtk_notebook_set_tab_pos(GTK_NOTEBOOK(mixer_container),GTK_POS_TOP);
+               for( i=0 ; i<card_num ; i++ )
+                       for( j=0 ; j<cards[i].info.mixerdevs ; j++ ) {
+                               if( cards[i].mixer[j].enable ) {
+                                       cards[i].mixer[j].w=make_mixer(i,j);
+                                       if( !cards[i].mixer[j].w ) return -1;
+                                       n_label=gtk_label_new(cards[i].mixer[j].info.name);
+                                       gtk_notebook_append_page(GTK_NOTEBOOK(mixer_container),
+                                                                                        cards[i].mixer[j].w,n_label);
+                               }
+                       }
+               break;
+       }
+
+       gtk_box_pack_start(GTK_BOX(main_vbox),mixer_container,TRUE,TRUE,0);
+       gtk_widget_show(mixer_container);
+
+       if( conf.width>0 && conf.height >0 && !conf.F_save ) {
+               gtk_widget_size_request(window,&rq);
+               gdk_window_resize(window->window,conf.width,conf.height);
+               conf.width=0;
+               conf.height=0;
+       }
+       return 0;
+}
+
+static void conf_callback(GtkWidget *w ,gpointer data) {
+       gint err;
+       GtkRequisition rq;
+
+       err=conf_win();
+       if( err < 0 )  gtk_signal_emit_by_name(GTK_OBJECT(exit_item),"activate");
+       if( err ) {
+               gtk_container_remove(GTK_CONTAINER(main_vbox),mixer_container);
+               if( disp_mixer() < 0 ) gtk_signal_emit_by_name(
+                                                                               GTK_OBJECT(exit_item),"activate");
+               gtk_widget_size_request(window,&rq);
+               gdk_window_resize(window->window,rq.width,rq.height);
+       }
+}
diff --git a/gamix/mkmixer.c b/gamix/mkmixer.c
new file mode 100644 (file)
index 0000000..73d01c8
--- /dev/null
@@ -0,0 +1,710 @@
+
+#include "gamix.h"
+
+static gchar *label_3d[]={
+       "wide","volume","center","space","depth","delay","feedback"};
+
+static void close_callback(GtkWidget *,s_mixer *);
+static void volume1_callback(GtkAdjustment *,s_element *);
+static void volume1_sw_callback(GtkToggleButton *,s_element *);
+static void switch1_callback(GtkToggleButton *,s_element *);
+static void switch2_callback(GtkToggleButton *,s_element *);
+static void chain_callback(GtkToggleButton *,s_group *);
+static void accu3_callback(GtkAdjustment *,s_element *);
+static void mux1_callback(GtkItem *,s_element *);
+static void mux2_callback(GtkItem *,s_element *);
+static void sw_3d_callback(GtkToggleButton *,s_element *);
+static void vol_3d_callback(GtkAdjustment *,s_element *);
+static void chain_callback2(GtkToggleButton *,s_eelements *);
+static gint mk_element(s_element *,GtkBox *);
+
+static void close_callback(GtkWidget *w,s_mixer *mixer) {
+       int i,j,err;
+       s_group *g;
+       s_eelements *ee;
+
+       for( i=0 ; i<mixer->groups.groups ; i++ ) {
+               g=&mixer->group[i];
+               g->enabled=FALSE;
+       }
+       for( i=0 ; i<mixer->ee_n ; i++ ) {
+               ee=&mixer->ee[i];
+               ee->enabled=FALSE;
+       }
+       snd_mixer_close(mixer->handle);
+       mixer->handle=NULL;
+}
+
+static void volume1_sw_callback(GtkToggleButton *b,s_element *e) {
+       int i,j,value,err;
+
+       for( i=0 ; i<e->e.data.volume1.voices; i++ ) {
+               if( b == GTK_TOGGLE_BUTTON(e->w[i]) ) break;
+       }
+       value=b->active?1:0;
+       if( e->e.data.volume1.pvoices[i] == value ) return;
+       if( e->e.data.volume1.voices > 1 && *e->chain ) {
+               for( j=0 ; j<e->e.data.volume1.voices; j++ ) {
+                       e->e.data.volume1.pvoices[j]=value;
+                       if( j!= i ) {
+                               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->w[j]),b->active);
+                       }
+               }
+       } else {
+               e->e.data.volume1.pvoices[i]=value;
+       }
+       err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+       if( err < 0 ) {
+               fprintf(stderr,_("mixer element write error: %s\n"),snd_strerror(err));
+       }
+}
+
+static void volume1_callback(GtkAdjustment *adj,s_element *e) {
+       int i,j,value,err;
+
+       for( i=0 ; i<e->e.data.volume1.voices; i++ ) {
+               if( adj == e->adj[i] ) break;
+       }
+       value=-(int)adj->value;
+       if( e->e.data.volume1.pvoices[i] == value ) return;
+       if( e->e.data.volume1.voices > 1 && *e->chain ) {
+               for( j=0 ; j<e->e.data.volume1.voices; j++ ) {
+                       e->e.data.volume1.pvoices[j]=value;
+                       if( j!= i ) {
+                               e->adj[j]->value=adj->value;
+                               gtk_signal_emit_by_name(GTK_OBJECT(e->adj[j]),"value_changed");
+                       }
+               }
+       } else {
+               e->e.data.volume1.pvoices[i]=value;
+       }
+       err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+       if( err < 0 ) {
+               fprintf(stderr,_("mixer element write error: %s\n"),snd_strerror(err));
+       }
+}
+
+static void switch1_callback(GtkToggleButton *b,s_element *e ) {
+       int i,j,k,err;
+
+       for( i=0 ; i<e->e.data.switch1.sw; i++ ) {
+               if( b == (GtkToggleButton *)e->w[i] ) break;
+       }
+       if(     (snd_mixer_get_bit(e->e.data.switch1.psw,i)?TRUE:FALSE) == b->active )
+               return;
+       if( e->e.data.switch1.sw > 1 && *e->chain ) {
+               for( j=0 ; j<e->e.data.switch1.sw; j++ ) {
+                       snd_mixer_set_bit(e->e.data.switch1.psw,j,b->active);
+                       if( j != i )
+                               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->w[j]),b->active);
+               }
+       } else {
+               snd_mixer_set_bit(e->e.data.switch1.psw,i,b->active);
+       }
+       snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+}
+
+static void switch2_callback(GtkToggleButton *b,s_element *e ) {
+       int err;
+
+       e->e.data.switch2.sw=b->active;
+       snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+}
+
+static void chain_callback(GtkToggleButton *b,s_group *g ) {
+       g->chain = b->active;
+}
+
+static void accu3_callback(GtkAdjustment *adj,s_element *e) {
+       int i,j,value,err;
+
+       for( i=0 ; i<e->e.data.accu3.voices; i++ ) {
+               if( adj == e->adj[i] ) break;
+       }
+       value=-(int)adj->value;
+       if( e->e.data.accu3.pvoices[i] == value ) return;
+       if( e->e.data.accu3.voices > 1 && *e->chain ) {
+               for( j=0 ; j<e->e.data.accu3.voices; j++ ) {
+                       e->e.data.accu3.pvoices[j]=value;
+                       if( j!= i ) {
+                               e->adj[j]->value=adj->value;
+                               gtk_signal_emit_by_name(GTK_OBJECT(e->adj[j]),"value_changed");
+                       }
+               }
+       } else {
+               e->e.data.accu3.pvoices[i]=value;
+       }
+       err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+       if( err < 0 ) {
+               fprintf(stderr,_("mixer element write error: %s\n"),snd_strerror(err));
+       }
+}
+
+static void mux1_callback(GtkItem *item,s_element *e ) {
+       int i,ch,no,err;
+
+       ch=(int)gtk_object_get_data(GTK_OBJECT(item),"ch");
+       no=(int)gtk_object_get_data(GTK_OBJECT(item),"no");
+
+       if( strcmp(e->mux[no].name,e->e.data.mux1.poutput[ch].name) == 0 &&
+               e->mux[no].index == e->e.data.mux1.poutput[ch].index &&
+               e->mux[no].type == e->e.data.mux1.poutput[ch].type ) return;
+
+       if( e->chain ) {
+               for( i=0 ; i<e->e.data.mux1.output ; i++ ) {
+                       e->e.data.mux1.poutput[i]=e->mux[no];
+                       if( ch != i ) gtk_option_menu_set_history(
+                                                                                         GTK_OPTION_MENU(e->w[i]),no);
+               }
+       } else {
+               e->e.data.mux1.poutput[ch]=e->mux[no];
+       }
+       err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+       if( err< 0 ) {
+               fprintf(stderr,_("mixer mux1 element write error: %s\n"),snd_strerror(err));
+       }
+}
+
+static void mux2_callback(GtkItem *item,s_element *e ) {
+       int i,no,err;
+
+       no=(int)gtk_object_get_data(GTK_OBJECT(item),"no");
+
+       if( strcmp(e->mux[no].name,e->e.data.mux2.output.name) == 0 &&
+               e->mux[no].index == e->e.data.mux2.output.index &&
+               e->mux[no].type == e->e.data.mux2.output.type ) return;
+
+       e->e.data.mux2.output=e->mux[no];
+       err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+       if( err< 0 ) {
+               fprintf(stderr,_("mixer mux1 element write error: %s\n"),snd_strerror(err));
+       }
+}
+
+static void sw_3d_callback(GtkToggleButton *b,s_element *e ) {
+       int err;
+
+       if( b == (GtkToggleButton *)e->w[0] ) {
+               e->e.data.teffect1.sw = b->active;
+       } else {
+               e->e.data.teffect1.mono_sw = b->active;
+       }
+       err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+}
+
+static void vol_3d_callback(GtkAdjustment *adj,s_element *e) {
+       int i,err,*v,value;
+
+       for( i=0 ; i<7 ; i++ ) {
+               if( adj == e->adj[i] ) break;
+       }
+       v=NULL;
+       switch( i ) {
+       case 0:
+               v=&e->e.data.teffect1.wide;
+               break;
+       case 1:
+               v=&e->e.data.teffect1.volume;
+               break;
+       case 2:
+               v=&e->e.data.teffect1.center;
+               break;
+       case 3:
+               v=&e->e.data.teffect1.space;
+               break;
+       case 4:
+               v=&e->e.data.teffect1.depth;
+               break;
+       case 5:
+               v=&e->e.data.teffect1.delay;
+               break;
+       case 6:
+               v=&e->e.data.teffect1.feedback;
+               break;
+       }
+       value=(int)adj->value;
+       if( v ) {
+               if( value == *v ) return;
+               *v=value;
+       } else return;
+       err=snd_mixer_element_write(cards[e->card].mixer[e->mdev].handle,&e->e);
+       if( err<0 ) {
+               fprintf(stderr,_("3D effect write error: %s\n"),snd_strerror(err));
+       }
+}
+
+static void chain_callback2(GtkToggleButton *b,s_eelements *ee ) {
+       ee->chain = b->active;
+}
+
+GtkWidget *make_mixer( gint c_n , gint m_n ) {
+       int i,j,k,l,err;
+       GtkWidget *mv_box,*m_name;
+       GtkWidget *s_win;
+       GtkWidget *mh_box;
+       GtkWidget *frame;
+       GtkWidget *iv_box;
+       GtkWidget *ih_box;
+       GtkWidget *c_l;
+       char gname[128];
+       s_mixer *mixer;
+       s_group *group;
+       s_element *e;
+       s_eelements *ee;
+
+       if( cards[c_n].mixer[m_n].handle ) {
+               snd_mixer_close(cards[c_n].mixer[m_n].handle);
+       }
+       if( (err=snd_mixer_open(&cards[c_n].mixer[m_n].handle,c_n,m_n)) < 0 ) {
+               return NULL;
+       }
+
+       mixer = &cards[c_n].mixer[m_n];
+
+       mv_box=gtk_vbox_new(FALSE,0);
+       gtk_widget_show(mv_box);
+
+       sprintf(gname,"%s:%s",cards[c_n].info.name,
+                       cards[c_n].mixer[m_n].info.name);
+       m_name=gtk_label_new(gname);
+       gtk_box_pack_start(GTK_BOX(mv_box),m_name,FALSE,FALSE,0);
+       gtk_widget_show(m_name);
+
+       mh_box=gtk_hbox_new(FALSE,2);
+       if( conf.scroll ) {
+               s_win=gtk_scrolled_window_new(NULL,NULL);
+               gtk_box_pack_start(GTK_BOX(mv_box),s_win,TRUE,TRUE,0);
+               gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(s_win),
+                                                                          GTK_POLICY_AUTOMATIC,
+                                                                          GTK_POLICY_NEVER);
+               gtk_widget_show(s_win);
+               gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(s_win),
+                                                                                         mh_box);
+               //gtk_container_add(GTK_CONTAINER(s_win),mh_box);
+       } else {
+               gtk_box_pack_start(GTK_BOX(mv_box),mh_box,TRUE,TRUE,4);
+       }
+       gtk_widget_show(mh_box);
+
+       for( i=0 ; i<mixer->groups.groups ; i++ ) {
+               if( mixer->group[i].enable ) {
+                       group = &mixer->group[i];
+                       group->v_frame=frame=gtk_frame_new(NULL);
+                       gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_OUT);
+                       gtk_box_pack_start(GTK_BOX(mh_box),frame,
+                                                          mixer->p_e,mixer->p_f,0);
+                       iv_box=gtk_vbox_new(FALSE,0);
+                       gtk_container_add(GTK_CONTAINER(frame),iv_box);
+                       group->chain_en=FALSE;
+                       for( j=0 ; j<group->g.elements ; j++ ) {
+                               e=&group->e[j];
+                               e->chain = &group->chain;
+                               e->chain_en = &group->chain_en;
+                               if( mk_element(e,GTK_BOX(iv_box))<0 ) return NULL;
+                       }
+                       if( mixer->group[i].g.gid.index > 0 ) {
+                               sprintf(gname,"%s%d",mixer->group[i].g.gid.name,
+                                               mixer->group[i].g.gid.index);
+                       } else {
+                               sprintf(gname,"%s",mixer->group[i].g.gid.name);
+                       }
+                       ih_box=gtk_hbox_new(FALSE,2);
+                       gtk_box_pack_start(GTK_BOX(iv_box),ih_box,FALSE,FALSE,0);
+                       if( group->chain_en ) {
+                               group->cwb=gtk_toggle_button_new();
+                               gtk_box_pack_start(GTK_BOX(ih_box),group->cwb,
+                                                                  FALSE,FALSE,4);
+                               gtk_widget_set_usize(group->cwb,10,10);
+                               gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(group->cwb)
+                                                                                       ,group->chain);
+                               gtk_widget_show(group->cwb);
+                               gtk_signal_connect(GTK_OBJECT(group->cwb),"toggled",
+                                                                  GTK_SIGNAL_FUNC(chain_callback),
+                                                                  (gpointer)group);
+                               c_l=gtk_label_new(_("Lock"));
+                               gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                               gtk_widget_show(c_l);
+                               gtk_widget_show(ih_box);
+                               if( strlen(gname) > 10 ) {
+                                       j=0;
+                                       while( gname[j]!=' ' && gname[j]!=0 ) j++;
+                                       if( gname[j]!=0 ) {
+                                               gname[j+3]=0;
+                                       }
+                               }
+                       } else {
+                               c_l=gtk_label_new(" ");
+                               gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                               gtk_widget_show(c_l);
+                               if( strlen(gname) > 5 ) {
+                                       j=0;
+                                       while( gname[j]!=' ' && gname[j]!=0 ) j++;
+                                       if( gname[j]!=0 ) {
+                                               gname[j+3]=0;
+                                       }
+                               }
+                       }
+                       gtk_frame_set_label(GTK_FRAME(frame),gname);
+                       gtk_widget_show(ih_box);
+                       gtk_widget_show(iv_box);
+                       gtk_widget_show(frame);
+                       group->enabled=TRUE;
+               } else {
+                       mixer->group[i].enabled=FALSE;
+               }
+       }
+       for( i=0 ; i<mixer->ee_n ; i++ ) {
+               if( mixer->ee[i].enable ) {
+                       ee=&mixer->ee[i];
+                       e=&ee->e;
+                       ee->v_frame=frame=gtk_frame_new(NULL);
+                       gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_OUT);
+                       gtk_box_pack_start(GTK_BOX(mh_box),frame,
+                                                          mixer->p_e,mixer->p_f,0);
+                       iv_box=gtk_vbox_new(FALSE,0);
+                       gtk_container_add(GTK_CONTAINER(frame),iv_box);
+                       ee->chain_en=FALSE;
+                       e->chain=&ee->chain;
+                       e->chain_en=&ee->chain_en;
+                       if( mk_element(e,GTK_BOX(iv_box))<0 ) return NULL;
+                       ih_box=gtk_hbox_new(FALSE,2);
+                       gtk_box_pack_start(GTK_BOX(iv_box),ih_box,FALSE,FALSE,0);
+                       if( e->e.eid.index > 0 ) {
+                               sprintf(gname,"%s%d",e->e.eid.name,e->e.eid.index);
+                       } else {
+                               sprintf(gname,"%s",e->e.eid.name);
+                       }
+                       if( ee->chain_en ) {
+                               ee->cwb=gtk_toggle_button_new();
+                               gtk_box_pack_start(GTK_BOX(ih_box),ee->cwb,FALSE,FALSE,4);
+                               gtk_widget_set_usize(ee->cwb,10,10);
+                               gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ee->cwb)
+                                                                                       ,group->chain);
+                               gtk_widget_show(ee->cwb);
+                               gtk_signal_connect(GTK_OBJECT(ee->cwb),"toggled",
+                                                                  GTK_SIGNAL_FUNC(chain_callback2),
+                                                                  (gpointer)ee);
+                               c_l=gtk_label_new(_("Lock"));
+                               gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                               gtk_widget_show(c_l);
+                               gtk_widget_show(ih_box);
+                               if( strlen(gname) > 10 ) {
+                                       j=0;
+                                       while( gname[j]!=' ' && gname[j]!=0 ) j++;
+                                       if( gname[j]!=0 ) {
+                                               gname[j+3]=0;
+                                       }
+                               }
+                       } else {
+                               c_l=gtk_label_new(" ");
+                               gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                               gtk_widget_show(c_l);
+                       }
+                       gtk_frame_set_label(GTK_FRAME(frame),gname);
+                       gtk_widget_show(ih_box);
+                       gtk_widget_show(iv_box);
+                       gtk_widget_show(frame);
+                       ee->enabled=TRUE;
+               } else {
+                       mixer->ee[i].enabled=FALSE;
+               }
+       }
+       gtk_signal_connect(GTK_OBJECT(mv_box),"destroy",
+                                          GTK_SIGNAL_FUNC(close_callback),(gpointer)mixer);
+       mixer->enabled=TRUE;
+       return mv_box;
+}
+
+#define MIX_3D_VOL(NO,name,min_name,max_name,sname) \
+  if( e->info.data.teffect1.effect & sname ) { \
+    ih_box=gtk_hbox_new(FALSE,2); \
+    gtk_box_pack_start(iv_box,ih_box,FALSE,FALSE,0); \
+    c_l=gtk_label_new(label_3d[NO]); \
+       gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0); \
+       gtk_widget_show(c_l); \
+       gtk_widget_show(ih_box); \
+       e->adj[NO]=(GtkAdjustment *)gtk_adjustment_new( \
+         (gfloat)e->e.data.teffect1.name, \
+         (gfloat)e->info.data.teffect1.min_name-0.5, \
+         (gfloat)e->info.data.teffect1.max_name+1.0, \
+         1.0,1.0,1.0); \
+       gtk_signal_connect(GTK_OBJECT(e->adj[NO]), \
+         "value_changed",GTK_SIGNAL_FUNC(vol_3d_callback),(gpointer)e);\
+       e->w[NO+2]=gtk_hscale_new(GTK_ADJUSTMENT(e->adj[NO])); \
+       gtk_scale_set_draw_value(GTK_SCALE(e->w[NO+2]),FALSE); \
+       gtk_box_pack_start(GTK_BOX(iv_box), e->w[NO+2],FALSE,FALSE,4); \
+       gtk_widget_show(e->w[NO+2]); \
+  } else { ;\
+       e->w[NO+2]=NULL; \
+       e->adj[NO]=NULL; \
+  }
+
+gint mk_element(s_element *e,GtkBox *iv_box) {
+       int i,j,k,err;
+       GtkWidget *ih_box;
+       GtkWidget *menu,*c_l,*item;
+
+       ih_box=gtk_hbox_new(TRUE,0);
+       switch( e->e.eid.type) {
+       case SND_MIXER_ETYPE_VOLUME1:
+               if( (e->info.data.volume1.prange[0].max-
+                        e->info.data.volume1.prange[0].min) == 1 ) {
+                       gtk_box_pack_start(iv_box,ih_box,FALSE,FALSE,0);
+               } else
+                       gtk_box_pack_start(iv_box,ih_box,TRUE,TRUE,0);
+               if( e->e.data.volume1.voices > 1 ) {
+                       *e->chain_en=TRUE;
+                       *e->chain=TRUE;
+               }
+               if( e->w == NULL ) {
+                       e->w = (GtkWidget **)g_malloc( e->e.data.volume1.voices *
+                                                                                  sizeof(GtkWidget *));
+               }
+               if( e->w == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               if( e->adj == NULL ) {
+                       e->adj=(GtkAdjustment **)g_malloc(e->e.data.volume1.voices*
+                                                                                         sizeof(GtkAdjustment *));
+               }
+               if( e->adj==NULL ) {
+                       printf(nomem_msg);
+                       return -1;
+               }
+               for( i=0 ; i<e->e.data.volume1.voices ; i++ ) {
+                       if( (e->info.data.volume1.prange[i].max-
+                                e->info.data.volume1.prange[i].min) == 1 ) {
+                               e->adj[i]=NULL;
+                               e->w[i]=gtk_toggle_button_new_with_label("V");
+                               gtk_box_pack_start(GTK_BOX(ih_box),e->w[i],
+                                                                  FALSE,FALSE,0);
+                               gtk_toggle_button_set_state(
+                                                                       GTK_TOGGLE_BUTTON(e->w[i]),
+                                                                       e->e.data.volume1.pvoices[i]);
+                               gtk_signal_connect(GTK_OBJECT(e->w[i]),"toggled",
+                                                                  GTK_SIGNAL_FUNC(volume1_sw_callback),
+                                                                  (gpointer)e);
+                               gtk_widget_show(e->w[i]);
+                       } else {
+                               e->adj[i]=(GtkAdjustment *)gtk_adjustment_new(
+                                               -(gfloat)e->e.data.volume1.pvoices[i],
+                                               -(gfloat)e->info.data.volume1.prange[i].max-0.5,
+                                               -(gfloat)e->info.data.volume1.prange[i].min+0.5,
+                                               1.0,4.0,1.0);
+                               gtk_signal_connect(GTK_OBJECT(e->adj[i]),"value_changed",
+                                                                  GTK_SIGNAL_FUNC(volume1_callback),
+                                                                  (gpointer)e);
+                               e->w[i]=gtk_vscale_new(GTK_ADJUSTMENT(e->adj[i]));
+                               gtk_scale_set_draw_value(GTK_SCALE(e->w[i]),FALSE);
+                               gtk_box_pack_start(GTK_BOX(ih_box),e->w[i],FALSE,FALSE,4);
+                               gtk_widget_show(e->w[i]);
+                       }
+               }
+               break;
+       case SND_MIXER_ETYPE_SWITCH1:
+               gtk_box_pack_start(iv_box,ih_box,FALSE,FALSE,4);
+               if( e->e.data.switch1.sw > 1 ) {
+                       *e->chain_en=TRUE;
+                       *e->chain=TRUE;
+               }
+               if( e->w == NULL ) {
+                       e->w = (GtkWidget **)g_malloc( e->e.data.switch1.sw *
+                                                                                  sizeof(GtkWidget *));
+               }
+               if( e->w == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               for( i=0 ; i<e->e.data.switch1.sw ; i++ ) {
+                       e->w[i]=gtk_toggle_button_new();
+                       gtk_box_pack_start(GTK_BOX(ih_box),e->w[i],FALSE,FALSE,0);
+                       gtk_widget_set_usize(e->w[i],10,10);
+                       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(e->w[i]),
+                                                                       snd_mixer_get_bit(e->e.data.switch1.psw,i)
+                                                                               );
+                       gtk_signal_connect(GTK_OBJECT(e->w[i]),"toggled",
+                                                          GTK_SIGNAL_FUNC(switch1_callback),(gpointer)e);
+                       gtk_widget_show(e->w[i]);
+               }
+               break;
+       case SND_MIXER_ETYPE_SWITCH2:
+               gtk_box_pack_start(iv_box,ih_box,FALSE,FALSE,4);
+               if( e->w == NULL ) {
+                       e->w = (GtkWidget **)g_malloc(sizeof(GtkWidget *));
+               }
+               if( e->w == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               e->w[0]=gtk_toggle_button_new();
+               gtk_box_pack_start(GTK_BOX(ih_box),e->w[0],FALSE,FALSE,0);
+               gtk_widget_set_usize(e->w[0],10,10);
+               gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(e->w[0]),
+                                                                       e->e.data.switch2.sw);
+               gtk_signal_connect(GTK_OBJECT(e->w[0]),"toggled",
+                                                  GTK_SIGNAL_FUNC(switch2_callback),
+                                                  (gpointer)e);
+               gtk_widget_show(e->w[0]);
+               break;
+       case SND_MIXER_ETYPE_ACCU3:
+               gtk_box_pack_start(iv_box,ih_box,FALSE,FALSE,0);
+               if( e->e.data.accu3.voices > 1 ) {
+                       *e->chain_en=TRUE;
+                       *e->chain=TRUE;
+               }
+               if( e->w == NULL ) {
+                       e->w = (GtkWidget **)g_malloc(e->e.data.accu3.voices *
+                                                                                 sizeof(GtkWidget *));
+               }
+               if( e->w == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               if( e->adj == NULL ) {
+                       e->adj=(GtkAdjustment **)g_malloc(e->e.data.accu3.voices*
+                                                                                         sizeof(GtkAdjustment *));
+               }
+               if( e->adj==NULL ) {
+                       printf(nomem_msg);
+                       return -1;
+               }
+               for( i=0 ; i<e->e.data.accu3.voices ; i++ ) {
+                       e->adj[i]=(GtkAdjustment *)gtk_adjustment_new(
+                                                               -(gfloat)e->e.data.accu3.pvoices[i],
+                                                               -(gfloat)e->info.data.accu3.prange[i].max-0.5,
+                                                               -(gfloat)e->info.data.accu3.prange[i].min+0.5,
+                                                               1.0,1.0,1.0);
+                       gtk_signal_connect(GTK_OBJECT(e->adj[i]),"value_changed",
+                                                          GTK_SIGNAL_FUNC(accu3_callback),(gpointer)e);
+                       e->w[i]=gtk_vscale_new(GTK_ADJUSTMENT(e->adj[i]));
+                       gtk_scale_set_draw_value(GTK_SCALE(e->w[i]),FALSE);
+                       gtk_box_pack_start(GTK_BOX(ih_box),e->w[i],FALSE,FALSE,4);
+                       gtk_widget_show(e->w[i]);
+               }
+               break;
+       case SND_MIXER_ETYPE_MUX1:
+               if( e->e.data.mux1.output > 1 ) {
+                       *e->chain_en=TRUE;
+                       *e->chain=TRUE;
+               }
+               if( e->w == NULL ) {
+                       e->w = (GtkWidget **)g_malloc(e->e.data.mux1.output *
+                                                                                 sizeof(GtkWidget *));
+               }
+               if( e->w == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               for( i=0 ; i<e->e.data.mux1.output ; i++ ) {
+                       e->w[i]=gtk_option_menu_new();
+                       menu=gtk_menu_new();
+                       k=0;
+                       for( j=0 ; j<e->mux_n; j++ ) {
+                               if( strcmp(e->mux[j].name,e->e.data.mux1.poutput[i].name)==0 &&
+                                       e->mux[j].index == e->e.data.mux1.poutput[i].index &&
+                                       e->mux[j].type == e->e.data.mux1.poutput[i].type ) k=j;
+                               item=gtk_menu_item_new_with_label(e->mux[j].name);
+                               gtk_object_set_data(GTK_OBJECT(item),"ch",(gpointer)i);
+                               gtk_object_set_data(GTK_OBJECT(item),"no",(gpointer)j);
+                               gtk_signal_connect(GTK_OBJECT(item),"activate",
+                                                                  GTK_SIGNAL_FUNC(mux1_callback),(gpointer)e);
+                               gtk_menu_append(GTK_MENU(menu),item);
+                               gtk_widget_show(item);
+                       }
+                       gtk_option_menu_set_menu(GTK_OPTION_MENU(e->w[i]),menu);
+                       gtk_box_pack_start(iv_box,e->w[i],FALSE,FALSE,4);
+                       gtk_widget_show(e->w[i]);
+                       gtk_option_menu_set_history(GTK_OPTION_MENU(e->w[i]),k);
+               }
+               break;
+       case SND_MIXER_ETYPE_MUX2:
+               if( e->w == NULL ) {
+                       e->w = (GtkWidget **)g_malloc(sizeof(GtkWidget *));
+               }
+               if( e->w == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               e->w[0]=gtk_option_menu_new();
+               menu=gtk_menu_new();
+               k=0;
+               for( j=0 ; j<e->mux_n; j++ ) {
+                       if( strcmp(e->mux[j].name,e->e.data.mux2.output.name)==0 &&
+                               e->mux[j].index == e->e.data.mux2.output.index &&
+                               e->mux[j].type == e->e.data.mux2.output.type ) k=j;
+                       item=gtk_menu_item_new_with_label(e->mux[j].name);
+                       gtk_object_set_data(GTK_OBJECT(item),"no",(gpointer)k);
+                       gtk_signal_connect(GTK_OBJECT(item),"activate",
+                                                          GTK_SIGNAL_FUNC(mux2_callback),(gpointer)e);
+                       gtk_menu_append(GTK_MENU(menu),item);
+                       gtk_widget_show(item);
+               }
+               gtk_option_menu_set_menu(GTK_OPTION_MENU(e->w[0]),menu);
+               gtk_box_pack_start(iv_box,e->w[0],FALSE,FALSE,4);
+               gtk_widget_show(e->w[0]);
+               gtk_option_menu_set_history(GTK_OPTION_MENU(e->w[0]),k);
+               break;
+       case SND_MIXER_ETYPE_3D_EFFECT1:
+               if( e->w == NULL ) {
+                       e->w = (GtkWidget **)g_malloc(9*sizeof(GtkWidget *));
+               }
+               if( e->w == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       return -1;
+               }
+               if( e->adj == NULL ) {
+                       e->adj=(GtkAdjustment **)g_malloc(7*sizeof(GtkAdjustment *));
+               }
+               if( e->adj==NULL ) {
+                       printf(nomem_msg);
+                       return -1;
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_SW ) {
+                       ih_box=gtk_hbox_new(FALSE,2);
+                       gtk_box_pack_start(iv_box,ih_box,FALSE,FALSE,0);
+                       e->w[0]=gtk_toggle_button_new();
+                       gtk_box_pack_start(GTK_BOX(ih_box),e->w[0],FALSE,FALSE,4);
+                       gtk_widget_set_usize(e->w[0],10,10);
+                       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(e->w[0])
+                                                                               ,e->e.data.teffect1.sw);
+                       gtk_widget_show(e->w[0]);
+                       gtk_signal_connect(GTK_OBJECT(e->w[0]),"toggled",
+                                                          GTK_SIGNAL_FUNC(sw_3d_callback),(gpointer)e);
+                       c_l=gtk_label_new(_("Enable"));
+                       gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                       gtk_widget_show(c_l);
+                       gtk_widget_show(ih_box);
+               } else {
+                       e->w[0]=NULL;
+               }
+               if( e->info.data.teffect1.effect & SND_MIXER_EFF1_MONO_SW ) {
+                       ih_box=gtk_hbox_new(FALSE,2);
+                       gtk_box_pack_start(iv_box,ih_box,FALSE,FALSE,0);
+                       e->w[1]=gtk_toggle_button_new();
+                       gtk_box_pack_start(GTK_BOX(ih_box),e->w[1],FALSE,FALSE,4);
+                       gtk_widget_set_usize(e->w[1],10,10);
+                       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(e->w[1])
+                                                                               ,e->e.data.teffect1.mono_sw);
+                       gtk_widget_show(e->w[1]);
+                       gtk_signal_connect(GTK_OBJECT(e->w[1]),"toggled",
+                                                          GTK_SIGNAL_FUNC(sw_3d_callback),(gpointer)e);
+                       c_l=gtk_label_new(_("MONO"));
+                       gtk_box_pack_start(GTK_BOX(ih_box),c_l,FALSE,FALSE,0);
+                       gtk_widget_show(c_l);
+                       gtk_widget_show(ih_box);
+               } else {
+                       e->w[1]=NULL;
+               }
+               MIX_3D_VOL(0,wide,min_wide,max_wide,SND_MIXER_EFF1_WIDE);
+               MIX_3D_VOL(1,volume,min_volume,max_volume,SND_MIXER_EFF1_VOLUME);
+               MIX_3D_VOL(2,center,min_center,max_center,SND_MIXER_EFF1_CENTER);
+               MIX_3D_VOL(3,space,min_space,max_space,SND_MIXER_EFF1_SPACE);
+               MIX_3D_VOL(4,depth,min_depth,max_depth,SND_MIXER_EFF1_DEPTH);
+               MIX_3D_VOL(5,delay,min_delay,max_delay,SND_MIXER_EFF1_DELAY);
+               MIX_3D_VOL(6,feedback,min_feedback,max_feedback,SND_MIXER_EFF1_FEEDBACK);
+               break;
+       }
+       gtk_widget_show(ih_box);
+       return 0;
+}
diff --git a/gamix/probe.c b/gamix/probe.c
new file mode 100644 (file)
index 0000000..4ff8be6
--- /dev/null
@@ -0,0 +1,370 @@
+
+#include "gamix.h"
+
+int card_num,mdev_num;
+s_card *cards;
+
+static gint ab_chk( s_mixer *,snd_mixer_eid_t * );
+static int s_element_build(snd_mixer_t *,s_element *,snd_mixer_elements_t *,
+                                                  snd_mixer_eid_t ,int , int);
+static gint mk_mux_lst(snd_mixer_t *,snd_mixer_elements_t *,snd_mixer_element_info_t *,snd_mixer_eid_t **);
+
+gint probe_mixer( void ) {
+       int err,i,j,k,l;
+       snd_ctl_t *p_handle;
+       snd_mixer_t *m_handle;
+       snd_mixer_elements_t es;
+       snd_mixer_element_t ee;
+       s_mixer *mixer;
+       s_group *group;
+
+       card_num=snd_cards();
+       cards=(s_card *)g_malloc(sizeof(s_card)*card_num);
+       if( cards == NULL ) {
+               fprintf(stderr,nomem_msg);
+               return -1;
+       }
+       mdev_num=0;
+       for( i = 0 ; i<card_num ; i++ ) {
+               if((err=snd_ctl_open(&p_handle,i))<0 ) {
+                       fprintf(stderr,_("open failed: %s\n"),snd_strerror(err));
+                       return -1;
+               }
+               err=snd_ctl_hw_info(p_handle, &cards[i].info);
+               if(err<0) {
+                       fprintf(stderr,_("hw info failed: %s\n"),snd_strerror(err));
+                       snd_ctl_close(p_handle);
+                       return -1;
+               }
+               cards[i].mixer=(s_mixer *)g_malloc(sizeof(s_mixer)*
+                                                                                  cards[i].info.mixerdevs);
+               if( cards[i].mixer == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       snd_ctl_close(p_handle);
+                       return -1;
+               }
+               mdev_num+=cards[i].info.mixerdevs;
+               for( j=0 ; j<cards[i].info.mixerdevs ; j++) {
+                       mixer=&cards[i].mixer[j];
+                       mixer->handle=NULL;
+                       mixer->ee=NULL;
+                       mixer->ee_n=0;
+                       mixer->enable=TRUE;
+                       mixer->enabled=FALSE;
+                       mixer->p_e=TRUE;
+                       mixer->p_f=TRUE;
+                       if((err=snd_mixer_open(&m_handle,i,j))<0 ) {
+                               fprintf(stderr,_("mixer %d/%d open error: %s\n"),i,j,
+                                               snd_strerror(err));
+                               snd_ctl_close(p_handle);
+                               return -1;
+                       }
+                       if((err=snd_ctl_mixer_info(p_handle,j,&mixer->info))<0) {
+                               fprintf(stderr,_("Mixer info failed: %s\n"),snd_strerror(err));
+                               snd_ctl_close(p_handle);
+                               snd_mixer_close(m_handle);
+                               return -1;
+                       }
+                       bzero(&mixer->groups,sizeof(snd_mixer_groups_t));
+                       if((err=snd_mixer_groups(m_handle,&mixer->groups))<0 ) {
+                               fprintf(stderr,_("Mixer %d/%d groups error: %s\n"),i,i,
+                                               snd_strerror(err));
+                               snd_mixer_close(m_handle);
+                               snd_ctl_close(p_handle);
+                               return -1;
+                       }
+                       mixer->groups.pgroups = (snd_mixer_gid_t *)g_malloc(
+                          mixer->groups.groups_over*sizeof(snd_mixer_eid_t));
+                       if( mixer->groups.pgroups == NULL ) {
+                               fprintf(stderr,nomem_msg);
+                               snd_ctl_close(p_handle);
+                               snd_mixer_close(m_handle);
+                       }
+                       mixer->group=(s_group *)g_malloc(mixer->groups.groups_over *
+                                                                                        sizeof(s_group));
+                       if( mixer->group == NULL ) {
+                               fprintf(stderr,nomem_msg);
+                               snd_ctl_close(p_handle);
+                               snd_mixer_close(m_handle);
+                       }
+                       mixer->groups.groups_size =     mixer->groups.groups_over;
+                       mixer->groups.groups_over =     mixer->groups.groups = 0;
+                       if((err=snd_mixer_groups(m_handle,&mixer->groups))<0 ) {
+                               fprintf(stderr,_("Mixer %d/%d groups (2) error: %s\n"),
+                                               i,j,snd_strerror(err));
+                               snd_ctl_close(p_handle);
+                               snd_mixer_close(m_handle);
+                               return -1;
+                       }
+                       bzero(&es, sizeof(snd_mixer_elements_t));
+                       if( (err=snd_mixer_elements(m_handle,&es))<0 ) {
+                               fprintf(stderr,_("mixer elements read failed: %s"),
+                                               snd_strerror(err));
+                               snd_ctl_close(p_handle);
+                               snd_mixer_close(m_handle);
+                               return -1;
+                       }
+                       es.pelements = (snd_mixer_eid_t *)g_malloc(
+                                                               es.elements_over * sizeof(snd_mixer_eid_t));
+                       if( es.pelements == NULL ) {
+                               fprintf(stderr,nomem_msg);
+                               snd_ctl_close(p_handle);
+                               snd_mixer_close(m_handle);
+                               return -1;
+                       }
+                       es.elements_size = es.elements_over;
+                       es.elements_over = es.elements = 0;
+                       if( (err=snd_mixer_elements(m_handle,&es))<0 ) {
+                               fprintf(stderr,_("mixer elements read failed(2): %s"),
+                                               snd_strerror(err));
+                               snd_ctl_close(p_handle);
+                               snd_mixer_close(m_handle);
+                               return -1;
+                       }
+                       //printf("Card %d mixer %d\n",i,j);
+                       for( k=0 ; k<mixer->groups.groups ; k++ ) {
+                               group=&mixer->group[k];
+                               //printf("  Group %s\n",mixer->groups.pgroups[k].name);
+                               bzero(group,sizeof(snd_mixer_group_t));
+                               group->enable=TRUE;
+                               group->enabled=FALSE;
+                               group->g.gid=mixer->groups.pgroups[k];
+                               if((err=snd_mixer_group_read(m_handle,&group->g)) <0 ) {
+                                       fprintf(stderr,_("Mixer %d/%d group error: %s\n"),i,j,
+                                                       snd_strerror(err));
+                                       snd_ctl_close(p_handle);
+                                       snd_mixer_close(m_handle);
+                                       return -1;
+                               }
+                               group->g.pelements = (snd_mixer_eid_t *)g_malloc(
+                                                       group->g.elements_over*sizeof(snd_mixer_eid_t));
+                               if( group->g.pelements == NULL ) {
+                                       snd_ctl_close(p_handle);
+                                       fprintf(stderr,nomem_msg);
+                                       snd_mixer_close(m_handle);
+                                       return -1;
+                               }
+                               group->g.elements_size = group->g.elements_over;
+                               group->g.elements = group->g.elements_over = 0;
+                               if((err=snd_mixer_group_read(m_handle,&group->g)) <0 ) {
+                                       fprintf(stderr,_("Mixer %d/%d group error (2): %s\n"),i,j,
+                                                       snd_strerror(err));
+                                       snd_ctl_close(p_handle);
+                                       snd_mixer_close(m_handle);
+                                       return -1;
+                               }
+                               group->e=(s_element *)g_malloc(group->g.elements_size*
+                                                                                          sizeof(s_element));
+                               if( group->e == NULL ) {
+                                       fprintf(stderr,nomem_msg);
+                                       snd_ctl_close(p_handle);
+                                       snd_mixer_close(m_handle);
+                                       return -1;
+                               }
+                               for( l=0 ; l<group->g.elements ; l++ ) {
+                                       err=s_element_build(m_handle,&group->e[l],&es,
+                                                                          group->g.pelements[l],i,j);
+                                       if( err<0 ) {
+                                               snd_ctl_close(p_handle);
+                                               snd_mixer_close(m_handle);
+                                               return -1;
+                                       }
+                               }
+                       }
+                       l=0;
+                       for( k=0 ; k<es.elements ; k++ ) {
+                               /*
+                                 printf("Element '%s',%d,%d\n",
+                                 mixer->es.pelements[k].name,
+                                 mixer->es.pelements[k].index,
+                                 mixer->es.pelements[k].type);
+                               */
+                               //if( mixer->es.pelements[k].type > 99 ) {
+                               if( ab_chk(mixer,&es.pelements[k]) ) {
+                                       l++;
+                                       /*
+                                         printf("Element '%s',%d,%d\n",
+                                         es.pelements[k].name,
+                                         es.pelements[k].index,
+                                         es.pelements[k].type);
+                                       */
+                               }
+                       }
+                       mixer->ee_n=l;
+                       //printf("extra %d elements\n",l);
+                       if( l>0 ) {
+                               mixer->ee=(s_eelements *)g_malloc0(l*sizeof(s_eelements));
+                               if( mixer->ee == NULL ) {
+                                       fprintf(stderr,nomem_msg);
+                                       snd_ctl_close(p_handle);
+                                       snd_mixer_close(m_handle);
+                                       return -1;
+                               }
+                               k=0;
+                               while(l>0) {
+                                       l--;
+                                       while( !ab_chk(mixer,&es.pelements[k]) ) k++;
+                                       err=s_element_build(m_handle,&mixer->ee[l].e,&es,
+                                                                               es.pelements[k],i,j);
+
+                                       mixer->ee[l].enable=TRUE;
+                                       mixer->ee[l].enabled=FALSE;
+                                       k++;
+                               }
+                       }
+                       g_free(es.pelements);
+                       snd_mixer_close(m_handle);
+               }
+               snd_ctl_close(p_handle);
+
+       }
+       return 0;
+}
+
+static gint ab_chk( s_mixer *mixer,snd_mixer_eid_t *eid ) {
+       int i,j;
+
+       switch( eid->type ) {
+       case SND_MIXER_ETYPE_SWITCH1:
+       case SND_MIXER_ETYPE_SWITCH2:
+       case SND_MIXER_ETYPE_SWITCH3:
+       case SND_MIXER_ETYPE_MUX1:
+       case SND_MIXER_ETYPE_MUX2:
+       case SND_MIXER_ETYPE_ACCU3:
+       case SND_MIXER_ETYPE_VOLUME1:
+       case SND_MIXER_ETYPE_VOLUME2:
+       case SND_MIXER_ETYPE_3D_EFFECT1:
+               break;
+       default:
+               return FALSE;
+       }
+
+       for( i=0 ; i<mixer->groups.groups ; i++ ) {
+               if( strncmp(mixer->groups.pgroups[i].name,eid->name,2) == 0 ) {
+                       for( j=0 ; j<mixer->group[i].g.elements ; j++ ) {
+                               if( strcmp(mixer->group[i].e[j].e.eid.name , eid->name) == 0 &&
+                                       mixer->group[i].e[j].e.eid.index == eid->index &&
+                                       mixer->group[i].e[j].e.eid.type == eid->type ) return FALSE;
+                       }
+               }
+       }
+       return TRUE;
+}
+
+static int s_element_build(snd_mixer_t *handle,s_element *e,
+                                                  snd_mixer_elements_t *es, snd_mixer_eid_t eid,
+                                                  int c,int m) {
+       int err;
+       bzero(&e->info,sizeof(snd_mixer_element_info_t));
+       bzero(&e->e,sizeof(snd_mixer_element_t));
+       e->e.eid = eid;
+       e->info.eid = eid;
+       if( eid.type != SND_MIXER_ETYPE_SWITCH1 &&
+               eid.type != SND_MIXER_ETYPE_SWITCH2 ) {
+               err=snd_mixer_element_info_build(handle,&e->info);
+               if( err<0 ) {
+                       preid(eid);
+                       fprintf(stderr,_("Mixer element info build failed: %s\n"),
+                                       snd_strerror(err));
+               }
+       }
+       e->w=NULL;
+       e->adj=NULL;
+       e->card=c;
+       e->mdev=m;
+       e->mux_n=0;
+       e->mux=NULL;
+
+       switch( e->e.eid.type ) {
+       case SND_MIXER_ETYPE_SWITCH1:
+       case SND_MIXER_ETYPE_SWITCH2:
+       case SND_MIXER_ETYPE_SWITCH3:
+       case SND_MIXER_ETYPE_MUX1:
+       case SND_MIXER_ETYPE_MUX2:
+       case SND_MIXER_ETYPE_ACCU3:
+       case SND_MIXER_ETYPE_VOLUME1:
+       case SND_MIXER_ETYPE_VOLUME2:
+       case SND_MIXER_ETYPE_3D_EFFECT1:
+               break;
+       default:
+               return 0;
+       }
+
+       err=snd_mixer_element_build(handle,&e->e);
+       if( err<0 ) {
+               preid(eid);
+               fprintf(stderr,_("Mixer element build failed: %s\n"),snd_strerror(err));
+       }
+       if( e->info.eid.type == SND_MIXER_ETYPE_MUX1 || 
+               e->info.eid.type == SND_MIXER_ETYPE_MUX2 ) {
+               e->mux_n=mk_mux_lst(handle,es,&e->info,&e->mux);
+               if( e->mux_n < 0 ) {
+                       snd_mixer_close(handle);
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static gint mk_mux_lst(snd_mixer_t *handle,snd_mixer_elements_t *es,
+                                               snd_mixer_element_info_t *info,
+                                               snd_mixer_eid_t **eids) {
+       int i,j,err,n=0;
+       snd_mixer_routes_t rt;
+       int *ee_lst;
+       snd_mixer_eid_t *eid_l;
+
+       ee_lst=(int *)g_malloc(es->elements*sizeof(int));
+       if( ee_lst == NULL ) {
+               fprintf(stderr,nomem_msg);
+               return -1;
+       }
+       for( i=0 ; i<es->elements ; i++ ) {
+               bzero(&rt,sizeof(rt));
+               rt.eid=es->pelements[i];
+               if(( err=snd_mixer_routes(handle,&rt))<0 ) {
+                       fprintf(stderr,_("Mixer route error: %s\n"),snd_strerror(err));
+                       g_free(ee_lst);
+                       return -1;
+               }
+               if (!rt.routes_over) continue;
+               rt.proutes=(snd_mixer_eid_t *)g_malloc(rt.routes_over *
+                                                                                               sizeof(snd_mixer_eid_t));
+               if( rt.proutes == NULL ) {
+                       fprintf(stderr,nomem_msg);
+                       g_free(ee_lst);
+                       return -1;
+               }
+               rt.routes_size=rt.routes_over;
+               rt.routes=rt.routes_over=0;
+               if( (err=snd_mixer_routes(handle,&rt)) < 0 ) {
+                       fprintf(stderr,_("Mixer route (2) error: %s\n"),snd_strerror(err));
+                       g_free(ee_lst);
+                       return -1;
+               }
+               for( j=0 ; j<rt.routes ; j++ ) {
+                       if( strcmp(rt.proutes[j].name,info->eid.name) == 0 &&
+                               rt.proutes[j].index == info->eid.index &&
+                               rt.proutes[j].type == info->eid.type ) {
+                               ee_lst[n++]=i;
+                               break;
+                       }
+               }
+               g_free(rt.proutes);
+       }
+       if( n == 0 ) {
+               *eids = NULL;
+               return 0;
+       }
+       eid_l = *eids = (snd_mixer_eid_t *)g_malloc(n*sizeof(snd_mixer_eid_t));
+       if( *eids == NULL ) {
+               fprintf(stderr,nomem_msg);
+               g_free(ee_lst);
+               return -1;
+       }
+       for( i=0 ; i<n ; i++ ) {
+               eid_l[i]=es->pelements[ee_lst[i]];
+       }
+       g_free(ee_lst);
+       return n;
+}