--- /dev/null
+GNU GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to
+share and change it. By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users. This General Public
+License applies to most of the Free Software Foundation's software and to
+any other program whose authors commit to using it. (Some other
+Free Software Foundation software is covered by the GNU Library General
+Public License instead.) You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the
+freedom to distribute copies of free software (and charge for this service
+if you wish), that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free programs;
+and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These
+restrictions translate to certain responsibilities for you if you distribute
+copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or
+for a fee, you must give the recipients all the rights that you have. You
+must make sure that they, too, receive or can get the source code. And you
+must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software.
+If the software is modified by someone else and passed on, we want its
+recipients to know that what they have is not the original, so that any
+problems introduced by others will not reflect on the original authors'
+reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program
+proprietary. To prevent this, we have made it clear that any patent must be
+licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under
+the terms of this General Public License. The "Program", below, refers to
+any such program or work, and a "work based on the Program" means
+either the Program or any derivative work under copyright law: that is to
+say, a work containing the Program or a portion of it, either verbatim
+or with modifications and/or translated into another language. (Hereinafter,
+translation is included without limitation in the term
+"modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running the
+Program is not restricted, and the output from the Program is covered only
+if its contents constitute a work based on the Program (independent
+of having been made by running the Program). Whether that is true depends on
+what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code
+as you receive it, in any medium, provided that you conspicuously
+and appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+License and to the absence of any warranty; and give any other recipients of
+the Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it,
+thus forming a work based on the Program, and copy and distribute
+such modifications or work under the terms of Section 1 above, provided that
+you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices stating
+that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in whole
+or in part contains or is derived from the Program or any part
+ thereof, to be licensed as a whole at no charge to all third parties
+under the terms of this License.
+
+ c) If the modified program normally reads commands interactively when
+run, you must cause it, when started running for such interactive
+ use in the most ordinary way, to print or display an announcement
+including an appropriate copyright notice and a notice that there is no
+ warranty (or else, saying that you provide a warranty) and that users
+may redistribute the program under these conditions, and telling the
+ user how to view a copy of this License. (Exception: if the Program
+itself is interactive but does not normally print such an announcement,
+ your work based on the Program is not required to print an
+announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be
+reasonably considered independent and separate works in themselves, then
+this License, and its terms, do not apply to those sections when you
+distribute them as separate works. But when you distribute the same sections
+as part of a whole which is a work based on the Program, the
+distribution of the whole must be on the terms of this License, whose
+permissions for other licensees extend to the entire whole, and thus to each
+and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the
+right to control the distribution of derivative or collective works based on
+the Program.
+
+In addition, mere aggregation of another work not based on the Program with
+the Program (or with a work based on the Program) on a volume
+of a storage or distribution medium does not bring the other work under the
+scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable source
+code, which must be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three years, to
+give any third party, for a charge no more than your cost of physically
+ performing source distribution, a complete machine-readable copy of the
+corresponding source code, to be distributed under the terms of
+ Sections 1 and 2 above on a medium customarily used for software
+interchange; or,
+
+ c) Accompany it with the information you received as to the offer to
+distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program in
+object code or executable form with such an offer, in accord with
+ Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it. For an executable work, complete source code
+means all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation and
+installation of the executable. However, as a special exception, the source
+code distributed need not include anything that is normally distributed
+(in either source or binary form) with the major components (compiler,
+kernel, and so on) of the operating system on which the executable runs,
+unless that component itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to
+copy from a designated place, then offering equivalent access to copy the
+source code from the same place counts as distribution of the source code,
+even though third parties are not compelled to copy the source along
+with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License. Any attempt otherwise to
+copy, modify, sublicense or distribute the Program is void, and will
+automatically terminate your rights under this License. However, parties who
+have received copies, or rights, from you under this License will not have
+their licenses terminated so long as such parties remain in full
+compliance.
+
+5. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute
+the Program or its derivative works. These actions are prohibited by law if
+you do not accept this License. Therefore, by modifying or distributing
+the Program (or any work based on the Program), you indicate your acceptance
+of this License to do so, and all its terms and conditions for
+copying, distributing or modifying the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these terms
+and conditions. You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein. You are not responsible
+for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from
+the conditions of this License. If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at
+all. For example, if a patent license would not permit royalty-free
+redistribution of the Program by all those who receive copies directly or
+indirectly through you, then the only way you could satisfy both it and
+this License would be to refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system, which is implemented by public license
+practices. Many people have made generous contributions to the wide range of
+software distributed through that system in reliance on consistent
+application of that system; it is up to the author/donor to decide if he or
+she is willing to distribute software through any other system and a
+licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an
+explicit geographical distribution limitation excluding those countries, so
+that distribution is permitted only in or among countries not thus excluded.
+In such case, this License incorporates the limitation as if written in
+the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of
+the General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail
+to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free
+Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to
+ask for permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals of
+preserving the free status of all derivatives of our free software and of
+promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE
+EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING
+THE COPYRIGHT HOLDERS
+AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR
+IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+PROGRAM IS WITH YOU.
+SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
+SERVICING, REPAIR OR
+CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER,
+OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS
+PERMITTED ABOVE, BE LIABLE
+TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO
+LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM
+TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS
+BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
\ No newline at end of file
--- /dev/null
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
--- /dev/null
+bin_PROGRAMS = xamixer2
+xamixer2_SOURCES = main.h structs.h xamixer2.c xamixer2.h callbacks.c callbacks.h cinit.c cinit.h display.c display.h util.c util.h config.c config.h switches.c switches.h options.c options.h
+sysconf_DATA = xamixer.conf
+EXTRA_DIST = README COPYING INSTALL AUTHORS NEWS TODO xamixer.home xamixer.conf
--- /dev/null
+/*****************************************************************************
+ callbacks.c - an Alsa based gtk mixer
+ Written by Raistlinn (lansdoct@cs.alfred.edu)
+ Copyright (C) 1998 by Christopher Lansdown
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+******************************************************************************/
+
+/*****************************************************************************/
+/* Begin #include's */
+
+#include "main.h"
+
+/* End #include's */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin Global Variables */
+
+extern GtkWidget *window;
+extern Card *card; /* And array of the cards */
+extern int cards; /* The number of cards in the system. */
+extern Config config; /* The system config */
+
+/* End Global Variables */
+/*****************************************************************************/
+
+
+void adjust_teffect1(GtkWidget *widget, CBData *data)
+{
+ int i, j, err;
+ Group *group;
+
+ i = data->element;
+ j = data->index;
+ group = data->group;
+
+ switch(j) {
+ case TYPE_SW:
+ if(GTK_TOGGLE_BUTTON(widget)->active)
+ group->element[i].data.teffect1.sw = 1;
+ else
+ group->element[i].data.teffect1.sw = 0;
+ break;
+ case TYPE_MONO_SW:
+ if(GTK_TOGGLE_BUTTON(widget)->active)
+ group->element[i].data.teffect1.mono_sw = 1;
+ else
+ group->element[i].data.teffect1.mono_sw = 0;
+ break;
+ case TYPE_WIDE:
+ group->element[i].data.teffect1.wide =
+ (int)GTK_ADJUSTMENT(widget)->value;
+ break;
+ case TYPE_VOLUME:
+ group->element[i].data.teffect1.volume =
+ (int)GTK_ADJUSTMENT(widget)->value;
+ break;
+ case TYPE_CENTER:
+ group->element[i].data.teffect1.center =
+ (int)GTK_ADJUSTMENT(widget)->value;
+ break;
+ case TYPE_SPACE:
+ group->element[i].data.teffect1.space =
+ (int)GTK_ADJUSTMENT(widget)->value;
+ break;
+ case TYPE_DEPTH:
+ group->element[i].data.teffect1.depth =
+ (int)GTK_ADJUSTMENT(widget)->value;
+ break;
+ case TYPE_DELAY:
+ group->element[i].data.teffect1.delay =
+ (int)GTK_ADJUSTMENT(widget)->value;
+ break;
+ case TYPE_FEEDBACK:
+ group->element[i].data.teffect1.feedback =
+ (int)GTK_ADJUSTMENT(widget)->value;
+ break;
+ default:
+ printf("Hit the default in adjust_teffect1 - this is bad.\n");
+ break;
+ }
+
+ /* Now let's write the new value to the card */
+ if ((err = snd_mixer_element_write(data->handle, &group->element[i])) < 0) {
+ printf("3D Effect Mixer element write error: %s\n", snd_strerror(err));
+ }
+
+ return;
+}
+void adjust_switch1(GtkWidget *widget, CBData *data)
+{
+ int i, j, err;
+
+ i = data->element;
+ j = data->index;
+
+ if(GTK_TOGGLE_BUTTON(widget)->active)
+ data->group->element[i].data.switch1.psw[j / sizeof(unsigned int)] |=
+ (1 << (j % sizeof(unsigned int)));
+ else
+ data->group->element[i].data.switch1.psw[j / sizeof(unsigned int)] &=
+ ~(1 << (j % sizeof(unsigned int)));
+
+ /* Now let's write the new value to the card */
+ if ((err = snd_mixer_element_write(data->handle, &data->group->element[i])) < 0) {
+ printf("Mixer element write error: %s\n", snd_strerror(err));
+ }
+
+ return;
+}
+
+void adjust_volume1(GtkWidget *widget, CBData *data)
+{
+ register int volume;
+ int i, j, err;
+
+ i = data->element;
+ j = data->index;
+
+ volume = (int)GTK_ADJUSTMENT(data->group->gtk[i].adjust[j])->value;
+ data->group->element[i].data.volume1.pvoices[j] = volume;
+
+ /* Now let's write the new value to the card */
+ if ((err = snd_mixer_element_write(data->handle, &data->group->element[i])) < 0) {
+ printf("Mixer element write error: %s\n", snd_strerror(err));
+ }
+
+
+ return;
+}
+
+
+void adjust_switch2(GtkWidget *widget, CBData *data)
+{
+ int i, j, err;
+
+ i = data->element;
+ j = data->index;
+
+ if(GTK_TOGGLE_BUTTON(data->group->gtk[i].interface[j])->active) {
+ data->group->element[i].data.switch2.sw = 1;
+ } else {
+ data->group->element[i].data.switch2.sw = 0;
+ }
+
+ /* Now let's write the new value to the card */
+ if ((err = snd_mixer_element_write(data->handle, &data->group->element[i])) < 0) {
+ printf("Mixer element write error: %s\n", snd_strerror(err));
+ }
+
+ return;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* Begin #include statements */
+
+
+
+/* End #include statements */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/* Begin function prototypes */
+
+void adjust_volume1(GtkWidget *widget, CBData *data);
+void adjust_switch1(GtkWidget *widget, CBData *data);
+void adjust_switch2(GtkWidget *widget, CBData *data);
+void adjust_teffect1(GtkWidget *widget, CBData *data);
+
+/* End function prototypes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin #define statements */
+
+
+
+/* End #define statements */
+/*****************************************************************************/
--- /dev/null
+/*****************************************************************************
+ cinit.c - routines to initialize the mixer devices
+ Written by Raistlinn (lansdoct@cs.alfred.edu)
+ Copyright (C) 1998 by Christopher Lansdown
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+******************************************************************************/
+
+
+/*****************************************************************************/
+/* Begin #include's */
+
+#include "main.h"
+
+/* End #include's */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin Global Variables */
+
+extern Card *card; /* And array of the cards */
+extern int cards; /* The number of cards in the system. */
+extern Config config; /* The system config */
+
+/* End Global Variables */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin function prototypes */
+
+int init_group(void *handle, Group *group);
+int init_element_route(void *handle, snd_mixer_routes_t *routes, snd_mixer_eid_t *eid);
+int misc_group_hack(Mixer *mixer, int index);
+
+/* End function prototypes */
+/*****************************************************************************/
+
+int init_cards()
+{
+ int i,j,k;
+ int err;
+ void *handle;
+
+ cards = snd_cards();
+ card = calloc(cards, sizeof(Card));
+ for(i = 0; i < cards; i++) {
+ /* Open the hardware */
+ if((err = snd_ctl_open(&handle, i)) < 0) {
+ printf("Unable to open card #%i!\nError: %s\n", i, snd_strerror(err));
+ card[i].mixer = NULL;
+ card[i].number = -1;
+ continue;
+ } else {
+ card[i].number = i;
+ }
+
+
+ /* Get the hardware info - the primary use of this is to find out how many
+ mixer devices the card has, but it's also useful to find out the human-readable
+ name of the card. */
+ if((err = snd_ctl_hw_info(handle, &card[i].hw_info)) < 0) {
+ printf("Unable to get hardware information about card #%i!\nError: %s\n",
+ i, snd_strerror(err));
+ printf("Trying to guess the appropriate values.\n");
+ card[i].hw_info.mixerdevs = 1;
+ }
+
+
+ /* Allocate out the mixer array */
+ card[i].mixer = calloc(card[i].hw_info.mixerdevs, sizeof(Mixer));
+
+ for(j = 0; j < card[i].hw_info.mixerdevs; j++) {
+ /* Open the mixer to begin with. Isn't it funny how there's all this
+ nice generalized code that can handle nearly any situation, and it
+ will be necessary in only a very small percentage of the situations.
+ Oh well, I guess that that's what distinguishes us from windows. :-) */
+ if((err = snd_mixer_open(&card[i].mixer[j].handle, i, j)) < 0) {
+ printf("Unable to open mixer #%i on card #%i~\nError: %s\n",
+ j, i, snd_strerror(err));
+ card[i].mixer[j].number = -1;
+ } else {
+ card[i].mixer[j].number = j;
+ }
+
+ /* Get the mixer info */
+ if((err = snd_mixer_info(card[i].mixer[j].handle, &card[i].mixer[j].info)) < 0) {
+ printf("Unable to get the info for mixer #%i on card %i! Error: %s\n", j, i, snd_strerror(err));
+ printf("There's not much more I can do on this mixer.");
+ printf(" Shutting it down.\n");
+ if((err = snd_mixer_close(card[i].mixer[j].handle)) < 0) {
+ printf("Oh well. I couldn't even close the mixer. I suspect that something is seriously wrong here. Good luck.\n");
+ }
+ card[i].mixer[j].number = -1;
+ continue;
+ }
+
+ bzero(&card[i].mixer[j].groups, sizeof(snd_mixer_groups_t));
+
+ if ((err = snd_mixer_groups(card[i].mixer[j].handle,
+ &card[i].mixer[j].groups)) < 0) {
+ printf("Mixer %i/%i groups error: %s",
+ i, j, snd_strerror(err));
+ return -1;
+ }
+
+ /* Allocate the space for the group array */
+ card[i].mixer[j].groups.pgroups = (snd_mixer_gid_t *)
+ calloc(card[i].mixer[j].groups.groups_over,
+ sizeof(snd_mixer_gid_t));
+
+ if (!card[i].mixer[j].groups.pgroups) {
+ printf("No enough memory");
+ return -1;
+ }
+
+ card[i].mixer[j].groups.groups_size = card[i].mixer[j].info.groups;
+ card[i].mixer[j].groups.groups_over = card[i].mixer[j].groups.groups = 0;
+ if ((err = snd_mixer_groups(card[i].mixer[j].handle,
+ &card[i].mixer[j].groups)) < 0) {
+ printf("Mixer %i/%i groups (2) error: %s",
+ i, j, snd_strerror(err));
+ return -1;
+ }
+
+ /* Allocate the space for the array of the groups - this is more than
+ just their gid's, it's got group-specific info in it */
+ card[i].mixer[j].group = calloc(card[i].mixer[j].info.groups + 1,
+ sizeof(Group));
+
+ /* get the group structures filled out */
+ for(k = 0; k < card[i].mixer[j].info.groups; k++) {
+ card[i].mixer[j].group[k].group.gid =
+ card[i].mixer[j].groups.pgroups[k];
+
+ init_group(card[i].mixer[j].handle,
+ &card[i].mixer[j].group[k]);
+
+ }
+ misc_group_hack(&card[i].mixer[j], k);
+
+ }
+
+
+ if((err = snd_ctl_close(handle)) < 0) {
+ printf("strange, there was an error closing card #%i!\nError: %s\n",
+ i, snd_strerror(err));
+ printf("Oh well.\n");
+ }
+ }
+
+
+ /* return a successful execution. */
+ return 0;
+}
+
+int misc_group_hack(Mixer *mixer, int index)
+{
+ /* This code is largely copied straight from amixer. - God I love the GPL. */
+ snd_mixer_elements_t elements;
+ snd_mixer_eid_t *element;
+ snd_mixer_group_t *group;
+ int err, idx, gdx, idx2;
+ int flag;
+ int count=0; /* The count of elements not in any group */
+ snd_mixer_eid_t **array;
+
+ bzero(&elements, sizeof(elements));
+ if ((err = snd_mixer_elements(mixer->handle, &elements)) < 0) {
+ printf("Mixer elements error: %s", snd_strerror(err));
+ return -1;
+ }
+ elements.pelements = (snd_mixer_eid_t *)malloc(elements.elements_over *
+ sizeof(snd_mixer_eid_t));
+ if (!elements.pelements) {
+ printf("Not enough memory");
+ return -1;
+ }
+ elements.elements_size = elements.elements_over;
+ elements.elements_over = elements.elements = 0;
+ if ((err = snd_mixer_elements(mixer->handle, &elements)) < 0) {
+ printf("Mixer elements (2) error: %s", snd_strerror(err));
+ return -1;
+ }
+
+ /* Allocate the temporary array to hold the mixer ID structs */
+ array = malloc(elements.elements * sizeof(snd_mixer_eid_t *));
+ if(!array)
+ printf("Not enough memory.\n");
+
+
+ for (idx = 0; idx < elements.elements; idx++) {
+ element = &elements.pelements[idx];
+ flag = 0; /* The flag will be set if the same element name & type
+ is encountered */
+ for(gdx = 0; gdx < mixer->info.groups; gdx++) {
+ group = &mixer->group[gdx].group;
+ for(idx2 = 0; idx2 < group->elements; idx2++) {
+ if(group && element)
+ if(group->pelements[idx2].type == element->type &&
+ is_same(group->pelements[idx2].name, element->name))
+ flag = 1;
+ }
+ }
+ if(!flag) {
+ /* We found a mixer element that's not in a group */
+ array[count] = element;
+ count++;
+ if(count > elements.elements)
+ printf("Houston, we have a problem.\n");
+ }
+ }
+
+ /* Set up the group member */
+ strncpy(mixer->group[index].group.gid.name, "Miscellaneous\0", 24);
+ mixer->group[index].group.gid.index = 0;
+ mixer->group[index].group.elements_size = 0; /* I hope that this doesn't matter */
+ mixer->group[index].group.elements = count;
+ mixer->group[index].group.elements_over = 0; /* I hope tha this doesn't matter */
+
+
+ mixer->group[index].group.pelements = (snd_mixer_eid_t *)malloc(count *
+ sizeof(snd_mixer_eid_t));
+ mixer->group[index].routes = calloc(mixer->group[index].group.elements,
+ sizeof(snd_mixer_routes_t));
+ mixer->group[index].element = calloc(mixer->group[index].group.elements,
+ sizeof(snd_mixer_element_t));
+ mixer->group[index].einfo = calloc(mixer->group[index].group.elements,
+ sizeof(snd_mixer_element_info_t));
+ mixer->group[index].gtk = calloc(mixer->group[index].group.elements,
+ sizeof(Gtk_Channel));
+ /* Copy the snd_mixer_eid_t structures into the new group structure and init the routes */
+
+ for(idx = 0; idx < count; idx++) {
+ mixer->group[index].group.pelements[idx] = *array[idx];
+
+ mixer->group[index].einfo[idx].eid = mixer->group[index].group.pelements[idx];
+ if(snd_mixer_element_has_info(&mixer->group[index].group.pelements[idx]) == 1)
+ if((err =
+ snd_mixer_element_info_build(mixer->handle,
+ &mixer->group[index].einfo[idx])) < 0) {
+ printf("Unable to get element information for element %s! ",
+ mixer->group[index].group.pelements[idx].name);
+ printf("Error: %s.\n", snd_strerror(err));
+ }
+
+ mixer->group[index].element[idx].eid = mixer->group[index].group.pelements[idx];
+ if((err = snd_mixer_element_build(mixer->handle,
+ &mixer->group[index].element[idx])) < 0) {
+ printf("Unable to read element %s! ",
+ mixer->group[index].group.pelements[idx].name);
+ printf("Error: %s.\n", snd_strerror(err));
+ }
+
+ init_element_route(mixer->handle,
+ &mixer->group[index].routes[idx],
+ &mixer->group[index].group.pelements[idx]);
+ }
+
+
+
+
+
+ /* Increase the number of groups to include the new group */
+ mixer->info.groups++;
+
+ if(elements.pelements)
+ free(elements.pelements);
+ if(array)
+ free(array);
+
+ return 1;
+}
+
+
+int init_group(void *handle, Group *group)
+{
+ /* This is largely a mess copied from amixer that gets the group info in a very strange
+ way, I wish that I knew how it really worked. Anyhow, once we get the group into
+ and the info about the elements in the group, we'll set up the element array. */
+ int idx, err;
+
+ if((err = snd_mixer_group(handle,
+ &group->group)) < 0) {
+ printf("Unable to get info for group %s! ", group->group.gid.name);
+ printf("Error: %s\n", snd_strerror(err));
+ printf("elements_size = %i, elements_over=%i, elements=%i\n",
+ group->group.elements_size,
+ group->group.elements_over,
+ group->group.elements);
+ return 0;
+ }
+ group->group.pelements = (snd_mixer_eid_t *)calloc(group->group.elements_over,
+ sizeof(snd_mixer_eid_t));
+ if (!group->group.pelements) {
+ printf("Not enough memory...");
+ return 0;
+ }
+ group->group.elements_size = group->group.elements_over;
+ group->group.elements = group->group.elements_over = 0;
+ if ((err = snd_mixer_group(handle, &group->group)) < 0) {
+ printf("Unable to get second group info for group %s. Error: %s\n",
+ group->group.gid.name, snd_strerror(err));
+ printf("elements_size = %i, elements_over=%i, elements=%i\n",
+ group->group.elements_size,
+ group->group.elements_over,
+ group->group.elements);
+ return 0;
+ }
+
+
+ /* Allocate out the arrays for the elements and element info */
+ group->element = calloc(group->group.elements, sizeof(snd_mixer_element_t));
+ group->einfo = calloc(group->group.elements, sizeof(snd_mixer_element_info_t));
+ group->routes = calloc(group->group.elements, sizeof(snd_mixer_routes_t));
+ group->gtk = calloc(group->group.elements, sizeof(Gtk_Channel));
+
+ /* Now go through and get that info */
+ for (idx = 0; idx < group->group.elements; idx++) {
+ group->einfo[idx].eid = group->group.pelements[idx];
+ if(snd_mixer_element_has_info(&group->group.pelements[idx]) == 1)
+ if((err = snd_mixer_element_info_build(handle, &group->einfo[idx])) < 0) {
+ printf("Unable to get element information for element %s! ",
+ group->group.pelements[idx].name);
+ printf("Error: %s.\n", snd_strerror(err));
+ }
+
+ group->element[idx].eid = group->group.pelements[idx];
+ if((err = snd_mixer_element_build(handle, &group->element[idx])) < 0) {
+ printf("Unable to read element %s! ",
+ group->group.pelements[idx].name);
+ printf("Error: %s.\n", snd_strerror(err));
+ }
+
+ init_element_route(handle, &group->routes[idx], &group->group.pelements[idx]);
+
+ }
+
+
+ return 1;
+}
+
+
+int init_element_route(void *handle, snd_mixer_routes_t *routes, snd_mixer_eid_t *eid)
+{
+ int err, idx;
+ /* Most of this code is taken straight from amixer as well. */
+ /* This just gets the routes for the mixer element and stores them. */
+
+ bzero(routes, sizeof(snd_mixer_routes_t));
+ routes->eid = *eid;
+ if ((err = snd_mixer_routes(handle, routes)) < 0) {
+ printf("Element %s route error: %s", eid->name, snd_strerror(err));
+ return -1;
+ }
+ if (!routes->routes_over)
+ return 0;
+ routes->proutes = (snd_mixer_eid_t *)malloc(routes->routes_over *
+ sizeof(snd_mixer_eid_t));
+ if (!routes->proutes) {
+ printf("No enough memory...");
+ return -1;
+ }
+ routes->routes_size = routes->routes_over;
+ routes->routes = routes->routes_over = 0;
+ if ((err = snd_mixer_routes(handle, routes)) < 0) {
+ printf("Element (2) %s route error: %s", eid->name, snd_strerror(err));
+ return -1;
+ }
+
+ return 1;
+}
+
--- /dev/null
+/*****************************************************************************/
+/* Begin #include statements */
+
+/* End #include statements */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin function prototypes */
+
+int init_cards();
+
+/* End function prototypes */
+/*****************************************************************************/
+
+
+
+/*****************************************************************************/
+/* Begin #define statements */
+
+
+/* End #define statements */
+/*****************************************************************************/
+
+
+
--- /dev/null
+/*****************************************************************************
+ config.c - parses the config file
+ Written by Raistlinn (lansdoct@cs.alfred.edu)
+ Copyright (C) 1998 by Christopher Lansdown
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+******************************************************************************/
+
+/*****************************************************************************/
+/* Begin #include's */
+
+#include "main.h"
+
+/* End #include's */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin #define's */
+
+#define CHANNEL_SIZE 64
+#define LABEL_SIZE 1024
+
+/* End #define's */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin Global Variables */
+
+extern Card *card; /* And array of the cards */
+extern int cards; /* The number of cards in the system. */
+Config config; /* The global config */
+
+/* End Global Variables */
+/*****************************************************************************/
+
+int config_init()
+{
+ /* Initialize the values to some reasonable defaults */
+ config.flags &= 0;
+ config.labels = NULL;
+ config.xpm = NULL;
+ config.icon = NULL;
+ config.mute = "M";
+ config.unmute = NULL;
+ config.simul = "|-|";
+ config.unsimul = NULL;
+ config.rec = "Rec";
+ config.unrec = NULL;
+ config.scale = 100;
+ config.x_pos = -1;
+ config.y_pos = -1;
+ config.padding = 5;
+ config.cdisplay = NULL;
+
+ return 1;
+}
+
+int config_read(const char *file)
+{
+ char *home_dir, *home_env;
+ FILE *stream;
+ char line[1025], *chr;
+ int state = 0; /* 0 = general config; 1 = history */
+ unsigned int i = 0;
+ int linelen = 0;
+ char channel[CHANNEL_SIZE]; /* The name of the channel */
+ char label[LABEL_SIZE]; /* The label or xpm name */
+ int linenum = 0;
+
+ stream = fopen(file, "r");
+
+ /* If there is no initialized value */
+ if(stream == NULL)
+ return TRUE;
+
+ while(fgets(line, 1024, stream)){
+ linenum++;
+ /* Get wrid of comments */
+ if(is_comment(line))
+ continue;
+ strip_comment(line);
+
+ /* Convert the line to upper case so that matches aren't case
+ sensitive (if not in history)*/
+ linelen = strlen(line);
+
+ if(strstr(line, "Position")) {
+ if(sscanf(line, "Position %i %i", &config.x_pos, &config.y_pos) < 2)
+ config.x_pos = config.y_pos = -1;
+ }
+ else if(strstr(line, "ShowCardName"))
+ config.flags |= CONFIG_SHOW_CARD_NAME;
+ else if(strstr(line, "ShowMixerNumber"))
+ config.flags |= CONFIG_SHOW_MIXER_NUMBER;
+ else if(strstr(line, "ShowMixerName"))
+ config.flags |= CONFIG_SHOW_MIXER_NAME;
+ else if(strstr(line, "IconXpm"))
+ if(sscanf(line, "IconXpm %s", label) < 1)
+ printf("Bad IconXpm entry at line %i.\n", linenum);
+ else {
+ config.icon = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.icon, label);
+ config.flags |= CONFIG_ICON_XPM;
+ }
+ else if(strstr(line, "IgnoreXpms"))
+ config.flags &= ~CONFIG_USE_XPMS;
+ else if(strstr(line, "UseXpms"))
+ config.flags |= CONFIG_USE_XPMS;
+ else if(strstr(line, "unMuteXpmLeft"))
+ if(sscanf(line, "unMuteXpmLeft %s", label) < 1)
+ printf("Bad unMuteXpmLeft entry at line %i.\n", linenum);
+ else {
+ config.unmute_l = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.unmute_l, label);
+ config.flags |= CONFIG_UNMUTE_XPM_L;
+ }
+ else if(strstr(line, "unMuteXpm"))
+ if(sscanf(line, "unMuteXpm %s", label) < 1)
+ printf("Bad unMuteXpm entry at line %i.\n", linenum);
+ else {
+ config.unmute = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.unmute, label);
+ config.flags |= CONFIG_UNMUTE_XPM;
+ }
+ else if(strstr(line, "unRecXpm"))
+ if(sscanf(line, "unRecXpm %s", label) < 1)
+ printf("Bad unRecXpm entry at line %i.\n", linenum);
+ else {
+ config.unrec = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.unrec, label);
+ config.flags |= CONFIG_UNREC_XPM;
+ }
+ else if(strstr(line, "unSimulXpm"))
+ if(sscanf(line, "unSimulXpm %s", label) < 1)
+ printf("Bad unSimulXpm entry at line %i.\n", linenum);
+ else {
+ config.unsimul = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.unsimul, label);
+ config.flags |= CONFIG_UNSIMUL_XPM;
+ }
+ else if(strstr(line, "MuteLabel"))
+ if(sscanf(line, "MuteLabel %s", label) < 1)
+ printf("Bad MuteLabel entry at line %i.\n", linenum);
+ else {
+ config.mute = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.mute, label);
+ config.flags &= ~CONFIG_MUTE_XPM;
+ }
+ else if(strstr(line, "SimulLabel"))
+ if(sscanf(line, "SimulLabel %s", label) < 1)
+ printf("Bad SimulLabel entry at line %i.\n", linenum);
+ else {
+ config.simul = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.simul, label);
+ config.flags &= ~CONFIG_SIMUL_XPM;
+ }
+ else if(strstr(line, "RecLabel"))
+ if(sscanf(line, "RecLabel %s", label) < 1)
+ printf("Bad RecLabel entry at line %i.\n", linenum);
+ else {
+ config.rec = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.rec, label);
+ config.flags &= ~CONFIG_REC_XPM;
+ }
+ else if(strstr(line, "MuteXpmLeft"))
+ if(sscanf(line, "MuteXpmLeft %s", label) < 1)
+ printf("Bad MuteXpmLeft entry at line %i.\n", linenum);
+ else {
+ config.mute_l = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.mute_l, label);
+ config.flags |= CONFIG_MUTE_XPM_L;
+ }
+ else if(strstr(line, "MuteXpm"))
+ if(sscanf(line, "MuteXpm %s", label) < 1)
+ printf("Bad MuteXpm entry at line %i.\n", linenum);
+ else {
+ config.mute = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.mute, label);
+ config.flags |= CONFIG_MUTE_XPM;
+ }
+ else if(strstr(line, "RecXpm"))
+ if(sscanf(line, "RecXpm %s", label) < 1)
+ printf("Bad RecXpm entry at line %i.\n", linenum);
+ else {
+ config.rec = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.rec, label);
+ config.flags |= CONFIG_REC_XPM;
+ }
+ else if(strstr(line, "SimulXpm"))
+ if(sscanf(line, "SimulXpm %s", label) < 1)
+ printf("Bad SimulXpm entry at line %i.\n", linenum);
+ else {
+ config.simul = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.simul, label);
+ config.flags |= CONFIG_SIMUL_XPM;
+ }
+ else if(strstr(line, "BackgroundXpm"))
+ if(sscanf(line, "BackgroundXpm %s", label) < 1)
+ printf("Bad BackgroundXpm entry at line %i.\n", linenum);
+ else {
+ config.background = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(config.background, label);
+ config.flags |= CONFIG_BACKGROUND_XPM;
+ }
+ else if(strstr(line, "Label")){
+ if(get_label(line, "Label", channel, CHANNEL_SIZE,
+ label, LABEL_SIZE, '[', ']')){
+ config.labels = channel_label_append(config.labels, channel, label);
+ }
+ else
+ printf("Bad Label entry found on line %i.\n", linenum);
+ }
+ else if(strstr(line, "Xpm")){
+ if(get_label(line, "Xpm", channel, CHANNEL_SIZE,
+ label, LABEL_SIZE, '[', ']')){
+ config.xpm = channel_label_append(config.xpm, channel, label);
+ }
+ else
+ printf("Bad Xpm entry found on line %i.\n", linenum);
+ }
+ else if(strstr(line, "ScaleSize"))
+ if(sscanf(line, "ScaleSize %i", &i) == 1)
+ config.scale = i;
+ else
+ printf("Bad ScaleSize entry at line %i.\n", linenum);
+ if(strstr(line, "ChannelPadding"))
+ if(sscanf(line, "ChannelPadding %i", &i) == 1)
+ config.padding = i;
+ else
+ printf("Bad ChannelPadding entry at line %i.\n", linenum);
+
+
+ } /* End of config loop */
+
+ /* Close the file */
+ fclose(stream);
+
+ return TRUE;
+}
+
+
+int setup_pixmaps(GtkWidget *xpmparent)
+{
+ GtkStyle *style;
+ int fd;
+
+ if(!(config.flags & CONFIG_USE_XPMS)) {
+ config.mute = "M";
+ config.simul = "|-|";
+ config.rec = "Rec";
+ return;
+ }
+
+
+
+ if(config.flags & CONFIG_ICON_XPM){
+ fd = open(config.icon, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.icon_xpm =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.icon_mask,
+ &style->bg[GTK_STATE_NORMAL],
+ config.icon);
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.icon);
+ config.flags &= ~CONFIG_ICON_XPM;
+ config.icon_xpm = NULL;
+ free(config.icon);
+ config.icon = NULL;
+ }
+ }
+
+
+ if(config.flags & CONFIG_MUTE_XPM_L){
+ fd=open(config.mute_l, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.mute_xpm_l =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.mute_mask_l,
+ &style->bg[GTK_STATE_NORMAL],
+ config.mute_l);
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.mute_l);
+ config.flags &= ~CONFIG_MUTE_XPM_L;
+ config.mute_xpm_l = NULL;
+ free(config.mute_l);
+ config.mute_l = NULL;
+ }
+ }
+
+
+ if(config.flags & CONFIG_MUTE_XPM){
+ fd=open(config.mute, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.mute_xpm =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.mute_mask,
+ &style->bg[GTK_STATE_NORMAL],
+ config.mute);
+ if(!(config.flags & CONFIG_MUTE_XPM_L)) {
+ config.mute_xpm_l = config.mute_xpm;
+ config.mute_mask_l = config.mute_mask;
+ config.flags |= CONFIG_MUTE_XPM_L;
+ }
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.mute);
+ config.flags &= ~CONFIG_MUTE_XPM;
+ config.mute_xpm = NULL;
+ free(config.mute);
+ config.mute = "M";
+ }
+ }
+
+
+
+ if(config.flags & CONFIG_UNMUTE_XPM_L) {
+ fd=open(config.unmute_l, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.unmute_xpm_l =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.unmute_mask_l,
+ &style->bg[GTK_STATE_NORMAL],
+ config.unmute_l);
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.unmute_l);
+ config.flags &= ~CONFIG_UNMUTE_XPM_L;
+ free(config.unmute_l);
+ config.unmute_l=NULL;
+ }
+ }
+
+
+
+ if(config.flags & CONFIG_UNMUTE_XPM) {
+ fd=open(config.unmute, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.unmute_xpm =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.unmute_mask,
+ &style->bg[GTK_STATE_NORMAL],
+ config.unmute);
+ if(!(config.flags & CONFIG_UNMUTE_XPM_L)) {
+ printf("Invoked!\n");
+ config.unmute_xpm_l = config.unmute_xpm;
+ config.unmute_mask_l = config.unmute_mask;
+ config.flags |= CONFIG_UNMUTE_XPM_L;
+ }
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.unmute);
+ config.flags &= ~CONFIG_UNMUTE_XPM;
+ free(config.unmute);
+ config.unmute=NULL;
+ }
+ }
+
+
+
+ if(config.flags & CONFIG_REC_XPM) {
+ fd=open(config.rec, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.rec_xpm =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.rec_mask,
+ &style->bg[GTK_STATE_NORMAL],
+ config.rec);
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.rec);
+ config.flags &= ~CONFIG_REC_XPM;
+ free(config.rec);
+ config.rec = "Rec";
+ }
+ }
+
+ if(config.flags & CONFIG_UNREC_XPM) {
+ fd=open(config.unrec, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.unrec_xpm =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.unrec_mask,
+ &style->bg[GTK_STATE_NORMAL],
+ config.unrec);
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.unrec);
+ config.flags &= ~CONFIG_UNREC_XPM;
+ free(config.unrec);
+ config.unrec=NULL;
+ }
+ }
+
+ if(config.flags & CONFIG_SIMUL_XPM) {
+ fd = open(config.simul, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.simul_xpm =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.simul_mask,
+ &style->bg[GTK_STATE_NORMAL],
+ config.simul);
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.simul);
+ config.flags &= ~CONFIG_SIMUL_XPM;
+ free(config.simul);
+ config.simul="|-|";
+ }
+ }
+
+ if(config.flags & CONFIG_UNSIMUL_XPM) {
+ fd = open(config.unsimul, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.unsimul_xpm =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.unsimul_mask,
+ &style->bg[GTK_STATE_NORMAL],
+ config.unsimul);
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.unsimul);
+ config.flags &= ~CONFIG_UNSIMUL_XPM;
+ free(config.unsimul);
+ config.unsimul=NULL;
+ }
+ }
+
+ if(config.flags & CONFIG_BACKGROUND_XPM) {
+ fd = open(config.background, O_RDONLY);
+ if(fd != -1) {
+ close(fd);
+ style = gtk_widget_get_style(xpmparent);
+ config.background_xpm =
+ gdk_pixmap_create_from_xpm(xpmparent->window,
+ &config.background_mask,
+ &style->bg[GTK_STATE_NORMAL],
+ config.background);
+ }
+ else {
+ printf("Unable to open pixmap %s.\n", config.background);
+ config.flags &= ~CONFIG_BACKGROUND_XPM;
+ free(config.background);
+ config.background=NULL;
+ }
+ }
+
+ return TRUE;
+}
+
+
--- /dev/null
+/*****************************************************************************/
+/* Begin #include statements */
+
+/* End #include statements */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/* Begin function prototypes */
+
+int config_init();
+int config_read(const char *file);
+int setup_pixmaps(GtkWidget *xpmparent);
+
+/* End function prototypes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin #define statements */
+
+#define HOME_FILE ".xamixer"
+
+/* End #define statements */
+/*****************************************************************************/
--- /dev/null
+AC_INIT(xamixer2.c)
+AM_INIT_AUTOMAKE(xamixer2,0.1.3)
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_HEADER_STDC
+AM_PATH_GTK(1.0.1)
+AM_PATH_ALSA(0.1.3)
+CFLAGS="$CFLAGS $GTK_CFLAGS $ALSA_FLAGS"
+LDFLAGS="$LDFLAGS $GTK_LIBS $ALSA_LIBS"
+
+AC_OUTPUT(Makefile)
--- /dev/null
+/*****************************************************************************
+ xamixer.c - an Alsa based gtk mixer
+ Written by Raistlinn (lansdoct@cs.alfred.edu)
+ Copyright (C) 1998 by Christopher Lansdown
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+******************************************************************************/
+
+/*****************************************************************************/
+/* Begin #include's */
+
+#include "main.h"
+
+/* End #include's */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin Global Variables */
+
+extern GtkWidget *window;
+extern Card *card; /* And array of the cards */
+extern int cards; /* The number of cards in the system. */
+extern Config config; /* The system config */
+
+/* End Global Variables */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin function prototypes */
+
+GtkWidget *group_elements(int card, int mixer, Group *group);
+GtkWidget *display_volume1(Group *group, int element, void *handle, char *route);
+GtkWidget *display_switch2(Group *group, int element, void *handle, char *route);
+GtkWidget *display_switch1(Group *group, int element, void *handle, char *route);
+GtkWidget *display_3deffect1(Group *group, int element, void *handle, char *route);
+
+/* End function protoypes */
+/*****************************************************************************/
+
+GtkWidget *create_mixer_page(int card_num, int mixer_num)
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *frame;
+ int i=card_num, j=mixer_num, k=0, l, m;
+ int w=1, col;
+
+ /* Compute the number of culumns to use */
+ // w = (int)sqrt((double)card[i].mixer[j].info.elements);
+ w = (int)(1.5 *
+ (float)card[i].mixer[j].info.elements /
+ (float)card[i].mixer[j].info.groups);
+
+ /* Compute the number of groups in a column */
+ col = (card[i].mixer[j].info.groups + w - 1)/ w;
+
+ /* Create the main bounding box */
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(hbox);
+
+
+ /* Make a vertical box for each column, then put that column's worth
+ of mixer groups into the column */
+ for(l = 0; l < w; l++) {
+ /* Make the vertical box to pack it in */
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
+
+ for(m = 0; m < col && k < card[i].mixer[j].info.groups; m++) {
+ /* Make the group frame */
+ frame = gtk_frame_new(card[i].mixer[j].group[k].group.gid.name);
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
+
+ gtk_container_add(GTK_CONTAINER(frame),
+ group_elements(card_num,
+ mixer_num,
+ &card[i].mixer[j].group[k]));
+
+
+ /* Now increment the count of which mixer group we're on */
+ k++;
+ }
+ }
+
+ return hbox;
+}
+
+
+GtkWidget *group_elements(int card_num, int mixer, Group *group)
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *label;
+ GtkWidget *box;
+ GtkWidget *widget;
+ char thor[128];
+ int i, j;
+ snd_mixer_element_t test;
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(vbox);
+
+ for(i = 0; i < group->group.elements; i++) {
+ /* Each element gets its own horizontal box */
+ hbox=gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+ snprintf(thor, 128, "%s routed to the %s",
+ group->group.pelements[i].name,
+ group->routes[i].proutes[0].name);
+
+/* label = gtk_label_new(thor); */
+/* gtk_widget_show(label); */
+/* gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); */
+
+
+ switch(group->group.pelements[i].type){
+
+ case SND_MIXER_ETYPE_VOLUME1:
+ gtk_box_pack_end(GTK_BOX(hbox),
+ display_volume1(group, i,
+ card[card_num].mixer[mixer].handle,
+ thor),
+ FALSE, FALSE, 0);
+ break;
+
+ case SND_MIXER_ETYPE_SWITCH1:
+ gtk_box_pack_end(GTK_BOX(hbox),
+ display_switch1(group, i,
+ card[card_num].mixer[mixer].handle,
+ thor),
+ FALSE, FALSE, 0);
+ break;
+
+ case SND_MIXER_ETYPE_SWITCH2:
+ gtk_box_pack_end(GTK_BOX(hbox),
+ display_switch2(group, i,
+ card[card_num].mixer[mixer].handle,
+ thor),
+ FALSE, FALSE, 0);
+ break;
+
+ case SND_MIXER_ETYPE_3D_EFFECT1:
+ gtk_box_pack_end(GTK_BOX(hbox),
+ display_3deffect1(group, i,
+ card[card_num].mixer[mixer].handle,
+ thor),
+ FALSE, FALSE, 0);
+ break;
+ }
+ }
+
+
+
+ return vbox;
+}
+
+GtkWidget *display_3deffect1(Group *group, int element, void *handle, char *route)
+{
+ GtkWidget *vbox;
+ GtkWidget *box;
+ GtkTooltips *tooltips;
+ GtkWidget *widget;
+ GtkWidget *label;
+ int i=element;
+ GtkObject *adj;
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(vbox);
+
+ group->gtk[i].interface = calloc(10, sizeof(GtkWidget *));
+ group->gtk[i].adjust = calloc(10, sizeof(GtkWidget *));
+
+ /* The on/off switch */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_SW) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+ widget = gtk_check_button_new();
+ if(group->element[i].data.teffect1.sw)
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), TRUE);
+
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+ /* Connect it to the callback */
+ gtk_signal_connect(GTK_OBJECT(widget), "toggled",
+ GTK_SIGNAL_FUNC(adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_SW));
+ }
+
+
+
+ /* The mono switch */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_MONO_SW) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect Mono");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+ widget = gtk_check_button_new();
+ if(group->element[i].data.teffect1.sw)
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), TRUE);
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+ /* Connect it to the callback */
+ gtk_signal_connect(GTK_OBJECT(widget), "toggled",
+ GTK_SIGNAL_FUNC(adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_MONO_SW));
+ }
+
+
+ /* the wide control */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_WIDE) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect Width");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+
+ adj = gtk_adjustment_new(group->element[i].data.teffect1.wide,
+ group->einfo[i].data.teffect1.min_wide,
+ group->einfo[i].data.teffect1.max_wide,
+ 1.0,
+ 3.0,
+ 0.0);
+ widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+ gtk_scale_set_value_pos(GTK_SCALE(widget),
+ GTK_POS_RIGHT);
+ gtk_widget_set_usize(widget, 100, -1);
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+
+ /* connect the signal */
+ gtk_signal_connect(GTK_OBJECT(adj),
+ "value_changed",
+ GTK_SIGNAL_FUNC (adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_WIDE));
+ }
+
+ /* the volume widget */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_VOLUME) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect Volume");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+
+ adj = gtk_adjustment_new(group->element[i].data.teffect1.volume,
+ group->einfo[i].data.teffect1.min_volume,
+ group->einfo[i].data.teffect1.max_volume,
+ 1.0,
+ 3.0,
+ 0.0);
+ widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+ gtk_scale_set_value_pos(GTK_SCALE(widget),
+ GTK_POS_RIGHT);
+ gtk_widget_set_usize(widget, 100, -1);
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+ /* connect the signal */
+ gtk_signal_connect(GTK_OBJECT(adj),
+ "value_changed",
+ GTK_SIGNAL_FUNC (adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_VOLUME));
+ }
+
+
+ /* The center widget */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_CENTER) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect Center");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+
+ adj = gtk_adjustment_new(group->element[i].data.teffect1.center,
+ group->einfo[i].data.teffect1.min_center,
+ group->einfo[i].data.teffect1.max_center,
+ 1.0,
+ 3.0,
+ 0.0);
+ widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+ gtk_scale_set_value_pos(GTK_SCALE(widget),
+ GTK_POS_RIGHT);
+ gtk_widget_set_usize(widget, 100, -1);
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(adj),
+ "value_changed",
+ GTK_SIGNAL_FUNC (adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_CENTER));
+ }
+
+
+ /* The Space widget */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_SPACE) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect Space");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+
+ adj = gtk_adjustment_new(group->element[i].data.teffect1.space,
+ group->einfo[i].data.teffect1.min_space,
+ group->einfo[i].data.teffect1.max_space,
+ 1.0,
+ 3.0,
+ 0.0);
+ widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+ gtk_scale_set_value_pos(GTK_SCALE(widget),
+ GTK_POS_RIGHT);
+ gtk_widget_set_usize(widget, 100, -1);
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(adj),
+ "value_changed",
+ GTK_SIGNAL_FUNC (adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_SPACE));
+ }
+
+ /* The depth widget */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_DEPTH) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect Depth");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+
+ adj = gtk_adjustment_new(group->element[i].data.teffect1.depth,
+ group->einfo[i].data.teffect1.min_depth,
+ group->einfo[i].data.teffect1.max_depth,
+ 1.0,
+ 3.0,
+ 0.0);
+ widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+ gtk_scale_set_value_pos(GTK_SCALE(widget),
+ GTK_POS_RIGHT);
+ gtk_widget_set_usize(widget, 100, -1);
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(adj),
+ "value_changed",
+ GTK_SIGNAL_FUNC (adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_DEPTH));
+ }
+
+ /* The delay widget */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_DELAY) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect Delay");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+
+ adj = gtk_adjustment_new(group->element[i].data.teffect1.delay,
+ group->einfo[i].data.teffect1.min_delay,
+ group->einfo[i].data.teffect1.max_delay,
+ 1.0,
+ 3.0,
+ 0.0);
+ widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+ gtk_scale_set_value_pos(GTK_SCALE(widget),
+ GTK_POS_RIGHT);
+ gtk_widget_set_usize(widget, 100, -1);
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(adj),
+ "value_changed",
+ GTK_SIGNAL_FUNC (adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_DELAY));
+ }
+
+
+ /* The feedback widget */
+ if(group->einfo[i].data.teffect1.effect & SND_MIXER_EFF1_FEEDBACK) {
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
+
+ label = gtk_label_new("3D Effect Feedback");
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+
+ adj = gtk_adjustment_new(group->element[i].data.teffect1.feedback,
+ group->einfo[i].data.teffect1.min_feedback,
+ group->einfo[i].data.teffect1.max_feedback,
+ 1.0,
+ 3.0,
+ 0.0);
+ widget = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+ gtk_scale_set_value_pos(GTK_SCALE(widget),
+ GTK_POS_RIGHT);
+ gtk_widget_set_usize(widget, 100, -1);
+ gtk_widget_show(widget);
+ gtk_box_pack_end(GTK_BOX(box), widget, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(adj),
+ "value_changed",
+ GTK_SIGNAL_FUNC (adjust_teffect1),
+ create_cb_data(group, handle, i, TYPE_FEEDBACK));
+ }
+
+
+
+ return vbox;
+}
+
+GtkWidget *display_switch1(Group *group, int element, void *handle, char *route)
+{
+ GtkWidget *box;
+ GtkTooltips *tooltips;
+ GtkWidget *button;
+ int i, j;
+
+ i = element;
+
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(box);
+
+ /* Allocate the widget array */
+ group->gtk[i].interface = calloc(group->element[i].data.switch1.sw, sizeof(GtkWidget *));
+
+ for(j = 0; j < group->element[i].data.switch1.sw; j++) {
+ button = gtk_check_button_new();
+ /* looks painful, doesn't it? It's checking the state of the appropriate bit */
+ if(group->element[i].data.switch1.psw[j / sizeof(unsigned int)] &
+ (1 << (j % sizeof(unsigned int))))
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON (button), TRUE);
+ gtk_widget_show(button);
+
+ /* Set up the tooltips */
+ tooltips = gtk_tooltips_new();
+ gtk_tooltips_set_tip (tooltips, button, route, NULL);
+
+
+ gtk_box_pack_start(GTK_BOX (box), button, FALSE, FALSE, 0);
+
+ /* Connect it to the callback */
+ gtk_signal_connect(GTK_OBJECT(button), "toggled",
+ GTK_SIGNAL_FUNC(adjust_switch1),
+ create_cb_data(group, handle, i, j));
+
+ /* Store the widget */
+ group->gtk[i].interface[j] = button;
+ }
+
+
+ return box;
+}
+
+
+GtkWidget *display_switch2(Group *group, int element, void *handle, char *route)
+{
+ GtkWidget *button;
+ GtkTooltips *tooltips;
+ int i, j=0;
+
+ i = element;
+
+ if(!group) {
+ printf("Group isn't initialized!\n");
+ return NULL;
+ }
+
+ button = gtk_check_button_new();
+
+ if(group->element)
+ if(group->element[i].data.switch2.sw) {
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
+ }
+
+ gtk_widget_show(button);
+
+ /* Set up the tooltip */
+ tooltips = gtk_tooltips_new();
+ gtk_tooltips_set_tip (tooltips, button, route, NULL);
+
+ if(group->gtk) {
+ group->gtk[i].interface = calloc(1, sizeof(GtkWidget *));
+ group->gtk[i].interface[j] = button;
+ } else {
+ printf("Something wasn't initialized properly.\n");
+ }
+
+ /* Connect it to the callback */
+ gtk_signal_connect(GTK_OBJECT(group->gtk[i].interface[j]),
+ "toggled",
+ GTK_SIGNAL_FUNC (adjust_switch2),
+ create_cb_data(group, handle, element, j));
+
+ return button;
+}
+
+GtkWidget *display_volume1(Group *group, int element, void *handle, char *route)
+{
+ GtkWidget *box;
+ GtkTooltips *tooltips;
+ int i,j;
+
+ i = element;
+
+ box = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(box);
+
+ group->gtk[i].adjust = calloc(group->element[i].data.volume1.voices,
+ sizeof(GtkObject *));
+ group->gtk[i].interface = calloc(group->element[i].data.volume1.voices,
+ sizeof(GtkWidget *));
+
+ for(j=0; j < group->element[i].data.volume1.voices; j++) {
+ group->gtk[i].adjust[j] =
+ gtk_adjustment_new(group->element[i].data.volume1.pvoices[j],
+ group->einfo[i].data.volume1.prange[0].min,
+ group->einfo[i].data.volume1.prange[0].max,
+ 1.0,
+ 3.0,
+ 0.0);
+
+ group->gtk[i].interface[j] =
+ gtk_hscale_new(GTK_ADJUSTMENT(group->gtk[i].adjust[j]));
+
+ gtk_signal_connect(GTK_OBJECT(group->gtk[i].adjust[j]),
+ "value_changed",
+ GTK_SIGNAL_FUNC (adjust_volume1),
+ create_cb_data(group, handle, element, j));
+
+/* gtk_scale_set_draw_value(GTK_SCALE(group->gtk[i].interface[j]), */
+/* FALSE); */
+
+ gtk_scale_set_value_pos(GTK_SCALE(group->gtk[i].interface[j]),
+ GTK_POS_RIGHT);
+
+ gtk_widget_set_usize(group->gtk[i].interface[j], 100, -1);
+
+ gtk_widget_show(group->gtk[i].interface[j]);
+ gtk_box_pack_start(GTK_BOX(box),
+ group->gtk[i].interface[j],
+ FALSE, FALSE, 0);
+
+ /* Set up the tooltip */
+ tooltips = gtk_tooltips_new();
+ gtk_tooltips_set_tip (tooltips, group->gtk[i].interface[j], route, NULL);
+
+ }
+
+
+
+ return box;
+}
--- /dev/null
+/*****************************************************************************/
+/* Begin #include statements */
+
+/* End #include statements */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/* Begin function prototypes */
+
+GtkWidget *create_mixer_page(int card_num, int mixer_num);
+
+
+/* End function prototypes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin #define statements */
+
+/* These types are for the callback data identification */
+#define TYPE_EFFECT 0
+#define TYPE_SW 1
+#define TYPE_MONO_SW 2
+#define TYPE_WIDE 3
+#define TYPE_VOLUME 4
+#define TYPE_CENTER 5
+#define TYPE_SPACE 6
+#define TYPE_DEPTH 7
+#define TYPE_DELAY 8
+#define TYPE_FEEDBACK 9
+
+/* End #define statements */
+/*****************************************************************************/
--- /dev/null
+/*****************************************************************************/
+/* Begin system #includes */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/asoundlib.h>
+#include <gtk/gtk.h>
+
+/* End system #includes */
+/*****************************************************************************/
+
+
+
+/*****************************************************************************/
+/* Begin program #includes */
+
+#include "structs.h"
+#include "util.h"
+#include "xamixer2.h"
+#include "cinit.h"
+#include "callbacks.h"
+#include "display.h"
+#include "config.h"
+#include "switches.h"
+#include "options.h"
+
+/* End program #includes */
+/*****************************************************************************/
+
+
+
+/*****************************************************************************/
+/* Begin #defines */
+
+#define CHANNEL_LEFT (1 << 0)
+#define CHANNEL_RIGHT (1 << 1)
+#define CHANNEL_MONO (1 << 2)
+#define CHANNEL_MUTE_RIGHT (1 << 3)
+#define CHANNEL_MUTE_LEFT (1 << 4)
+#define CHANNEL_MUTE_MONO (1 << 5)
+#define CHANNEL_RECORD (1 << 6)
+#define CHANNEL_RECORD_RIGHT (1 << 7)
+#define CHANNEL_RECORD_LEFT (1 << 8)
+#define CHANNEL_SIMULTANEOUS (1 << 9)
+#define CHANNEL_DISPLAYED (1 << 10)
+#define CHANNEL_LTOR (1 << 11)
+#define CHANNEL_RTOL (1 << 12)
+
+
+#define CONFIG_USE_XPMS (1 << 0)
+#define CONFIG_ICON_XPM (1 << 1)
+#define CONFIG_MUTE_XPM (1 << 2)
+#define CONFIG_MUTE_XPM_L (1 << 3)
+#define CONFIG_UNMUTE_XPM (1 << 4)
+#define CONFIG_UNMUTE_XPM_L (1 << 5)
+#define CONFIG_REC_XPM (1 << 6)
+#define CONFIG_UNREC_XPM (1 << 7)
+#define CONFIG_SIMUL_XPM (1 << 8)
+#define CONFIG_UNSIMUL_XPM (1 << 9)
+#define CONFIG_LTOR_XPM (1 << 10)
+#define CONFIG_UNLTOR_XPM (1 << 11)
+#define CONFIG_RTOL_XPM (1 << 12)
+#define CONFIG_UNRTOL_XPM (1 << 13)
+#define CONFIG_BACKGROUND_XPM (1 << 14)
+#define CONFIG_SHOW_CARD_NAME (1 << 15)
+#define CONFIG_SHOW_MIXER_NUMBER (1 << 16)
+#define CONFIG_SHOW_MIXER_NAME (1 << 17)
+#define CONFIG_SWITCHES_HIDDEN (1 << 18)
+
+/* End #defines */
+/*****************************************************************************/
+
+
+
+/*****************************************************************************/
+/* Gtk 1.0 compatability */
+
+#ifndef GTK_HAVE_FEATURES_1_1_0
+#define gtk_button_set_relief(a,b)
+#endif
+
+/* End Gtk 1.0 compatability */
+/*****************************************************************************/
+
+
+
+
--- /dev/null
+/******************************************************************************/
+/* Begin Structures */
+
+struct _Gtk_Channel
+{
+ GtkWidget **interface; /* And array of the interfaces (slider, button, etc.) */
+ GtkObject **adjust; /* An array of the adjustments */
+};
+typedef struct _Gtk_Channel Gtk_Channel;
+
+struct _Group
+{
+ snd_mixer_group_t group; /* The group structure */
+ snd_mixer_element_t *element; /* an array of all the elements in the group */
+ snd_mixer_element_info_t *einfo; /* an array of the info about all of the elements */
+ snd_mixer_routes_t *routes; /* an array of all the routes for the elements */
+ Gtk_Channel *gtk; /* The Gtk+ widgets used for each mixer element */
+};
+typedef struct _Group Group;
+
+struct _Mixer
+{
+ int number; /* The number of the mixer device */
+ void *handle;
+ snd_mixer_info_t info; /* The info for the mixer */
+ int cnum; /* The number of channels present */
+ int snum; /* The number of mixer switches present */
+ snd_mixer_groups_t groups; /* The mixer groups */
+ Group *group; /* An array of the mixer groups */
+ char name[80]; /* The name of the mixer */
+ GtkWidget *switch_table;
+};
+typedef struct _Mixer Mixer;
+
+
+
+struct _Card
+{
+ snd_ctl_hw_info_t hw_info; /* The hardware info about the card. */
+ int number; /* The card's number */
+ void *handle; /* The handle for the mixer */
+ char name[80]; /* The name of the card */
+ Mixer *mixer; /* A dynamic array of all of the mixers */
+ int nmixers; /* The number of mixers on the card */
+ int npcms; /* The number of pcm devices */
+};
+typedef struct _Card Card;
+
+
+struct _MixerInfo
+{
+ Mixer *mixer; /* Which card */
+ int channel; /* Which channel */
+ unsigned int flags; /* flags */
+ GtkWidget *other; /* The other range widget */
+ GtkWidget *mute; /* The mute pixmap */
+ GtkWidget *unmute; /* The unmute pixmap */
+};
+typedef struct _MixerInfo MixerInfo;
+
+
+struct _ChannelLabel
+{
+ struct _ChannelLabel *next; /* pointer to the next node in the list */
+ char *channel; /* The channel name */
+ char *label; /* The channel label or pixmap */
+};
+typedef struct _ChannelLabel ChannelLabel;
+
+
+struct _CBData
+{
+ Group *group; /* The group */
+ void *handle; /* The mixer handle */
+ int element; /* The element number to use as an index */
+ int index; /* The index such as the voice # or something like that */
+};
+typedef struct _CBData CBData;
+
+
+
+struct _Config
+{
+ unsigned int flags; /* Flags */
+ ChannelLabel *labels; /* The text labels for channels */
+ ChannelLabel *xpm; /* The pixmaps (file names) for channels */
+ char *icon; /* The Icon pixmap to use */
+ char *mute; /* The mute label or pixmap (indicated in a flag) */
+ char *mute_l; /* The left mute label or pixmap (indicated in a flag) */
+ char *unmute; /* The unmute label or pixmap (indicated in a flag) */
+ char *unmute_l; /* The left unmute label or pixmap (indicated in a flag) */
+ char *simul; /* The simultaneous label or pixmap (indicated in a flag */
+ char *unsimul; /* The unsimultaneous label or pixmap (indicated in a flag */
+ char *rec; /* The record label or pixmap (indicated in a flag) */
+ char *unrec; /* The unrecord label or pixmap (indicated in a flag) */
+ char *background; /* The background xpm */
+ unsigned int scale; /* The size in pixels that the scales should be set to */
+ unsigned int padding; /* The padding between channels */
+ int x_pos, y_pos; /* The position to start out at -1 = default */
+ GtkWidget *cdisplay; /* The channel display window */
+ GdkPixmap *icon_xpm; /* The icon xpm */
+ GdkPixmap *mute_xpm; /* The mute pixmap */
+ GdkPixmap *unmute_xpm; /* The unmute pixmap */
+ GdkPixmap *mute_xpm_l; /* The left mute pixmap */
+ GdkPixmap *unmute_xpm_l; /* The left unmute pixmap */
+ GdkPixmap *rec_xpm; /* The record pixmap */
+ GdkPixmap *unrec_xpm; /* The record off pixmap */
+ GdkPixmap *simul_xpm; /* The sumultaneous pixmap */
+ GdkPixmap *unsimul_xpm; /* The independent pixmap */
+ GdkPixmap *background_xpm; /* The background pixmap */
+ GdkBitmap *icon_mask;
+ GdkBitmap *mute_mask;
+ GdkBitmap *unmute_mask;
+ GdkBitmap *mute_mask_l;
+ GdkBitmap *unmute_mask_l;
+ GdkBitmap *rec_mask;
+ GdkBitmap *unrec_mask;
+ GdkBitmap *simul_mask;
+ GdkBitmap *unsimul_mask;
+ GdkBitmap *background_mask;
+};
+typedef struct _Config Config;
+
+/* End Structures */
+/******************************************************************************/
+
+
+#if 0
+struct _Channel
+{
+ int num; /* The channel's number */
+ snd_mixer_channel_t data; /* the data */
+ snd_mixer_channel_info_t info; /* The info */
+ unsigned int flags; /* The Channel's flags */
+ GtkWidget *lm, *rm, *mm, *rec; /* The associated widgets */
+ GtkWidget *lrec, *rrec; /* More associated widgets */
+ GtkObject *ladj, *radj, *madj; /* The associated objects */
+ GtkTooltips *left_tt, *right_tt, *mono_tt; /* The tooltips */
+ GtkWidget *lscal, *rscal, *mscal; /* The scale widgets */
+ GtkWidget *label, *lock;
+ GtkWidget *ltor_in, *rtol_in;
+ void *mixer; /* A pointer to the mixer */
+};
+typedef struct _Channel Channel;
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ GtkWidget *window;
+ GtkWidget *scale;
+ GtkObject *adj;
+
+
+ gtk_init(&argc, &argv);
+
+ window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ adj = gtk_adjustment_new(1.0,
+ 0.0,
+ 110.0,
+ 1.0,
+ 4.0,
+ 0.0);
+ scale = gtk_hscale_new(GTK_ADJUSTMENT(adj));
+ gtk_widget_show(scale);
+ gtk_container_add(GTK_CONTAINER(window), scale);
+
+
+ gtk_widget_show(window);
+ gtk_main();
+
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+main()
+{
+ printf("The value is %i\n", ~(1 << 1));
+
+
+
+
+ return 0;
+}
--- /dev/null
+/*****************************************************************************
+ xamixer.c - an Alsa based gtk mixer
+ Written by Raistlinn (lansdoct@cs.alfred.edu)
+ Copyright (C) 1998 by Christopher Lansdown
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+******************************************************************************/
+
+/*****************************************************************************/
+/* Begin #include's */
+
+#include "main.h"
+
+/* End #include's */
+/*****************************************************************************/
+extern Config config; /* The system config */
+
+
+int is_same(char *string1, char *string2)
+{
+ int i = 0;
+
+ if(strlen(string1) != strlen(string2))
+ return 0;
+
+ while(string1[i] != '\0')
+ if(string1[i] != string2[i])
+ return 0;
+ else
+ i++;
+
+ return 1;
+
+}
+
+void strip_comment(char *string)
+{
+ char *place;
+ int i = 0, j = 0, size;
+
+ size = strlen(string);
+ /* Get wrid of the comments */
+ place = string;
+ while((place = strchr(place, '#'))){
+ if(string[(place - string) -1] != '\\')
+ *place = '\0';
+ place++;
+ }
+
+ /* Replace the escape sequences */
+ place = calloc(1, strlen(string));
+ while(string[i] != '\0'){
+ if(string[i] == '\\')
+ place[j] = string[++i];
+ else
+ place[j] = string[i];
+
+ i++;
+ j++;
+ }
+
+ EAZERO(string, size);
+ strncpy(string, place, size);
+ free(place);
+ return;
+}
+
+int is_comment(char *string)
+{
+ int i=0;
+
+ while (string[i] != '\0'){
+ if (string[i] == '#')
+ return 1;
+ if (string[i] != ' ' && string[i] != '\t')
+ return 0;
+ i++;
+ }
+ return 0;
+}
+
+ChannelLabel *channel_label_append(ChannelLabel *head, char *channel, char *label)
+{
+ ChannelLabel *tmp;
+
+ tmp = calloc(1, sizeof(ChannelLabel));
+
+ tmp->next = head;
+ tmp->channel = calloc(strlen(channel) + 1, sizeof(char));
+ strcpy(tmp->channel, channel);
+ tmp->label = calloc(strlen(label) + 1, sizeof(char));
+ strcpy(tmp->label, label);
+
+ return tmp;
+}
+
+int get_label(char *line, char *expect, char *value1, size_t value1_len,
+ char *value2, size_t value2_len, char quote1, char quote2)
+{
+ char *tmp;
+ int len, i;
+
+ len = strlen(line);
+
+ if(expect) {
+ tmp = strstr(line, expect);
+ if(!tmp)
+ return FALSE;
+ tmp = &tmp[strlen(expect)];
+ }
+ else
+ tmp = line;
+
+
+ tmp = strchr(tmp, quote1) + 1;
+ if(!tmp)
+ return FALSE;
+ for(i = 0; i < (value1_len - 1) && tmp[i] != quote2; i++)
+ value1[i] = tmp[i];
+ value1[i] = '\0';
+
+ tmp = strchr(tmp, quote1) + 1;
+ if(!tmp)
+ return FALSE;
+ for(i = 0; i < (value2_len - 1) && tmp[i] != quote2; i++)
+ value2[i] = tmp[i];
+ value2[i] = '\0';
+
+
+
+ return TRUE;
+}
+
+MixerInfo *create_mixer_info(Mixer *mixer, int num, unsigned int flags)
+{
+ MixerInfo *info;
+ info = calloc(1, sizeof(MixerInfo));
+
+ info->mixer = mixer;
+ info->channel = num;
+ info->flags = flags;
+ info->other = NULL;
+ info->mute = NULL;
+ info->unmute = NULL;
+
+ return info;
+}
+
+CBData *create_cb_data(Group *group, void *handle, int element, int index)
+{
+ CBData *data;
+
+ data = malloc(sizeof(CBData));
+
+ data->group = group;
+ data->handle = handle;
+ data->element = element;
+ data->index = index;
+
+ return data;
+}
--- /dev/null
+/*****************************************************************************/
+/* Begin #include statements */
+
+/* End #include statements */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/* Begin function prototypes */
+
+int is_same(char *string1, char *string2);
+void strip_comment(char *string);
+int is_comment(char *string);
+ChannelLabel *channel_label_append(ChannelLabel *head, char *channel, char *label);
+int get_label(char *line, char *expect, char *value1, size_t value1_len,
+ char *value2, size_t value2_len, char quote1, char quote2);
+MixerInfo *create_mixer_info(Mixer *mixer, int num, unsigned int flags);
+CBData *create_cb_data(Group *group, void *handle, int element, int index);
+
+/* End function prototypes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin #define statements */
+
+
+/* End #define statements */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin Macros */
+
+#define EAZERO(S, L) S[L-1] = '\0';
+#define MIXER(m) ((Mixer *)m)
+
+/* End Macros */
+/*****************************************************************************/
+
--- /dev/null
+# XAmixer home file
+# Comments are preceded anywhere on the line by a '#'
+# All channel arguments (string & pixmap) must be enclosed in [ ] [ ]
+UseXpms
+#IgnoreXpms
+ScaleSize 115
+ChannelPadding 5
+Position -1 -1 # Both arguments must be set (and >= 0) to get positioning.
+ShowCardName
+#ShowMixerNumber
+#ShowMixerName
+#MuteLabel Mute
+#RecLabel Record
+RecLabel R
+#SimulLabel Lock
+#BackgroundXpm /usr/local/share/xamixer/pixmaps/test.xpm
+#BackgroundXpm /home/raistlin/xamixer/pixmaps/background5.xpm
+#BackgroundXpm /home/raistlin/xamixer/pixmaps/background.xpm
+#BackgroundXpm /tmp/background.xpm
+IconXpm /usr/local/share/xamixer/pixmaps/icon3.xpm
+#MuteXpm /usr/local/share/xamixer/pixmaps/mute3.xpm
+#unMuteXpm /usr/local/share/xamixer/pixmaps/unmute3.xpm
+MuteXpm /usr/local/share/xamixer/pixmaps/mute3.xpm
+unMuteXpm /usr/local/share/xamixer/pixmaps/unmute3.xpm
+#RecXpm /usr/local/share/xamixer/pixmaps/record.xpm
+#unRecXpm /usr/local/share/xamixer/pixmaps/unrecord.xpm
+RecXpm /usr/local/share/xamixer/pixmaps/rec.xpm
+unRecXpm /usr/local/share/xamixer/pixmaps/unrec.xpm
+#RecXpm /home/raistlin/xamixer/pixmaps/record.xpm
+#unRecXpm /home/raistlin/xamixer/pixmaps/unrecord.xpm
+SimulXpm /usr/local/share/xamixer/pixmaps/simul.xpm
+unSimulXpm /usr/local/share/xamixer/pixmaps/unsimul.xpm
+Label [Master] [Mstr]
+Label [Master M] [MstrM]
+Label [Line-In] [LineIn]
+Label [Record-Gain] [RGain]
+Label [PC Speaker] [Spkr]
+Label [Aux A] [AuxA]
+Label [In-Gain] [IGain]
+Label [Out-Gain] [OGain]
+Xpm [Master] [/usr/local/share/xamixer/pixmaps/master.xpm]
+Xpm [CD] [/usr/local/share/xamixer/pixmaps/cd.xpm]
+Xpm [MIC] [/usr/local/share/xamixer/pixmaps/mic.xpm]
+Xpm [PCM] [/usr/local/share/xamixer/pixmaps/pcm.xpm]
+Xpm [Synth] [/usr/local/share/xamixer/pixmaps/synth.xpm]
+Xpm [Line-In] [/usr/local/share/xamixer/pixmaps/line-in.xpm]
+Xpm [PC Speaker] [/usr/local/share/xamixer/pixmaps/speaker.xpm]
--- /dev/null
+# XAmixer home file
+# Comments are preceded anywhere on the line by a '#'
+# All channel arguments (string & pixmap) must be enclosed in [ ] [ ]
+UseXpms
+#IgnoreXpms
+ScaleSize 115
+ChannelPadding 5
+Position -1 -1 # Both arguments must be set (and >= 0) to get positioning.
+ShowCardName
+#ShowMixerNumber
+#ShowMixerName
+#MuteLabel Mute
+#RecLabel Record
+RecLabel R
+#SimulLabel Lock
+#BackgroundXpm /usr/local/share/xamixer/pixmaps/test.xpm
+#BackgroundXpm /home/raistlin/xamixer/pixmaps/background5.xpm
+#BackgroundXpm /home/raistlin/xamixer/pixmaps/background.xpm
+#BackgroundXpm /tmp/background.xpm
+IconXpm /usr/local/share/xamixer/pixmaps/icon3.xpm
+#MuteXpm /usr/local/share/xamixer/pixmaps/mute3.xpm
+#unMuteXpm /usr/local/share/xamixer/pixmaps/unmute3.xpm
+MuteXpm /usr/local/share/xamixer/pixmaps/mute3.xpm
+unMuteXpm /usr/local/share/xamixer/pixmaps/unmute3.xpm
+#RecXpm /usr/local/share/xamixer/pixmaps/record.xpm
+#unRecXpm /usr/local/share/xamixer/pixmaps/unrecord.xpm
+RecXpm /usr/local/share/xamixer/pixmaps/rec.xpm
+unRecXpm /usr/local/share/xamixer/pixmaps/unrec.xpm
+#RecXpm /home/raistlin/xamixer/pixmaps/record.xpm
+#unRecXpm /home/raistlin/xamixer/pixmaps/unrecord.xpm
+SimulXpm /usr/local/share/xamixer/pixmaps/simul.xpm
+unSimulXpm /usr/local/share/xamixer/pixmaps/unsimul.xpm
+Label [Master] [Mstr]
+Label [Master M] [MstrM]
+Label [Line-In] [LineIn]
+Label [Record-Gain] [RGain]
+Label [PC Speaker] [Spkr]
+Label [Aux A] [AuxA]
+Label [In-Gain] [IGain]
+Label [Out-Gain] [OGain]
+Xpm [Master] [/usr/local/share/xamixer/pixmaps/master.xpm]
+Xpm [CD] [/usr/local/share/xamixer/pixmaps/cd.xpm]
+Xpm [MIC] [/usr/local/share/xamixer/pixmaps/mic.xpm]
+Xpm [PCM] [/usr/local/share/xamixer/pixmaps/pcm.xpm]
+Xpm [Synth] [/usr/local/share/xamixer/pixmaps/synth.xpm]
+Xpm [Line-In] [/usr/local/share/xamixer/pixmaps/line-in.xpm]
+Xpm [PC Speaker] [/usr/local/share/xamixer/pixmaps/speaker.xpm]
--- /dev/null
+/*****************************************************************************
+ xamixer.c - an Alsa based gtk mixer
+ Written by Raistlinn (lansdoct@cs.alfred.edu)
+ Copyright (C) 1998 by Christopher Lansdown
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+******************************************************************************/
+
+/*****************************************************************************/
+/* Begin #include's */
+
+#include "main.h"
+
+/* End #include's */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin Global Variables */
+
+GtkWidget *window;
+Card *card; /* And array of the cards */
+int cards; /* The number of cards in the system. */
+extern Config config; /* The system config */
+
+/* End Global Variables */
+/*****************************************************************************/
+
+int main(int argc, char **argv)
+{
+
+ /* Begin Variable Declarations */
+ GtkWidget *mainbox;
+ GtkWidget *notebook;
+ GtkWidget *frame;
+ GtkWidget *label;
+ GtkWidget *table;
+ GtkWidget *switch_button;
+ GtkWidget *tmpbox;
+ GtkWidget *tablebox;
+ GtkWidget *separator;
+ int i,j,k,xpm,found,fd;
+ char title[32];
+ char name[128];
+ ChannelLabel *tmp;
+ char labelname[256];
+ char *home_env, *home_dir;
+ GtkStyle *style;
+ GtkWidget *hbox;
+ /* End Variable Declarations */
+
+ /* Go through gtk initialization */
+ gtk_init(&argc, &argv);
+
+ /* Read the personal config file - these values override the global config */
+ home_env = getenv("HOME");
+ home_dir = calloc((strlen(home_env) + 2 + strlen(RCFILE)), 1);
+ strcpy(home_dir, home_env);
+ strcat(home_dir, "/");
+ strcat(home_dir, RCFILE);
+ gtk_rc_parse(home_dir);
+ free(home_dir);
+
+ /* Read in the soundcard info */
+ if(init_cards()) {
+ printf("Error. Unable to initialize sound cards.\n");
+ return 1;
+ }
+
+ /* Read in normal config info */
+ config_init();
+ config_read("/usr/local/etc/xamixer.conf");
+ home_env = getenv("HOME");
+ home_dir = calloc((strlen(home_env) + 2 + strlen(HOME_FILE)), 1);
+ strcpy(home_dir, home_env);
+ strcat(home_dir, "/");
+ strcat(home_dir, HOME_FILE);
+ config_read(home_dir);
+ free(home_dir);
+
+ /* Make the title */
+ sprintf(title, "XAmixer2 %s", VERSION);
+
+ /* Create the main window */
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(window), title);
+ gtk_signal_connect(GTK_OBJECT (window), "delete_event",
+ (GtkSignalFunc) gtk_main_quit, NULL);
+ signal(SIGINT, (void *)gtk_main_quit);
+ /* Set the policy */
+ gtk_window_set_policy(GTK_WINDOW (window), TRUE, TRUE, TRUE);
+ /* Set the position, if one has been defined */
+ gtk_widget_set_uposition(window, config.x_pos, config.y_pos);
+ /* Realize the window so that we can start drawing pixmaps to it */
+ gtk_widget_realize(window);
+
+ /* Set up the pixmaps */
+ setup_pixmaps(window);
+
+
+ /* Create the notebook */
+ notebook = gtk_notebook_new();
+ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
+
+ gtk_widget_show(notebook);
+ gtk_container_add(GTK_CONTAINER(window), notebook);
+
+
+ /* Create the notebook pages */
+ for(i = 0; i < cards; i++) {
+ for(j = 0; j < card[i].hw_info.mixerdevs; j++) {
+
+ frame = create_mixer_page(i, j);
+
+
+
+
+ /* Create the label and add the page to the notebook */
+ bzero(labelname, 256);
+ if(config.flags & CONFIG_SHOW_CARD_NAME) {
+ strcpy(labelname, card[i].hw_info.name);
+ if(config.flags & (CONFIG_SHOW_MIXER_NAME |
+ CONFIG_SHOW_MIXER_NUMBER))
+ strcat(labelname, ", ");
+ }
+
+ if(config.flags & CONFIG_SHOW_MIXER_NUMBER) {
+ /* Do some trickery to get around an additional
+ variable, plus this may be more efficient,
+ since strcat() has to figure out where the end
+ of the line is anyhow, plus the copying. */
+ sprintf(&labelname[strlen(labelname)], "Mixer %i", j);
+ if(config.flags & CONFIG_SHOW_MIXER_NAME)
+ strcat(labelname, ", ");
+ }
+
+ if(config.flags & CONFIG_SHOW_MIXER_NAME)
+ strcat(labelname, card[i].mixer[j].info.name);
+
+ /* Just in case nothing is specified in the config file */
+ if(!(config.flags & (CONFIG_SHOW_CARD_NAME |
+ CONFIG_SHOW_MIXER_NAME |
+ CONFIG_SHOW_MIXER_NUMBER)))
+ sprintf(labelname, "%i", i + j);
+
+ label = gtk_label_new(labelname);
+ gtk_widget_show(label);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
+
+
+ }
+ }
+
+ /* Create the options page */
+ frame = gtk_frame_new("");
+ gtk_widget_show(frame);
+ // gtk_container_add(GTK_CONTAINER (frame), create_options_page());
+ label = gtk_label_new("Options");
+ gtk_widget_show(label);
+ gtk_notebook_append_page(GTK_NOTEBOOK (notebook), frame, label);
+
+
+ /* Set up the icon, if one has been defined. */
+ if(config.flags & CONFIG_ICON_XPM && config.icon_xpm)
+ gdk_window_set_icon(window->window, NULL,
+ config.icon_xpm, config.icon_mask);
+
+
+ /* Show the whole kit and kaboodle */
+ gtk_widget_show(window);
+
+ /* And go into the gtk loop - why does this feel like the first
+ plunge in a roller coaster after the big hill at the beginning? */
+ gtk_main();
+
+ return 0;
+}
--- /dev/null
+/*****************************************************************************/
+/* Begin #include statements */
+
+/* End #include statements */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/* Begin function prototypes */
+
+
+/* End function prototypes */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* Begin #define statements */
+
+#define RCFILE ".xamixerrc"
+
+/* End #define statements */
+/*****************************************************************************/
+
+
+